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

WeiyiGeek發表於2022-04-15

本章目錄

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】聯絡我喲!

相關文章