Nginx 通過 certbot 為網站自動配置 SSL 證書並續期


一、背景知識

1.1、http 和 https 是什么?

簡單來說,http 是一個傳輸網頁內容的協議,比如你看到的 http 開頭的網站 http://www.163.com ,其網頁上的文字、圖片、 CSS 、 JS 等文件都是通過 http 協議傳輸到我們的瀏覽器,然后被我們看到。

而 https 可以理解為“ HTTP over SSL/TLS ”,好端端的 http 為什么需要“ over SSL/TLS ”呢,因為 http 是明文傳輸的,通過 http 協議傳輸的內容很容易被偷看和篡改,為了安全(你肯定不想被人偷看或者篡改網頁內容吧,比如網站銀行密碼什么的。)就為 http 協議再加上了一層 SSL/TLS 安全協議,所以就有了 https 。

1.2、SSL/TLS 是什么?

“ HTTP over SSL/TLS ”字面意思就是帶”安全套接層”的 http 協議,內心純潔的同學也可以理解為“帶安全套的 http ”,因為帶了安全套,所以當然會比較安全。其中 SSL 是“ Secure Sockets Layer ” 的縮寫,是“安全套接層”的意思。 TLS 是 “Transport Layer Security” 的縮寫,是 ” 傳輸層安全協議 ” 的意思。 SSL 和 TLS 是同一個東西的不同階段,理解為同一個東西也行,都是安全協議就對了。

1.3、為什么要部署 https?

說到底,就是 https 更安全。甚至為了安全,一個專業可靠的網站, https 是必須的。 Firefox 和 Chrome 都計划將沒有配置 SSL 加密的 http 網站標記為不安全(貌似 Firefox 50 已經這么干了),目前它們也正在聯合其他相關的基金會與公司推動整個互聯網 https 化,現在大家訪問的一些主要的網站。如 Google 多年前就已經全部啟用 https ,國內的淘寶、搜狗、知乎、百度等等也全面 https 了。甚至 Google 的搜索結果也正在給予 https 的網站更高的排名和優先收錄權。

1.4、怎么部署 https 呢?

你只需要有一張被信任的 CA ( Certificate Authority )也就是證書授權中心頒發的 SSL 安全證書,並且將它部署到你的網站服務器上。一旦部署成功后,當用戶訪問你的網站時,瀏覽器會在顯示的網址前加一把小綠鎖,表明這個網站是安全的,當然同時你也會看到網址前的前綴變成了 https ,不再是 http 了。

1.5、怎么獲得 SSL 安全證書呢?

理論上,我們自己也可以簽發 SSL 安全證書,但是我們自己簽發的安全證書不會被主流的瀏覽器信任,所以我們需要被信任的證書授權中心( CA )簽發的安全證書。而一般的 SSL 安全證書簽發服務都比較貴,比如 Godaddy 、 GlobalSign 等機構簽發的證書一般都需要20美金一年甚至更貴,不過為了加快推廣 https 的普及, EEF 電子前哨基金會、 Mozilla 基金會和美國密歇根大學成立了一個公益組織叫 ISRG ( Internet Security Research Group ),這個組織從 2015 年開始推出了 Let’s Encrypt 免費證書。這個免費證書不僅免費,而且還相當好用,所以我們就可以利用 Let’s Encrypt 提供的免費證書部署 https 了。那么怎么獲得 Let’s Encrypt 安全證書,並且將它部署在自己的網站服務器上呢?這就是這篇文章要講的內容了。

二、Let’s Encrypt 及 Certbot 簡介

前面已經介紹過, Let’s Encrypt 是 一個叫 ISRG ( Internet Security Research Group ,互聯網安全研究小組)的組織推出的免費安全證書計划。參與這個計划的組織和公司可以說是互聯網頂頂重要的先驅,除了前文提到的三個牛氣哄哄的發起單位外,后來又有思科(全球網絡設備制造商執牛耳者)、 Akamai 加入,甚至連 Linux 基金會也加入了合作,這些大牌組織的加入保證了這個項目的可信度和可持續性。

后來 ISRG 的發起者 EFF (電子前哨基金會)為 Let’s Encrypt 項目發布了一個官方的客戶端 Certbot ,利用它可以完全自動化的獲取、部署和更新安全證書。這真是非常容易、方便呀,所以我們就可以直接使用官方客戶端,不需要再使用第三方的工具了。雖然第三方工具也可以使用,但是官方工具更權威,風險也更小,而且遇到問題也更容易解決,畢竟有官方的支持。何況 Certbot 確實非常方便,也比所有的第三方工具都更方便,何樂而不用呢?

2.1、Authenticators 和 Installers

Certbot 支持兩種類型的 plugin,一種是用來獲取和安裝證書的,成為稱為 Authenticators;另外一種是用來安裝證書的,稱為 Installers。有的 plugin 支持一種,有的兩種都支持,如 nginx。
Authenticators plugin 使用 certonly 命令來獲取證書,而 Installers plugin 使用install命令來安裝證書。

2.2、plugin 說明

下面列舉幾個常用的 plugin 作簡要說明:

  • Webroot:本地有運行 webserver 並且有能力修改其配置,就可以用該種方式(創建隱藏文件.well-known),獲取證書時無需暫停 webserver 的運行。
  • Standalone:服務器未運行 webserver 可以使用該方式,要保持 80 或 443 端口開放。
  • Nginx:自動獲取和安裝證書(自動修改配置文件)。

2.3、安裝 certbot

Certbot 的官方網站是 https://certbot.eff.org/ ,打開這個鏈接選擇自己使用的 web server 和操作系統,EFF 官方會給出詳細的使用方法,以下以本網站域名( bbs.wzlinux.com )舉例。

我們的系統環境為 CentOS 7,Web 服務器為 epel 源中的 nginx,只是為了掩飾安裝證書,沒有做什么網頁,大家了解這個過程為主,我們使用下面命令進行安裝 certbot。

yum install certbot python2-certbot-nginx

三、Certbot 為 nginx 自動獲取安裝證書

3.1、生成證書

我們在使用 certbot 生成證書之前,要把域名解析到當前的服務器,使用令生certbot --nginx成證書,並且會幫我們自動配置到 nginx 上面,過程中需要我們輸入郵箱地址。

[root@lnmp-1 ~]# certbot --nginx
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator nginx, Installer nginx
Enter email address (used for urgent renewal and security notices) (Enter 'c' to
cancel): wangzan18@126.com
Starting new HTTPS connection (1): acme-v02.api.letsencrypt.org

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Please read the Terms of Service at
https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf. You must
agree in order to register with the ACME server at
https://acme-v02.api.letsencrypt.org/directory
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(A)gree/(C)ancel: A

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Would you be willing to share your email address with the Electronic Frontier
Foundation, a founding partner of the Let's Encrypt project and the non-profit
organization that 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: Y
Starting new HTTPS connection (1): supporters.eff.org
No names were found in your configuration files. Please enter in your domain
name(s) (comma and/or space separated)  (Enter 'c' to cancel): bbs.wzlinux.com
Obtaining a new certificate
Performing the following challenges:
http-01 challenge for bbs.wzlinux.com
Waiting for verification...
Cleaning up challenges
Resetting dropped connection: acme-v02.api.letsencrypt.org
Deploying Certificate to VirtualHost /etc/nginx/nginx.conf

Please choose whether or not to redirect HTTP traffic to HTTPS, removing HTTP access.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1: No redirect - Make no further changes to the webserver configuration.
2: Redirect - Make all requests redirect to secure HTTPS access. Choose this for
new sites, or if you're confident your site works on HTTPS. You can undo this
change by editing your web server's configuration.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Select the appropriate number [1-2] then [enter] (press 'c' to cancel): 2
Redirecting all traffic on port 80 to ssl in /etc/nginx/nginx.conf

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Congratulations! You have successfully enabled https://bbs.wzlinux.com

You should test your configuration at:
https://www.ssllabs.com/ssltest/analyze.html?d=bbs.wzlinux.com
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at:
   /etc/letsencrypt/live/bbs.wzlinux.com/fullchain.pem
   Your key file has been saved at:
   /etc/letsencrypt/live/bbs.wzlinux.com/privkey.pem
   Your cert will expire on 2019-07-25. To obtain a new or tweaked
   version of this certificate in the future, simply run certbot again
   with the "certonly" option. To non-interactively renew *all* of
   your certificates, run "certbot renew"
 - Your account credentials have been saved in your Certbot
   configuration directory at /etc/letsencrypt. You should make a
   secure backup of this folder now. This configuration directory will
   also contain certificates and private keys obtained by Certbot so
   making regular backups of this folder is ideal.
 - If you like Certbot, please consider supporting our work by:

   Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
   Donating to EFF:                    https://eff.org/donate-le

按照提示輸入自己的信息即可,如果希望自己手動配置 nginx 證書,可以使用下面的命令。

certbot --nginx certonly

3.2、配置證書

目前已經自動幫我們配置證書了,我們可以看下配置的形式,后續可以自己配置。

server {
        server_name bbs.wzlinux.com;   # managed by Certbot
        root         /usr/share/nginx/html;

        # Load configuration files for the default server block.
        include /etc/nginx/default.d/*.conf;

        location / {
        }

        error_page 404 /404.html;
            location = /40x.html {
        }

        error_page 500 502 503 504 /50x.html;
            location = /50x.html {
        }
    

    listen [::]:443 ssl ipv6only=on; # managed by Certbot
    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/bbs.wzlinux.com/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/bbs.wzlinux.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

}

server {
    if ($host = bbs.wzlinux.com) {
        return 301 https://$host$request_uri;
    } # managed by Certbot


    listen       80 ;
    listen       [::]:80 ;
    server_name bbs.wzlinux.com;
    return 404; # managed by Certbot


}

3.3、更新證書

既然已經按照好了,我們可以查看一下證書的安裝情況。


出於安全策略, Let’s Encrypt 簽發的證書有效期只有 90 天,所以需要每隔三個月就要更新一次安全證書,雖然有點麻煩,但是為了網絡安全,這是值得的也是應該的。好在 Certbot 也提供了很方便的更新方法。
我們可以在 www.ssllabs.com 測試證書是否正常。

  • 測試一下更新,這一步沒有在真的更新,只是在調用 Certbot 進行測試。
certbot renew --dry-run

建議在服務器上面添加一個定時任務,讓服務器定時請求進行更新。

0 0,12 * * * python -c 'import random; import time; time.sleep(random.random() * 3600)' && certbot renew

四、Certbot Webroot 模式配置證書

這里我不想使用CertBot的standalone模式,這個模式雖然可以配置好服務器,但是以后Renew的時候,需要讓服務停止一下,再啟動。因此拋棄這個模式,我們使用Webroot配置模式。

因為,CertBot在驗證服務器域名的時候,會生成一個隨機文件,然后CertBot的服務器會通過HTTP訪問你的這個文件,因此要確保你的Nginx配置好,以便可以訪問到這個文件。

我這里的 web 服務器使用 LNMP 一鍵安裝包來安裝的,我們之間為 其中的 nginx 配置證書,首先我們先生成證書。

4.1、配置虛擬主機

我們使用的 lnmp 一鍵安裝包進行安裝的,我們可以直接使用命令 lnmp vhost add命令添加我們需要的主機。

[root@test ~]# lnmp vhost add
+-------------------------------------------+
|    Manager for LNMP, Written by Licess    |
+-------------------------------------------+
|              https://lnmp.org             |
+-------------------------------------------+
Please enter domain(example: www.lnmp.org): bbs1.wzlinux.com
 Your domain: bbs1.wzlinux.com
Enter more domain name(example: lnmp.org *.lnmp.org): 
Please enter the directory for the domain: bbs1.wzlinux.com
Default directory: /home/wwwroot/bbs1.wzlinux.com: 
Virtual Host Directory: /home/wwwroot/bbs1.wzlinux.com
Allow access log? (y/n) 
Disable access log.
Please enter Administrator Email Address: 
Administrator Email Address will set to webmaster@example.com!
Create database and MySQL user with same name (y/n) 
Add SSL Certificate (y/n) n

Press any key to start create virtul host...

Create Virtul Host directory......
set permissions of Virtual Host directory......
Test Nginx configure file......
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful

Reload Nginx......
Test Apache configure file...
test apache configure... Syntax OK
 done
Restart Apache...
graceful apache...  done
================================================
Virtualhost infomation:
Your domain: bbs1.wzlinux.com
Home Directory: /home/wwwroot/bbs1.wzlinux.com
Enable log: yes
Create database: no
Create ftp account: no
================================================

4.2、申請證書

[root@test ~]# certbot certonly --webroot -w /home/wwwroot/bbs1.wzlinux.com/ -d bbs1.wzlinux.com
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator webroot, Installer None
Enter email address (used for urgent renewal and security notices) (Enter 'c' to
cancel): wangzan18@126.com
Starting new HTTPS connection (1): acme-v02.api.letsencrypt.org

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Please read the Terms of Service at
https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf. You must
agree in order to register with the ACME server at
https://acme-v02.api.letsencrypt.org/directory
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(A)gree/(C)ancel: A

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Would you be willing to share your email address with the Electronic Frontier
Foundation, a founding partner of the Let's Encrypt project and the non-profit
organization that 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: Y
Starting new HTTPS connection (1): supporters.eff.org
Obtaining a new certificate
Performing the following challenges:
http-01 challenge for bbs1.wzlinux.com
Using the webroot path /home/wwwroot/bbs1.wzlinux.com for all unmatched domains.
Waiting for verification...
Cleaning up challenges
Resetting dropped connection: acme-v02.api.letsencrypt.org

IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at:
   /etc/letsencrypt/live/bbs1.wzlinux.com/fullchain.pem
   Your key file has been saved at:
   /etc/letsencrypt/live/bbs1.wzlinux.com/privkey.pem
   Your cert will expire on 2019-08-06. 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"
 - Your account credentials have been saved in your Certbot
   configuration directory at /etc/letsencrypt. You should make a
   secure backup of this folder now. This configuration directory will
   also contain certificates and private keys obtained by Certbot so
   making regular backups of this folder is ideal.
 - If you like Certbot, please consider supporting our work by:

   Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
   Donating to EFF:                    https://eff.org/donate-le

4.3、配置證書

生成的證書位置如下:

[root@test ~]# ll /etc/letsencrypt/live/bbs1.wzlinux.com/
total 4
lrwxrwxrwx. 1 root root  40 May  8 18:50 cert.pem -> ../../archive/bbs1.wzlinux.com/cert1.pem
lrwxrwxrwx. 1 root root  41 May  8 18:50 chain.pem -> ../../archive/bbs1.wzlinux.com/chain1.pem
lrwxrwxrwx. 1 root root  45 May  8 18:50 fullchain.pem -> ../../archive/bbs1.wzlinux.com/fullchain1.pem
lrwxrwxrwx. 1 root root  43 May  8 18:50 privkey.pem -> ../../archive/bbs1.wzlinux.com/privkey1.pem
-rw-r--r--. 1 root root 692 May  8 18:50 README

目前生成的 nginx 配置文件/usr/local/nginx/conf/vhost/bbs1.wzlinux.com.conf如下:

server
    {
        listen 80;
        #listen [::]:80;
        server_name bbs1.wzlinux.com ;
        index index.html index.htm index.php default.html default.htm default.php;
        root  /home/wwwroot/bbs1.wzlinux.com;

        #error_page   404   /404.html;

        # Deny access to PHP files in specific directory
        #location ~ /(wp-content|uploads|wp-includes|images)/.*\.php$ { deny all; }

        include proxy-pass-php.conf;

        location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$
        {
            expires      30d;
        }

        location ~ .*\.(js|css)?$
        {
            expires      12h;
        }

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

        location ~ /\.
        {
            deny all;
        }

        access_log off;
    }

然后我們為其添加 SSL 證書,修改后的配置文件如下:

server
        {
        listen 443 ssl http2;
        #listen [::]:443 ssl http2;
        server_name     bbs1.wzlinux.com;
        index index.html index.htm index.php default.html default.htm default.php;
        root  /home/wwwroot/bbs1.wzlinux.com;
        ssl on;
        ssl_certificate /etc/letsencrypt/live/bbs1.wzlinux.com/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/bbs1.wzlinux.com/privkey.pem;
        ssl_session_timeout 5m;
        ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
        ssl_prefer_server_ciphers on;
        ssl_ciphers "EECDH+CHACHA20:EECDH+CHACHA20-draft:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5";
        ssl_session_cache builtin:1000 shared:SSL:10m;
        # openssl dhparam -out /usr/local/nginx/ssl/dhparam.pem 2048
        #ssl_dhparam /usr/local/nginx/ssl/dhparam.pem;
        
        #error_page   404   /404.html;

        # Deny access to PHP files in specific directory
        #location ~ /(wp-content|uploads|wp-includes|images)/.*\.php$ { deny all; }

        include enable-php.conf;

        location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$
        {
            expires      30d;
        }

        location ~ .*\.(js|css)?$
        {
            expires      12h;
        }

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

        location ~ /\.
        {
            deny all;
        }

        access_log  off;
}

server
        {
        listen          80;
        server_name bbs1.wzlinux.com;
        return 301 https://$server_name$request_uri;
}

4.4 配置站點 bbs2

在做一個bbs2.wzlinux.com,同樣的做法去生成證書。

[root@test bbs2.wzlinux.com]# certbot certonly --webroot -w /home/wwwroot/bbs2.wzlinux.com/ -d bbs2.wzlinux.com --email wangzan18@126.com
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator webroot, Installer None
Starting new HTTPS connection (1): acme-v02.api.letsencrypt.org
Obtaining a new certificate
Performing the following challenges:
http-01 challenge for bbs2.wzlinux.com
Using the webroot path /home/wwwroot/bbs2.wzlinux.com for all unmatched domains.
Waiting for verification...
Cleaning up challenges
Resetting dropped connection: acme-v02.api.letsencrypt.org

IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at:
   /etc/letsencrypt/live/bbs2.wzlinux.com/fullchain.pem
   Your key file has been saved at:
   /etc/letsencrypt/live/bbs2.wzlinux.com/privkey.pem
   Your cert will expire on 2019-08-06. 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"
 - If you like Certbot, please consider supporting our work by:

   Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
   Donating to EFF:                    https://eff.org/donate-le

配置后的 nginx 配置文件內容為:

server
        {
        listen 443 ssl http2;
        #listen [::]:443 ssl http2;
        server_name     bbs2.wzlinux.com;
        index index.html index.htm index.php default.html default.htm default.php;
        root  /home/wwwroot/bbs2.wzlinux.com;
        ssl on;
        ssl_certificate /etc/letsencrypt/live/bbs2.wzlinux.com/fullchain.pem;     
        ssl_certificate_key /etc/letsencrypt/live/bbs2.wzlinux.com/privkey.pem;
        ssl_trusted_certificate /etc/letsencrypt/live/bbs2.wzlinux.com/chain.pem;
        ssl_session_timeout 5m;
        ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
        ssl_prefer_server_ciphers on;
        ssl_ciphers "EECDH+CHACHA20:EECDH+CHACHA20-draft:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5";
        ssl_session_cache builtin:1000 shared:SSL:10m;
        # openssl dhparam -out /usr/local/nginx/ssl/dhparam.pem 2048
        #ssl_dhparam /usr/local/nginx/ssl/dhparam.pem;
        
        #error_page   404   /404.html;

        # Deny access to PHP files in specific directory
        #location ~ /(wp-content|uploads|wp-includes|images)/.*\.php$ { deny all; }

        include enable-php.conf;

        location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$
        {
            expires      30d;
        }

        location ~ .*\.(js|css)?$
        {
            expires      12h;
        }

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

        location ~ /\.
        {
            deny all;
        }

        access_log  off;
}

server
        {
        listen          80;
        server_name bbs2.wzlinux.com;
        return 301 https://$server_name$request_uri;
}

最后我們給服務器添加一個定時任務。

0 3 */7 * * /bin/certbot renew --force-renew --disable-hook-validation --renew-hook "/etc/init.d/nginx reload"

由此我們也可以看出,同一個 IP 的服務器可以為多個域名同時做 https。

最后祝願我們所有的站點都升級為 https,讓 https 人人都可以用得起。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM