• Code-server에 Nginx 구성 후 SSL(Let’s Encrypt 무료)인증서를 적용해봅니다. (Update: Mar 13, 2021)

환경 구성

1. Install certbot-nginx

; dns-01 방식으로 진행합니다. (도메인은 변경없이, server ip와 sub-domain은 변경 가능)
; 공인ip를 요구하는 http-01 방식도 가능하지만 언제든 다른 곳, ip로 변경할 수 있도록 보류

USER1@ ~]$ sudo yum install -y certbot python3-certbot-nginx
USER1@ ~]$ sudo certbot -d vm2.mydomain.com --manual --preferred-challenges dns certonly
 (...생략...)
Plugins selected: Authenticator manual, Installer None
Enter email address (used for urgent renewal and security notices)
 (Enter 'c' to cancel): {myEmail}@hotmail.com
 (...생략...)
agree in order to register with the ACME server. Do you agree?
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(Y)es/(N)o: y

;news, campains…? No.

 (...생략...)
develops Certbot? We'd like to send you email about our work encrypting the web,
EFF news, campaigns, and ways to support digital freedom.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(Y)es/(N)o: n
Account registered.
Requesting a certificate for vm2.mydomain.com
Performing the following challenges:
dns-01 challenge for vm2.mydomain.com

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Please deploy a DNS TXT record under the name
_acme-challenge.vm2.mydomain.com with the following value:

-FzP4bCvVVXm1p9TTB7v8FCc80TejN83FhKTuIOnQwQ

Before continuing, verify the record is deployed.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Press Enter to Continue

; 여기에서는 위의 도메인 TXT 레코드 등록과 nslookup 확인 후 진행합니다.
; 개인 도메인을 등록해 사용중인 cloudflare DNS 서비스에 등록했습니다.

;TXT 레코드 등록 확인

USER1@ ~]$ dig -t txt _acme-challenge.vm2.mydomain.com

; <<>> DiG 9.10.6 <<>> -t txt _acme-challenge.vm2.mydomain.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 35168
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

(...생략...)

;; ANSWER SECTION:
_acme-challenge.vm2.mydomain.com. 286 IN TXT	"-FzP4bCvVVXm1p9TTB7v8FCc80TejN83FhKTuIOnQwQ"

(...생략...)

;nslookup 확인 후, {Enter키 입력} 다시 진행합니다.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Please deploy a DNS TXT record under the name
_acme-challenge.vm2.mydomain.com with the following value:

-FzP4bCvVVXm1p9TTB7v8FCc80TejN83FhKTuIOnQwQ

Before continuing, verify the record is deployed.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Press Enter to Continue
Waiting for verification...
Cleaning up challenges

IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at:
   /etc/letsencrypt/live/vm2.mydomain.com/fullchain.pem
   Your key file has been saved at:
   /etc/letsencrypt/live/vm2.mydomain.com/privkey.pem
   Your certificate will expire on 2021-06-11. To obtain a new or
   tweaked version of this certificate in the future, simply run
   certbot again. To non-interactively renew *all* of your
   certificates, run "certbot renew"

2. Nginx 인증서 적용

; 정상 완료되면 /etc/nginx/sites-enabled/code-server.conf 파일에 인증서 설정이 수정되어 있습니다.
; 다른 글의 Ubuntu 인증서 적용 과정에서의 http to https 리디렉션 설정이 생략되어 추가로 넣었습니다.
; Liten {http port} 를 삭제하거나 주석처리합니다.

[변경 후]
upstream vm2-code-server {
     server 127.0.0.1:8080;
}

server {
     #listen 7788;
     #listen [::]:7788;
     server_name vm2.mydomain.com;

     location / {
             proxy_pass http://vm2-code-server;
             proxy_set_header Host $host;
             proxy_set_header Upgrade $http_upgrade;
             proxy_set_header Connection upgrade;
             proxy_set_header Accept-Encoding gzip;
             auth_basic "Authentication Page";
             auth_basic_user_file /etc/nginx/.htpasswd;
             proxy_buffering off;
     }

 listen [::]:443 ssl ipv6only=on; # managed by Certbot
 listen 443 ssl; # managed by Certbot
 ssl_certificate /etc/letsencrypt/live/vm2.mydomain.com/fullchain.pem; # managed by Certbot
 ssl_certificate_key /etc/letsencrypt/live/vm2.mydomain.com/privkey.pem; # managed by Certbot
 include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
 ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot

}

; (Ubuntu 설정 과정에는 자동 추가되는) http → https redirection 설정을 원한다면 추가해줍니다.

server {
 if ($host = vm2.mydomain.com) {
     return 301 https://$host$request_uri;
 }

     listen 80 ;
     listen [::]:80 ;
 server_name vm2.mydomain.com;
 return 404;
}

;설정 완료된 파일

upstream vm2-code-server {
     server 127.0.0.1:8080;
}

server {
        #listen 7788;
        #listen [::]:7788;
        server_name vm2.mydomain.com;

        location / {
                proxy_pass http://vm2-code-server;
                proxy_set_header Host $host;
                proxy_set_header Upgrade $http_upgrade;
                proxy_set_header Connection upgrade;
                proxy_set_header Accept-Encoding gzip;
                auth_basic "Authentication Page";
                auth_basic_user_file /etc/nginx/.htpasswd;
                proxy_buffering off;
        }

    listen [::]:443 ssl ipv6only=on; # managed by Certbot
    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/vm2.mydomain.com/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/vm2.mydomain.com/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot

}

# Redirection http to https
server {
    if ($host = vm2.mydomain.com) {
        return 301 https://$host$request_uri;
    }

        listen 80 ;
        listen [::]:80 ;
    server_name vm2.mydomain.com;
    return 404;
}
USER1@ ~]$ sudo systemctl restart nginx.service

3. 인증서 자동 갱신

;root권한 cronjob으로 만료 2주전에 갱신되도록 설정합니다.

USER1@ ~]$ touch RenewCert.sh; chmod 700 RenewCert.sh

USER1@ ~]$ vi RenewCert.sh
#!/bin/bash
VALID=($(certbot certificates | grep VALID))
VALID_DATE=$(expr ${VALID[5]})
#인증서 갱신시 dns 레코드를 수정해야되어 webroot 인증으로 자동 갱신 변경
#if [ $VALID_DATE -lt 15 ]; then 
#	echo "\r" | certbot --text --agree-tos -d vm2.mydomain.com --manual --preferred-challenges dns --expand --renew-by-default --manual-public-ip-logging-ok certonly --post-hook "systemctl restart nginx.service"
#fi

if [ $VALID_DATE -lt 15 ]; then
     echo "\r" | /bin/letsencrypt certonly --webroot --webroot-path /usr/share/nginx/html/ --agree-tos -d vm2.mydomain.com --renew-by-default --post-hook "/usr/bin/systemctl restart nginx.service"
fi

[USER1@vm2 cronjobs]$ sudo vi /etc/crontab
55 13   * * *   root    /bin/sh /home/USER1/RenewCert.sh > /dev/null 2>&1

참고 글

;Centos에서 code-server, nignx proxy, certbot 을 구성하며 몰랐던 부분도 많이 배웠네요. 먼저 진행하며 공유해주신 분들께 감사드립니다.