NGINX 好用設定

技術筆記

Certbot

(let’s encrypt 簽 https)

Install

find here

  • Ubuntu
    $ sudo apt-get update
    $ sudo apt-get install software-properties-common
    $ sudo add-apt-repository ppa:certbot/certbot
    $ sudo apt-get update
    $ sudo apt-get install python-certbot-nginx 
    
  • Fedora
    sudo dnf install certbot-nginx
    

簽署

  • 自動幫改 nginx 設定檔
sudo certbot --nginx
  • 手動改 nginx 設定檔
sudo certbot --nginx certonly
  • 自動更新憑證
sudo certbot renew --dry-run
  • 手動更新憑證
certbot renew

Redirect to https

  • 301
    server {
    
        listen 443 ssl; # managed by Certbot        
        ssl_certificate /etc/letsencrypt/live/notebook.calee.xyz/fullchain.pem; # managed by Certbot
        ssl_certificate_key /etc/letsencrypt/live/notebook.calee.xyz/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
    
        if ($scheme != "https") {                   
            return 301 https://$host$request_uri;   
        }
    
    }
    
  • rewrite
    • 除了 301 redirect 之外,nginx 還有一個 Force HTTPS 是用 rewrite 來處理 不過要小心也可能出現 Mixed Content too many 的問題
    • 301 與 rewrite 差別
    • nginx rewrite
    rewrite     ^   https://$server_name$request_uri? permanent;
    

Redirect too many

如果你的 domain 有上 CDN,會有 redirect too many 的問題,解法是偵測請求協定是否為 http,若是,才可以 redirect 了 通常出現在 DNS 是由 cloud flare 代管,並且有上 CDN 的情況下 find here find here

server {
    listen 80;

    if ($http_x_forwarded_proto = "http") {
        return 301 https://$server_name$request_uri;
    }

}

hsts

find here

server {
    listen 443 ssl;
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
    
    # Because this 'location' block contains another 'add_header' directive,
    # we must redeclare the STS header
    location /servlet {
        add_header X-Served-By "My Servlet Handler";
        add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
        proxy_pass http://localhost:8080;
    }
}
  • includeSubDomains: always; 會讓所有 subdomains 都上 hsts,此處需要小心
  • (servlet) 如果有一個的 block 本身有自己加 header,需要重新把 hsts 寫進去,不然會被覆蓋掉

加密檢測

  • SSL Test
  • 是否還有其他資源未加密
    • 如果你透過Chrome瀏覽器發現網站的連線變成「https」然後是灰色,你可以點一下即可查資訊,他會顯示「這個網頁含有其他不安全的資源」,那代表網站有使用到非https的圖片、js、css的資源,那就得修正了。
    • 有時候可能是 hsts subdomain 還沒全部生效,重轉幾次就好了 (?)

Problem

Load Balance

這裡指的是 proxy pass 的 load balance

利用 upstream 參數,參考 這裡

upstream backend {
  server backend1.example.com       weight=5; # 可以設定權重
    server backend2.example.com:8080; # 可以用 port
    server unix:/tmp/backend3; # 可以用 unix domain socket

    server backup1.example.com:8080   backup; # 備援
    server backup2.example.com:8080   backup;
}

server {
  listen 443 ssl http2;
  location / {
    proxy_pass https://backend; # 記得使用 upstream 定義的參數
  }
}

IPv6 enable

其實很簡單,參考 nginx.conf 也有寫的,只要多加 ipv6 的 ip 在 port 前面,沒寫 ip 預設只有 ipv4。

server {
  listen 443;
  listen [::]:443;
  listen 80;
  listen [::]:80;
}
comments powered by Disqus

Related