解決 Let's Encrypt tls-sni-01 的問題

Let's Encrypt

使用 TLS-SNI-01 取得憑證的方式存在漏洞,現在改用 HTTP-01 的方式來取得憑證。

使用 Webroot 的安裝方式避掉 tls-sni-01 的問題

如果你使用我前一篇 HTTPS 連線,使用 Let's Encrypt 的申請方式,會得到 tls-sni-01 錯誤訊息,大概像這樣:

Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator nginx, Installer nginx
Cert is due for renewal, auto-renewing...
Renewing an existing certificate
Performing the following challenges:
tls-sni-01 challenge for www.example.com
Waiting for verification...
Cleaning up challenges
Failed authorization procedure. www.example.com (tls-sni-01): urn:acme:error:unauthorized :: The client lacks sufficient authorization :: Incorrect validation certificate for tls-sni-01 challenge. Requested ee907737e622349b0780ac256f64cf0d.89aa5e1ddb9323e1039ca8910a19837a.acme.invalid from 123.456.123.456:443. Received 2 certificate(s), first certificate had names "www.example.com"

IMPORTANT NOTES:
 - The following errors were reported by the server:

   Domain: www.example.com
   Type:   unauthorized
   Detail: Incorrect validation certificate for tls-sni-01 challenge.
   Requested
   ee907737e622349b0780ac256f64cf0d.89aa5e1ddb9323e1039ca8910a19837a.acme.invalid
   from 123.456.123.456:443. Received 1 certificate(s), first
   certificate had names "www.example.com"

   To fix these errors, please make sure that your domain name was
   entered correctly and the DNS A/AAAA record(s) for that domain
   contain(s) the right IP address.

如果確認 DNS 設定沒問題的話,那很可能就是 tls-sni-01 所造成的問題了。

根據 IMPORTANT: What you need to know about TLS-SNI validation issues 這篇的說明,使用 TLS-SNI-01 取得憑證的方式存在漏洞,可能讓你取得不屬於你的 domain 的憑證,建議改用 HTTP-01DNS-01 的方式取得憑證。使用 webroot 的方式即是使用 HTTP-01

註:本文使用 Nginx 伺服器。

補充:這裡使用的 Certbot 指令有新版本,請先到 Certbot 選擇網站伺服器及作業系統來安裝新版本的指令工具。

首先,在網站文件的根目錄建立一個 Let's Encrypt 專用的目錄:

mkdir -p /usr/share/nginx/html/letsencrypt/.well-known/acme-challenge

這個目錄會在申請憑證時,暫時寫入驗證用的資料,申請完就會自動刪除,多個子網域都能共用。

接著,在每個虛擬主機的配置檔的 HTTP 段落加入以下內容:

server {
  listen       80;
  listen       [::]:80;
  server_name  www.example.com;
  
  root   /usr/share/nginx/html;
  index  index.html index.htm;
  
  ##### 加入以下區塊的內容 #####
  location /.well-known/acme-challenge/ {
    root /usr/share/nginx/html/letsencrypt;
  }
  ######################
}

記得讓 Nginx 重載配置檔:

nginx -s reload

最後就可以使用 webroot 的方式更新或新申請憑證了,這裡要確認 certbot 執行檔是否為 0.21.0 之後的版本。

certbot certonly --webroot --email xxx@email.com --webroot-path /usr/share/nginx/html/letsencrypt -d www.example.com
# --email 的參數值,請填入申請者的 email,可以收到即將過期的通知
# -d 的參數值,你要申請的網址名稱

如果要申請多個網址,請重複執行以上指令,但是把最後面的網址換成另一個。

這個申請方式並不會自動安裝憑證到 Nginx 伺服器的虛擬主機上,必須手動加入,例如:

server { 
  listen       443 ssl http2;
  # ...略

  ssl_certificate "/etc/pki/nginx/server.crt";
  ssl_certificate_key "/etc/pki/nginx/private/server.key";
}
如果你之前已經申請過憑證,此次只是更新的話,應該就已經有此設定。



本文網址:http://blog.tonycube.com/2018/08/lets-encrypt-tls-sni-01.html
Tony Blog 撰寫,請勿全文複製,轉載時請註明出處及連結,謝謝 😀

我要留言

留言小提醒:
1.回覆時間通常在晚上,如果太忙可能要等幾天。
2.請先瀏覽一下其他人的留言,也許有人問過同樣的問題。
3.程式碼請先將它編碼後再貼上。(線上編碼:http://bit.ly/1DL6yog)
4.文字請加上標點符號及斷行,難以閱讀者恕難回覆。
5.感謝您的留言,您的問題也可能幫助到其他有相同問題的人。