/ Nginx

[筆記] SSL, Nginx, HSTS, SPDY, BREACH, FIPS, OCSP Stapling

因為剛好有一批 SSL 很便宜,所以去幫自己的 blog.hinablue.me 買了五年,順手設定一些事情。筆記一下撞牆的經過這樣。


SSL Report

SSL Report

Nginx Settings


# Use SPDY
listen 443 ssl spdy;

ssl on;
ssl_certificate ssl/ca-bundle.crt;
ssl_certificate_key ssl/myserver.key;

# Stronger DHE Parameters
ssl_dhparam ssl/dhparam.pem;

# OCSP Stapling
ssl_stapling on;
ssl_stapling_verify on;
ssl_stapling_file ssl/myserver.staple;
ssl_trusted_certificate ssl/ca-chain.crt;

# FIPS chiper
ssl_ciphers "[email protected]:!aNULL:!eNULL";

# Disable Beast Attacks
ssl_prefer_server_ciphers on;

# TLS Only
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;

# Session Cache
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;

# Resolver
resolver 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 5s;

# SPDY compression
spdy_headers_comp 6;

# BREACH
gzip off;

# HSTS
add_header Strict-Transport-Security max-age=63072000;

# Others
add_header X-Frame-Options DENY;
add_header X-Content-Type-Options nosniff;

基本的設定是這樣,比較簡單的 dhparam.pem 簽法,

openssl dhparam -out dhparam.pem 4096

然後關於 OCSP Stapling 的作法,網路上有很多,但是每個作法好像都不太一樣。這邊記錄一下我自己的設定過程,

  1. 第三方 SSL 簽回來會有 issuer CA 憑證(某個中繼憑證,用這個憑證加上你的根憑證,做成一個檔案給 ssl_trusted_certificate 使用。
  2. 這個檔案跟 ssl_certificate 不一樣,不要搞混。
  3. 利用 openssl 來抓取 OCSP Server 的回應,產生一個 DER 檔案給 ssl_stapling_file 使用。
  4. 如果不給 ssl_stapling_file 其實 OCSP Stapling 在 SSL 驗證的時候並不會被標記為開啟。

製作憑證的檔案就不贅述了,記錄一下查詢與抓取 OCSP 的相關動作,

查詢所使用的 OCSP,

OLDIFS=$IFS; IFS=':' certificates=$(openssl s_client -connect google.com:443 -showcerts -tlsextdebug -tls1 2>&1 </dev/null | sed -n '/-----BEGIN/,/-----END/ {/-----BEGIN/ s/^/:/; p}'); for certificate in ${certificates#:}; do echo $certificate | openssl x509 -noout -ocsp_uri; done; IFS=$OLDIFS

上述指令當中的 google.com 請改成你自己的 Domain Name,他會有以下回應,

# 以 google.com 為例
http://clients1.google.com/ocsp

取得 OCSP Server 的回應,

openssl ocsp -text -no_nonce -issuer yourIssuerCA.crt -CAfile ca-bundle.crt -cert myserver.crt -VAfile yourIssuerCA.crt -url http://clients1.google.com/ocsp -respout myserver.staple

這樣就會存成 myserver.staple 這個檔案給 Nginx 使用。

接著可以利用 openssl 來查詢 OCSP 的回應狀態,

echo QUIT | openssl s_client -connect www.digitalocean.com:443 -tls1 -tlsextdebug -status 2> /dev/null | grep -A 17 'OCSP response:' | grep -B 17 'Next Update'

www.digitalocean.com 為例,

OCSP response:
======================================
OCSP Response Data:
    OCSP Response Status: successful (0x0)
    Response Type: Basic OCSP Response
    Version: 1 (0x0)
    Responder Id: 4C58CB25F0414F52F428C881439BA6A8A0E692E5
    Produced At: Dec  3 00:46:00 2014 GMT
    Responses:
    Certificate ID:
      Hash Algorithm: sha1
      Issuer Name Hash: B8A299F09D061DD5C1588F76CC89FF57092B94DD
      Issuer Key Hash: 4C58CB25F0414F52F428C881439BA6A8A0E692E5
      Serial Number: 0161FF00CCBFF6C07D2D3BB4D8340A23
    Cert Status: good
    This Update: Dec  3 00:46:00 2014 GMT
    Next Update: Dec 10 01:01:00 2014 GMT

OCSP Testing

小狀況

  1. 就算 ssl_trusted_certificate 或是 ssl_stapling_file 不給,OCSP Server 回應其實也會正常,只是 OCSP stapling 不會開而已。
  2. ssl_stapling_file 給錯一定會讓 Nginx 無法啟動,或是 OCSP stapling 失效。
  3. ssl_stapling on; 看起來煞有其事,其實只是在設定檔裡寫爽的。
  4. openssl 指令偶爾會需要 -CAfile 來做些處理,不然都會拿到 Verify return code: 20 (unable to get local issuer certificate) 的錯誤。
  5. HSTS 的部分,如果你有使用 upstream 的話,兩邊都要加。
  6. BREACH 的部分,因為 gzip off; 所以請務必確認你支援 SPDY,不然還是開著好了 XD

相關資料