主頁 > 企業開發 > 小白入門學習Nginx代理服務器?看這篇最新Nginx進階學習最佳配置實踐指南就OK了

小白入門學習Nginx代理服務器?看這篇最新Nginx進階學習最佳配置實踐指南就OK了

2022-04-16 07:16:59 企業開發

前置基礎知識學習

  • 1.Nginx基礎安裝與配置詳細 https://blog.weiyigeek.top/2019/9-1-121.html

  • 2.Nginx進階學習之最佳配置實踐指南 https://blog.weiyigeek.top/2019/9-1-124.html

  • 3.Nginx模塊學習使用實踐指南 https://blog.weiyigeek.top/2021/3-1-633.html

  • 4.Nginx安全加固與性能調優最佳指南 https://blog.weiyigeek.top/2019/9-2-122.html

  • 5.Nginx常遇問題入坑出坑整理 https://blog.weiyigeek.top/2020/9-2-622.html

0x00 編譯實踐

描述:在企業線上生產環境中推薦進行Nginx編譯安裝,可以按照業務側重點進行相應 Nginx 編譯引數配置,所以編譯引數不是功能加的越多越好,應該盡可能少編譯模塊不用的最好不要加入,本小結將以最新的Nginx版本以及依賴版本進行編譯演示,

Nginx-1.21.6+OpenSSL-1.1.1n

最新原始碼構建安裝整理,當前最新版本nginx-1.21.6,實踐時間【2022年3月24日】
版本說明: pcre-8.45 、zlib-1.2.11、openssl-1.1.1n、nginx-1.21.6,

官方安裝參考地址: https://docs.nginx.com/nginx/admin-guide/installing-nginx/installing-nginx-open-source/#downloading-the-sources

步驟 01.在從源代碼編譯 NGINX Open Source 之前,您需要為其依賴項安裝庫:

  • PCRE – 支持正則運算式,NGINX Core 和 Rewrite 模塊需要,
# http://pcre.org/
# https://sourceforge.net/projects/pcre/files/
wget -c https://nchc.dl.sourceforge.net/project/pcre/pcre/8.45/pcre-8.45.tar.bz2
tar -jxf pcre-8.45.tar.bz2 && cd pcre-8.45
./configure
make  && sudo make install
  • zlib – 支持標頭壓縮, NGINX Gzip 模塊需要,
# http://www.zlib.net/
wget -c http://zlib.net/zlib-1.2.11.tar.gz
tar -zxf zlib-1.2.11.tar.gz && cd zlib-1.2.11
./configure
make && sudo make install
  • OpenSSL – 支持 HTTPS 協議, NGINX SSL 模塊和其他模塊需要,
# https://www.openssl.org/source/
wget -c http://www.openssl.org/source/openssl-1.1.1n.tar.gz
tar -zxf openssl-1.1.1n.tar.gz && cd openssl-1.1.1n
./config --prefix=/usr/local/openssl
make && sudo make install
# lib 庫加載到系統
echo "/usr/local/openssl/lib" >> /etc/ld.so.conf.d/libc.conf
ldconfig
# 可以看到當下系統的Openssl版本已經更新到最新
# root@weiyigeek-top:/usr/local/openssl/bin# openssl version
# OpenSSL 1.1.1n  15 Mar 2022

步驟 02.從 nginx.org 下載穩定版和主線版本的源代碼檔案,要下載并解壓最新主線版本的源代碼,請運行:

# https://nginx.org
sudo mkdir -vp /usr/local/nginx/module /usr/lib/nginx/modules /var/cache/nginx/{client_temp,proxy_temp,fastcgi_temp,uwsgi_temp,scgi_temp} 
wget https://nginx.org/download/nginx-1.21.6.tar.gz
tar zxf nginx-1.21.6.tar.gz && cd nginx-1.21.6
$ ./configure \
--prefix=/usr/local/nginx \
--with-pcre=../pcre-8.45 \
--with-zlib=../zlib-1.2.11 \
--user=ubuntu --group=ubuntu \
--sbin-path=/usr/sbin/nginx \
--conf-path=/usr/local/nginx/nginx.conf \
--pid-path=/usr/local/nginx/nginx.pid \
--error-log-path=/var/log/nginx/error.log \
--http-log-path=/var/log/nginx/access.log \
--lock-path=/var/run/nginx.lock \
--modules-path=/usr/lib/nginx/modules \
--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 \
--with-stream --with-stream_realip_module --with-stream_ssl_module --with-stream_ssl_preread_module --with-stream_geoip_module \
--with-threads --with-mail --with-mail_ssl_module \
--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-compat --with-file-aio \
--with-cc-opt='-Os -fomit-frame-pointer -g' --with-ld-opt=-Wl,--as-needed,-O1,--sort-common
# <!-- --add-dynamic-module=/usr/local/nginx/module -->

Tips :請注意 geoip_module 模塊, 如果需要使用則需要提前安裝好 GeoIP library,例如在Ubuntu系統上執行apt-get install libgeoip-dev如下命令,

Tips : 請注意 通過yum或者apt安裝的nginx,通常會將nginx的組態檔放在/etc/nginx,而手動編譯構建的一般是在 /usr/local/nginx 目錄中,

步驟 03.執行./configure命令后的結果如下

Configuration summary
  + using threads
  + using PCRE library: ../pcre-8.45
  + using system OpenSSL library
  + using zlib library: ../zlib-1.2.11

  nginx path prefix: "/usr/local/nginx"
  nginx binary file: "/usr/sbin/nginx"
  nginx modules path: "/usr/lib/nginx/modules"
  nginx configuration prefix: "/usr/local/nginx"
  nginx configuration file: "/usr/local/nginx/nginx.conf"
  nginx pid file: "/usr/local/nginx/nginx.pid"
  nginx error log file: "/var/log/nginx/error.log"
  nginx http access log file: "/var/log/nginx/access.log"
  nginx http client request body temporary files: "/var/cache/nginx/client_temp"
  nginx http proxy temporary files: "/var/cache/nginx/proxy_temp"
  nginx http fastcgi temporary files: "/var/cache/nginx/fastcgi_temp"
  nginx http uwsgi temporary files: "/var/cache/nginx/uwsgi_temp"
  nginx http scgi temporary files: "/var/cache/nginx/scgi_temp"

步驟 04.執行構建安裝后查看nginx版本以及構建引數等資訊

$ nginx -V
nginx version: nginx/1.21.6
built by gcc 9.4.0 (Ubuntu 9.4.0-1ubuntu1~20.04)
built with OpenSSL 1.1.1n  15 Mar 2022
TLS SNI support enabled
  configure arguments: --prefix=/usr/local/nginx --with-pcre=../pcre-8.45 --with-zlib=../zlib-1.2.11 --user=ubuntu --group=ubuntu --sbin-path=/usr/sbin/nginx --conf-path=/usr/local/nginx/nginx.conf --pid-path=/usr/local/nginx/nginx.pid --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --lock-path=/var/run/nginx.lock --modules-path=/usr/lib/nginx/modules --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 --with-stream --with-stream_realip_module --with-stream_ssl_module --with-stream_ssl_preread_module --with-stream_geoip_module --with-threads --with-mail --with-mail_ssl_module --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-compat --with-file-aio --with-cc-opt='-Os -fomit-frame-pointer -g' --with-ld-opt=-Wl,--as-needed,-O1,--sort-common

步驟 05.執行/usr/sbin/nginx命令, 啟用nginx服務并查看提供的服務,

# 查看Nginx并發行程數
$ ps -ef | grep nginx | grep -v "grep" | wc -l
3

Nginx編譯(configure) 引數一覽

描述: 我們可以執行./configure --help便可以查看編譯相關引數,

# 常用選項 #
--prefix= #指向安裝目錄
--user= #指定程式運行時的非特權用戶
--group= #指定程式運行時的非特權用戶組
--with-perl= #設定perl庫檔案路徑啟用pcre庫
--with-perl_modules_path= #設定perl模塊路徑
--with-pcre-opt= 在編譯時為pcre庫設定附加引數

--with-zlib= #指向zlib庫目錄
--with-zlib-opt= #在編譯時為zlib設定附加引數
--with-zlib-asm= #為指定的CPU使用zlib匯編源進行優化,CPU型別為pentium, pentiumpro

--with-openssl= #指向openssl安裝目錄
--with-openssl-opt #在編譯時為openssl設定附加引數
--with-http_ssl_module #啟用ngx_http_ssl_module支持(使支持https請求,需已安裝openssl)

--with-cc-opt= #設定C編譯器引數將被添加到CFLAGS變數(PCRE庫,需要指定–with-cc-opt=”-I /usr/local/include”,如果使用select()函式則需要同時增加檔案描述符數量,可以通過–with-cc- opt=”-D FD_SETSIZE=2048”指定,)
--with-ld-opt= #設定連接檔案引數鏈接系統庫,(PCRE庫,需要指定–with-ld-opt=”-L /usr/local/lib”,)
--with-cpu-opt= #指定編譯的CPU,可用的值為: pentium, pentiumpro, pentium3, pentium4, athlon, opteron, amd64, sparc32, sparc64, ppc64


#下面按需配置
--conf-path= #指向組態檔(nginx.conf)
--error-log-path= #指向錯誤日志目錄
--pid-path= #指向pid檔案(nginx.pid)
--sbin-path= #指向(執行)程式檔案(nginx)
--lock-path= #指向lock檔案(nginx.lock)(安裝檔案鎖定,防止安裝檔案被別人利用,或自己誤操作,)
--builddir= #指向編譯目錄

#模塊添加
--with-rtsig_module #啟用rtsig模塊支持(實時信號)
--with-select_module #啟用select模塊支持(一種輪詢模式,不推薦在高載環境下使用)禁用:–without-select_module
--with-poll_module #啟用poll模塊支持(功能與select相同,與select特性相同,為一種輪詢模式,不推薦在高載環境下使用)
--with-file-aio #啟用file aio支持(一種APL檔案傳輸格式)
--with-ipv6 #啟用ipv6支持
--with-http_realip_module #啟用ngx_http_realip_module支持(這個模塊允許從請求標頭更改客戶端的IP地址值,默認為關)
--with-http_addition_module #啟用ngx_http_addition_module支持(作為一個輸出過濾器,支持不完全緩沖,分部分回應請求)
--with-http_xslt_module #啟用ngx_http_xslt_module支持(過濾轉換XML請求)
--with-http_image_filter_module #啟用ngx_http_image_filter_module支持(傳輸JPEG/GIF/PNG 圖片的一個過濾器)(默認為不啟用、gd庫要用到)
--with-http_geoip_module #啟用ngx_http_geoip_module支持(該模塊創建基于與MaxMind GeoIP二進制檔案相配的客戶端IP地址的ngx_http_geoip_module變數)
--with-http_sub_module #啟用ngx_http_sub_module支持(允許用一些其他文本替換nginx回應中的一些文本)
--with-http_dav_module #啟用ngx_http_dav_module支持(增加PUT,DELETE,MKCOL:創建集合,COPY和MOVE方法)默認情況下為關閉,需編譯開啟
--with-http_flv_module #啟用ngx_http_flv_module支持(提供尋求記憶體使用基于時間的偏移量檔案)
--with-http_gzip_static_module #啟用ngx_http_gzip_static_module支持(在線實時壓縮輸出資料流)
--with-http_random_index_module #啟用ngx_http_random_index_module支持(從目錄中隨機挑選一個目錄索引)
--with-http_secure_link_module #啟用ngx_http_secure_link_module支持(計算和檢查要求所需的安全鏈接網址)
--with-http_degradation_module  #啟用ngx_http_degradation_module支持(允許在記憶體不足的情況下回傳204或444碼)
--with-http_stub_status_module   #啟用ngx_http_stub_status_module支持(獲取nginx自上次啟動以來的作業狀態)

--without-http_charset_module #禁用ngx_http_charset_module支持(重新編碼web頁面,但只能是一個方向–服務器端到客戶端,并且只有一個位元組的編碼可以被重新編碼)
--without-http_gzip_module #禁用ngx_http_gzip_module支持(該模塊同-with-http_gzip_static_module功能一樣)

--without-http_ssi_module #禁用ngx_http_ssi_module支持(該模塊提供了一個在輸入端處理處理服務器包含檔案(SSI)的過濾器,目前支持SSI命令的串列是不完整的)

--without-http_userid_module #禁用ngx_http_userid_module支持(該模塊用來處理用來確定客戶端后續請求的cookies)

--without-http_access_module #禁用ngx_http_access_module支持(該模塊提供了一個簡單的基于主機的訪問控制,允許/拒絕基于ip地址)

--without-http_auth_basic_module #禁用ngx_http_auth_basic_module(該模塊是可以使用用戶名和密碼基于http基本認證方法來保護你的站點或其部分內容)

--without-http_autoindex_module #禁用disable ngx_http_autoindex_module支持(該模塊用于自動生成目錄串列,只在ngx_http_index_module模塊未找到索引檔案時發出請求,)

--without-http_geo_module #禁用ngx_http_geo_module支持(創建一些變數,其值依賴于客戶端的IP地址)

--without-http_map_module #禁用ngx_http_map_module支持(使用任意的鍵/值對設定配置變數)

--without-http_split_clients_module #禁用ngx_http_split_clients_module支持(該模塊用來基于某些條件劃分用戶,條件如:ip地址、報頭、cookies等等)

--without-http_referer_module #禁用disable ngx_http_referer_module支持(該模塊用來過濾請求,拒絕報頭中Referer值不正確的請求)

--without-http_rewrite_module #禁用ngx_http_rewrite_module支持(該模塊允許使用正則運算式改變URI,并且根據變數來轉向以及選擇配置,如果在server級 別設定該選項,那么他們將在 location之前生效,如果在location還有更進一步的重寫規則,location部分的規則依然會被執行,如果這個URI重寫是因為 location部分的規則造成的,那么 location部分會再次被執行作為新的URI, 這個回圈會執行10次,然后Nginx會回傳一個500錯誤,)

--without-http_proxy_module #禁用ngx_http_proxy_module支持(有關代理服務器)

--without-http_fastcgi_module #禁用ngx_http_fastcgi_module支持(該模塊允許Nginx 與FastCGI 行程互動,并通過傳遞引數來控制FastCGI 行程作業, )FastCGI一個常駐型的公共網關介面,

--without-http_uwsgi_module #禁用ngx_http_uwsgi_module支持(該模塊用來醫用uwsgi協議,uWSGI服務器相關)

--without-http_scgi_module #禁用ngx_http_scgi_module支持(該模塊用來啟用SCGI協議支持,SCGI協議是CGI協議的替代,它是一種應用程式與HTTP服務介面標準,它有些像FastCGI但他的設計 更容易實作,)

--without-http_memcached_module #禁用ngx_http_memcached_module支持(該模塊用來提供簡單的快取,以提高系統效率)
-without-http_limit_zone_module #禁用ngx_http_limit_zone_module支持(該模塊可以針對條件,進行會話的并發連接數控制)
--without-http_limit_req_module #禁用ngx_http_limit_req_module支持(該模塊允許你對于一個地址進行請求數量的限制用一個給定的session或一個特定的事件)
--without-http_empty_gif_module #禁用ngx_http_empty_gif_module支持(該模塊在記憶體中常駐了一個1*1的透明GIF影像,可以被非常快速的呼叫)
--without-http_browser_module #禁用ngx_http_browser_module支持(該模塊用來創建依賴于請求報頭的值,如果瀏覽器為modern ,則$modern_browser等于modern_browser_value指令分配的值;如 果瀏覽器為old,則$ancient_browser等于 ancient_browser_value指令分配的值;如果瀏覽器為 MSIE中的任意版本,則 $msie等于1)
--without-http_upstream_ip_hash_module #禁用ngx_http_upstream_ip_hash_module支持(該模塊用于簡單的負載均衡)
--with-http_perl_module #啟用ngx_http_perl_module支持(該模塊使nginx可以直接使用perl或通過ssi呼叫perl)


--http-log-path=           # 設定access log路徑
--http-client-body-temp-path= # 設定http客戶端請求臨時檔案路徑
--http-proxy-temp-path=    # 設定http代理臨時檔案路徑
--http-fastcgi-temp-path=  # 設定http fastcgi臨時檔案路徑
--http-uwsgi-temp-path=    # 設定http uwsgi臨時檔案路徑
--http-scgi-temp-path=    # 設定http scgi臨時檔案路徑

-without-http # 禁用http server功能
--without-http-cache # 禁用http cache功能

--with-mail #啟用POP3/IMAP4/SMTP代理模塊支持
--with-mail_ssl_module 啟用ngx_mail_ssl_module支持
--without-mail_pop3_module #禁用pop3協議(POP3即郵局協議的第3個版本,它是規定個人計算機如何連接到互聯網上的郵件服務器進行收發郵件的協議,是因特網電子郵件的第一個離 線協議標 準,POP3協議允許用戶從服務器上把郵件存盤到本地主機上,同時根據客戶端的操作洗掉或保存在郵件服務器上的郵件,POP3協議是TCP/IP協議族中 的一員,主要用于 支持使用客戶端遠程管理在服務器上的電子郵件)
--without-mail_imap_module #禁用imap協議(一種郵件獲取協議,它的主要作用是郵件客戶端可以通過這種協議從郵件服務器上獲取郵件的資訊,下載郵件等,IMAP協議運行在 TCP/IP協議之上, 使用的埠是143,它與POP3協議的主要區別是用戶可以不用把所有的郵件全部下載,可以通過客戶端直接對服務器上的郵件進行操作,)
--without-mail_smtp_module #禁用smtp協議(SMTP即簡單郵件傳輸協議,它是一組用于由源地址到目的地址傳送郵件的規則,由它來控制信件的中轉方式,SMTP協議屬于 TCP/IP協議族,它幫助每臺計算機在發送或中轉信件時找到下一個目的地,)
--with-google_perftools_module #啟用ngx_google_perftools_module支持(除錯用,剖析程式性能瓶頸)
--with-cpp_test_module #啟用ngx_cpp_test_module支持

--add-module= #啟用外部模塊支持

--with-cc=  # 指向C編譯器路徑
--with-cpp= # 指向C預處理路徑

--without-pcre #禁用pcre庫

--with-md5=     # 指向md5庫檔案目錄(訊息摘要演算法第五版,用以提供訊息的完整性保護)
--with-md5-opt= # 在編譯時為md5庫設定附加引數
--with-md5-asm  # 使用md5匯編源

--with-sha1=     # 指向sha1庫目錄(數字簽名演算法,主要用于數字簽名)
--with-sha1-opt= # 在編譯時為sha1庫設定附加引數
--with-sha1-asm  # 使用sha1匯編源

--with-libatomic  # 為原子記憶體的更新操作的實作提供一個架構
--with-libatomic= # 指向libatomic_ops安裝目錄

--with-debug # 啟用debug日志

Shell腳本一鍵部署虛擬主機(附上關鍵性腳本):
完整代碼:https://github.com/weiyigeek/SecOpsDev/Application/Web/Nginx/nginxVirtualHost-v1.sh

#!/bin/bash
#@Desc:Nginx多實體部署虛擬主機
#@Author:WeiyiGeek
#@CreatTime:2020年3月8日 12點06分
#@Site:WeiyiGeek.top
#@Test_Linux: Linux weiyigeek 3.10.0-693.el7.x86_64 #1 SMP Tue Aug 22 21:09:27 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux
#@release:CentOS Linux release 7.4.1708 (Core)

## Define nginx variable
NGX_VER=1.16.1
NGX_URI="http://nginx.org/download/nginx-${NGX_VER}.tar.gz"
NGX_SRC="https://www.cnblogs.com/WeiyiGeek/archive/2022/04/15/nginx-${NGX_VER}.tar.gz"
NGX_NAME=${NGX_SRC%.tar.gz}
NGX_DIR="/usr/local/nginx/${NGX_VER}"
NGX_ARGS="--prefix=${NGX_DIR} --user=nginx --group=nginx --with-http_stub_status_module"
NGX_SRCCODE="${NGX_NAME}/src/core/nginx.h"
NGX_VHDIR="${NGX_DIR}/conf/domains"

## Define 防火墻開放埠
FIREWALL_PORT=(80 8080)


## [Nginx INSTALL]
function nginx_install(){
    echo -e "\e[32m1.核查安裝依賴....... \e[0m"
    CHECK_SOFT=$(rpm -qa | grep -cE "^gcc|^pcre|^zlib")
    if [ $CHECK_SOFT -lt 2 ];then yum install -y gcc gcc-c++ pcre pcre-devel zlib-devel;fi

    echo -e "\e[32m2.檢查nginx原始碼包是否存在....... \e[0m"
    if [ ! -f $NGX_SRC ];then wget -c $NGX_URI;fi
    if [ ! -d $NGX_NAME ];then tar -zxf $NGX_SRC;fi

    echo -e "\e[32m3.nginx安裝陸軍是否存在....... \e[0m"
    if [ ! -f $NGX_DIR/sbin/nginx ];then mkdir -vp $NGX_DIR;fi

    echo -e "\e[32m3.驗證nginx用戶是否存在不存在則建立低權限用戶....... \e[0m"
    CHECK_USER=$(getent passwd | grep -wc nginx)
    if [ $CHECK_USER -eq 0 ];then useradd -s /sbin/nologin nginx -M; fi

    echo -e "安全設定:Nginx版本隱藏......"
    sed -i "s/$NGX_VER//g" $NGX_SRCCODE
    sed -i 's/nginx\//JWS/g' $NGX_SRCCODE
    sed -i 's/"NGINX"/"JWS"/g' $NGX_SRCCODE

    echo -e "\e[32m4.進行nginx預編譯及其編譯安裝....... \e[0m"
    cd $NGX_NAME && ./configure $NGX_ARGS 
    if [ $? -eq 0 ];then
        #進行2個執行緒并行編譯(可以根據你處理器個數選擇)
        make -j2 && make -j2 install
    else
        echo -e "\e[31m#Error: 預編譯失敗!終止安裝,請檢查軟體依賴! \e[0m"
        exit
    fi
    if [ $? -ne 0 ];then echo -e "\e[31m#Error: 編譯安裝失敗!終止安裝 \e[0m";exit;fi
    echo -e "\e[32m Nginx 成功安裝....... \n安裝目錄:${NGX_DIR} \n 正在啟動Nginx....\e[0m"
    $NGX_DIR/sbin/nginx
}

## [Nginx CONFIG]
function nginx_vhost(){
    NGX_VHOSTS=$1
    firewall_config
    cd ${NGX_DIR}
    NGX_CNF="${NGX_DIR}/conf/nginx.conf"
    if [ ! -f $NGX_CONF ];then echo -e "Nginx-組態檔不存在請仔細檢查!";exit;fi
    #判斷是否已經存在domains組態檔是則不同重新建立;
    grep "domains" ${NGX_CNF} >>/dev/null 2>&1
    if [ $? -ne 0 ];then
        #備份NGX組態檔
        cp ${NGX_CNF}{,_$(date +%F_%H%M%S).bak}
    	mkdir -vp ${NGX_VHDIR}
        sed -i "s/#user  nobody/user  nginx/g" ${NGX_CNF}
        sed -i "s/#gzip/gzip/g" ${NGX_CNF}
        #去除空行以及注釋
	    grep -vE "#|^$" ${NGX_CNF} > ${NGX_CNF}.swp
        #重點洗掉server字符到檔案末尾
	    sed -i '/server/,$d' ${NGX_CNF}.swp
        cp ${NGX_CNF}.swp ${NGX_CNF}
	    echo -e "    include domains/*;\n}" >> ${NGX_CNF}
    fi
    
cat>${NGX_VHDIR}/$NGX_VHOSTS.conf<<EOF
server {
    listen       80;
    server_name  $NGX_VHOSTS;

    location / {
        root   html/$NGX_VHOSTS;
        index  index.html index.htm;
    }
    #Nginx 監控模塊啟用
    location /nginxStatus {
        stub_status;
    }
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   html;
    }
}
EOF
   

echo -e "\e[32m$NGX_VHOSTS 網站目錄建立之中.....\e[0m"
if [ ! -d $NGX_DIR/html/$NGX_VHOSTS/ ];then
    mkdir -vp $NGX_DIR/html/$NGX_VHOSTS/
cat>$NGX_DIR/html/$NGX_VHOSTS/index.html<<EOF
<h1>$NGX_VHOSTS Test Pages. </h1>
<p>By WeiyiGeek.top </p>
<hr color=red>
EOF
fi
    echo -e "\e[32mNginx組態檔驗證中.....\e[0m"
    $NGX_DIR/sbin/nginx -t
    if [ $? -ne 0 ];then
        echo -e "\e[31mNginx組態檔有誤,請處理錯誤后重啟Nginx服務器:\n ${NGX_DIR}/sbin/nginx -s reload"
    fi
    cat ${NGX_VHDIR}/$NGX_VHOSTS.conf

    echo -e "\e[32mNginx重啟之中.....\e[0m"
    $NGX_DIR/sbin/nginx -s reload
    CHECK_STATUS=$(netstat -tlnp | grep -wc "nginx")
    if [ $CHECK_STATUS -ne 0 ];then
        echo -e "\e[32m#Nginx 啟動成功.... \e[0m"
    else
        echo -e "\e[31m#Nginx 啟動失敗.... \e[0m"
    fi
}

運行效果:
WeiyiGeek.運行效果

測驗效果:
WeiyiGeek.測驗效果


0x01 Nginx 配置最佳實踐

Nginx 之 多組態檔配置

描述: Nginx組態檔中支持包含多個組態檔,比如下面的虛擬主機的配置將使用,在程式加載運行時候首先會讀取nginx.conf 的組態檔,然后再讀取 /etc/nginx/conf.d/下面的組態檔;

例如,我們需要在/etc/nginx/nginx.conf檔案中,進行如下設定include /etc/nginx/conf.d/*.conf;

http {
  ....
  include conf.d/*.conf;
  ....
}

WeiyiGeek.


Nginx 之 Server 偵聽埠主機頭配置淺析

描述:常規網站編譯安裝后運行只是單個網站訪問,我們如何可以做到多網站同時運行到該Nginx服務器上,那我們便可使用Nginx提供的虛擬機主機方式, 使得一個服務埠可以訪問不同的服務應用;

常規有三種方式:

    1. 多埠
    1. 多IP
    1. 多域名:虛擬主機(VirtualHost)

環境準備:

cat >> /etc/hosts<<END
127.0.0.1 v1.weiyigeek.top v2.weiyigeek.top
END

流程步驟:

  • 1.修改移除Nginx.conf組態檔中的Server {...}包含的引數添加include domains/*;;
user  nginx;
worker_processes  1;
events {
    worker_connections  1024;
}
http {
  include       mime.types;
  default_type  application/octet-stream;
  sendfile        on;
  keepalive_timeout  65;
  gzip  on;
  include domains/*;
}
  • 2.在Nginx的Conf目錄中建立一個domains目錄(注意這里不要建立到上級目錄之中,否則會出現nginx master行程已經啟動但是無監聽埠),進入該目錄中建立虛擬主機v1.weiyigeek.top.conf檔案
server {
  listen       80;
  server_name  v1.weiyigeek.top;  #關鍵點
  location / {
    #關鍵點
    root   html/v1.weiyigeek.top;
    index  index.html index.htm;
  }
  #Nginx 監控模塊啟用
  location /nginxStatus {
      stub_status;
  }
  error_page   500 502 503 504  /50x.html;
  location = /50x.html {
      root   html;
  }
}
  • 3.在nginx安裝目錄中的html中建立一個與虛擬主機同名的檔案夾(當然名字您可以任意取,但是必須和v1.weiyigeek.top.conf中指定路與的root一致)
[root@WeiyiGeek html]# pwd
/usr/local/nginx/1.16.1/html
[root@WeiyiGeek html]# ls
50x.html  index.html  v1.weiyigeek.top  v2.weiyigeek.top

配置示例

server {
  # 使用標準 HTTP 協議
  listen 80;
  # 使用標準 HTTPS 協議
  listen 443 ssl;
  # 使用 http2 協議
  listen 443 ssl http2;
  # 使用IPV6地址監聽80埠
  listen [::]:80;
  # 只使用IPV6地址監聽80埠
  listen [::]:80 ipv6only=on;

  # 匹配指定域名訪問
  server_name weiyigeek.top;
  # 匹配多域名訪問
  server_name weiyigeek.top www.weiyigeek.top;
  # 匹配weiyigeek.top下所有子域名
  server_name *.weiyigeek.top;
  # 匹配所有的包含weiyigeek.top的頂級域名
  server_name weiyigeek.top.*;
  # 僅匹配IP地址訪問
  server_name "";
  server_name _;
}

溫馨提示: 當網站設定支持http2以后可以從請求回應頭中看到如下欄位 X-Firefox-Spdy:h2
WeiyiGeek.nginx-http/2


Nginx 之 Location 規則配置淺析

描述: Location 語法規則:location [=|~|~*|^~] /uri/ { … }

  • =: 表示精確匹配.
  • /: 表示通用匹配, 即任何請求都會匹配到,
  • ~: 表示區分大小寫的正則匹配.
  • ~*: 表示不區分大小寫的正則匹配.
  • !~,!~* : 分別標識為區分大小寫不匹配及不區分大小寫不匹配的正則
  • ^~: 表示URL以某個常規字串開頭,可以理解為匹配url路徑即可,值得注意的是Nginx不對URL做編碼,例如會將請求為/static/20%/aa被^~ /static/ /aa規則匹配到,

默認情況下 location 的匹配順序為精確匹配 -> 開頭匹配(^~) -> 檔案順序中的正則匹配 -> 通用匹配(/), 當有匹配成功的URL則停止匹配,

例如,有如下匹配規則:

location = / {
  #規則A.精確匹配 / URL 下的操作,
}
location = /login {
  #規則B.精確匹配 /login URL 下的操作,
}
location ^~ /static/ {
  #規則C.正則匹配 /static/ URL 下的操作,
}
location ~ \.(gif|jpg|png|svg|js|css)$ {
  #規則D,注意:是根據括號內的大小寫進行匹配,括號內全是小寫只匹配小寫,
}
location ~* \.(gif|jpg|png|svg|js|css)$ {
  #規則D,注意:忽略大寫來匹配靜態資源后綴,
}
location ~* \.png$ {
  #規則E.匹配以.png或者.PNG結尾的靜態資源,
}
location !~ \.xhtml$ {
  #規則F.不匹配.xhtml為后綴的資源,
}
location !~* \.xhtml$ {
  #規則G.不匹配.xhtml或者.XHTML為后綴的資源,
}
location / {
  #規則H.通用匹配,當上述匹配都不能匹配時,使用該規則,
}

在實踐程序中常見, 有如下幾種匹配規則:

# 第一個必選規則是直接匹配網站根,通過域名訪問網站首頁比較頻繁,使用這個會加速處理,
# 這里可以是直接轉發給后端應用服務器了,也可以是一個靜態首頁,
location = / {
  root /usr/local/nginx/html
  proxy_pass http://tomcat:8080/index
}
 
# 第二個必選規則是處理靜態檔案請求,這是nginx作為http服務器的強項
# 有兩種配置模式,目錄匹配或后綴匹配,任選其一或搭配使用
location ^~ /static/ {                             # // 以xx開頭
  root /webroot/static/;   # 注意,需要指定跟目錄.
}
location ~* \.(gif|jpg|jpeg|png|css|js|ico)$ {     # // 以xx結尾
  root /webroot/res/;  
}
 
#第三個規則就是通用規則,用來轉發動態請求到后端應用服務器
#非靜態檔案請求就默認是動態請求,自己根據實際把握
location / {
  proxy_pass http://tomcat:8080/
}

Nginx 之 規則判斷運算式淺析

Nginx 常用判斷運算式如下:

  • -f和!-f: 用來判斷是否存在檔案
  • -d和!-d:用來判斷是否存在目錄
  • -e和!-e:用來判斷是否存在檔案或目錄
  • -x和!-x:用來判斷檔案是否可執行
  • 除此之外我們還可以使用上一小節的正則匹配符進行判斷,

nginx 全域變數一覽:

arg_PARAMETER      # 這個變數包含GET請求中,如果有變數PARAMETER時的值,
args               # 這個變數等于請求行中(GET請求)的引數,如:foo=123&bar=blahblah;
binary_remote_addr # 二進制的客戶地址,
body_bytes_sent    # 回應時送出的body位元組數數量,即使連接中斷,這個資料也是精確的,
content_length    # 請求頭中的Content-length欄位,
content_type      # 請求頭中的Content-Type欄位,
cookie_COOKIE     # cookie COOKIE變數的值
document_root     # 當前請求在root指令中指定的值,
document_uri      # 與uri相同,
host              # 請求主機頭欄位,否則為服務器名稱,
hostname          # 設定為gethostname回傳的機器主機名
http_HEADER       # 請求header頭欄位
is_args           # 如果有args引數,這個變數等于”?”,否則等于”",空值,
http_user_agent   # 客戶端agent資訊
http_cookie       # 客戶端cookie資訊
limit_rate        # 這個變數可以限制連接速率,
query_string      # 與args相同,
request_body_file  #客戶端請求主體資訊的臨時檔案名,
request_method    #客戶端請求的動作,通常為GET或POST,
remote_addr          #客戶端的IP地址,
remote_port          #客戶端的埠,
remote_user          #已經經過Auth Basic Module驗證的用戶名,
request_completion #如果請求結束,設定為OK. 當請求未結束或如果該請求不是請求鏈串的最后一個時,為空(Empty),
request_method    #GET或POST
request_filename  #當前請求的檔案路徑,由root或alias指令與URI請求生成,
request_uri          #包含請求引數的原始URI,不包含主機名,如:”/foo/bar.php?arg=baz”,不能修改,
scheme                #HTTP方法(如http,https),
server_protocol      #請求使用的協議,通常是HTTP/1.0或HTTP/1.1,
server_addr          #服務器地址,在完成一次系統呼叫后可以確定這個值,
server_name        #服務器名稱,
server_port          #請求到達服務器的埠號,

Nginx 決議URL用作判斷的全域變數,例如,訪問的URL為http://weiyigeek.top:8080/test1/test2/test.php.

$host:weiyigeek.top
$server_port:8080
$request_uri:http://weiyigeek.top:8080/test1/test2/test.php
$document_uri:/test1/test2/test.php
$document_root:/data/nginx/html
$request_filename:/data/html/test1/test2/test.php

簡單示例:

  • 1.判斷請求的靜態資源檔案是否是存在的,如不存在則回傳403.
location ~* \.(js|css|jpg|jpeg|gif|png|swf)$ {
  if (-f $request_filename) { 
    return 403;
    break;
  }
}
  • 2.判斷Nginx全域變數并進行跳轉到指定頁面,
if ( $host !~* weiyigeek\.top ) {
  return 301 https://space.bilibili.com/385802642;
}
  • 3.檔案反盜鏈并設定過期時間
location ~*^.+\.(jpg|jpeg|gif|png|swf|rar|zip|css|js)$ {
  valid_referers none blocked *.weiyigeek.top localhost 127.0.0.1;
  if ($invalid_referer) {
      rewrite ^/ https://weiyigeek.top/wechat.html;
      return 412;
      break;
  }
  root /usr/local/nginx/html
  access_log  off;
  expires 3d;
  break;
}
  • 4.自定義變數判斷跳轉到指定頁面.
# 僅允許222.222.222.222或者內網的兩個IP訪問,其他IP都rewrite到停服頁面
if ( $remote_addr = 222.222.222.222){set $my_ip 1;}
if ( $remote_addr = 192.168.1.170 ){ set $my_ip 1;}
if ( $remote_addr = 192.168.1.169 ){ set $my_ip 1;}
if ( $my_ip != 1) {rewrite ^/design/(.*)\.php$ /weiyigeek.html?$1&;}  #將*.php轉到tingfu.html

溫馨提示: 此處以Nginx暴露給互聯網, 所以利用 $remote_addr 變數獲取訪問者地址, 如果用了負載均衡的話此處應該是$http_x_forwarded_for 變數,


Nginx 之 Redirect重定向與ReWrite重寫 配置淺析

Redirect(重定向)語法示例

# http 向 https 跳轉 (永久)
server {
  listen 80;
  server_name weiyigeek.top www.weiyigeek.top;
  return 301 https://$host$request_uri;
}

# http 向 https 跳轉(臨時)
server {
  listen 80;
  server_name weiyigeek.top www.weiyigeek.top;
  return 302 https://www.weiyigeek.top$request_uri;
}

ReWrite 重寫語法示例
rewrite 正則運算式以及其可用引數:

  • last : 基本上都用這個Flag,
  • break : 中止 Rewirte 不在繼續匹配
  • redirect : 回傳臨時重定向的HTTP狀態302
  • permanent : 回傳永久重定向的HTTP狀態301
# http 向 https 跳轉
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;
  }
}

# 利用重寫規則防止盜鏈
location ~* \.(gif|jpg|png|svg|css|js)$ {
  valid_referers none blocked *.weiyigeek.top localhost 127.0.0.1 server_names ~\.google\. ~\.baidu\.;
  if ($invalid_referer) {
    rewrite ^/ https://www.weiyigeek.top/403.jpg;
  }
}

# 利用重寫功能可將網頁中舊的訪問目錄重寫到新的訪問路徑
# 例如, 如果訪問https://blogwww.weiyigeek.top/2020/10/515.html 則將顯示首頁,
if ( $document_uri ~* /([0-9]+)/([0-9]+)/([0-9]+)\.html$) {
  rewrite ^/ /index.html last;
}

溫馨提示:301 與 302 狀態碼的不同區別,

  • 301 redirect: 301 代表永久性轉移( Permanently Moved ) - 網站SEO推薦,
  • 302 redirect: 302 代表暫時性轉移( Temporarily Moved )

Nginx 之 SSL 證書安全配置淺析

描述: 通常為了保證網站資料在傳輸程序中不被竊取和篡改,我們需要為其配置SSL證書,而在Nginx中配置方法是非常的簡單的,不過最重要的還是你要生成私鑰以及證書申請檔案csr向證書頒發機構生成網站證書,

# Permanent Redirect for HTTP to HTTPS
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;

  # 開啟 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;
}

補充說明: 為Nginx服務器配置RSA與ECDSA雙證書的兩種方式,

# 1.首先是將兩個證書鏈都加入 Nginx 的組態檔
ssl_certificate     example.com.rsa.crt;
ssl_certificate_key example.com.rsa.key;
ssl_certificate     example.com.ecdsa.crt;
ssl_certificate_key example.com.ecdsa.key;

# 2.或者使用 CT 的話有兩種方法,一個是將兩個證書的 CT 資訊放到同一目錄,并做如下設定,Nginx CT 模塊會自動在這個目錄下查找相應證書的 CT 資訊并發送驗證:
ssl_ct on;
ssl_ct_static_scts /path/to/sct/dir;

# 我們也可以單獨配置每個證書的 CT 檔案
ssl_ct on;
ssl_certificate example.com.rsa.crt;
ssl_certificate_key example.com.rsa.key;
ssl_ct_static_scts xample.com.rsa.scts;
 
ssl_certificate example.com.ecdsa.crt;
ssl_certificate_key example.com.ecdsa.key;
ssl_ct_static_scts example.com.ecdsa.scts;

Nginx 之 資源壓縮配置淺析

描述: 為了降低服務器帶寬壓力以及優化回應速度, 通常我們需要在Nginx服務器配置中為其開啟gzip壓縮,

配置示例:

# 開啟gzip
gzip on;
# 啟用gzip壓縮的最小檔案,小于設定值的檔案將不會壓縮
gzip_min_length 2k;
# gzip 壓縮級別,1-10,數字越大壓縮的越好,也越占用CPU時間,后面會有詳細說明
gzip_comp_level 2;
# 進行壓縮的檔案型別,javascript有多種形,其中的值可以在 mime.types 檔案中找到,
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 font/ttf font/opentype image/svg+xml;
# 建議在http header中添加Vary: Accept-Encoding支持
gzip_vary on;

Nginx 之 靜態資源expires快取過期時間配置

描述: 在 Nginx 配置 expires 指令可以起到控制頁面快取的作用, 配置靜態資源的 expires 可以有效的減少客戶端對服務器的請求,該配置項適用于: http、server 以及 location 塊中,

expires(過期時間語法)語法示例

; 語法: `expires [time|epoch|max|off]`
* epoch:指定Expires的值為 1 January,1970,00:00:01 GMT
* max: 指定Expires的值為31 December2037 23:59:59GMT,"Cache-Control"的值為10年,
* -1:指定Expires的值為當前服務器時間-1s,即永遠過期,
* off:不修改Expires和"Cache-Control"的值

# location 塊 ~ 使用正則匹配
location ~ \.(gif|jpg|jpeg|png|bmp|ico)$ {
  # 靜態資源源路徑必須配置否則,靜態資源可能無法找到
  root /var/www/img/;
  # 禁用404錯誤日志
  log_not_found off;
  # 關閉access訪問日志
  access_log off;
  # 靜態資源過期時間
  expires 7d;
}

該指令控制HTTP應答中的"Expires"和"Cache-Control"Header頭部資訊, 例如在配置后expires指令請求 https://blog.weiyigeek.top/img/avatar.jpg URL:

HTTP/1.1 304 Not Modified
Server: nginx
Date: Fri, 01 Apr 2022 09:19:09 GMT
Last-Modified: Wed, 30 Mar 2022 15:42:30 GMT
Connection: keep-alive
ETag: "62447a66-35db"
Expires: Fri, 08 Apr 2022 09:19:09 GMT # 表示資源過期時間,由當前訪問時間加上max-age指令值所得
Cache-Control: max-age=604800          # 使用max-age指令指定組件被快取多久,負數表示no-cache,正數或零表示max-age=time
Access-Control-Allow-Origin: *.weiyigeek.top
Access-Control-Allow-Methods: GET,POST
Access-Control-Allow-Headers: DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization

實踐示例:

# 網頁資源快取
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;
}

Nginx 之 反向代理資源基本快取配置

描述: 在 Nginx 中往往我們會對指定站點進行反代(反向代理), 而在反代站點中存在動態資源與靜態資源,我們可以使用下述指令開啟簡單的快取配置,

首先我們需要了解一下三種快取型別:

  • 客戶端快取
  • 代理快取(Proxy Cache)
  • 服務端快取

這里主要講解Nginx作為代理服務器進行代理快取的配置采用的引數以及示例:

  • 1.proxy_cache:定義用于快取的共享記憶體區域,同一個區域可以用于多個地方
Syntax: 	proxy_cache zone | off;
Default: 	proxy_cache off;
Context: 	http, server, location
  • 2.proxy_cache_path:設定快取的路徑和其他引數快取資料存盤在檔案中,快取中的檔案名是將MD5函式應用于快取鍵的結果
Context: http
Syntax: proxy_cache_path path [levels=levels] [use_temp_path=on|off] keys_zone=name:size [inactive=time] [max_size=size] [manager_files=number] [manager_sleep=time] [manager_threshold=time] [loader_files=number] [loader_sleep=time] [loader_threshold=time] [purger=on|off] [purger_files=number] [purger_sleep=time] [purger_threshold=time];

#例如,在下面的配置中level引數定義快取的層次結構級別:從1到3,每個級別接受值1或2,
proxy_cache_path /data/nginx/cache levels=1:2 keys_zone=one:10m; #10M = 10 * 8000 個密鑰
#/data/nginx/cache/c/29/b7f54b2df7773722d382f4809d65029c
  • 3.proxy_cache_valid:設定快取過期時間
Syntax: 	proxy_cache_valid [code ...] time;
Context: 	http, server, location

#例如,為不同的回應代碼設定快取時間,
proxy_cache_valid 200 302 10m;
proxy_cache_valid 404      1m;

#If only caching time is specified (指定),也可以可以指定any引數來快取任何回應:
proxy_cache_valid 5m;
proxy_cache_valid any      1m;
  • 4.proxy_cache_key:設定快取維度
Syntax: 	proxy_cache_key string;
Default: 	proxy_cache_key $scheme$proxy_host$request_uri;
Context: 	http, server, location

#例如,定義用于快取的鍵,
proxy_cache_key "$host$request_uri $cookie_user";
proxy_cache_key $scheme$proxy_host$uri$is_args$args; #默認情況下指令也是字串不用加上""
  • 5.proxy_cache_purge:定義將在何種條件下將請求視為快取清除請求,如果字串引數中至少有一個值不為空且不等于“0”,則洗掉具有相應快取鍵的快取項,通過回傳204 (No Content)回應來指示操作成功的結果,
Syntax: 	proxy_cache_purge string ...;
Context: 	http, server, location

# Example configuration: 
map $request_method $purge_method {
    PURGE   1;
    default 0;
}
  • 6.proxy_no_cache:指定不快取的部分頁面,可以與proxy_cache_bypass指令一起使用,
Syntax: 	proxy_no_cache string ...;
Context: 	http, server, location

#如果字串引數中至少有一個值不為空且不等于“0”,則不會保存回應:
proxy_no_cache $cookie_nocache $arg_nocache$arg_comment;
proxy_no_cache $http_pragma    $http_authorization;

proxy_cache 相關指令集簡述
描述: 其中proxy_cache_path指令配置了快取名稱以及其存放地址、快取大小等相關其它引數配置, 而proxy_cache指令配置是為了啟用創建的mycache名稱的快取,

  • proxy_no_cache : 該指令用于定義滿足條件的回應不會被保存到快取中,在條件字串中至少有一個條件不為慷訓者0,符合這樣條件的回應才不會被快取, 其一般會配合proxy_cache_bypass共同使用;
  • proxy_cache_bypass : 該指令用于定義哪些情況不從cache讀取直接從backend獲取資源配置同上,
  • proxy_cache_key : 該指令給快取資料定義一個鍵,
  • proxy_cache_methods :該指令用于設定快取哪些HTTP方法,默認快取HTTP GET/HEAD方法不快取POST方法,
  • proxy_cache_valid :該指令用于設定不同回應碼的快取時間,
  • proxy_cache_min_uses : 該指令用于設定快取的最小使用次數,默認值為1
  • proxy_cache_use_stale : 該指令開啟(增強)容錯能力,即使用快取內容來回應客戶端的請求

示例演示:

# 1.其中,cookie_nocache、arg_nocache...皆為變數,可以根據你訪問的匹配策略來設定,其值只有2類,0和非0;
# 訪問匹配策略, 如果在此鏈式配置中,只要有一個值不為 0 則不會cache,
if ($request_uri ~ ^/(login|register|password\/reset)/) { set $cookie_nocache 1; }
proxy_no_cache $cookie_nocache(0) $arg_nocache(1) $arg_comment(0)
proxy_no_cache $http_pragma $http_authorization;

# 2.默認情況下,該指令的值的字串,給快取資料定義一個鍵,
proxy_cache_key $scheme$proxy_host$uri$is_args$args; # 預設
proxy_cache_key $scheme$proxy_host$request_uri;

# 4.預設快取GET HEAD請求,
proxy_cache_methods GET HEAD;

# 5.只對回應碼為200,301,302的訪問請求資源設定快取時間,此外可以個性化定制,
proxy_cache_valid 200 302 10m; 
proxy_cache_valid 301 1h; 
proxy_cache_valid 404 1m; 
proxy_cache_valid any 1m;

# 6.設定快取的最小使用次數,
proxy_cache_min_uses 1;

# 7.當作為cache的NGINX收到源站回傳error、timeout或者其他指定的5XX錯誤,并且在其快取中有請求檔案的陳舊版本,則會將這些陳舊版本的檔案而不是錯誤資訊發送給客戶端,
proxy_cache_use_stale error timeout http_500 http_502 http_503 http_504;  

實踐配置: 多磁盤分割快取,如果有多個硬碟則可以用來在多個硬碟之間分割快取,

# 假設每塊硬碟掛載在相應的目錄中:/mnt/disk1、/mnt/disk2、/mnt/disk3, 使用了3個獨立的快取,每個快取專用一塊硬碟,另外,3個獨立的執行緒池也各自專用一塊硬碟,
proxy_cache_path /mnt/disk1 levels=1:2 keys_zone=cache_1:256m max_size=1024G use_temp_path=off;
proxy_cache_path /mnt/disk2 levels=1:2 keys_zone=cache_2:256m max_size=1024G use_temp_path=off;
proxy_cache_path /mnt/disk3 levels=1:2 keys_zone=cache_3:256m max_size=1024G use_temp_path=off;

# 快取之間(其結果就是磁盤之間)的負載均衡使用 split_clients 模塊
split_clients $request_uri $disk {
  33.3%     1;
  33.3%     2;
  *         3;
}
location / {
  proxy_pass http://127.0.0.1:9090;
  proxy_cache_key $request_uri;
  proxy_cache cache_$disk;
}

實踐示例:

  • 示例1.
proxy_cache_path /path/to/cache levels=1:2 keys_zone=mycache:10m max_size=10g inactive=60m use_temp_path=off;
upstream my_upstream {
  server 192.168.1.20:8080 weight=5 max_fails=5 fail_timeout=30s;
  server 192.168.1.10:8080 weight=5 max_fails=5 fail_timeout=30s;
}
server {
  location / {
    proxy_cache mycache;
    proxy_pass http://my_upstream;
  }
}
  • 示例2:
http {
    ...
    proxy_cache_path /opt/app levels:1:2 keys_zone=weiyigeek_cache:10m max_size=10g inactive=60m use_temp_path=off; 
    map $request_method $purge_method {
      PURGE   1;
      default 0;
    }
    ...
    server {
      ...
      location / {
          proxy_cache weiyigeek_cache;
          proxy_pass http://weiyigeek;
          proxy_cache_valid 200 304 12h;
          proxy_cache_valid any 10m;
          proxy_cache_key $host$uri$is_args$args;
          proxy_cache_purge $purge_method;
          add_header Nginx-Cache "$upstream_cache_status";
          proxy_net_upstream error timeout invalid_header http_500 http_502;
          include proxy_params;
      }
      ...
    }
}

溫馨提示: 在proxy_cache_path指令中的use_temp_path=off引數,表示會將臨時檔案保存在快取資料的同一目錄中,此舉避免在更新快取時,磁盤之間互相復制回應資料,減少磁盤IO壓力,


補充說明:
問: 如何清理指定快取?

> 1.rm -rf 洗掉快取目錄內容
> 2.第三方擴展模塊ngx_cache_purge

Nginx 之 黑白名單限制與請求限流

描述: 通常為了防止黑客攻擊以及惡意爬蟲爬取, 我們需要針對Nginx服務器配置黑白名單和限流措施,

黑白名單之deny 與 allow
描述: 利用 include 指令添加黑白名單組態檔,該指令可以在http, server, location, limit_except陳述句塊,例如:

# 白名單
include whiteip.conf;
# allow 192.168.12.0/24; # 允許IP段
# allow 127.0.0.1;       # 允許單個IP
# allow all;             # 允許所有IP

# 黑名單
include blockip.conf;
# deny 127.0.0.1; # 屏蔽單個IP
# deny all; # 屏蔽所有IP

溫馨提示: 當被屏蔽的 IP 再次訪問我們的nginx服務器網頁是,將會顯示 403 頁面,


訪問限制之并發連接與請求速率
描述: 我們可以分別利用Nginx提供的 limit_conn_zone 與 limit_req_zone 模塊來限制每個IP的連接數以及請求數,$binary_remote_addr 是限制同一客戶端ip地址(節約空間), 注意不是使用$remote_addr變數;

http {
  # - limit_conn_zone:限制每個IP的并發連接數
  # 例如 blogweiyigeektop 是定義的一個會話區其用于記錄會話狀態資訊,
  limit_conn_zone $binary_remote_addr zone=blogweiyigeektop:10m;
  limit_conn_zone $server_name zone=serverweiyigeektop:10m;
  limit_conn_log_level info;

  # - limit_req_zone:限制每個IP的請求數
  limit_req_zone $binary_remote_addr zone=weiyigeek_top:10m rate=1r/s;
	limit_req_zone $binary_remote_addr $uri zone=blog_weiyigeek_top:3m rate=1r/s; # $uri 表示同個ip 訪問同個uri 才會進入限制
  
  server {
    # 限連接數
    location  ^~ /download1/ {  
      limit_conn serverweiyigeektop 1000; # 表示該服務提供的總連接數最大不超過1000,超過的請求會被拒絕
      limit_conn blogweiyigeektop 4;   # 表示對blogweiyigeektop空間中的每個IP的最大并發連接數為4
      limit_rate 200k;                 # 注意此處是對連接的限速不是對IP的限速
      alias /data/www.weiyigeek.top/download1/;
    }

    # 限請求速率
    location  ^~ /download2/ {  
      # 允許超過頻率限制的請求數不多于5個,無延遲表示請求超過頻次時,可提供處理(burst + rate)個請求的能力,注意 nodelay 是要和 burst 配合使用的,
			limit_req zone=weiyigeek_top burst=5 nodelay; 
			alias /data/blog.weiyigeek.top/download2/;
    }
  }
}

動態屏蔽惡意IP
Step 1.從logs目錄下日志檔案中安裝指定規則查找要屏蔽的IP執行如下命令awk '{print $1}' access.log |sort |uniq -c|sort -n即可,就可以統計出IP的訪問次數,

68 218.76.35.4
73 42.192.96.35
94 139.155.14.45
221 223.202.212.140
  • Step 2.自動化腳本簡單實作訪問請求次數多的IP將進行封禁,
#! /bin/bash
log_nginx="/var/log/nginx"            	# nginx日志檔案
blockfile="/usr/local/nginx/conf.d"     # ip黑名單存放目錄
ip_tempfile="/tmp/nginx/ip.txt"        

# 取出日志中符合條件的ip寫入ip.txt,并過濾掉重復的
grep "/atom.xml" $log_nginx/access.log | awk '{print $1}' | sort -rn |uniq -c |awk '{print $2}' > /tmp/nginx/ip.txt

for ip in `cat /home/shell/ip.txt`;do
  result=$(grep $ip $blockfile/blockip.conf)

  #判斷ip是否已經被屏蔽
  if [ -z "$result" ]; then
 
  #分析ip請求的次數
  count=$(grep $ip $log_nginx/access.log|grep "app/user/getCode"|wc -l)
 
  # 請求次數大于等于20次就進行屏蔽
  if [ $count -ge 20 ]; then
    echo "deny $ip;" >> $blockfile/blockip.conf
  fi
fi
done
 
#重啟nginx
/usr/local/nginx/sbin/nginx -s reload

溫馨提示: 上述并不是一個非常好的方式,此種方式誤殺明顯,建議與請求限制聯合使用,于此同時我們可以利用Lua + redis實作一個動態封禁與解封(這個后續在實作),


白名單與限制聯合使用:
描述: 如果 Nginx 前面有 lvs 或者 haproxy 之類的負載均衡或者反向代理,nginx 獲取的都是來自負載均衡的連接或請求,此時是不應該限制負載均衡的連接和請求,這就需要 geo 和 map 模塊設定白名單了;

geo $whiteiplist  {
  default 1;
  10.11.15.161 0;
}
map $whiteiplist $limit {
  1 $binary_remote_addr;
  0 "";
}
limit_req_zone $limit zone=one:10m rate=10r/s;
limit_conn_zone $limit zone=addr:10m;

原文連接: https://blog.weiyigeek.top/2019/9-1-124.html

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

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

轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/458296.html

標籤:其他

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

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

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • IEEE1588PTP在數字化變電站時鐘同步方面的應用

    IEEE1588ptp在數字化變電站時鐘同步方面的應用 京準電子科技官微——ahjzsz 一、電力系統時間同步基本概況 隨著對IEC 61850標準研究的不斷深入,國內外學者提出基于IEC61850通信標準體系建設數字化變電站的發展思路。數字化變電站與常規變電站的顯著區別在于程序層傳統的電流/電壓互 ......

    uj5u.com 2020-09-10 03:51:52 more
  • HTTP request smuggling CL.TE

    CL.TE 簡介 前端通過Content-Length處理請求,通過反向代理或者負載均衡將請求轉發到后端,后端Transfer-Encoding優先級較高,以TE處理請求造成安全問題。 檢測 發送如下資料包 POST / HTTP/1.1 Host: ac391f7e1e9af821806e890 ......

    uj5u.com 2020-09-10 03:52:11 more
  • 網路滲透資料大全單——漏洞庫篇

    網路滲透資料大全單——漏洞庫篇漏洞庫 NVD ——美國國家漏洞庫 →http://nvd.nist.gov/。 CERT ——美國國家應急回應中心 →https://www.us-cert.gov/ OSVDB ——開源漏洞庫 →http://osvdb.org Bugtraq ——賽門鐵克 →ht ......

    uj5u.com 2020-09-10 03:52:15 more
  • 京準講述NTP時鐘服務器應用及原理

    京準講述NTP時鐘服務器應用及原理京準講述NTP時鐘服務器應用及原理 安徽京準電子科技官微——ahjzsz 北斗授時原理 授時是指接識訓通過某種方式獲得本地時間與北斗標準時間的鐘差,然后調整本地時鐘使時差控制在一定的精度范圍內。 衛星導航系統通常由三部分組成:導航授時衛星、地面檢測校正維護系統和用戶 ......

    uj5u.com 2020-09-10 03:52:25 more
  • 利用北斗衛星系統設計NTP網路時間服務器

    利用北斗衛星系統設計NTP網路時間服務器 利用北斗衛星系統設計NTP網路時間服務器 安徽京準電子科技官微——ahjzsz 概述 NTP網路時間服務器是一款支持NTP和SNTP網路時間同步協議,高精度、大容量、高品質的高科技時鐘產品。 NTP網路時間服務器設備采用冗余架構設計,高精度時鐘直接來源于北斗 ......

    uj5u.com 2020-09-10 03:52:35 more
  • 詳細解讀電力系統各種對時方式

    詳細解讀電力系統各種對時方式 詳細解讀電力系統各種對時方式 安徽京準電子科技官微——ahjzsz,更多資料請添加VX 衛星同步時鐘是我京準公司開發研制的應用衛星授時時技術的標準時間顯示和發送的裝置,該裝置以M國全球定位系統(GLOBAL POSITIONING SYSTEM,縮寫為GPS)或者我國北 ......

    uj5u.com 2020-09-10 03:52:45 more
  • 如何保證外包團隊接入企業內網安全

    不管企業規模的大小,只要企業想省錢,那么企業的某些服務就一定會采用外包的形式,然而看似美好又經濟的策略,其實也有不好的一面。下面我通過安全的角度來聊聊使用外包團的安全隱患問題。 先看看什么服務會使用外包的,最常見的就是話務/客服這種需要大量重復性、無技術性的服務,或者是一些銷售外包、特殊的職能外包等 ......

    uj5u.com 2020-09-10 03:52:57 more
  • PHP漏洞之【整型數字型SQL注入】

    0x01 什么是SQL注入 SQL是一種注入攻擊,通過前端帶入后端資料庫進行惡意的SQL陳述句查詢。 0x02 SQL整型注入原理 SQL注入一般發生在動態網站URL地址里,當然也會發生在其它地發,如登錄框等等也會存在注入,只要是和資料庫打交道的地方都有可能存在。 如這里http://192.168. ......

    uj5u.com 2020-09-10 03:55:40 more
  • [GXYCTF2019]禁止套娃

    git泄露獲取原始碼 使用GET傳參,引數為exp 經過三層過濾執行 第一層過濾偽協議,第二層過濾帶引數的函式,第三層過濾一些函式 preg_replace('/[a-z,_]+\((?R)?\)/', NULL, $_GET['exp'] (?R)參考當前正則運算式,相當于匹配函式里的引數 因此傳遞 ......

    uj5u.com 2020-09-10 03:56:07 more
  • 等保2.0實施流程

    流程 結論 ......

    uj5u.com 2020-09-10 03:56:16 more
最新发布
  • 使用Django Rest framework搭建Blog

    在前面的Blog例子中我們使用的是GraphQL, 雖然GraphQL的使用處于上升趨勢,但是Rest API還是使用的更廣泛一些. 所以還是決定回到傳統的rest api framework上來, Django rest framework的官網上給了一個很好用的QuickStart, 我參考Qu ......

    uj5u.com 2023-04-20 08:17:54 more
  • 記錄-new Date() 我忍你很久了!

    這里給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 大家平時在開發的時候有沒被new Date()折磨過?就是它的諸多怪異的設定讓你每每用的時候,都可能不小心踩坑。造成程式意外出錯,卻一下子找不到問題出處,那叫一個煩透了…… 下面,我就列舉它的“四宗罪”及應用思考 可惡的四宗罪 1. Sa ......

    uj5u.com 2023-04-20 08:17:47 more
  • 使用Vue.js實作文字跑馬燈效果

    實作文字跑馬燈效果,首先用到 substring()截取 和 setInterval計時器 clearInterval()清除計時器 效果如下: 實作代碼如下: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta ......

    uj5u.com 2023-04-20 08:12:31 more
  • JavaScript 運算子

    JavaScript 運算子/運算子 在 JavaScript 中,有一些運算子可以使代碼更簡潔、易讀和高效。以下是一些常見的運算子: 1、可選鏈運算子(optional chaining operator) ?.是可選鏈運算子(optional chaining operator)。?. 可選鏈操 ......

    uj5u.com 2023-04-20 08:02:25 more
  • CSS—相對單位rem

    一、概述 rem是一個相對長度單位,它的單位長度取決于根標簽html的字體尺寸。rem即root em的意思,中文翻譯為根em。瀏覽器的文本尺寸一般默認為16px,即默認情況下: 1rem = 16px rem布局原理:根據CSS媒體查詢功能,更改根標簽的字體尺寸,實作rem單位隨螢屏尺寸的變化,如 ......

    uj5u.com 2023-04-20 08:02:21 more
  • 我的第一個NPM包:panghu-planebattle-esm(胖虎飛機大戰)使用說明

    好家伙,我的包終于開發完啦 歡迎使用胖虎的飛機大戰包!! 為你的主頁添加色彩 這是一個有趣的網頁小游戲包,使用canvas和js開發 使用ES6模塊化開發 效果圖如下: (覺得圖片太sb的可以自己改) 代碼已開源!! Git: https://gitee.com/tang-and-han-dynas ......

    uj5u.com 2023-04-20 08:01:50 more
  • 如何在 vue3 中使用 jsx/tsx?

    我們都知道,通常情況下我們使用 vue 大多都是用的 SFC(Signle File Component)單檔案組件模式,即一個組件就是一個檔案,但其實 Vue 也是支持使用 JSX 來撰寫組件的。這里不討論 SFC 和 JSX 的好壞,這個仁者見仁智者見智。本篇文章旨在帶領大家快速了解和使用 Vu ......

    uj5u.com 2023-04-20 08:01:37 more
  • 【Vue2.x原始碼系列06】計算屬性computed原理

    本章目標:計算屬性是如何實作的?計算屬性快取原理以及洋蔥模型的應用?在初始化Vue實體時,我們會給每個計算屬性都創建一個對應watcher,我們稱之為計算屬性watcher ......

    uj5u.com 2023-04-20 08:01:31 more
  • http1.1與http2.0

    一、http是什么 通俗來講,http就是計算機通過網路進行通信的規則,是一個基于請求與回應,無狀態的,應用層協議。常用于TCP/IP協議傳輸資料。目前任何終端之間任何一種通信方式都必須按Http協議進行,否則無法連接。tcp(三次握手,四次揮手)。 請求與回應:客戶端請求、服務端回應資料。 無狀態 ......

    uj5u.com 2023-04-20 08:01:10 more
  • http1.1與http2.0

    一、http是什么 通俗來講,http就是計算機通過網路進行通信的規則,是一個基于請求與回應,無狀態的,應用層協議。常用于TCP/IP協議傳輸資料。目前任何終端之間任何一種通信方式都必須按Http協議進行,否則無法連接。tcp(三次握手,四次揮手)。 請求與回應:客戶端請求、服務端回應資料。 無狀態 ......

    uj5u.com 2023-04-20 08:00:32 more