728x90
반응형

이번 포스트에서는 Dockerfile의 환경 ( dev or prod )에 따라 Nginx를 다르게 빌드하는 법을 알아보겠다.

 

1. dev.default.conf 생성

upstream client{
  server client:3000;
}

upstream server{
  server server:8080;
}

server {
    listen       80;
    listen  [::]:80;
    server_name  localhost;

    #access_log  /var/log/nginx/host.access.log  main;
    location /api {
        proxy_pass http://server;
        proxy_redirect off;
        rewrite ^/api/(.*)$ /$1 break;
    }

    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
        proxy_pass http://client;
    }

    #error_page  404              /404.html;

    # redirect server error pages to the static page /50x.html
    #
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }
}

 

2,  prod.default.conf 생성

upstream client{
  server client:3000;
}

upstream server{
  server server:8080;
}

server {
    listen       80;
    listen  [::]:80;
    server_name  [도메인이름];

    location ^~ /.well-known/acme-challenge/ {
      default_type "text/plain";
      root /var/www/certbot;
    }

    location / {
        return 301 https://[도메인이름]$request_uri;
    }
}

server {

        listen 443 ssl default_server;
        listen [::]:443 ssl default_server;
        server_name  [도메인이름];

        ssl_certificate /etc/nginx/ssl/live/[도메인이름]/fullchain.pem;
        ssl_certificate_key /etc/nginx/ssl/live/[도메인이름]/privkey.pem;

        #access_log  /var/log/nginx/host.access.log  main;
        location /api {
            proxy_pass http://server;
            proxy_redirect off;
            rewrite ^/api/(.*)$ /$1 break;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection 'upgrade';
            proxy_set_header Host $host;
        }

        location / {
            proxy_pass http://client;
            root   /usr/share/nginx/html;
            index  index.html index.htm;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection 'upgrade';
            proxy_set_header Host $host;
        }

        #error_page  404              /404.html;

        # redirect server error pages to the static page /50x.html
        #
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   /usr/share/nginx/html;
        }

        #allow deny ip
        #allow 12.0.0.0;
        #deny all;
}

 

3. .env 변수 추가

# Build 환경 변수 설정
BUILD_ENV=dev

 

4. docker compose 파일 수정

services:
  nginx:
    build:
      context: ./docker/nginx
      args:
        BUILD_ENV: ${BUILD_ENV} // 이 부분 추가
    ports:
      - "80:80"
      - "443:443"
    restart: always
    environment:
      TZ: Asia/Seoul
      BUILD_ENV: ${BUILD_ENV}
    volumes:
      - ${CERTBOT_WWW_DIR}:/var/www/certbot/:ro
      - ${CERTBOT_CONF_DIR}:/etc/nginx/ssl/:ro
    depends_on:
      - client
      - server

 

5. Dockerfile 수정

FROM nginx:latest

ARG BUILD_ENV=BUILD_ENV

COPY ./$BUILD_ENV.default.conf /etc/nginx/conf.d/default.conf

CMD ["nginx", "-g", "daemon off;"]
728x90
반응형
728x90
반응형

이전 포스트와 다르게 Docker를 활용한 SSL 인증을 구현해보았다. Cerbot 컨테이너를 만들고, docker compose 명령어를 통해 동작

1. /docker/nginx/default.conf 생성

최초 certbot 인증 시에는 아래와 같이 기본 세팅으로 해야한다.

server {
    listen 80;
    listen [::]:80;

    server_name 도메인 이름;
    server_tokens off;

    location /.well-known/acme-challenge/ {
        root /var/www/certbot;
    }

}

 

2. /docker/nginx/ Dockerfile 생성

FROM nginx:latest
COPY ./default.conf /etc/nginx/conf.d/default.conf

CMD ["nginx", "-g", "daemon off;"]

 

3. docker-compose.yml 추가

services:
  nginx:
    build: ./docker/nginx
    ports:
      - "80:80"
      - "443:443"
    restart: always
    environment:
      TZ: Asia/Seoul
    volumes:
      - ${CERTBOT_WWW_DIR}:/var/www/certbot/:ro
      - ${CERTBOT_CONF_DIR}:/etc/nginx/ssl/:ro
    depends_on:
      - client
      - server

  certbot:
    image: certbot/certbot:latest
    volumes:
      - ${CERTBOT_WWW_DIR}:/var/www/certbot/:rw
      - ${CERTBOT_CONF_DIR}:/etc/letsencrypt/:rw
      
  client:
  	...
  server:
  	...

 

4. .env파일 작성

...

# CERTBOT
CERTBOT_WWW_DIR=/data/certbot/www
CERTBOT_CONF_DIR=/data/certbot/conf

5. Docker compose up

$ docker compose up -d

인증서 발급을 위해 Nginx 서버를 켜준다.

6. 인증서 발급

$ docker compose run --rm  certbot certonly --webroot --webroot-path /var/www/certbot/ -d 도메인이름

 

pem 키 위치 확인

 

7. default.conf 파일 수정

upstream client{
  server client:3000;
}

upstream server{
  server server:8080;
}

server {
    listen       80;
    listen  [::]:80;
    server_name  [도메인이름];

    location ^~ /.well-known/acme-challenge/ {
      default_type "text/plain";
      root /var/www/certbot;
    }

    location / {
        return 301 https://[도메인이름]$request_uri;
    }
}

server {

        listen 443 ssl default_server;
        listen [::]:443 ssl default_server;
        server_name  [도메인이름];

        ssl_certificate /etc/nginx/ssl/live/[도메인이름]/fullchain.pem;
        ssl_certificate_key /etc/nginx/ssl/live/[도메인이름]/privkey.pem;

        #access_log  /var/log/nginx/host.access.log  main;
        location /api {
            proxy_pass http://server;
            proxy_redirect off;
            rewrite ^/api/(.*)$ /$1 break;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection 'upgrade';
            proxy_set_header Host $host;
        }

        location / {
            proxy_pass http://client;
            root   /usr/share/nginx/html;
            index  index.html index.htm;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection 'upgrade';
            proxy_set_header Host $host;
        }

        #error_page  404              /404.html;

        # redirect server error pages to the static page /50x.html
        #
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   /usr/share/nginx/html;
        }

        #allow deny ip
        #allow 12.0.0.0;
        #deny all;
}

 

8. docker 재시작

$ docker compose up -d

Nginx Service에 restart:always 옵션이 존재하기 때문에 Nginx Service는 재시작된다.

 

9. 인증서 관련 명령어

 

- 인증서 확인

$ docker compose run --rm certbot certificates

 

- 인증서 갱신

$ docker compose run --rm certbot renew

 

10. 크론 탭 활용 (crontab)

- /bin/letsencrypt.sh 파일 작성

cd /home
date >> /home/certbot_renew.log
sudo docker compose run --rm certbot renew >> /home/certbot_renew.log
sudo docker compose restart nginx

 

- 실행 권한 부여

$ sudo chmod +x /bin/letsencrypt.sh

 

- 크론탭 열고 편집 

$ sudo crontab -e

 

- 아래 배치잡 생성

30 4 * * 0 /bin/letsencrypt.sh

 

- 저장 후 배치잡 확인

$ sudo crontab -l

 

-저장하고 크론 다시 실행

$ sudo service cron restart
728x90
반응형
728x90
반응형

Let's Encrypt로 받는 인증은 90일에 한 번씩 갱신을 해주어야 한다.

 

Let's Encrypt로 인증받는 방법은 4가지가 있다.

  1. webroot : 사이트 디렉토리 내에 인증서 유효성을 확인할 수 있는 파일을 업로드하여 인증서를 발급하는 방법
    . 실제 작동하고 있는 웹서버의 특정 데렉토리의 특정 파일 쓰기 작업을 통해서 인증
    . 이 방식의 장점은 nginx를 중단시킬 필요가 없음.
    . 이 방법의 단점은 인증 명령에 하나의 도메인 인증서만 발급 가능
  2. 웹서버
    . Nginx나 아파치와 같은 웹서버에서 직접 SSL 인증을 실시하고 웹서버에 맞는 SSL세팅값을 부여
    . 발급이나 갱신을 위해 웹서버를 중단시킬 필요가 없음
    . 인증서 갱신 시 상황에 맞게 세팅을 자동으로 업데이트
    . 사용자가 세팅을 변경할 수 있지만 자동 업데이트 시 반영되지는 않음
  3. Standalone : 사이트 작동을 멈추고 이 사이트의 네크워킹을 이용해 사이트 유효성을 확인해 Let’s Encrypt SSL 인증서를 발급하는 방식
    . 80포트로 가상 staandalone 웹서버를 띄워 인증서를 발급
    . 이 방식은 동시에 여러 도메인을 발급 받을 수 있음
    . 그렇지만 인증서 발급 전에 Nginx를 중단하고 발급 완료 후 다시 Nginx를 시작해야 함
  4. DNS : 도메인을 쿼리해 확인되는 TXT 레코드로 사이트 유효성을 확인하는 방법
    . 와일드 카드 방식으로 인증서를 발급 가능
    . 이 방법은 당연하게도 서버 관리자가 도메인 DNS를 관리/수정할 수 있어야 하며
    . 인증서 갱신 시마다 DNS에서 TXT값을 변경해야 하므로
    외부에서 TXT 레코드를 입력할 수 있도록 DNS가 API를 제공하는 경우만 갱신 과정을 자동으로 처리(클라우두플레어 API가 대표적인 사례)

여기서 설명할 방법은 webroot를 이용한 방법이다.

 

1. certbot ( letsencrypt ) 설치해준다

$ sudo apt-get install certbot

 

2. 폴더를 만들어준다. 

$ mkdir -p /var/www/letsencrypt/.well-known/acme-challenge

 

3. 아래 명령어로 파일을 만들고 내용을 추가해준다.

$ vi /etc/nginx/snippets/letsencrypt.conf

letsencrypt.conf

location ^~ /.well-known/acme-challenge/ {
default_type "text/plain";
root /var/www/letsencrypt;
}

4. nginx 를 설정해준다. 

https://typo.tistory.com/entry/nginx-%EC%84%A4%EC%B9%98-%EB%B0%8F-%EB%B0%A9%ED%99%94%EB%B2%BD-%EA%B5%AC%EC%84%B1

 

nginx 설치 및 방화벽 구성(http)

1. 먼저 업데이트를 실행 후 nginx를 설치해준다. $sudo apt update $sudo apt install nginx 2. 방화벽을 설정해준다. $sudo ufw allow 'Nginx Full' $sudo ufw status 3. 설정 파일을 확인해준다. $vi /etc/ngin..

typo.tistory.com

 

5. nginx 설정에 아래와 같이 include를 추가해준다.

server {
    listen 80 default_server;
    listen [::]:80 default_server ipv6only=on;
    server_name [도메인이름];

    include /etc/nginx/snippets/letsencrypt.conf;

    location / {
        return 301 https://[도메인이름]$request_uri;
        expires epoch;
        # return 301 아래에 expires epoch; 을 붙여주는 것은 301 리다이렉트가 캐싱되지 않도록 하기 위함
    }

}

 

6. 서버를 킨 상태에서 인증서를 발급한다.

$ certbot certonly --webroot --webroot-path=/var/www/letsencrypt  -d 사이트명

 

결과화면

 

7. 위 사진을 보고  pem의 위치를 알아두고 nginx 설정파일에 다음과 같이 추가해준다.

server {
        listen 80 default_server;
        listen [::]:80 default_server;

        server_name [도메인이름];

        location / {
                proxy_pass http://localhost:3000;
                proxy_http_version 1.1;
                proxy_set_header Upgrade $http_upgrade;
                proxy_set_header Connection 'upgrade';
                proxy_set_header Host $host;
                proxy_cache_bypass $http_upgrade;
                return 301 https://[도메인이름]$request_uri;
                expires epoch;
                # return 301 아래에 expires epoch; 을 붙여주는 것은 301 리다이렉트가 캐싱되지 않도록 하기 위함
        }

}

server {

        listen 443 ssl default_server;
        listen [::]:443 ssl default_server;
        server_name [도메인이름];

        include /etc/nginx/snippets/letsencrypt.conf;

        ssl_certificate /etc/letsencrypt/live/[도메인이름]/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/[도메인이름]/privkey.pem;
        ssl_session_cache shared:SSL:1m;
        ssl_session_timeout 1440m;
        ssl_buffer_size 8k;
        ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
        ssl_prefer_server_ciphers on;
        ssl_stapling on;
        ssl_stapling_verify on;

        access_log  /var/log/nginx/web.access.log;
        error_log /var/log/nginx/web.error.log;

        location / {
                proxy_pass http://localhost:3000;
                proxy_http_version 1.1;
                proxy_set_header Upgrade $http_upgrade;
                proxy_set_header Connection 'upgrade';
                proxy_set_header Host $host;
                proxy_cache_bypass $http_upgrade;
        }
}

 

도메인이 여러개일 경우 server를 여러개 만들어준다.

8. nginx 를 재시동 하고 서버를 켜보면 !!

$ sudo systemctl restart nginx

 

 

자물쇠가 잘 생긴 것을 볼 수 있다.

 

이외의 명령어들

 

- 인증서 남은 기간 확인

$ certbot certificates

 

- 제대로 갱신이 되는지 확인

$ certbot renew --dry-run

 

- 자동 갱신 명령어 입력

$ certbot renew

 

- 크론탭을 이용한 예약 명령어

$ vi /etc/crontab
0 0 1 * * /usr/bin/certbot renew --renew-hook="서비스재시작명령어"
728x90
반응형

+ Recent posts