Linux

CentOS8 Nginx SSL 인증서 적용하기

Jack Moon 2020. 7. 21. 16:26

원래 SSL 인증서는 인증된 기관( CA )으로부터 발급 받아야 하는데, Let's Encrypt을 이용하면 무료로 인증서를 발급 받을 수 있다. 단, 90일 동안만 인증서가 유효하므로 서버에서 cron을 이용하여 주기적으로 인증서를 갱신해야 한다.

 

Step 1 – 필요한 프로그램을 설치

# yum install git bc wget curl socat

Step 2 – Let's Encrypt를 적용할 라이브러리인 acme.sh를 설치

# cd /tmp/
# git clone https://github.com/Neilpang/acme.sh.git
# cd acme.sh/
# ./acme.sh --install

터미널을 닫고 다시 엽니다

acme.sh 버전 확인

# acme.sh --version

Step 3 – nginx 기본설정

도메인: moon0sool.duckdns.org

# vi /etc/nginx/conf.d/moon0sool.duckdns.org.conf
# http port 80
server {
    listen      80;
    server_name moon0sool.duckdns.org;
    access_log  /var/log/nginx/http_moon0sool.duckdns.org_access.log;
    error_log   /var/log/nginx/http_moon0sool.duckdns.org_error.log;
    root        /usr/share/nginx/html;
}

설정파일 체크및 재시작

# nginx -t
# systemctl restart nginx.service

Step 4 – DH 파라미터 파일 생성

# mkdir -pv /etc/nginx/ssl/duckdns.org/
# cd /etc/nginx/ssl/duckdns.org/
# openssl dhparam -out dhparams.pem -dsaparam 4096

Step 5 – 도메인에 사용될 인증서 얻기

# acme.sh --issue -d moon0sool.duckdns.org -k 2048 --nginx

Step 6 – nginx ssl 설정

# vi /etc/nginx/conf.d/moon0sool.duckdns.org.conf
## http port 80: START http://moon0sool.duckdns.org/ config ##
server {
    listen 80;
    listen [::]:80;
    access_log  /var/log/nginx/http_moon0sool.duckdns.org_access.log;
    error_log   /var/log/nginx/http_moon0sool.duckdns.org_error.log;
    server_name moon0sool.duckdns.org;
    root        /usr/share/nginx/html;
    #
    # redirect all HTTP requests to HTTPS with a 301 Moved Permanently response.
    #
    return 301 https://$host$request_uri;
}
## https port 443: START https://moon0sool.duckdns.org/ config ##
server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name moon0sool.duckdns.org;
    root /usr/share/nginx/html;
    # certs sent to the client in SERVER HELLO are concatenated in ssl_certificate
    ssl_certificate  /etc/nginx/ssl/duckdns.org/moon0sool.duckdns.org.cer;
    ssl_certificate_key /etc/nginx/ssl/duckdns.org/moon0sool.duckdns.org.key;
    ssl_session_timeout 1d;
    ssl_session_cache shared:MozSSL:10m;  # about 40000 sessions
    ssl_session_tickets off;
    ssl_dhparam /etc/nginx/ssl/duckdns.org/dhparams.pem;
    #
    # Supports Firefox 27, Android 4.4.2, Chrome 31, Edge, IE 11 on Windows 7, Java 8u31, OpenSSL 1.0.1, Opera 20, and Safari 9 and above
    #
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384';
    ssl_prefer_server_ciphers off;
    # HSTS (ngx_http_headers_module is required) (63072000 seconds)
    add_header Strict-Transport-Security "max-age=63072000" always;
    # OCSP stapling
    ssl_stapling on;
    ssl_stapling_verify on;
    # replace with the IP address of your resolver
    resolver 8.8.8.8;
    ## add other config below such as fastcgi or php and so on ##
}

Step 7 – 인증서 설치

# acme.sh --installcert -d moon0sool.duckdns.org \
--key-file /etc/nginx/ssl/duckdns.org/moon0sool.duckdns.org.key \
--fullchain-file /etc/nginx/ssl/duckdns.org/moon0sool.duckdns.org.cer \
--reloadcmd 'systemctl reload nginx.service'

포트오픈 확인

# netstat -lntp

아래와 같이 443과 80 포트가 열려 있어야 한다.

tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      6702/nginx: master  
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      1240/sshd           
tcp        0      0 0.0.0.0:443             0.0.0.0:*               LISTEN      6702/nginx: master  

Step 8 – 방화벽 설정및 reload

# firewall-cmd --permanent --add-service=http --add-service=https
# firewall-cmd --reload

Step 9 – 인증서 갱신

# acme.sh --renew -d moon0sool.duckdns.org
[Wed Jul 22 02:17:27 UTC 2020] Renew: 'moon0sool.duckdns.org'
[Wed Jul 22 02:17:27 UTC 2020] Skip, Next renewal time is: Sat Sep 19 06:37:04 UTC 2020
[Wed Jul 22 02:17:27 UTC 2020] Add '--force' to force to renew.

인증서 갱신을 하면 60일 이후 갱신되므로 skip한다.

따라서 cron에 보름이나 한달에 한번 설정해 놓으면 60 지났을때 갱신된다.