배포를 해보자 AWS, nginx, HTTPS 그리고 Spring #1

우테코 레벨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...]

 

 

  • 위의 명령어를 실행 후 유효한 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/

 

docker run 커맨드 사용법

Engineering Blog by Dale Seo

www.daleseo.com

 

추후 참고해볼것

 

https://kensei.co.kr/974

 

certbot 명령어 (let's encrypt)

인증서 갱신하기 certbot renew 인증서 갱신 관련 방화벽 설정 인바운드 tcp 80번 북미 해외쪽 접근 허용 필요 현재 셋팅되어 있는 인증서 목록 보기 certbot certificates 인증서 삭제하기 (설정까지 삭제)

kensei.co.kr

 

댓글



Designed by JB FACTORY