VeryNginx 是一個功能強大而對人類友好的 Nginx 擴展程序,這是作者的原話。很久之前我就看到過這個項目,直到最近我纔在本站試用了一把,確實好用,於是想通過本文把它介紹給更多人。
VeryNginx 主要由兩部分組成:基於 lua-nginx-module 開發的 Lua 腳本,以及基於 HTML/CSS/JS 開發的 Web 控制面板 —— 用於生成和管理 Lua 腳本所需配置。
lua-nginx-module 能讓 Lua 腳本直接跑在 Nginx 內部,比用 C 語言開發 Nginx 模塊更容易上手,同時還能充分利用 Nginx 的非阻塞 I/O 模型,非常適合開發功能複雜、性能優異的 Web 應用。它也是大家熟知的 OpenResty 套件中一個最核心的模塊。
VeryNginx 通過在請求的不同階段(如 init_by_lua*/rewrite_by_lua*/access_by_lua*/log_by_lua*)執行不同 Lua 腳本,實現給請求打標籤及對擁有不同標籤的請求進行不同的處理的功能。除此之外,它還支持常見的統計報表展示。
安裝 VeryNginx
VeryNginx 依賴以下三個 Nginx 模塊:
- lua-nginx-module
- http_stub_status_module
- http_ssl_module
如果對 Nginx 沒有定製化需求,建議直接使用 VeryNginx 默認的安裝腳本,它會同時裝好 VeryNginx 自身和 OpenResty 套件,最爲方便。具體步驟請查看官方文檔。
對於我這樣喜歡各種折騰 Nginx 的人來說,修改之前的 Nginx 編譯步驟,把上面三個模塊加進去,也不算複雜。具體步驟後面再介紹,先來搞定 VeryNginx 工具本身。
這一步很簡單:下載 VeryNginx 最新版代碼並安裝即可:
BASHwget https://github.com/alexazhou/VeryNginx/archive/v0.3.3.zip
unzip v0.3.3.zip
cd VeryNginx-0.3.3/
sudo python install.py install verynginx
cd ../
安裝 VeryNginx 用到了 Python 腳本,但這個項目跟 Python 沒有半毛錢關係,不信可以看下 install.py
中的 install_verynginx
方法,只做了拷貝文件和修改配置目錄權限兩件事。
VeryNginx 默認會被裝到 /opt/verynginx/
目錄,本文使用默認配置。
編譯 Nginx
VeryNginx 依賴的 http_stub_status_module
和 http_ssl_module
只需要在 configure 時加上就可以。lua-nginx-module
稍微麻煩一點,它有以下依賴:
- LuaJIT 2.0 或 LuaJIT 2.1(推薦)或 Lua 5.1(5.2 目前不支持);
- ngx_devel_kit(NDK);
- ngx_lua 源碼;
下面分別來搞定它們。本文使用 Ubuntu 16.04.1 LTS,全部採用默認路徑安裝。如果你的環境跟我不一樣,一些命令請自行調整。
LuaJIT
下載並安裝 LuaJIT:
BASHwget http://luajit.org/download/LuaJIT-2.1.0-beta2.zip
unzip LuaJIT-2.1.0-beta2.zip
cd LuaJIT-2.1.0-beta2/
make
sudo make install
cd ../
設置環境變量:
export LUAJIT_LIB=/usr/local/lib
export LUAJIT_INC=/usr/local/include/luajit-2.1/
ngx_devel_kit
下載並解壓 ngx_devel_kit:
wget https://github.com/simpl/ngx_devel_kit/archive/v0.3.0.zip
unzip v0.3.0.zip
ngx_lua
下載並解壓 ngx_lua:
wget https://github.com/openresty/lua-nginx-module/archive/v0.10.7.zip
unzip v0.10.7.zip
Nginx
本站編譯 Nginx 的詳細步驟,都記錄在這篇文章,可以照搬。只有 configure 要改一下:
./configure --with-ld-opt="-Wl,-rpath,/usr/local/lib/" --add-module=../ngx_devel_kit-0.3.0 --add-module=../lua-nginx-module-0.10.7 --add-module=../ngx_brotli --add-module=../nginx-ct-1.3.2 --with-openssl=../openssl --with-http_v2_module --with-http_ssl_module --with-http_gzip_static_module --with-http_stub_status_module
make
#make install 前請務必停止已有 Nginx 服務,sudo /etc/init.d/nginx stop
sudo make install
編譯並安裝好 Nginx 之後,建議通過 -V
參數再次確認:
BASH/usr/local/nginx/sbin/nginx -V
nginx version: nginx/1.11.7
built by gcc 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.4)
built with OpenSSL 1.0.2j 26 Sep 2016
TLS SNI support enabled
configure arguments: --with-ld-opt=-Wl,-rpath,/usr/local/lib/ --add-module=../ngx_devel_kit-0.3.0 --add-module=../lua-nginx-module-0.10.7 --add-module=../ngx_brotli --add-module=../nginx-ct-1.3.1 --with-openssl=../openssl --with-http_v2_module --with-http_ssl_module --with-http_gzip_static_module --with-http_stub_status_module
配置 VeryNginx
在 Nginx 中引入 VeryNginx 的配置文件,就可以讓 VeryNginx 工作起來。首先要修改的是 Nginx 的主配置,一般位於 /usr/local/nginx/conf/nginx.conf
。
在主配置文件的最外層,加入以下配置:
include /opt/verynginx/verynginx/nginx_conf/in_external.conf;
在主配置的 http
段落中,加入以下配置:
include /opt/verynginx/verynginx/nginx_conf/in_http_block.conf;
在具體站點配置的 server
段落中,加入以下配置:
include /opt/verynginx/verynginx/nginx_conf/in_server_block.conf;
加完之後,建議通過 -t
參數確保配置無誤:
/usr/local/nginx/sbin/nginx -t
如果提示 test is successful
,說明配置無誤,可以重啓 Nginx 服務;否則請根據提示排查。
如果一切順利,訪問 http://yourdomain.com/verynginx/index.html
就可以見到 VeryNginx 的 Web 控制面板。默認用戶名和密碼都是 verynginx
,登錄後請務必修改。
使用示例
VeryNginx 使用非常簡便,基本上不需要做過多說明。只是有一點需要注意:在 Web 控制面板中對任何配置項進行增刪改之後,在點擊頁面右下角「Save」按鈕之前並不會生效;點擊「Reload」可還原到上一次配置。
VeryNginx 可以根據多種特徵(Client IP、Host、UserAgent、URI、Referer、Request Args)來組合出不同的規則,用來給請求打上標記(Matcher);可以給擁有不同標記的請求指定不同的處理動作(Custom Action)。
下面通過一個實際案例來演示 VeryNginx 的基本用法。
最近我發現某搜索引擎對本站的索引中,有大量重複內容(一共索引了 5000 多條記錄,其他搜索引擎都只有幾百):
一般來說,並不是說搜索引擎收錄的頁面越多越好,相反如果收錄的不同 URL 都指向了同樣的內容,很可能被判作弊,從而導致站點被降權。
從訪問日誌中,可以看到這家搜索引擎在大量抓取本站首頁,並帶上了一個無意義的 p 參數:
BASH106.120.173.72 - - [10/Dec/2016:05:50:43 +0800] "GET /index.html?p=142&pn=7 HTTP/1.1" 200 6098 "-" "Sogou web spider/4.0(+http://www.sogou.com/docs/help/webmasters.htm#07)" 0.007 0.007
106.120.173.72 - - [10/Dec/2016:05:50:53 +0800] "GET /index.html?p=134&pn=1 HTTP/1.1" 200 4793 "-" "Sogou web spider/4.0(+http://www.sogou.com/docs/help/webmasters.htm#07)" 0.007 0.007
106.120.173.72 - - [10/Dec/2016:05:51:03 +0800] "GET /index.html?p=94&pn=1 HTTP/1.1" 200 4793 "-" "Sogou web spider/4.0(+http://www.sogou.com/docs/help/webmasters.htm#07)" 0.006 0.006
本站沒有使用 p 參數,這樣會導致 Spider 抓取的頁面雖然 URL 不一樣,但內容完全一樣,從而導致大量重複索引。如果是 Google 出現這種情況,可以通過 Google Webmaster 告訴 Spider 忽略指定參數。但這家搜索引擎的站長平臺我一直無法認證成功,所以這條路不通。
有了 VeryNginx,這種情況就很好處理了。首先通過 UserAgent 是否包含關鍵字、請求中是否存在 p 參數兩個條件,對流量進行標記:
然後使用「Filter」這個 Custom Action,直接將擁有這個標記的流量響應爲 404:
在 Web 控制面板保存配置後,立即生效。馬上來測試一下:
BASHcurl -I -H'User-Agent: Sogou web spider/4.0(+http://www.sogou.com/docs/help/webmasters.htm#07)' 'https://imququ.com/?p=95&pn=17'
HTTP/1.1 404 Not Found
Server: nginx
... ...
是不是很棒!通常,如果搜索引擎發現某個網址多次無法訪問,就會從將其從索引庫及 Spider 抓取列表中移除。
可以看到,使用 VeryNginx 對特定流量進行標記和干預,比直接修改 Nginx 配置方便得多,也強大得多。除了前面演示的「Filter」之外,VeryNginx 還提供了「Scheme Lock、Redirect、URI Rewrite、Browser Verify、Frequency Limit」這幾個 Custom Action,其中「Browser Verify」可以用來驗證發起請求的客戶端是否支持 Cookie 或者 JavaScript,達到防 CC 攻擊的目的。
大家都知道,我特別關注本站的訪問速度。經過這段時間的試用,VeryNginx 在請求處理和內存佔用上的表現,都令人滿意。
本文就寫到這裏,如果想要了解 VeryNginx 更多細節,推薦查看官方文檔。