배포를 해보자 AWS, nginx, HTTPS 그리고 Spring #1
- 우아한테크코스
- 2021. 6. 10. 16:42
우테코 레벨2 마지막 미션은 프론트엔드 크루들과 함께 미션을 진행하는 '협업 미션'이 주어졌다. 프론트엔드 크루들이 우리가 만든 서버를 사용할 수 있도록 배포를 해야 했다. 이번 포스팅에서는 협업미션을 하면서 AWS, nginx, HTTPS를 적용하여 개발환경을 구축한 것을 정리해 보려고 한다.
서버 생성
- 서버로 사용 할 EC2를 만든다.
- EC2는 AWS로 부터 컴퓨터 한대를 임대해서 사용 할 수 있는 서비스
- EC2를 생성했다면 EC2서버에 접속해서 환경을 꾸린다.
EC2에 도커 설치
$ sudo apt-get update && \
sudo apt-get install -y apt-transport-https ca-certificates curl software-properties-common && \
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add - && \
sudo apt-key fingerprint 0EBFCD88 && \
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" && \
sudo apt-get update && \
sudo apt-get install -y docker-ce && \
sudo usermod -aG docker ubuntu && \
sudo curl -L "https://github.com/docker/compose/releases/download/1.23.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose && \
sudo chmod +x /usr/local/bin/docker-compose && \
sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose
Reverse Proxy
- 우리의 웹 애플리케이션 앞단에 Reverse Proxy를 구성 할 것이다.
- 외부망에 Nginx로 Reverse Porxy를 구성
Proxy Server란
- 클라이언트가 자신을 통해, 다른 네트워크 서비스에 접속하게 해줄 수 있는 서버를 의미
Foward Porxy
- 클라이언트가 외부 인터넷에 직접 접근하는 것이 아니라, 클라이언트가 Proxy Server에 외부 인터넷 접근 요청을하고, Proxy Server가 외부 인터넷에 대신 요청을 하여 결과를 받은 후 클라이언트에 전달
Reverse Proxy
- 클라이언트가 Reverse Proxy에 요청하면 Reverse Proxy가 관련 요청에 따라, 적절한 내부 서버에 요청을 전달 하고 응답을 받은 후 클라이언트에게 전달
- 내부 데이터베이스 등 직접 접속을 허용하지 않을 수 있으므로 보안에도 유익함
- 요청 트래픽을 관리할 수 있는 로드 밸런싱 등에도 유리함
Forward Porxy는 서버로 부터 클라이언트를 숨기고, Reverse Proxy는 클라이언트로 부터 서버를 숨긴다.
Nginx 도커 이미지 만들기
- nginx설치를 위한 Dockfile를 만든다.
- nginx.conf는 도커 외부에서 만들어 전달 해 준다.
FROM nginx
COPY nginx.conf /etc/nginx/nginx.conf
- 위의 Dockfile에서는 같은 경로의 nginx.conf를 도커의 /etc/nginx/nginx.conf에 복사한다.
events {}
http {
upstream app {
server 127.0.0.1:8080;
}
server {
# 80으로 요청이 오면 localhost 의 8080포트로 연결해준다는 의미예요.
listen 80;
location / {
proxy_pass http://app;
}
}
}
- 80번 포트로 요청이 들어오면 모든 요청을 http://app으로 proxy_pass 한다.
- http://app은 127.0.0.1:8080을 의미한다.
upstream app {
server 127.0.0.1:8080;
}
- 즉, nginx의 proxy_pass를 통해 80포트의 요청을 8080포트의 웹 애플리케이션에 전달하는 Reverse Porxy서버를 구축한 것이다.
nginx 도커 이미지 실행하기
- 위에서 정의한 Dockfile로 도커이미지를 만들고 실행한다.
- 도커 이미지 이름은 저장소/이미지이름:태그로 설정한다.
$ docker build -t nextstep/reverse-proxy:0.0.1 .
$ docker run -d -p 80:80 --name proxy nextstep/reverse-proxy:0.0.1
- 여기까지 완료 했다면 docker ps 명령어로 실행중인 컨테이너를 확인 해 본다.
TLS 설정
- Reverse Proxy에 TLS 설정
HTTPS
- 도메인이 있어야 한다.
- 도메인에 맞는 인증서를 발급을 받아야 한다.
사전준비
- AWS EC2의 고정 IP로 도메인을 발급받는다.
letsencrypt
- letsencrpt를 통해 무료로 TLS 인증서를 발급 받을 수 있다.
$ docker run -it --rm --name certbot \
-v '/etc/letsencrypt:/etc/letsencrypt' \
-v '/var/lib/letsencrypt:/var/lib/letsencrypt' \
certbot/certbot certonly -d 'yourdomain.com' --manual --preferred-challenges dns --server https://acme-v02.api.letsencrypt.org/directory
- 와 돜린이 한테 너무나 어려운 명령어였다.
- 우선 docker run 명령어의 구조를 살펴보자
docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
- OPTIONS
- -it
- --rm
- --name certbot
- -v '/etc/letsencrypt:/etc/letsencrypt'
- -v '/var/lib/letsencrypt:/var/lib/letsencrypt'
- IMAGE
- certbot/certbot
- dockerhub에서 찾으니 진짜 레포이름이 certbot/certbot이다...
- certbot/certbot
- COMMAND
- certonly -d 'yourdomain.com' --manual --preferred-challenges dns --server https://acme-v02.api.letsencrypt.org/directory
- 위의 명령어를 실행 후 유효한 URL 인지 확인을 위해 DNS 서비스에 추가한다.
- 위 실습의 경우엔 내도메인 한국
- 그리고 진행을 하면 /etc/letsencrypt/live/[도메인주소]에 pem키가 생성된 것을 볼 수 있다.
Nginx TLS 설정
certbot 도커 컨테이너 실행 시 옵션을 아래와 같이 주었다. 그래서 호스트에도 저 경로에 pem키들이 있을 것이다.
- -v '/etc/letsencrypt:/etc/letsencrypt'
- -v '/var/lib/letsencrypt:/var/lib/letsencrypt'
- pem키들을 nginx.conf와 같은 경로로 복사 해오자.
$ cp /etc/letsencrypt/live/[도메인주소]/fullchain.pem ./
$ cp /etc/letsencrypt/live/[도메인주소]/privkey.pem ./
- Dockfile을 아래와 같이 수정 한다.
FROM nginx
COPY nginx.conf /etc/nginx/nginx.conf
COPY fullchain.pem /etc/letsencrypt/live/[도메인주소]/fullchain.pem
COPY privkey.pem /etc/letsencrypt/live/[도메인주소]/privkey.pem
- nginx.conf 파일을 아래와 같이 수정한다.
events {}
http {
upstream app {
server 172.17.0.1:8080;
}
# Redirect all traffic to HTTPS
server {
listen 80;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
ssl_certificate /etc/letsencrypt/live/[도메인주소]/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/[도메인주소]/privkey.pem;
# Disable SSL
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
# 통신과정에서 사용할 암호화 알고리즘
ssl_prefer_server_ciphers on;
ssl_ciphers ECDH+AESGCM:ECDH+AES256:ECDH+AES128:DH+3DES:!ADH:!AECDH:!MD5;
# Enable HSTS
# client의 browser에게 http로 어떠한 것도 load 하지 말라고 규제합니다.
# 이를 통해 http에서 https로 redirect 되는 request를 minimize 할 수 있습니다.
add_header Strict-Transport-Security "max-age=31536000" always;
# SSL sessions
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
location / {
proxy_pass http://app;
}
}
}
- TLS설정이 추가되었으므로 Nginx 도커 컨테이너를 중지 & 삭제하고 새로운 설정을 반영하여 다시 띄운다.
$ docker stop proxy && docker rm proxy
$ docker build -t nextstep/reverse-proxy:0.0.2 .
$ docker run -d -p 80:80 -p 443:443 --name proxy nextstep/reverse-proxy:0.0.2
스프링 설정 파일 나누기는 다음 포스팅에...
참고
https://www.daleseo.com/docker-run/
추후 참고해볼것
'우아한테크코스' 카테고리의 다른 글
SpringBoot Security 없이 Oauth2.0 로그인 Naver편 (8) | 2021.07.06 |
---|---|
SpringBoot Security 없이 Oauth2.0 로그인 Kakao편 (0) | 2021.07.05 |
자동차 경주 피드백 (0) | 2021.06.09 |
도커는 너무 어려워요 (1) | 2021.05.31 |
네트워크는 너무 어려워요 (2) | 2021.05.01 |