How To Secure Nginx with Let's Encrypt on Ubuntu 16.04

緣起

想做個微信小程序,把娃們的網站,在微信里展現給老人看,而做微信小程序,要求網站是 https 的,我也舍不得買證書,于是就打算使用 Let's Encrypt 提供的免費證書。

環境

  • Ubuntu 16.04.1 LTS
  • NGINX 1.10
  • kernel 4.9.4-040904-generic

步驟

安裝軟件

apt-get -y install letsencrypt;
# letsencrypt 是 Let's Encrypt 官方軟件
# certbot 在 Ubuntu 16.04 上的名字

獲取證書

letsencrypt certonly \
    --webroot \
        -w /opt/www/blog.xiaoyuer.cn \
        -d blog.xiaoyuer.cn;
letsencrypt certonly 
    --webroot \
        -w /opt/www/blog.lukeyang.us \
        -d blog.lukeyang.us;
# 這里 blog.xiaoyuer.cn 和 blog.lukeyang.us 是娃的網站
# 其實支持在一條命令里用多個 -w 參數配合 -d 參數,
# 為什么沒有這樣做而是單獨一條命令一個域名這么做呢,
# 主要是不想把所有證書放在一起......
# 
# 獲取證書過程中會彈出個窗口讓輸入郵件地址,
# 輸入一個常用的即可

Generate Strong Diffie-Hellman Group(optional)

openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048;
# 密鑰交換時使用更強的 2048 位密鑰

配置 NGINX 的 ssl 參數(optional)

cat <<EOF >/etc/nginx/snippets/ssl-params.conf
# from https://cipherli.st/
# and https://raymii.org/s/tutorials/Strong_SSL_Security_On_nginx.html

ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH";
ssl_ecdh_curve secp384r1;
ssl_session_cache shared:SSL:10m;
ssl_session_tickets off;
ssl_stapling on;
ssl_stapling_verify on;
#resolver 8.8.8.8 8.8.4.4 valid=300s;
#resolver_timeout 5s;
# Disable preloading HSTS for now.  You can use the commented out header line that includes
# the "preload" directive if you understand the implications.
#add_header Strict-Transport-Security "max-age=63072000; includeSubdomains; preload";
add_header Strict-Transport-Security "max-age=63072000; includeSubdomains";
add_header X-Frame-Options DENY;
add_header X-Content-Type-Options nosniff;

ssl_dhparam /etc/ssl/certs/dhparam.pem;
EOF

# 如果沒有做上一步,最后 ssl_dhparam 那句請注釋掉

NGINX 的虛擬機配置

vim /etc/nginx/sites-enabled/blog.xiaoyuer.cn;

server {} 配置塊中添加如下內容:

listen 443 ssl http2 default_server;
include snippets/ssl-params.conf;
ssl_certificate /etc/letsencrypt/live/blog.xiaoyuer.cn/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/blog.xiaoyuer.cn/privkey.pem;

location ~ /.well-known {
    allow all;
}

同樣的,

vim /etc/nginx/sites-enabled/blog.lukeyang.us;

server {} 配置塊中添加如下內容:

listen 443 ssl http2;
include snippets/ssl-params.conf;
ssl_certificate /etc/letsencrypt/live/blog.lukeyang.us/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/blog.lukeyang.us/privkey.pem;

location ~ /.well-known {
    allow all;
}

注意

這個配置里的 listen 443 ssl httpd2 一行并沒有 default_server 字樣,那是一個端口因為只能有一個 default_server,前面那個虛機已經在 443 端口上指定了 default_server,所以這里不能重復指定了

重啟 NGINX 服務

systemctl restart nginx.service;

配置自動更新證書

由于 Let's Encrypt 的證書會在三個月后過期,但是官方工具提供了自動更新的功能,我們只需要用 cron 定時調用即可。

cat <<EOF >/etc/cron.d/renew_ssl
25 3 * * 3 root /usr/bin/letsencrypt renew>/var/log/le-renew.log"
35 3 * * 3 root /bin/systemctl reload nginx
EOF

這里的邏輯是每周(三)檢查一次是否需要更新證書,如果需要,則自動更新證書。檢查完,再做一次 nginx 的 reload 操作,重新載入新證書(如果有的話)。

參考

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容