Nginx 常用配置
為什麼寫這篇文章?
- 在工作中發現很多開發者隻關注于開發,認為 nginx 屬于運維的事,然而無論大小公司,開發中都會涉及到一部分伺服器配置,小公司基本都是開發和運維一體。即使是大公司可能也會涉及到一些 cors、特殊 http 頭配置問題。尤其是 cors,很多人不知道完整的 http 配置
- 一些人想搭建自己的伺服器,但是伺服器不太會配置
- 記錄,供日後檢視(由于涉及内容太多,隻寫關鍵内容,如需要更詳細内容,還請搜尋關鍵詞,确實有必要,可以留言添加)
我的配置
通路一下nginx.conf
user web_admin; # 一般網站出現403之類的,可能是nginx 網站檔案夾權限配置錯誤,或者是這個配的使用者錯誤
worker_processes 1; # 一般設定成邏輯CPU的數量
error_log /var/log/nginx/error.log warn; # 錯誤日志,
pid /var/run/nginx.pid;
worker_rlimit_nofile 65535;
events {
worker_connections 4096;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
index index.html;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main; # 通路日志,格式采用上面定義的 main
sendfile on;
tcp_nopush on;
etag on;
expires 3d; # 緩存
server_names_hash_bucket_size 128;
keepalive_timeout 65;
# gzip config
gzip on;
gzip_min_length 1k; # 小于 1kb 的内容可能壓縮完體積更大
gzip_comp_level 9;
gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png;
gzip_vary on;
gzip_disable "MSIE [1-6]\."; # 現在加不加這個無所謂了,因為IE6早就沒了
include /etc/nginx/conf.d/*.conf; # 導入/etc/nginx/conf.d 下面的所有.conf 配置檔案
}
yingyj.com.conf
server {
server_name yingyj.com www.yingyj.com;
listen 443 ssl http2;
include /etc/nginx/ssl/options-ssl-nginx.conf;
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains" always;
root /home/web_admin/www/yingyj.com;
#charset koi8-r;
access_log /var/log/nginx/yingyj.com.access.log main;
location / {
autoindex on;
autoindex_exact_size off;
index index.html;
}
location = /50x.html {
root /usr/share/nginx/html;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
}
# 完全不使用 http 可以采用下面的配置,将本機80 端口轉到要通路的 https 網址
server {
listen 80 default_server;
server_name _;
return 301 https://$host$request_uri;
}
ssl/options-ssl-nginx.conf
# This file contains important security parameters. If you modify this file
# manually, Certbot will be unable to automatically provide future security
# updates. Instead, Certbot will print and log an error message with a path to
# the up-to-date file that you will need to refer to when manually updating
# this file.
ssl on;
ssl_session_cache shared:le_nginx_SSL:20m;
ssl_session_timeout 60m;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
# https://wiki.mozilla.org/Security/Server_Side_TLS#Modern_compatibility
# 這個參數會影響浏覽器相容性
ssl_ciphers 'TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384';
ssl_certificate /etc/nginx/ssl/yingyj.com/fullchain.cer; # 不用這個
ssl_certificate_key /etc/nginx/ssl/yingyj.com/yingyj.com.key;
# ssl_trusted_certificate /etc/nginx/ssl/yingyj.com/fullchain.cer;
關于安裝
公司使用建議自己編譯,有利于優化,個人小站點不想折騰可以直接 使用 linux 的包管理工具安裝。筆者的伺服器采用編譯安裝,主要是想嘗試下 TLS 1.3,編譯教程參考
imququ.comHTTPS
個人站點直接使用
letsencrypt(支援泛域名),然後采用定時任務自動續簽證書。筆者看到國外有些企業也是使用 letsencrypt,而國内公司都是采用付費證書。
證書配置完成之後可以用
ssllabs檢查,有問題的項會高亮顯示,相容和安全有時候需要取舍。
其中 ssl_ciphers 決定啟用哪些
Cipher suites
,會影響浏覽器相容,具體請看
wikiHSTS 不正确配置會導緻網址無法通路,使用之後隻能使用https通路網站,一定程度保證安全性。chrome等浏覽器,會将正确設定了HSTS
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains" always;
的網址加入寫死。
使用 HTTP2 的前提的 開始HTTPS,
listen 443 ssl http2;
不用HTTPS?,難道你想要你的網站被竄改?比如突然彈個廣告、比如惡意連結、如果打賞二維碼換成别人的 :)
cors
筆者更意向于将必要資源使用 nginx 放到一個域名,不存在跨域,自然也就沒有cors需求。
cors 涉及的 http header
- Access-Control-Allow-Origin: | 使用 雖然可以适用大部分情景,但是他不夠安全,部分場景(如支付相關邏輯層面不允許使用 *)
- Access-Control-Expose-Headers: X-My-Custom-Header, X-Another-Custom-Header 讓伺服器把允許浏覽器通路的頭放入白名單
- Access-Control-Max-Age: 指定了preflight請求的結果能夠被緩存多久
- Access-Control-Allow-Credentials: true 是否允許攜帶cookie
- Access-Control-Allow-Methods: [, ]* 涉及到複雜請求需要使用 OPTIONS 請求,大部分公司使用 GET, POST, OPTIONS
- Access-Control-Allow-Headers: [, ]* 指明了實際請求中允許攜帶的HTTP header, 有時候使用CDN,需要攜帶特殊的CDN頭,否者無法請求
緩存
緩存分以下幾類:
- 伺服器緩存(如 Redis 之類)
- CDN 緩存,部分 CDN 檔案更新之後無法立即生效
- 浏覽器緩存(強緩存、協商緩存、ServiceWorker?)
其中1、2和本文無關,暫不言表。
強緩存和HTTP header 的Cache-Control
和
Expires 有關
,
Cache-Control
優先級高于
Expires`。若本地有對應檔案緩存且緩存還在有效期,則直接使用本地緩存。
協商緩存和多個 成對的 http 頭有關,分别是:
-
和Etag
優先級高于第二個 (nginx 開啟If-None-Match
)etag on;
-
Last-Modified
If-Modified-Since
-
Vary
完全禁用緩存:
Cache-Control: no-cache, no-store, must-revalidate
對于不放cdn的檔案,一般來說,我們可以将永遠不會變的檔案設定很長時間的強緩存(比如 js 插件)。而現在的前端檔案,一般都是 hash 檔案名,除了html 檔案,是以我們隻需要根據需求設定好 html 檔案緩存,其他檔案可以強緩存。
有時候遇到前端檔案全部放cdn,導緻 index.html 檔案被錯誤緩存了,可以考慮将 index.html 單獨提取出來。
本文章使用 markdown 編輯器 Typora 編輯,推薦使用。