NGINX 好用設定
技術筆記
Certbot
(let’s encrypt 簽 https)
Install
- 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
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
- permission deny 問題: https://serverfault.com/questions/748561/nginx-doesnt-have-permission-to-access-files-with-the-same-ownership
- 簡言之,nginx 要全部的歷遍權限都有才能讀檔案,所以路徑上的 file 都要 o+x
- SELinux reverse proxy:
- https://www.nginx.com/blog/using-nginx-plus-with-selinux/
- SELinux 有擋 reverse,隨便的 port 不能開 http (可能怕 SSRF ?)
- 需要下
semanage port -a -t http_port_t -p tcp {to port no.}
- 上面那個好像不用下,下這個就好
setsebool -P httpd_can_network_connect 1
- (待釐清)
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;
}