Let's Encrypt,站點加密之旅

Macken發表於2016-09-06

HTTPS(全稱:Hyper Text Transfer Protocol over Secure Socket Layer),是以安全為目標的HTTP通道,簡單講是HTTP的安全版。即HTTP下加入SSL層,HTTPS的安全基礎是SSL,因此加密的詳細內容就需要SSL。

Let’s Encrypt,是2016年4月12日成立的一家證照授權中心,提供免費的傳輸層安全(TLS)X.509證照,透過自動化的過程消除目前安全網站證照需要手工建立,加密,簽名,安裝以及更新的複雜性。

一直以來都覺得瀏覽器網址開頭的那把小綠鎖很別緻啊,現在Let’s Encrypt橫空出世提供免費證照,說明https勢在必行,那我也來動手給部落格加把鎖吧,看著就安全是吧。

Let’s Encrypt 的官網提供的指令碼看起來更加自動化一些,但我沒有親自嘗試,而是在Github上搜到了一個開源指令碼acme-tiny,用下來之後成功將部落格加密完成。

特別提醒:請注意使用者許可權問題,下文都是使用的普通使用者,而非 root ,請根據自己的情況調整。

file

根據acme-tiny提供的說明文件和我自己的實施過程列出以下幾步:

###克隆指令碼

sudo git clone https://github.com/diafygi/acme-tiny.git  
cd acme-tiny

###建立Let’s Encrypt私鑰

openssl genrsa 4096 > account.key

###建立CSR(Certificate Signing Request,證照籤名請求) 檔案

ACME協議 (Let’s Encrypt所使用的) 需要一個csr檔案,用來進行證照籤名和證照更新。

將需要加密的域名加到下面的程式碼中,目前一張證照最多可以加密 100 個域名:

openssl genrsa 4096 > domain.key     
openssl req -new -sha256 -key domain.key -subj "/" -reqexts SAN -config <(cat /etc/ssl/openssl.cnf <(printf "[SAN]\nsubjectAltName=DNS:yoursite.com,DNS:www.yoursite.com")) > domain.csr

注意:openssl.cnf 檔案的位置可能會因為linux版本的不同而有變

###證明你擁有該域名

acme-tiny指令碼會生成驗證檔案並寫入到你指定的目錄下,然後透過 “.well-known/acme-challenge/“ 這個URL來訪問到驗證檔案. 注意: Let’s Encrypt 會對你的伺服器做一次http請求來進行驗證,因此你需要保證80埠能夠訪問.

  • 手動生成challenges目錄,用來存放驗證檔案(路徑可以根據需要修改)

    mkdir -p /var/www/challenges

  • 配置nignx的80埠

    server {

        listen 80;
        server_name yoursite.com www.yoursite.com;

        if ( $request_uri !~ "/.well-known/acme-challenge/*" ) { # 讓 Let's Encrypt 成功訪問到驗證檔案不受 301 影響
                  return 301 https://yoursite.com$request_uri; # 注意進行301重定向到https,否則透過http仍能訪問你的站點
        }

        location /.well-known/acme-challenge/ {
            alias /var/www/challenges/;
            try_files $uri =404;
        }

        #...你的其他配置
    }

Apache 則需修改 .htaccess 檔案配置301重定向:

RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]

###獲取簽名證照

sudo chmod +x acme_tiny.py  
sudo python acme_tiny.py --account-key ./account.key --csr ./domain.csr --acme-dir /var/www/challenges/ > ./signed.crt

###安裝證照

針對nginx, 你還需要將 Let’s Encrypt 的中介軟體證照 intermediate.pem 內容附加在簽名證照signed.crt之後:

    wget -O - https://letsencrypt.org/certs/lets-encrypt-x3-cross-signed.pem > intermediate.pem  
    cat signed.crt intermediate.pem > chained.pem
    server {
        listen 443 ssl;
        server_name yoursite.com www.yoursite.com;

        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;

        #...你的其他配置
    }

###證照自動更新定時任務

恭喜!你的網站已經使用上了HTTPS。 但Let’s Encrypt 證照有效期只有90天, 所以需要定期更新。現在只需要寫一個更新指令碼並把它放到定時任務中即可。

指令碼內容:

    #!/usr/bin/sh

    python /path/to/acme_tiny.py --account-key /path/to/account.key --csr /path/to/domain.csr --acme-dir /var/www/challenges/ > /tmp/signed.crt || exit

    wget -O - https://letsencrypt.org/certs/lets-encrypt-x3-cross-signed.pem > intermediate.pem

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

    service nginx reload

定時任務可以設定為每個月執行一次:
0 0 1 * * sudo bash /path/to/renew_cert.sh 2>> /var/log/acme_tiny.log

原文連結:macken.me/article/encrypt-your-web...

本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章