免費 HTTPS 證書 Let's Encrypt 安裝教程

nfangxu發表於2018-11-20

第零步:本文使用環境

  • 阿里雲伺服器
  • ubuntu 16.04
  • nginx

第一步:建立 Let's Encrypt 賬號

Let's Encrypt使用一個私鑰來進行賬號的建立與登陸,因此我們需要使用openssl建立一個account.key。

openssl genrsa 4096 > account.key

如果你已經有一個Let's Encrypt key的話,那麼只需要做一次轉換,因為Let's Encrpt 的客戶端生成的key是JWK格式,而acm-tiny使用的是PEM格式。轉換key需要使用一個指令碼

# 下載指令碼
wget -O - "https://gist.githubusercontent.com/JonLundy/f25c99ee0770e19dc595/raw/6035c1c8938fae85810de6aad1ecf6e2db663e26/conv.py" > conv.py

# 把private key 拷貝到你的工作目錄
cp /etc/letsencrypt/accounts/acme-v01.api.letsencrypt.org/directory/<id>/private_key.json private_key.json

# 建立一個DER編碼的private key
openssl asn1parse -noout -out private_key.der -genconf <(python conv.py private_key.json)

# 轉換成PEM格式
openssl rsa -in private_key.der -inform der > account.key

第二步:建立域名的CSR(CERTIFICATE SIGNING REQUEST)

Let's Encrypt 使用的ACME協議需要一個CSR檔案,可以使用它來重新申請HTTPS證照,接下來我們就可以建立域名CSR,在建立CSR之前,我們需要給我們的域名建立一個私鑰(這個和上面的賬戶私鑰無關)。

openssl genrsa 4096 > domain.key #建立普通域名私鑰 

接下來,使用你的域名私鑰建立CSR檔案,這一步裡面是可以增加最多100個需要加密的域名的,替換下面的foofish.net即可(注意,稍後會說到,每個域名都會涉及到驗證)

# 單個域名
openssl req -new -sha256 -key domain.key -subj "/CN=nfangxu.com" > domain.csr

# 多個域名(如果你有多個域名,比如:www.foofish.net和foofish.net,使用這種方式)
openssl req -new -sha256 -key domain.key \
-subj "/" -reqexts SAN \
-config <(cat /etc/ssl/openssl.cnf \
<(printf "[SAN]\nsubjectAltName=DNS:nfangxu.com,DNS:www.nfangxu.com")) \
> domain.csr

執行這一步時,需要指定 openssl.cnf 檔案,一般這個檔案在你的 openssl 安裝目錄底下。

第三步:配置域名驗證

CA 在簽發 DV(Domain Validation)證照時,需要驗證域名所有權。傳統 CA 的驗證方式一般是往 admin@foofish.net 發驗證郵件,而 Let's Encrypt 是在你的伺服器上生成一個隨機驗證檔案,再通過建立 CSR 時指定的域名訪問,如果可以訪問則表明你對這個域名有控制權。 首先建立用於存放驗證檔案的目錄,例如:

mkdir -p /path/to/your/web/root/.well-known/acme-challenge/

然後配置一個 HTTP 服務,以 Nginx 為例:(注意:這裡的埠是80,不是443

server {
    listen 80;

    server_name nfangxu.com www.nfangxu.com;

    root /path/to/your/web/root/;
    index index.php;

    location ^~ /.well-known/acme-challenge/ {
            try_files $uri =404;
    }

    # 後期加的, 用於 http 向 https 的跳轉
    location / {
            rewrite ^(.*)$ https://nfangxu.com/$1 permanent;
    }
}

這個驗證服務以後更新證照還要用到,需要一直保留。

第四步:獲取網站證照

先把 acme-tiny 指令碼儲存到之前的 ssl 目錄:

wget https://raw.githubusercontent.com/diafygi/acme-tiny/master/acme_tiny.py

指定賬戶私鑰、CSR 以及驗證目錄,執行指令碼:

python acme_tiny.py \ 
--account-key ./account.key \ 
--csr ./domain.csr \ 
--acme-dir /path/to/your/web/root/.well-known/acme-challenge/ \ 
> ./signed.crt

如果一切正常,當前目錄下就會生成一個 signed.crt,這就是申請好的證照檔案。

第五步:安裝證照

證照生成後,就可以把它配置在web 伺服器上了,需要注意的是,Nginx需要追加一個Let's Encrypt的中間證照,在 Nginx 配置中,需要把中間證照和網站證照合在一起:

# 獲取證照
wget -O - https://letsencrypt.org/certs/lets-encrypt-x1-cross-signed.pem > intermediate.pem

# 合併證照
cat signed.crt intermediate.pem > chained.pem

最終,修改 Nginx 中有關證照的配置並 reload 服務即可:

server {
    listen 443;

    # ssl 配置
    ssl on;
    ssl_certificate /path/to/chained.pem;
    ssl_certificate_key /path/to/domain.key;
    ssl_session_timeout 5m;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA;
    ssl_session_cache shared:SSL:50m;
    ssl_prefer_server_ciphers on;
    # END

    server_name nfangxu.com www.nfangxu.com;

    root /path/to/your/web/root/;
    index index.php index.html index.htm index.nginx-debian.html;

    location / {
            try_files $uri $uri/ /index.php;
    }

    location ~ \.php$ {
            include snippets/fastcgi-php.conf;
            fastcgi_pass unix:/run/php/php7.2-fpm.sock;
    }

    location ~ /\.ht {
            deny all;
    }
}

第六步:定期更新

Let’s Encrypt 簽發的證照只有90天有效期,但可以通過指令碼定期更新。你可以建立了一個自動更新指令碼 cert_refresh.sh ,內容如下:

#!/bin/bash

# 建立CSR
python /path/to/acme_tiny.py --account-key /path/to/account.key --csr /path/to/domain.csr --acme-dir /path/to/your/web/root/.well-known/acme-challenge/ > /tmp/signed.crt || exit

# 獲取
wget -O - https://letsencrypt.org/certs/lets-encrypt-x1-cross-signed.pem > /tmp/intermediate.pem

# 合併
cat /tmp/signed.crt /tmp/intermediate.pem > /path/to/chained.pem

# 重新載入 nginx 配置檔案
service nginx restart

修改crontab配置,加入以下內容:

# 每個月執行一次
0 0 1 * * /path/to/cert_refresh.sh 2>> /var/log/acme_tiny.log

大功告成,訪問下自己的HTTPS網站是否正常,不出意外的話,網站已經正式啟用HTTPS了 !

原文網站

相關文章