HTTPS 지원 Reverse Proxy 서버 구축

SummerToday·2024년 5월 15일

도커, 서버 기술

목록 보기
32/34
post-thumbnail

docker-compose.yml

version: "3"

services:
  webserver:
    image: nginx:latest
    container_name: proxy
    restart: always
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./myweb:/usr/share/nginx/html
      - ./nginx/nginx.conf:/etc/nginx/nginx.conf
      - ./certbot-etc:/etc/letsencrypt

  nginx:
    image: nginx:latest
    container_name: myweb
    restart: always
    volumes:
      - ./myweb:/usr/share/nginx/html

  certbot:
    depends_on:
      - webserver
    image: certbot/certbot
    container_name: certbot
    volumes:
      - ./certbot-etc:/etc/letsencrypt
      - ./myweb:/usr/share/nginx/html
    command: certonly --webroot --webroot-path=/usr/share/nginx/html --email kom347@naver.com --agree-tos --no-eff-email --keep-until-expiring -d inkyung.site -d www.inkyung.site
  • 해당 글 전에서 작성했던 docker-compose.yml 파일에서 --dry-run 옵션을 제외하여 작성하였다.

nginx.conf (HTTPS 미지원)

user nginx;
worker_processes  auto;

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;

events {
    worker_connections 1024;
}

http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" "$request_uri" "$uri"'
                      '"$http_user_agent" "$http_x_forwarded_for"';
    access_log  /var/log/nginx/access.log  main;
    sendfile on;
    keepalive_timeout 65;

    upstream docker-web {
        server nginx:80;
    }

    server {
        location ~ /.well-known/acme-challenge {
                allow all;
                root /usr/share/nginx/html;
                try_files $uri =404;
        }

        location / {
                allow all;
                root /usr/share/nginx/html;
                try_files $uri =404;
        }
    }
}
  • 직전 글에서 작성했던 nginx.conf와 동일하게 작성하였다.

Docker Compose 실행 / 인증서 발급 확인

  1. 도커 컴포즈를 백그라운드로 실행 한다.

    docker-compose up -d

  2. certbot 컨테이너의 로그를 확인하여 인증서가 성공적으로 발급되었는지 확인한다.

    docker logs certbot

    위 문구가 나왔다면 성공적으로 인증서가 발급되었다는 것이다.

    하지만 인증서 확인을 위해 cd live 명령어를 입력해도 권한 오류가 발생한다.
    따라서 인증서를 확인해보고 싶다면 설정된 루트 패스워드를 통해 접근을 해야하지만, 루트 패스워드를 설정하지 않은 경우에는 따로 sudo passwd 명령어를 통해 EC2 루트 사용자 패스워드를 설정해준다.

    su -

    패스워드 설정 후 위 명령어를 통해 루트 사용자로 접속해준다.
    따라서 루트 사용자로 접속 후 위에 명시된 인증서가 발급된 경로로 들어가 인증서들을 확인할 수 있게된다.

    su - ubuntu

    인증서 확인 후 위 명령어를 통해 다시 자신의 아이디로 돌아올 수 있다.


nginx.conf 파일 교체

mv nginx.conf nginx.conf.init

mv nginx.conf.https nginx.conf

HTTPS를 지원하기 위해 기존 nginx.conf 파일을 nginx.conf.https 파일로 대체한다.


nginx.conf (HTTPS 지원)

user nginx;
worker_processes  auto;

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;

events {
    worker_connections 1024;
}

http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" "$request_uri" "$uri"'
                      '"$http_user_agent" "$http_x_forwarded_for"';
    access_log  /var/log/nginx/access.log  main;
    sendfile on;
    keepalive_timeout 65;

    upstream docker-web {
        server nginx:80;
    }

    server {
        listen 80;
        server_name inkyung.site www.inkyung.site;

        location ~ /.well-known/acme-challenge {
                allow all;
                root /usr/share/nginx/html;
                try_files $uri =404;
        }

        location / {
                return 301 https://$host$request_uri;
        }
    }

    server {
        listen 443 ssl;
        server_name inkyung.site www.inkyung.site;

        ssl_certificate /etc/letsencrypt/live/inkyung.site/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/inkyung.site/privkey.pem;
        include /etc/letsencrypt/options-ssl-nginx.conf; # 보안 강화를 위한 옵션 추가
        ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;   # 보안 강화를 위한 옵션 추가

        location / {
            proxy_pass         http://docker-web;       # docker-web 컨테이너로 포워딩
            proxy_redirect     off;                     # 서버 응답 헤더의 주소 변경 (불필요)
            proxy_set_header   Host $host;
            proxy_set_header   X-Real-IP $remote_addr;
            proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header   X-Forwarded-Host $server_name;
            proxy_set_header   X-Forwarded-Proto $scheme;
        }
    }
}
  • listen 80, location / {return 301 https://$host$request_uri;}
    80 포트로 들어오는 HTTP 요청을 모두 HTTPS(443)으로 변환시킨다.

    301: 영구적인 리디렉션. 사이트 주소를 변경하거나 새로운 페이지로 영구적으로 이동하는 경우에 사용. (HTTP 요청을 HTTPS로 리디렉션할 때 많이 사용된다.)

    302: 임시적인 리디렉션. 주로 리다이렉션을 사용하여 요청을 다른 서버로 전달하거나, 일시적으로 특정 페이지를 다른 곳으로 이동시킬 때 사용.

    $host 및 $request_uri는 Nginx에서 사용되는 변수이다.

    • $host
      해당 변수는 현재 요청된 호스트의 이름을 나타낸다. 즉, HTTP 요청의 호스트 헤더에 있는 값을 가져온다. 해당 변수는 사용자가 요청한 호스트의 도메인 이름을 나타내며, "www.example.com"과 같은 형식을 갖는다.

    • $request_uri
      해당 변수는 현재 요청된 URI(Uniform Resource Identifier)를 나타낸다. URI는 요청된 리소스의 위치를 식별하는 데 사용되며, 쿼리 매개변수 및 기타 요청 정보를 포함하며, "/page1.html?param=value"와 같은 형식을 갖습니다.

      따라서 $host, $request_uri를 함께 사용하면 현재 요청된 호스트와 URI를 조합하여 완전한 요청된 URL을 생성할 수 있게되고, 리디렉션이나 요청을 다른 위치로 전달할 때 사용된다.

Docker Compose 재실행 / 인증서 확인

HTTPS를 지원하도록 nginx.conf 파일을 수정한 후 Docker Compose를 재실행한다.

cf. 재실행 전 아래 명령어들을 통해 이전에 생성했던 컨테이너, 이미지, 볼륨 등을 삭제한 후 재실행한다.

#모든 컨테이너 삭제
docker stop $(docker ps -a -q)
docker rm $(docker ps -a -q)
docker rmi -f $(docker images -q)

#쓰지 않는 볼륨 삭제
docker volume prune

#쓰지 않는 이미지, 볼륨, 네트워크 삭제
docker system prune -a --volumes

  1. 도커 컴포즈를 백그라운드로 실행 한다.

    docker-compose up -d

  2. certbot 컨테이너의 로그를 확인하여 인증서를 확인한다.

    docker logs certbot

    --keep-until-expiring 옵션으로 인해 발급 받은 인증서가 아직 만료가 되지 않아 갱신을 하지 않음을 의미하는 문구가 위와 같이 표시가 된다.


테스트

inkyung.site에 들어가 https로 정상 작동하는지 확인한다.

https://inkyung.site

myweb 컨테이너의 index.html이란 테스트 파일이 화면에 보여지므로 정상 작동하는 것을 확인할 수 있다.




해당 글은 다음 강의의 내용을 참고한 글임을 밝힙니다. 자세한 내용은 다음 강의에서 확인해볼 수 있습니다.
인프런, 잔재미 코딩, ⌜풀스택을 위한 도커와 최신 서버 기술(리눅스, nginx, AWS, HTTPS, flask 배포) [풀스택 Part3]⌟
profile
블로그 이관했습니다.

0개의 댓글