安全開發運維必備,如何進行Nginx代理Web服務器性能優化與安全加固配置,看這篇指南就夠了


本章目錄

1.引言

  • 1.1 目的
  • 1.2 目標范圍
  • 1.3 讀者對象

2.參考說明

  • 2.1 幫助參考
  • 2.2 參數說明
  • 3.3 模塊說明

3.服務優化

  • 3.1 系統內核
  • 3.2 編譯優化
  • 3.3 性能優化
  • 3.4 運營優化
  • 3.5 配置優化

4.安全配置

  • 0.隱藏nginx服務及其版本
  • 1.低權限用戶運行服務
  • 2.配置SSL及其會話復用
  • 3.限制SSL協議與加密套件
  • 4.攔截垃圾信息
  • 5.惡意掃描攔截
  • 6.禁用WebDAV
  • 7.禁用Nginx狀態模塊
  • 8.關閉默認錯誤頁上的Nginx版本號
  • 9.設置client_body_timeout超時
  • 10.設置client_header_timeout
  • 11.設置keepalive_timeout超時
  • 12.設置send_timeout超時
  • 13.Nginx可用的方法應限制為GET, HEAD, POST
  • 14.控制並發連接limit_zone slimits
  • 15.控制並發連接limit_conn slimits
  • 16.主機防webshell跨目錄瀏覽以及列目錄
  • 17.文件名解析漏洞php_info,加入fcgi.conf即可
  • 18.訪問權限控制nginx
  • 19.異常狀態返回200隱藏URL
  • 20.安全模塊的選擇
  • 21.記錄訪問者真實IP
  • 22.地區訪問響應措施
  • 23.資源防盜鏈設置
  • 24.常規安全響應頭配置
  • 25.防止非所屬域名解析到服務器
  • 25.限制指定客戶端地址訪問

5.配置說明
6.補充知識


修訂控制頁

版本 修訂日期 修訂人 修訂摘要
1.0 2019年9月8日 09點18分 WeiyiGeek 初稿
2.0 2022年1月8日 18點18分 WeiyiGeek 擴充

前置基礎知識學習


1.引言

1.1 目的

為了更好的指導部署與測試藝術升系統nginx網站服務器高性能同時下安全穩定運行,需要對nginx服務進行調優與加固;

本次進行Nginx服務調優加固主要從以下幾個部分:

  • 模塊性能優化
  • 系統內核優化
  • 編譯安裝優化
  • 性能參數優化
  • 安全加固配置
1.2 目標范圍

本文檔僅供內部使用,禁止外傳,幫助研發人員,運維人員對系統長期穩定的運行提供技術文檔參考。

1.3 讀者對象
  1. 項目經理
  2. 開發人員
  3. 測試人員
  4. 運維人員
  5. 相關領導

2.參考說明

2.1 幫助參考

Nginx是一個高性能的HTTP和反向代理服務器,也是一個IMAP/POP3/SMTP服務器。Nginx作為負載均衡服務器, Nginx 既可以在內部直接支持 Rails 和 PHP 程序對外進行服務,也可以支持作為 HTTP代理服務器對外進行服務。

Nginx版本選擇:

  • Mainline version 最新版本,推薦測試的業務項目的時候使用
  • Stable version 穩定版本,推薦項目上線實際使用
  • Legacy versions 歷史版本,不推薦選擇可能存在脆弱性漏洞

項目結構:

#編譯后的nginx項目結結構
/etc/nginx/
├── client_body_temp  #客戶端上面的臨時文件存放目錄
├── conf              #nginx的配置文件存放目錄
├── fastcgi_temp      #fastcgi的臨時文件存放目錄
├── html              #存放靜態資源或者腳本文件的地方
├── logs              #nginx日志文件
├── proxy_temp        #nginx正向/反向代理緩存文件存放目錄
├── sbin              #nginx可執行文件
├── scgi_temp         #scgi臨時文件目錄
└── uwsgi_temp        #uwsgi臨時文件存放目錄

Nginx文檔幫助: http://nginx.org/en/docs/
Nginx首頁地址目錄: /usr/share/nginx/html
Nginx配置文件:

  • /etc/nginx/nginx.conf
  • /usr/local/nginx/conf/nginx.conf
  • /usr/local/etc/nginx/nginx.conf

2.2 參數說明

localtion 請求匹配的url實是一個正則表達式:

# 語法規則: 
location [=|~|~*|^~] /uri/ { ... }

# 參數解析: 
= 表示精確匹配,這個優先級也是最高的
/ 通用匹配,任何請求都會匹配到,默認匹配.
~ 表示區分大小寫的正則匹配
~* 表示不區分大小寫的正則匹配(和上面的唯一區別就是大小寫) !~和!~*分別為區分大小寫不匹配及不區分大小寫不匹配的正則
!~,!~* : 分別標識為區分大小寫不匹配及不區分大小寫不匹配的正則
^~ 表示 uri 以某個常規字符串開頭,理解為匹配 url 路徑即可。nginx 不對 url 做編碼,因此請求為/static/20%/aa,可以被規則^~ /static/ /aa 匹配到(注意是空格)

Nginx 匹配判斷表達式:

-f 和 !-f: 用來判斷是否存在文件
-d 和 !-d: 用來判斷是否存在目錄
-e 和 !-e: 用來判斷是否存在文件或目錄
-x 和 !-x: 用來判斷文件是否可執行

例如,匹配末尾為如下后綴的靜態並判斷是否存在該文件, 如不存在則404。

location ~* \.(js|css|jpg|jpeg|gif|png|swf)$ {
  if (-f $request_filename) { 
    return 403;
    break;
  }
}

3.3 模塊說明

查看可用模塊編譯參數:http://nginx.org/en/docs/configure.html

#可以通過運行 "./configure --help" 查看編譯幫助,決定是否需要安裝哪些模塊,比如下面的ssi模塊能夠實現訪問shtml頁面
./configure -help

http_gzip模塊
開啟gzip壓縮輸出(常常是大於1kb的靜態文件),減少網絡傳輸;

gzip_min_length 1k #設置允許壓縮的頁面最小字節數頁面字節數從content-length中進行獲取,默認值是20
gzip_buffers 4 16k #設置系統獲取幾個單位的緩存用於存儲gzip的壓縮結果數據流。4 16k代表以16k為單位,安裝原始數據大小以16k為單位的4倍申請內存。
gzip_comp_level 2 #gzip壓縮比,其值從1到9數字越大壓縮率越高,越消耗CPU負載也越高
gzip_types #匹配mime類型進行壓縮,無論是否指定”text/html”類型總是會被壓縮的,推薦配置:`gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript。`
gzip_http_version 1.0 #用於識別 http 協議的版本早期的瀏覽器不支持 Gzip 壓縮,用戶就會看到亂碼,所以為了支持前期版本加上了這個選項;如果你用了 Nginx 的反向代理並期望也啟用 Gzip 壓縮的話,由於末端通信是 http/1.0,故請設置為 1.0。
gzip_proxied any #Nginx作為反向代理的時候啟用,決定開啟或者關閉后端服務器返回的結果是否壓縮,匹配的前提是后端服務器必須要返回包含”Via”的 header頭。
gzip_vary on #和http頭有關系會在響應頭加個 Vary: Accept-Encoding ,可以讓前端的緩存服務器緩存經過gzip壓縮的頁面,例如用Squid緩存經過Nginx壓縮的數據。

http_fastcgi_module模塊
nginx可以用來請求路由到FastCGI服務器運行應用程序由各種框架和PHP編程語言等。可以開啟FastCGI的緩存功能以及將靜態資源進行剝離,從而提高性能。

指令:fastcgi_temp_path  #定義FastCGI緩存文件保存臨時路徑。
指令:fastcgi_cache_path  #定義FastCGI緩存文件保存路徑和緩存的其它參數。緩存數據以二進制數據文件形式存儲,緩存文件名和key都是通過對訪問URL使用MD5計算獲得的結果。緩存文件先保存至fastcgi_temp_path指定的臨時目錄下,然后通過重命名操作移至fastcgi_cache_path指定的緩存目錄。建議fastcgi_temp_path和fastcgi_cache_path設為同一分區,同分區移動操作效率更高。示例:
fastcgi_temp_path /tmp/fastcgi_temp;
fastcgi_cache_path /tmp/fastcgi_cache levels=1:2 keys_zone=cache_fastcgi:16m inactive=30m max_size=1g;
# levels指定了目錄結構,子目錄數以16為基數;
# keys_zone指定了共享內存區名和大小,用於保存緩存key和數據信息;
# inactive指定了緩存數據保存的時間,當這段時間內未被訪問將被移出;
# max_size指定了緩存使用的最大磁盤空間,超過容量時將最近最少使用數據刪除。
#示例中使用/tmp/fastcgi_temp作為FastCGI緩存的臨時目錄;/tmp/fastcgi_cache作為FastCGI緩存保存的最終目錄;一級子目錄為16的一次方16個,二級子目錄為16的2次方256個;共享內存區名為cache_fastcgi,占用內存128MB;緩存過期時間為30分鍾;緩存數據保存於磁盤的最大空間大小為1GB。

指令:fastcgi_cache_key        # 定義FastCGI緩存關鍵字。啟用FastCGI緩存必須加上這個配置,不然訪問所有PHP的請求都為訪問第一個PHP文件URL的結果。
指令:fastcgi_cache_valid      # 為指定的Http狀態碼指定緩存時間。
指令:fastcgi_cache_min_uses   # 指定經過多少次請求相同的URL將被緩存。
指令:fastcgi_cache_use_stale  # 指定當連接FastCGI服務器發生錯誤時,哪些情況使用過期數據回應。
指令:fastcgi_cache            # 緩存使用哪個共享內存區

keepalive模塊
長連接對性能有很大的影響,通過減少CPU和網絡開銷需要開啟或關閉連接;

  • keepalive_timeout 閑長連接保持打開狀態的時間;
  • keepalive_requests 單個客戶端長連接可以請求的數量;
  • keepalive 上游服務器長連接的相關指令,每個工作進程中空閑長連接到上游服務器保持開啟的連接數量(沒有默認值)。
    要使用連接到上游服務器的長連接,必須要配置文件中下面的指令:
    proxy_http_version 1.1;
    proxy_set_header Connection "";

http_ssl_module模塊
Nginx開啟支持Https協議的SSL模塊

#Nginx SSL性能調優
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
#注意這里的加密方式
ssl_ciphers ECDHE-RSA-AES256-SHA384:AES256-SHA256:RC4:HIGH:!MD5:!aNULL:!eNULL:!NULL:!DH:!EDH:!AESGCM;
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;

3.服務優化

3.1 系統內核

Linux內核參數部分默認值不適合高並發,Linux內核調優,主要涉及到網絡和文件系統、內存等的優化,

  • 臨時方法可以通過調整/Proc文件系統,需要注意調整/Proc文件系統系統重啟后還原至默認值(不推薦)。
  • 永久修改/etc/sysctl.conf配置文件永久保存

下面是我常用的內核調優配置:

grep -q "net.ipv4.tcp_max_tw_buckets" /etc/sysctl.conf || cat >> /etc/sysctl.conf << EOF
########################################
net.core.rmem_default = 262144
net.core.rmem_max = 16777216
net.core.wmem_default = 262144
net.core.wmem_max = 16777216

#緩沖區隊列設置與連接及其如何排隊相關#
#調節系統同時發起的tcp連接數,在高並發的請求中,默認的值可能會導致鏈接超時或者重傳,因此需要結合並發請求數來調節此值。
#net.core.somaxconn = 262144
#在提交到CPU前網卡中數據包緩沖的速率,高帶寬下提高這個值可提高性能;檢查內核日志文件中有關這個設置的錯誤,根據網卡文檔中的建議修改這個值。
net.core.netdev_max_backlog = 262144
#設定系統中最多有多少個TCP套接字不被關聯到任何一個用戶文件句柄上
net.ipv4.tcp_max_orphans = 262144
#用於記錄那些尚未收到客戶端確認信息的連接請求的最大值(根據類才更改)
net.ipv4.tcp_max_syn_backlog = 1024

#設定timewait的數量默認是180000設為10000。
net.ipv4.tcp_max_tw_buckets = 10000

#在高並發情況端口值的起止范圍一般端口號設置是1024到65000,用來設定允許系統打開的端口范圍;
net.ipv4.ip_local_port_range = 1024 65500

#用於設置啟用timewait快速回收
net.ipv4.tcp_tw_recycle = 1

#用於設置開啟重用,允許將TIME-WAIT sockets重新用於新的TCP連接。
net.ipv4.tcp_tw_reuse = 1

#用於設置開啟SYN Cookies,當出現SYN等待隊列溢出時,啟用cookies進行處理。
net.ipv4.tcp_syncookies = 1

#決定了內核放棄連接之前發送SYN+ACK包的數量。
net.ipv4.tcp_synack_retries = 1
#表示在內核放棄建立連接之前發送SYN包的數量。
net.ipv4.tcp_syn_retries = 1
#決定了套接字保持在FIN-WAIT-2狀態的時間。默認值是60秒。
#正確設置這個值非常重要,有時即使一個負載很小的Web服務器,也會出現大量的死套接字而產生內存溢出的風險。
net.ipv4.tcp_fin_timeout = 30
#選項表示當keepalive啟用的時候,TCP發送keepalive消息的頻度。默認值是2(單位是小時)。
net.ipv4.tcp_keepalive_time = 600
net.ipv4.tcp_keepalive_intvl = 30
net.ipv4.tcp_keepalive_probes = 3
net.ipv4.tcp_mem = 786432 1048576 1572864


#文件描述符系統級別的限制#
kernel.sem = 250 32000 100 128
fs.file-max = 6815744
vm.swappiness = 10
fs.aio-max-nr = 1048576
EOF
sysctl -p

文件描述符
文件描述符是操作系統資源,用於表示連接、打開的文件,以及其他信息。NGINX 每個連接可以使用兩個文件描述符。
例如如果NGINX充當代理時,通常一個文件描述符表示客戶端連接,另一個連接到代理服務器,如果開啟了HTTP 保持連接,這個比例會更低(譯注:為什么更低呢)。

對於有大量連接服務的系統,下面的設置可能需要調整一下:

#修改文件描述符方式
vim /etc/security/limits.conf
* - nofile 65536  #用戶級別文件描述符限制

#然后進行啟動文件修改
echo "ulimit -Hsn 65536" >> /etc/profile

3.2 編譯優化

精簡模塊:Nginx由於不斷添加新的功能,附帶的模塊也越來越多,建議一般常用的服務器軟件使用源碼編譯安裝管理;

(1) 減小Nginx編譯后的文件大小

  • 編譯Nginx時默認以debug模式進行,而在debug模式下會插入很多跟蹤和ASSERT之類的信息,編譯完成后一個Nginx要有好幾兆字節;因此可以在編譯之前,修改相關源碼,取消debug模式;
# 找到源碼目錄下 auto/cc/gcc  文件 debug
CFLAGS="$CFLAGS -g" #注釋掉或刪掉這兩行,即可取消debug模式。

ls -alh /usr/local/nginx/sbin/nginx
-rwxr-xr-x. 1 root root 915K Aug 17 09:49 /usr/local/nginx/sbin/nginx  #可以看到體積大大減少

(2) 指定GCC編譯參數
修改GCC編譯參數提高編譯優化級別穩妥起見采用 -O2 這也是大多數軟件編譯推薦的優化級別。

  • Nginx源碼文件 auto/cc/gcc 搜索 NGX_GCC_OPT默認GCC編譯參數為-O,可以直接修改內容為 NGX_GCC_OPT="-O2" 或者在 ./configure配置時添加--with-cc-opt='-O2'選項
--with-cc-opt='-O3'  #編譯級別
--with-cpu-opt=CPU   #為特定的 CPU 編譯,有效的值包括:pentium, pentiumpro, pentium3, # pentium4, athlon, opteron, amd64, sparc32, sparc64, ppc64

WeiyiGeek.

GCC編譯參數優化 [可選項] 總共提供了5級編譯優化級別:

  • -O0:無優化。
  • -O和-O1:使用能減少目標代碼尺寸以及執行時間並且不會使編譯時間明顯增加的優化,在編譯大型程序的時候會顯著增加編譯時內存的使用。
  • -O2:包含-O1的優化並增加了不需要在目標文件大小和執行速度上進行折衷的優化。編譯器不執行循環展開以及函數內聯。此選項將增加編譯時間和目標文件的執行性能。
  • -Os:可以看成 -O2.5,專門優化目標文件大小,執行所有的不增加目標文件大小的-O2優化選項,並且執行專門減小目標文件大小的優化選項。適用於磁盤空間緊張時使用。但有可能有未知的問題發生,況且目前硬盤容量很大,常用程序無必要使用。
  • -O3:打開所有 -O2 的優化選項外增加 -finline-functions、-funswitch-loops、-fgcse-after-reload 優化選項。相對於 -O2 性能並未有較多提高,編譯時間也最長,生成的目標文件也更大更占內存,有時性能不增反而降低,甚至產生不可預知的問題(包括錯誤),所以並不被大多數軟件安裝推薦,除非有絕對把握方可使用此優化級別。

常用編譯參數:

#編譯0:常規編譯參數
configure arguments: 
#安裝的目錄或者路徑#
--prefix=/etc/nginx 
--sbin-path=/usr/sbin/nginx 
--modules-path=/usr/lib64/nginx/modules 
--conf-path=/etc/nginx/nginx.conf 
--error-log-path=/var/log/nginx/error.log 
--http-log-path=/var/log/nginx/access.log 
--pid-path=/var/run/nginx.pid 
--lock-path=/var/run/nginx.lock
#執行對應模塊nginx所保留的臨時文件#
--http-client-body-temp-path=/var/cache/nginx/client_temp 
--http-proxy-temp-path=/var/cache/nginx/proxy_temp 
--http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp 
--http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp 
--http-scgi-temp-path=/var/cache/nginx/scgi_temp 
#啟動的用戶和組用戶#
--user=nginx 
--group=nginx 
#模塊參數#
--with-compat 
--with-file-aio 
--with-threads 
--with-http_addition_module 
--with-http_auth_request_module 
--with-http_dav_module 
--with-http_flv_module 
--with-http_gunzip_module 
--with-http_gzip_static_module 
--with-http_mp4_module 
--with-http_random_index_module 
--with-http_realip_module 
--with-http_secure_link_module 
--with-http_slice_module 
--with-http_ssl_module 
--with-http_stub_status_module 
--with-http_sub_module 
--with-http_v2_module 
--with-mail 
--with-mail_ssl_module 
--with-stream 
--with-stream_realip_module 
--with-stream_ssl_module 
--with-stream_ssl_preread_module
#設置額外的參數將被添加到CFLAGS#
--with-cc-opt='-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic -fPIC' 
#設置附件參數,鏈接系統庫#
-with-ld-opt='-Wl,-z,relro -Wl,-z,now -pie'


#編譯1:除多余模塊
./configure \
"--prefix=/App/nginx" \ 
"--user=nginx" \ 
"--group=nginx" \
"--with-http_stub_status_module" \
"--without-http_auth_basic_module" \
"--without-http_autoindex_module" \
"--without-http_browser_module" \
"--without-http_empty_gif_module" \
"--without-http_geo_module" \
"--without-http_limit_conn_module" \
"--without-http_limit_req_module" \
"--without-http_map_module" \
"--without-http_memcached_module" \
"--without-http_proxy_module" \
"--without-http_referer_module" \
"--without-http_scgi_module" \
"--without-http_split_clients_module" \
"--without-http_ssi_module" \
"--without-http_upstream_ip_hash_module" \
"--without-http_upstream_keepalive_module" \
"--without-http_upstream_least_conn_module" \
"--without-http_userid_module" \
"--without-http_uwsgi_module" \
"--without-mail_imap_module" \
"--without-mail_pop3_module" \
"--without-mail_smtp_module" \
"--without-poll_module" \
"--without-select_module" \
"--with-cc-opt='-O2'"

3.3 性能優化

緩存和壓縮與限制可以提高性能
NGINX的一些額外功能可用於提高Web應用的性能,調優的時候web應用不需要關掉但值得一提,因為它們的影響可能很重要。

  • 1)緩存
    一個啟用NGINX緩存的情景,一組web或者應用服務器負載均衡,可以顯著縮短對客戶端的響應時間,同時大幅度降低后端服務器的負載。緩存本身就可以作個專題來講,這里我們就不試圖講它了。
# 網頁資源緩存
location ~* \.(xml|html|htm)$ {
  # 資源決絕對目錄設置
  root /var/www/html;
  # 日志文件的相對路徑或完整路徑
  access_log /path/to/file.log;
  # 開啟日志記錄
  access_log on;
  # 設置過期時間
  expires 24h;
}

# 樣式、JS、圖片資源緩存
location ~* \.(css|js|ico|gif|jpg|jpeg|png)$ {
  root /var/www/html/res;
  # 禁用404錯誤日志
  log_not_found off;
  # 關閉日志
  access_log off;
  # 緩存時間7天
  expires 7d;
}

# 字體資源緩存
location ~* \.(eot|ttf|otf|woff|woff2|svg)$ {
  root /var/www/html/static;
  log_not_found off;
  access_log off;
  expires max;
}
  • 2)壓縮
    所以使用更小的網絡帶寬。然而盡管壓縮數據會消耗CPU資源,但當需要減少網絡帶寬使用時這樣做非常有效。需要注意的是,不能對已壓縮的文件再壓縮例如JPEG 文件。
# 啟用 gzip 壓縮
gzip on;
# 啟用gzip壓縮的最小文件,小於設置值的文件將不會壓縮
gzip_min_length 2k;
# gzip 壓縮級別,1-10,數字越大壓縮的越好,也越占用CPU時間,后面會有詳細說明
gzip_comp_level 2;
# 進行壓縮的文件類型,javascript有多種形,其中的值可以在 mime.types 文件中找到。
gzip_types text/plain text/css text/javascript application/javascript application/x-javascript application/xml application/x-httpd-php image/x-icon image/jpeg image/gif image/png image/svg+xml image/avif image/webp font/ttf font/opentype;
# 建議在http header中添加Vary: Accept-Encoding支持
gzip_vary on;
  • 3)限制
    防止用戶消耗太多的資源,避免影響系統性能和用戶體驗及安全性,以下是相關的指令:
limit_conn and limit_conn_zone  # NGINX接受客戶連接的數量限制,例如單個IP地址的連接。設置這些指令可以防止單個用戶打開太多的連接,消耗超出自己的資源。
limit_req and limit_req_zon #NGINX處理請求的速度限制,與limit_rate有相同的功能。可以提高安全性,尤其是對登錄頁面,通過對用戶限制請求速率設置一個合理的值,避免太慢的程序覆蓋你的應用請求(比如DDoS攻擊)。
limit_rate #  傳輸到客戶端響應速度的限制(每個打開多個連接的客戶消耗更多的帶寬)。設置這個限制防止系統過載,確保所有客戶端更均勻的服務質量。
max_conns #上游配置塊中服務器指令參數。在上游服務器組中單個服務器可接受最大並發數量。使用這個限制防止上游服務器過載。設置值為0(默認值)表示沒有限制。
queue (NGINX Plus - 商業版本提供) # 創建一個隊列,用來存放在上游服務器中超出他們最大max_cons限制數量的請求。這個指令可以設置隊列請求的最大值,還可以選擇設置在錯誤返回之前最大等待時間(默認值是60秒)。如果忽略這個指令,請求不會放入隊列。

簡單示例:

http {
  # 請根據業務需求配置同一IP地址連接數
  limit_conn_zone $binary_remote_addr zone=www_weiyigeek_top:10m;
  # 請根據業務需求配置同一IP地址請求速率
  limit_req_zone $binary_remote_addr zone=blog_weiyigeek_top:10m rate=1r/s;

  server {
    # 建議創建黑白名單
    allow 內部IP或負載均衡IP;
    deny 惡意IP;
    
    # 限流
    location ^~ /download/ { 
      # 表示單個IP連接數不超過 2 個
      limit_conn www_weiyigeek_top 2; 
      # 表示單個IP請求速率為1s一個, 允許超過頻率限制的請求數不多於5個,最多請求不能超過 burst + rate 數量。
      limit_req zone=blog_weiyigeek_top burst=5 nodelay; 
      alias /data/weiyigeek.top/download/;
    }
  }
}

  • 4)減少磁盤IO
    減少磁盤IO次數可以幫助我們更好的提升服務器性能,增強服務器的負載能力。
# 關閉不需要記錄指定目錄或者文件訪問日志
access_log off;
error_log /dev/null

# 為日志寫入創建緩存區減少IO次數,例如下面當緩存達到128k或者日志刷新時間為1m時將寫入日志文件中(gzip 壓縮日志-按需開啟)
access_log /var/log/nginx/access.log main buffer=128k gzip flush=1m;

3.4 運營優化

1) 永久重定向

如果你的站點需要讓http URL跳轉到https,則非建議設置永久重定向,而非臨時重定向,這可以幫助你站點更好的被收錄(SEO)。

例如,配置 http 向 https 跳轉 (永久)

# 方式1.Redirect(重定向)- 推薦
server {
  listen 80;
  server_name weiyigeek.top www.weiyigeek.top;
  return 301 https://$host$request_uri;
}

# 方式2.ReWrite 重寫
server {
  listen 80;
  server_name weiyigeek.top www.weiyigeek.top;
  # 判斷請求host是否是 www.weiyigeek.top ,如果是 weiyigeek.top 則重寫為 www.weiyigeek.top 
  if ($http_host !~ "^www\.weiyigeek\.top$" {
    rewrite ^(.*) https://www.weiyigeek.top$1 permanent;
  }
}

3.5 配置優化

nginx配置文件指令優化一覽表

位置 指令 說明 優化
main worker_processes 工作進程數的選擇包括(但不限於)CPU核心的數量、存儲數據的硬盤數量及負載模式 設置 auto 或者 `cat /proc/cpuinfo
main worker_cpu_affinity Nginx默認未開啟CPU綁定,綁定工作進程到對應CPU核心 多核CPU建議設置CPU綁定,綁定樣例:
worker_processes 4;
worker_cpu_affinity 0001 0010 0100 1000;
main worker_rlimit_nofile 打開文件數限制(默認值1024),受限於系統的用戶進程打開文件數限制,未設置則使用系統默認值 修改用戶打開文件數限制:
echo "* - nofile 65536" >> /etc/security/limits.conf
修改所有Shell和通過Shell啟動的進程打開文件數限制:
echo "ulimit -n 65536" >> /etc/profile
臨時生效(重啟后生效): ulimit -n 65536
main worker_connections Nginx一個工作進程的最大同時連接數,不僅限於客戶端連接,包括了和后端被代理服務器等其他的連接 建議設置成與 worker_rlimit_nofile 值相等
mian sendfile 在http或server或location環境中包含sendfile指令。
NGINX可以不需要切換到用戶態,就把緩存或磁盤上的內容寫入套接字而且寫的速度非常快,消耗更少的CPU周期。
注意盡管使用sendfile()數據拷貝可以繞過用戶態但不適用於常規的NGINX處理改變內容的鏈和過濾器比如gzip
建議設置成 on
main-events accept_mutex 驚群問題:
如果指令值為 on 啟用,那么將輪流喚醒一個工作進程接收處理新的連接,其余工作進程繼續保持睡眠
如果指令值為 off 關閉,那么將喚醒所有工作進程,由系統通過use指令指定的網絡IO模型調度決定由哪個工作進程處理,未接收到連接請求的工作進程繼續保持睡眠
on開啟狀態為了穩定參數值;
off關閉狀態提高性能和吞吐量但是會帶來上下文切換增多或者負載升高等等其它資源更多消耗的后果(推薦)
main-events use 定義了Nginx設置用於復用客戶端線程的輪詢方法(也可稱多路復用網絡IO模型),自然是選擇效率更高的優先(默認即可) use epoll
main open_file_cache 開啟關閉打開文件緩存默認值 off 關閉,強烈建議開啟可以避免重新打開同一文件帶來的系統開銷節省響應時間 max=數字設置緩存元素的最大數量
inactive=時間設置超時 當緩存溢出時使用LRU(最近最少使用)算法刪除緩存中的元素;在這段時間內緩存元素如果沒有被訪問將從緩存中刪除;
open_file_cache max=65536 inactive=60s
main open_file_cache_valid 設置檢查open_file_cache緩存的元素的時間間隔 80s
main open_file_cache_min_uses 設置在由open_file_cache指令的inactive參數配置的超時時間內文件應該被訪問的最小次數。
如果訪問次數大於等於此值,文件描述符會保留在緩存中,否則從緩存中刪除。
1
main error_log 錯誤的訪問請求日志記錄,當並發很大時Nginx的訪問日志和錯誤日志的保存肯定會造成對磁盤的大量讀寫也將影響Nginx的性能 注釋即可 或者 錯誤日志設置為 error 或者 crit
main-http access_log 成功的訪問請求日志記錄, 如必須保存日志,可以按每日或者每時或者其它時間段對日志做切割,這也可以減小IO,雖然可能效果不是特別大,不過因為日志文件尺寸變小了很多,也方便查閱或歸檔分析日志 建議開啟日志記錄級別 main
main-http gzip 默認開啟了gzip壓縮功能:增加CPU的處理時間和負載(默認即可)
關閉gzip壓縮功能:雖然減少了CPU計算節省了服務器的響應時間,但網站頁面總體響應時間反而加長了靜態文件數據傳輸時間增加;
設置 gzip on 即可;(該模塊中有附帶參數)
main-http keepalive_timeout 空閑長連接保持打開狀態的時間;復用之前已建立的TCP連接接收請求、發送回應,減少重新建立TCP連接的資源時間開銷 正數為開啟持久連接(常規設置120)而0關閉。
當網站頁面內容以靜態為主時,開啟持久連接;
動態網頁且不能被轉化為靜態頁面,則關閉持久連接;
main-http keepalive_requests 單個客戶端長連接可以請求的數量但是當使用壓力測試工具從一個客戶端發送多個請求測試時,這個值設更高些特別有用 默認值是100
main-http-server-location expires 瀏覽器緩存設置HTTP應答中的“Expires”和“Cache-Control”頭標。"Expires"一般結合"Last-Modified"使用比較緩存時間,避免了從服務器再次傳送文件內容減小了服務器壓力,節省了帶寬同時也提高了用戶訪問速度 -1 表示永遠過期不緩存,推薦靜態文件如js/css等等訪問設置 expires 30da;

4.安全配置

描述:Nginx因為安全配置不合適導致的安全問題,Nginx的默認配置中存在一些安全問題,例如版本號信息泄露、未配置使用SSL協議等。
對Nginx進行安全配置可以有效的防范一些常見安全問題,按照基線標准做好安全配置能夠減少安全事件的發生,保證采用Nginx服務器系統應用安全運行;

Nginx安全配置項:

0.隱藏nginx服務及其版本

溫馨提示: 在修改相應的源代碼文件后需重新編譯。

#方式1:
#vi nginx-1.9.11/src/http/ngx_http_header_filter_module.c
static char ngx_http_server_string[] = "Server: LTWS" ; #修改處
#修改nginx_http_header_filter_module
#vi nginx-1.9.11/src/http/ngx_http_special_response.c
static u_char ngx_http_error_full_tail[] =
"<center> NGINX_VER </center>" 
"<hr><center> http://www.weiyigeek.com</center>" 
"</body>" 
"</html>" 
;

static u_char ngx_http_error_tail[] =
"<hr><center>LTWS</center>" 
"</body>" 
"</html>" 
;

#設置響應頭版本版本
#vim src/core/nginx.h
#define NGINX_VERSION      "secWaf"            #可以改成你要的版本號
#define NGINX_VER          "1.1" NGINX_VERSION #改成你的服務名稱

WeiyiGeek.修改服務名及其版本對應文件

設置成功后驗證:
WeiyiGeek.驗證服務名及其版本修改


1.低權限用戶運行服務

應配置非root低權限用戶來運行nginx服務,設置如下建立Nginx用戶組和用戶,采用user指令指運行用戶

加固方法:

groupadd nginxweb;
useradd -M -g nginxweb -s /sbin/nologin nginxweb 

#nginx.conf 中配置 或者編譯 的時候指定
#nginx 安裝編譯參數--user=nginx --group=nginx
user nginxweb

2.配置SSL及其會話復用

我們應該為提供的站點配置Secure Sockets Layer Protocol (SSL協議),配置其是為了數據傳輸的安全,SSL依靠證書來驗證服務器的身份,並為瀏覽器和服務器之間的通信加密。

server {
  # 開啟 SSL 與 http2 支持
  listen 443 ssl http2;
  listen [::]:443 ssl http2;
  # 開啟 SSL ,如果想http 與 https 公用一個配置則可以將其注釋( the "ssl" directive is deprecated )
  # ssl on;

  # 配置證書鏈與證書密鑰
  ssl_certificate      /etc/nginx/ssl/fullchain.cer;
  ssl_certificate_key  /etc/nginx/ssl/weiyigeek.top.key;

  # ssl會話復用超時時間以及會話復用緩存大小
  ssl_session_timeout 1d;
  ssl_session_cache shared:MozSSL:10m;  # about 40000 sessions
  ......
}

3.限制SSL協議與加密套件

不應使用不安全SSLv2、SSLv3協議即以下和存在脆弱性的加密套件(ciphers), 我們應該使用較新的TLS協議也應該優於舊的,並使用安全的加密套件。

# 兼容性較為通用的SSL協議與加密算法套件
ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
ssl_ciphers 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:ECDHE:ECDH:AES:HIGH:EECDH+CHACHA20:EECDH+CHACHA20-draft:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:!NULL:!aNULL:!eNULL:!EXPORT:!PSK:!ADH:!DH:!DES:!MD5:!RC4;

# 瀏覽器客戶端自動協商加密套件(為了兼容性)
ssl_prefer_server_ciphers  on;

4.攔截垃圾信息

HTTP Referrer Spam是垃圾信息發送者用來提高他們正在嘗試推廣的網站的互聯網搜索引擎排名一種技術,如果他們的垃圾信息鏈接顯示在訪問日志中,並且這些日志被搜索引擎掃描,則會對網站排名產生不利影響
加固方法:

if ( $http_referer ~* (babes|forsale|girl|jewelry|love|nudit|organic|poker|porn|sex|teen) ){
  return 403;
}

5.惡意掃描攔截

當惡意攻擊者采用掃描器進行掃描時候利用use-agent判斷是否是常用的工具掃描以及特定的版本,是則返回錯誤或者重定向;

# 封殺各種user-agent
if ($http_user_agent ~* "java|python|perl|ruby|curl|bash|echo|uname|base64|decode|md5sum|select|concat|httprequest|httpclient|nmap|scan|nessus|wvs" ) {
    return 403;
}

if ($http_user_agent ~* "" ) {
    return 403;
}

# 封殺特定的文件擴展名比如.bak以及目錄;
location ~* \.(bak|swp|save|sh|sql|mdb|svn|git|old)$ {
  rewrite ^/(.*)$  $host  permanent;
}
location /(admin|phpadmin|status)	{ deny all; }

WeiyiGeek.惡意掃描攔截


6.禁用WebDAV

Nginx支持webdav,雖然默認情況下不會編譯。如果使用webdav,則應該在Nginx策略中禁用此規則。
加固方法: dav_methods 應設置為off


7.禁用Nginx狀態模塊

當訪問一個特制的URL時,如"../nginx.status",stub_status模塊提供一個簡短的Nginx服務器狀態摘要,大多數情況下不應啟用此模塊。
加固方法:nginx.conf文件中stub_status不應設置為:on


8.關閉默認錯誤頁上的Nginx版本號

如果在瀏覽器中出現Nginx自動生成的錯誤消息,默認情況下會包含Nginx的版本號,這些信息可以被攻擊者用來幫助他們發現服務器的潛在漏洞
加固方法: 關閉"Server"響應頭中輸出的Nginx版本號將server_tokens應設置為:off

server_tokens off 

9.設置client_body_timeout超時

client_body_timeout設置請求體(request body)的讀超時時間。僅當在一次readstep中,沒有得到請求體,就會設為超時。超時后Nginx返回HTTP狀態碼408(Request timed out)。
加固方法:nginx.conf文件中client_body_timeout應設置為:10


10.設置client_header_timeout

client_header_timeout設置等待client發送一個請求頭的超時時間(例如:GET / HTTP/1.1)。僅當在一次read中沒有收到請求頭,才會設為超時。超時后Nginx返回HTTP狀態碼408(Request timed out)。

加固方法:nginx.conf文件中client_header_timeout應設置為:10


11.設置keepalive_timeout超時

keepalive_timeout設置與client的keep-alive連接超時時間。服務器將會在這個時間后關閉連接。

加固方法:nginx.conf文件中keepalive_timeout應設置為:55


12.設置send_timeout超時

send_timeout設置客戶端的響應超時時間。這個設置不會用於整個轉發器,而是在兩次客戶端讀取操作之間。如果在這段時間內,客戶端沒有讀取任何數據,Nginx就會關閉連接。

加固方法:nginx.conf文件中send_timeout應設置為:10


13.Nginx可用的方法應限制為GET, HEAD, POST

GET和POST是Internet上最常用的方法。Web服務器方法在RFC 2616中定義禁用不需要實現的可用方法。

加固方法:

#nginx.conf文件中應存在
if ($request_method !~ ^(GET|HEAD|POST)$ )

14.控制並發連接limit_zone slimits

limit_zone 配置項限制來自客戶端的同時連接數。通過此模塊可以從一個地址限制分配會話的同時連接數量或特殊情況。

加固方法:nginx.conf文件中limit_zone應設置為:slimits $binary_remote_addr 5m

# 設定保存各個鍵(例如$binary_remote_addr)狀態的共享內存空間的參數,zone=空間名字:大小大小的計算與變量有關
limit_conn_zone $binary_remote_addr zone=ops:10m;

15.控制並發連接limit_conn slimits

該配置項控制一個會話同時連接的最大數量,即限制來自單個IP地址的連接數量。

加固方法:nginx.conf 文件中 limit_conn 應設置為: slimits 5

# 表示同一IP同一時間只允許10個連接
limit_conn ops 5;

16.主機防webshell跨目錄瀏覽以及列目錄

加固方法:

a.在nginx.conf里把每個虛擬主機站點請求端口給區別開
b.為每個站點建一個conf,並進行配置
c.修改php-fpm啟動腳本
d.啟動服務

#在main-http-server段中設置開啟或者關閉(對於需要列目錄的則開啟,否則默認是關閉的)
autoindex off

17.文件名解析漏洞php_info,加入fcgi.conf即可
if ($request_filename ~* (.*)\.php) {
    set $php_url $1;
}

if (!-e $php_url.php) {
    return 403;
}

18.訪問權限控制nginx

加固方法:

#nginx.conf
location ~ ^/script/ {
    auth_basic "welcome to weiyigeek.github.io";
    auth_basic_user_file /var/www/test/script/.htpasswd;
}

#建立htpasswd密碼進行認證
mkdir /var/www/test/script
perl -e "print crypt('baidu.eud',"n");"
nnUygd3RSf3u6

echo 'nginx:nnUygd3RSf3u6' > /var/www/test/script/.htpasswd
/usr/local/nginx/sbin/nginx -s reload

WeiyiGeek.


19.異常狀態返回200隱藏URL

解決辦法:

server{
  listen       80;
  server_name  weiyigeek.top;
  index index.html index.htm index.php;
  root  /data/web;
  error_page 404 =200 /404.jpg;
}

20.安全模塊的選擇
# 安全檢測模塊選擇
http_sub_module
http_stub_status_module
xss-nginx-module
with-http_ssl_module

21.記錄訪問者真實IP

描述后端獲取Proxy后的真實Client的IP獲取需要安裝--with-http_realip_module,然后后端程序采用JAVA(request.getAttribute("X-Real-IP"))進行獲取;

set_real_ip_from 100.0.0.0/8;#(這里是已知的代理ip)
real_ip_header X-Forwarded-For;
real_ip_recursive on;

# 代理轉發
location / {
  proxy_pass http://weiyigeek.top
}

proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
set $Real $http_x_forwarded_for;
if ( $Real ~ (\d+)\.(\d+)\.(\d+)\.(\d+),(.*) ){
    set $Real $1.$2.$3.$4;
}
proxy_set_header X-Real-IP $remote_addr;

#區別
$proxy_add_x_forwarded_for #較下面多一個$remote_addr的(只能獲取到與服務器本身直連的上層請求ip)
$http_x_forwarded_for

#日志獲取
$http_x_real_ip|$remote_addr  #前提條件是cdn 那邊也設置了X-forward否則獲取的是cdn的ip

22.地區訪問響應措施

描述: 如果要使用geoip地區選擇,我們需要再nginx編譯時加入 --with-http_geoip_module 編譯參數。

# 例如,訪問者IP地址不為中國或者美國的都返回403。
if ( $geoip_country_code !~  ^(CN|US)$ ) {
  return 403;
}

23.資源防盜鏈設置

描述: 為了防止外部站點引用我們的靜態資源,我們需要設置那些域名可以訪問我們的靜態資源。

# none : "Referer" 來源頭部為空的情況
# blocked : "Referer" 來源頭部不為空
# server_names : "Referer"來源頭部包含當前的server_names(當前域名)
location ~* \.(gif|jpg|png|swf|flv)$ { 
  valid_referers none blocked weiyigeek.top server_names ~\.google\. ~\.baidu\.; #這是可以盜鏈的域名或IP地址,一般情況可以把google,baidu,sogou,soso,bing,feedsky,zhuaxia,photozero等域名放進來
  if ($invalid_referer) { 
    #這樣設置能夠防盜鏈,不斷地302重定向很多次,可能會加重服務器的負擔,所以不建議這么做,除非有單獨的圖片服務器支持
    return 403; # 或者返回 403 錯誤代碼 或者 JSON 字符串

    # 返回json
    add_header Content-Type 'application/json; charset=utf-8';
    return 200 "{'msg':'valid'}"; 
    # 本地目錄重寫
    rewrite ^/.*.(gif|jpg|jpeg|png)$ /static/qrcode.jpg last;
    # 重寫遠程URL
    rewrite ^/ https://www.weiyigeek.top/picture/images/details-image-1.jpg;

  } 
}

24.常規安全響應頭配置

描述: 下面收集了Web服務中常規的安全響應頭, 它可以保證不受到某些攻擊,建議在指定的 server{} 代碼塊進行配置。

# HSTS (ngx_http_headers_module is required) 應該只使用 HTTPS 而不是使用 HTTP 通信
add_header Strict-Transport-Security "max-age=31536000;includeSubDomains;preload" always;

# XXS-Protection
add_header X-XSS-Protection "1; mode=block";

# MIME 模擬探測
add_header X-Content-Type-Options nosniff;

# Frame 安全控制
add_header X-Frame-Options ALLOW-FROM music.163.com;

# Spider Robots 爬取策略限制
add_header X-Robots-Tag none;

# CORS 跨域設置
add_header Access-Control-Allow-Origin '*.weiyigeek.top';
add_header Access-Control-Allow-Methods 'GET';
add_header Access-Control-Allow-Headers 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';

# CSP
# 現在讓我們允許自托管 scripts、images、CSS、fonts 和 AJAX,以及 jQuery CDN 托管腳本和 Google Analytics 的內容:
Content-Security-Policy: default-src 'none'; script-src 'self' https://code.jquery.com https://www.google-analytics.com; img-src 'self' https://www.google-analytics.com; connect-src 'self'; font-src 'self'; style-src 'self';

25.防止非所屬域名解析到服務器

描述: 為了防止某些未備案的域名或者惡意鏡像站域名綁定到我們服務器上, 導致服務器被警告關停,將會對業務或者SEO排名以及企業形象造成影響,我們可以通過如下方式進行防范。

server {
  listen 80 default_server;
  server_name 82.156.18.253;
  # 禁止搜索引擎收錄IP
  add_header X-Robots-Tag 'noindex,noarchive,nosnippet';
  location ^~ / {
    # IP地址訪問強制301跳轉
    if ( $host = 82.156.18.253 ){
      return 301 https://www.weiyigeek.top/index.html;
    }
    # 請求host非指定域名時返回json
    if ( $host !~* weiyigeek\.top ) {
      add_header Content-Type 'application/json; charset=utf-8';
      return 200 '{"status":"error","Author":"WeiyiGeek","Site":"https://www.weiyigeek.top","Chinese":"大佬, 請不要把你的域名解析到我的服務器上","English":"Friend, Please do not resolve your domain name to my server"}';
      # return 301 https://space.bilibili.com/385802642;
    }
  }
...
}

執行結果:

$ curl -I 82.156.18.253
HTTP/1.1 301 Moved Permanently
Server: nginx
Date: Mon, 11 Apr 2022 12:15:02 GMT
Content-Type: text/html
Content-Length: 162
Connection: keep-alive
Location: https://www.weiyigeek.top/index.html
X-Robots-Tag: noindex,noarchive,nosnippet

$ curl --insecure -I https://82.156.18.253
HTTP/2 301
server: nginx
date: Mon, 11 Apr 2022 12:15:24 GMT
content-type: text/html
content-length: 162
location: https://www.weiyigeek.top/index.html
x-robots-tag: noindex,noarchive,nosnippet

$ curl weiyigeek.cn
{"status":"error","Author":"WeiyiGeek","Site":"https://www.weiyigeek.top","Chinese":"大佬, 請不要把你的域名解析到我的服務器上","English":"Friend, Please do not resolve your domain name to my server"}

25.限制指定客戶端地址訪問

描述: 有時你的網站可能只需要被某一IP或者IP段的地址請求訪問,那么非白名單中的地址訪問將被阻止訪問, 我們可以如下配置;

location / {
  allow  12.97.167.194; 
  allow  12.33.1.2; 
  allow  12.152.49.4;
  deny  all;
}

5.配置說明

常用nginx配置文件解釋:

#[Main] Nginx啟動的用戶(建議非root用戶)
user nginx;

#[Main] NGINX工作進程數設置值和CPU核心數一致(優化選項)
#采用 grep ^processor /proc/cpuinfo | wc -l 進行查看或者auto
worker_processes  auto;

#[Main] 工作模式與連接數上限即每個工作進程可以處理並發的最大連接數(優化選項)
events {
    #[Main-events] nginx作為反向代理服務器單個進程最大連接數(最大連接數=連接數*進程數)
    #建議與worker_rlimit_nofile一致
    worker_connections  65535;
    #[Main-events] use [ kqueue | rtsig | epoll | /dev/poll | select | poll ]; 
    #epoll模型是Linux 2.6以上版本內核中的高性能網絡I/O模型,如果跑在FreeBSD上面,就用kqueue模型。
    use epoll;
    #[Main-events] 提高性能和吞吐量
    accept_mutex off;
}

#[Main] 高並發參數(通過設置cpu粘性來降低由於多CPU核切換造成的寄存器等現場重建帶來的性能損耗)(優化選項)
worker_cpu_affinity 0001 0010 0100 1000; #四核的時候
#假如是8 cpu 分配如下: worker_cpu_affinity 00000001 00000010 00000100 00001000 0001000000100000 01000000 10000000

#[Main] 默認是沒有設置,可以限制為操作系統最大的限制65535。(優化選項)
worker_rlimit_nofile 65535

#[Main]日志位置和日志級別[ debug | info | notice | warn | error | crit ]
#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;
error_log logs/error.log  error;

#服務進程啟動文件
pid /var/run/nginx.pid;

#當前主配置文件包含其他的nginx模塊配置文件
include /etc/nginx/conf.d/*.conf; 

#[Main部分] http服務器提供http服務相關的一些配置參數。例如:是否使用keepalive啊,是否使用gzip進行壓縮等。
http {
    #文件擴展名與文件類型映射表
    include       mime.types;
    #默認文件類型
    default_type  text/html;
    #響應的編碼格式
    charset UTF-8;
    #服務器名字的hash表大小
    server_names_hash_bucket_size   128;
    #緩沖區代理緩沖用戶端請求的最大字節數, 
    client_body_buffer_size 128k
    #上傳文件大小限制
    client_header_buffer_size 4k;
    #允許客戶端請求的最大單文件字節數。如果有上傳較大文件,請設置它的限制值
    client_max_body_size 10m

    #文件訪問緩存設置與系統文件描述符設置一致
    open_file_cache max=65536  inactive=60s;
    open_file_cache_valid      80s;
    open_file_cache_min_uses   1;

    large_client_header_buffers 4 64k; #設定請求緩

    #nginx日志記錄格式
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                     '"$http_user_agent" "$http_x_forwarded_for"';

    #使用緩沖而不是每條日志記錄都單獨執行寫操作,NGINX會緩沖一連串的日志記錄使用單個操作把它們一起寫到文件中。
    access_log  logs/access.log  main buffer=1024 flush=60s;

    #關閉server信息頭響應
    server_tokens off;


    #[MAIN-http]開啟高效文件傳輸模式,指定nginx是否調用sendfile函數來輸出文件,減少用戶空間到內核空間的上下文切換(與accept_mutex關聯配置)
    #對於普通應用設為 on,如果用來進行下載等應用磁盤IO重負載應用可設置為off,以平衡磁盤與網絡I/O處理速度,降低系統的負載。
    #系統調用可以實現從一個文件描述符到另一個文件描述符的數據拷貝,通常實現零拷貝,這能加速TCP數據傳輸
    #當配置環境下有sendfile指令和激活內容更改過濾器的指令時NGINX會自動禁用sendfile。#(優化選項)
    sendfile        on; 
    #防止網絡阻塞,不過要包涵在keepalived參數才有效
    tcp_nopush on; 
    tcp_nodelay on; 

    #空閑長連接保持打開狀態的時間(優化選項)
    #長連接請求大量小文件的時候,可以減少重建連接的開銷,但假如有大文件上傳120s內沒上傳完成會導致失敗。如果設置時間過長,用戶又多,長時間保持連接會占用大量資源。
    keepalive_timeout  120;
    
    #用於指定響應客戶端的超時時間。這個超時僅限於兩個連接活動之間的時間,如果超過這個時間客戶端沒有任何活動,Nginx將會關閉連接
    #send_timeout  180s
    
    ###模塊http_gzip#####
    #開啟gzip壓縮輸出,減少網絡傳輸。
    gzip  on;
    #最小壓縮文件大小(注意不能小於1k)
    gzip_min_length 1k;
    #壓縮緩沖區
    gzip_buffers 4 64k;
    #壓縮版本(默認1.1,前端如果是squid2.5請使用1.0)
    gzip_http_version 1.1;
    #壓縮等級
    gzip_comp_level 2;
    ##壓縮類型,默認就已經包含text/html,
    gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;
    
    ###模塊fastcgi#####
    #FastCGI相關參數是為了改善網站的性能:減少資源占用,提高訪問速度。
    # fastcgi_temp_path  /tmp/fastcgi_temp;
    # fastcgi_cache_path /tmp/fastcgi_cache levels=1:2 keys_zone=cache_fastcgi:128m inactive=30m max_size=1g;
    # fastcgi_cache_key  $host$request_uri;
    #指定的Http狀態碼指定緩存時間
    # fastcgi_cache_valid 200 302 1h; 
    # fastcgi_cache_valid 301 1d;
    # fastcgi_cache_valid any 1m;
    # fastcgi_cache_min_uses 1;
    # fastcgi_cache_use_stale error timeout http_500 http_503 invalid_header;
    #指定鏈接到后端FastCGI的超時時間。
    # fastcgi_connect_timeout 300;
    #向FastCGI傳送請求的超時時間,這個值是指已經完成兩次握手后向FastCGI傳送請求的超時時間。
    # fastcgi_send_timeout 300;
    #指定接收FastCGI應答的超時時間,這個值是指已經完成兩次握手后接收FastCGI應答的超時時間。
    # fastcgi_read_timeout 300;
    #指定讀取FastCGI應答第一部分需要用多大的緩沖區,這個值表示將使用1個64KB的緩沖區讀取應答的第一部分(應答頭),可以設置為gastcgi_buffers選項指定的緩沖區大小。
    # fastcgi_buffer_size 64k;
    #一個php腳本所產生的頁面大小為256KB,那么會分配4個64KB的緩沖區來緩存
    # fastcgi_buffers 4 64k; 
    #建議設置為fastcgi_buffer的兩倍,繁忙時候的buffer
    # fastcgi_busy_buffers_size 128k;
    # fastcgi_temp_file_write_size 128k;

    
    #[Main-http]配置虛擬主機設置
    #http服務上支持若干虛擬主機。每個虛擬主機一個對應的server配置項,配置項里面包含該虛擬主機相關的配置
    server {
        #[Main-http-server] ngnix監聽端口
        listen       80;
        
        #服務器名:虛擬主機的域名可以寫多個域名,可以通過正則匹配。
        server_name  localhost;

        #實現訪問http時自動跳轉到https
        return 301 https://$host$request_uri;
        #access_log  logs/host.access.log  main;

        #請求正則匹配的來判斷訪問路徑,默認訪問localhost:80 訪問的是下面這個路徑的網頁
        location / {
            #站點根目錄你網站文件存放的地方
            root   html;
            #定義路徑下默認訪問的文件名,一般跟着root放
            index  index.html index.htm;
            
            #開啟限制IP連接數的時候需要使用
            #limit_zone crawler $binary_remote_addr 10m; 

            #訪問控制模塊默認就會安裝,而且寫法也非常簡單,可以分別有多個allow,deny,允許或禁止某個ip或ip段訪問,
            #依次滿足任何一個規則就停止往下匹配 (安全選項)
            allow 192.168.10.100;
            allow 172.29.73.0/24;
            deny all;
            
            #認證訪問 通過httpd-devel 工具的 htpasswd 來為訪問的路徑設置登錄密碼 (安全選項)
            #比如:htpasswd -c nginx.htpasswd admin 生成了默認使用CRYPT加密的密碼文件#
            auth_basic "Nginx Status"
            auth_basic_user_file /usr/local/nginx/nginx.passwd
            
            #列出目錄 autoindex Nginx默認是不允許列出整個目錄的合適下載服務器。(非常不推薦)
            #如需此功能,打開nginx.conf文件,在location,server 或 http段中加入autoindex on;
            #autoindex on
            #顯示出文件的確切大小單位是bytes。改為off后顯示出文件的大概大小,單位是kB或者MB或者GB
            #autoindex_exact_size off
            #默認為off,顯示的文件時間為GMT時間。改為on后,顯示的文件時間為文件的服務器時間
            #autoindex_localtime on;
        }
        
        #error_page  404              /404.html;
        #將服務器錯誤頁面直接指向靜態頁面/50x.html
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }

        #代理PHP腳本到Apache上監聽127.0.0.1:80 末尾以php或者php5結尾的
        #location ~ \.(php|php5)?$ {
        #    proxy_pass   http://127.0.0.1;
        #}

        #將PHP腳本傳遞到正在監聽127.0.0.1:9000的FastCGI服務器
        #location ~ .+\.(php|php5)$ {
        #    root           html;
        #    fastcgi_pass   127.0.0.1:9000;
        #    fastcgi_pass   unix:/tmp/php.sock;  #為了安全推薦方式
        #    fastcgi_index  index.php;
        #    fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
        #    include        fastcgi_params;
        #    fastcgi_cache  cache_fastcgi;
        #}


        # 如果Apache的文檔根目錄與nginx的根目錄一致,則拒絕訪問.htaccess文件
        #location ~ /\.ht {
        #    deny  all;
        #}
        
        #靜態資源正則請求路徑匹配
        location ~ .+\.(gif|jpg|jpeg|png|bmp|swf|txt|csv|doc|docx|xls|xlsx|ppt|pptx|flv)$ {  
          root  e:wwwroot; 
          expires 30d;  #緩存有效期30天
          access_log off; #訪問記錄
        } 
        #JS和CSS緩存時間設置
        location ~ .+\.(js|css|html|xml)$ { expires 30d;}

        #訪問控制也可以加入認證
        location /nginx-status{
            #nginx中的stub_status模塊主要用於查看Nginx的一些狀態信息. 本模塊默認沒有安裝需要編譯安裝。
            stub_status on;
            allow 192.168.1.0/24;
            allow 127.0.0.1;
            deny all;
        }
    }
    
    #### Nginx反向代理 ######
    #[Main-http] upstream模塊設置反向代理和負載均衡的連接的內部web應用服務IP端口
    upstream monitor_server {
        #seesion記錄訪問的主機,比如第一次訪問該服務器后就記錄,之后再訪問都是該服務器了-進行了綁定
        ip_hash;
        #內網的應用服務,weigth參數表示權值越高被分配到的幾率越大。
        #max_fails當有max_fails個請求失敗,就表示后端的服務器不可用,默認為1將其設置為0可以關閉檢查 
        #fail_timeout 在以后的fail_timeout時間內nginx不會再把請求發往已檢查出標記為不可用的服務器 
        server 192.168.0.131:80 weight=9 max_fails=5 fail_timeout=600s;  
        server 192.168.0.132:80 weight=1 max_fails=5 fail_timeout=600s;
    } 
    
    
    #server指令配置項
    server { 
        listen 80; 
        #請求響應的域名
        server_name blog.weiyigeek.top; 
        
        location / {
          ##### 模塊http_proxy:##### 反向代理主要配置
          #即反向代理,對應upstream負載均衡器
          proxy_pass http://monitor_server;
          
          #代理服務器相關信息頭設置
          proxy_redirect off;
          #如果是有涉及redirect的服務,一定要加上端口8081,否 則默認tomcat在redirect時候默認找80端口 
          proxy_set_header Host $host;
          #轉發請求的原IP地址,程序中通過request.getHeader("Proxy-Client-IP")獲得ip 
          proxy_set_header X-Real-IP $remote_addr;
          #端的Web服務器可以通過X-Forwarded-For獲取用戶真實IP
          proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 
          
          ##nginx跟后端服務器連接超時時間(代理連接超時)
          #模塊http_proxy代理超時設置
          proxy_connect_timeout 60s;  
          
          ##nginx跟后端服務器連接超時時間(代理連接超時) 
          proxy_read_timeout 60s;     
          
          #后端服務器數據回傳時間(代理發送超時) 間
          proxy_send_timeout 30s;
          
          #設置代理服務器(nginx)從后端realserver讀取並保存用戶頭信息的緩沖區大小,默認與proxy_buffers大小相同,其實可以將這個指令值設的小一點
          proxy_buffer_size 4k
          #proxy_buffers緩沖區,nginx針對單個連接緩存來自后端realserver的響應,網頁平均在32k以下的
          proxy_buffers 4 32k
          
          #高負荷下緩沖大小(proxy_buffers*2)
          proxy_busy_buffers_size 64k
          
          #當proxy_buffers放不下后端服務器的響應內容時,會將一部分保存到硬盤的臨時文件中,這個值用來設置最大臨時文件大小,默認1024M
          #它與proxy_cache沒有關系。大於這個值,將從upstream服務器傳回。設置為0禁用。
          proxy_max_temp_file_size 0
          
          #當緩存被代理的服務器響應到臨時文件時,限制每次寫臨時文件的大小。proxy_temp_path(可以在編譯的時候)指定寫到哪那個目錄。
          proxy_temp_file_write_size 64k

          #把cookie的作用域替換成我們的域名。
          #proxy_cookie_domain google.com.hk www.example.com;  
          #proxy_set_header Host "www.google.com.hk";          #設置反向代理得header請求頭
          #proxy_redirect http://www.google.com.hk/ ;          #重定向
          #proxy_redirect http:// https://;
          #sub_filter www.google.com.hk www.example.com;       #把谷歌的域名替換成自己的,注意需要安裝nginx的sub_filter模塊
          #反向代理的配置. END
        }

        #本地動靜分離反向代理配置
        #所有jsp的頁面均交由tomcat或resin處理
        location ~ .(jsp|jspx|do)?$ {
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_pass http://127.0.0.1:8080;
        }

        #所有靜態文件由nginx直接讀取不經過tomcat或resin
        location ~ \.(htm|html|gif|jpg|jpeg|png|bmp|swf|ioc|rar|zip|txt|flv|mid|doc|ppt|pdf|xls|mp3|wma)$ { expires 15d; }

        location ~ \.(js|css)$ { expires 1h; }

    } 
    
    # 另一個虛擬主機,混合使用IP、名稱和基於端口的配置
    server {
      listen 80;
      listen [::]:80;
      server_name weiyigeek.top;
      return 301 https://$host$request_uri;
   }

    server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name weiyigeek.top;

    # HSTS (ngx_http_headers_module is required) 應該只使用 HTTPS 而不是使用 HTTP 通信
    add_header Strict-Transport-Security "max-age=31536000;includeSubDomains;preload" always;

    # XXS-Protection
    add_header X-XSS-Protection "1; mode=block";

    # MIME 模擬探測
    add_header X-Content-Type-Options nosniff;

    # Frame 安全控制
    add_header X-Frame-Options ALLOW-FROM music.163.com;

    # Spider Robots 爬取策略限制
    # add_header X-Robots-Tag none; # 不限制
    # add_header X-Robots-Tag noindex, noarchive, nosnippet; # 限制

    # 開啟 SSL ,如果想http 與 https 公用一個配置則可以將其注釋( the "ssl" directive is deprecated )
    # ssl on;

    # 配置證書鏈與證書密鑰
    ssl_certificate      /etc/nginx/ssl/fullchain.cer;
    ssl_certificate_key  /etc/nginx/ssl/weiyigeek.top.key;

    # ssl會話復用超時時間以及會話復用緩存大小
    ssl_session_timeout 1d;
    ssl_session_cache shared:MozSSL:10m;  # about 40000 sessions

    # 配置雙證書時開啟否則應該關閉
    ssl_session_tickets off;  

    ## OCSP stapling
    ssl_stapling on;
    ssl_stapling_verify on;
    # 使用根 CA 和中間證書驗證 OCSP 響應的信任鏈
    ssl_trusted_certificate /etc/nginx/ssl/ca.cer;

    # 僅使用ECDH是不用配置ssl_dhparam的否則你應該為它配置上 
    # curl https://ssl-config.mozilla.org/ffdhe2048.txt > /path/to/dhparam
    ssl_dhparam /path/to/dhparam;

    # 兼容性較為通用的SSL協議與加密算法套件
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
    ssl_ciphers 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:ECDHE:ECDH:AES:HIGH:EECDH+CHACHA20:EECDH+CHACHA20-draft:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:!NULL:!aNULL:!eNULL:!EXPORT:!PSK:!ADH:!DH:!DES:!MD5:!RC4;
    # 安全配置: ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4:!DH:!DHE;
    # 證書常規握手加密算法方式共十八個,ECDHE、DHE、AES開頭分別6個
    ; ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:HIGH:!NULL:!aNULL:!eNULL:!EXPORT:!PSK:!ADH:!DES:!MD5:!RC4;
    
    # 為了兼容性推薦服務器自動選擇要使用的算法套件
    ssl_prefer_server_ciphers  on;

    # replace with the IP address of your resolver
    resolver 223.6.6.6 8.8.8.8 192.168.12.254;
  }
}

6.補充知識

(1) 阿里巴巴提供的Concat或者Google的PageSpeed模塊實現這個合並文件的功能。


(2) PHP-FPM的優化
如果您高負載網站使用PHP-FPM管理FastCGI對於PHP-FPM的優化非常重要

  • 1.增加FastCGI進程數:把PHP FastCGI子進程數調到100或以上,在4G內存的服務器上200就可以建議通過壓力測試獲取最佳值。
  • 2.增加 PHP-FPM打開文件描述符的限制
# vi /path/to/php-fpm.conf
找到“1024”,把1024更改為 4096 或者更高,之后重啟 PHP-FPM
# /etc/security/limits.conf
* hard nofile 65536
* soft nofile 65536
  • 3.適當增加max_requests: 標簽max_requests指明了每個children最多處理多少個請求后便會被關閉默認的設置是500。

(3) 配置Resin on Linux或者Windows為我們可以打開 resin-3.1.9/bin/httpd.sh 在不影響其他代碼的地方加入:-Dhttps.protocols=TLSv1.2, 例如

exec $JAVA_EXE -jar  -Dhttps.protocols=TLSv1.2 ${RESIN_HOME}/lib/resin.jar $*
#exec $JAVA_EXE -jar  ${RESIN_HOME}/lib/resin.jar $*

原文地址: https://blog.weiyigeek.top/2019/9-2-122.html

文章書寫不易,如果您覺得這篇文章還不錯的,請給這篇專欄 【點個贊、投個幣、收個藏、關個注,轉個發】(人間五大情),這將對我的肯定,謝謝!。

本文章來源 我的Blog站點WeiyiGeek 公眾賬號 以及 我的BiliBili專欄 (技術交流、友鏈交換請郵我喲),謝謝支持!(๑′ᴗ‵๑) ❤
歡迎各位志同道合的朋友一起學習交流,如文章有誤請留下您寶貴的知識建議,通過郵箱【master#weiyigeek.top】聯系我喲!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM