Nginx + Lua 搭建網站WAF防火牆
- 2019 年 10 月 3 日
- 筆記
前言
對於項目裡面只是使用代理等常用功能,在線安裝即可,如需制定化模組,則推薦編譯安裝
PS:本文不僅僅包含Nginx相關的知識點,還包含了逆天學習方法(對待新事物的處理)
官方網站:https://nginx.org/
Nginx書籍:
1.在線安裝
1.1.修改yum源地址
清華源:https://mirrors.tuna.tsinghua.edu.cn/help/centos/

更新軟體包快取:yum makecache

1.2.在線安裝Nginx
在線安裝比較簡單,參考官方文檔即可:https://nginx.org/en/linux_packages.html
PS:線上選
stable的就行了,記得把$releasever改成你的版本號,eg:7

安裝圖示:

# 創建nginx的yum vi /etc/yum.repos.d/nginx.repo # 內容如下: [nginx-stable] name=nginx stable repo baseurl=http://nginx.org/packages/centos/7/$basearch/ gpgcheck=1 enabled=1 gpgkey=https://nginx.org/keys/nginx_signing.key # 在線安裝 yum install nginx -y 1.3.埠放行
放行80埠:firewall-cmd --zone=public --add-port=80/tcp --permanent
PS:規則生效:
firewall-cmd --reload

1.4.驗證安裝

2.知識拓展
2.1.編譯參數
離線安裝可以參考在線安裝的配置:nginx -V:編譯參數(nginx -v:查看版本)

編譯參數詳解(點我展開)
```shell # 1.編譯選項 ## Nginx的安裝主目錄 --prefix=/etc/nginx ## Nginx的執行文件路徑 --sbin-path=/usr/sbin/nginx ## Nginx的模組目錄 --modules-path=/usr/lib64/nginx/modules ## Nginx的配置文件路徑 --conf-path=/etc/nginx/nginx.conf ## Nginx的錯誤日誌路徑 --error-log-path=/var/log/nginx/error.log ## Nginx的訪問日誌 --http-log-path=/var/log/nginx/access.log ## Nginx的pid文件路徑 --pid-path=/var/run/nginx.pid ## Nginx的lock路徑 --lock-path=/var/run/nginx.lock # 2.編譯選項(執行對應模組時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 # 3.設置Nginx許可權組(雖然root許可權安裝,但可以指定nginx的運行許可權) --user=nginx --group=nginx # 4.優化 ## 啟用gzip壓縮模組(常用) --with-http_gzip_static_module --with-http_gunzip_module # 文件使用aio非同步操作 --with-file-aio ## C系列優化 --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' # HTTP內容替換 --with-http_sub_module # 其他優化選項 or 模組 --with-compat --with-threads --with-http_addition_module --with-http_auth_request_module --with-http_dav_module --with-http_flv_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_v2_module --with-mail --with-mail_ssl_module --with-stream --with-stream_realip_module --with-stream_ssl_module --with-stream_ssl_preread_module ```2.2.安裝目錄
在線安裝的包都可以通過:rpm -ql xxx查看安裝到哪些目錄
安裝目錄詳解(點我展開)
```shell [root@localhost dnt]# rpm -ql nginx # Nginx使用用logrotate服務對日誌進行切割的配置文件(eg:按天切割) /etc/logrotate.d/nginx # Nginx的核心目錄 /etc/nginx # 主要配置文件,Nginx啟動的時候會讀取 /etc/nginx/nginx.conf /etc/nginx/conf.d # nginx.conf沒變更久讀default.conf(默認Server載入的文件) /etc/nginx/conf.d/default.conf # Nginx對Python的wsgi配置 /etc/nginx/uwsgi_params # fastcgi配置 /etc/nginx/fastcgi_params # scgi配置 /etc/nginx/scgi_params # Nginx快取目錄 /var/cache/nginx # Nginx日誌目錄 /var/log/nginx # Nginx默認網站存放的路徑 /usr/share/nginx/html /usr/share/nginx/html/50x.html /usr/share/nginx/html/index.html # 設置http的Content-Type與擴展名對應關係的配置文件 /etc/nginx/mime.types # Nginx模組所在目錄 /usr/lib64/nginx/modules /etc/nginx/modules # 二進位執行文件 /usr/sbin/nginx /usr/sbin/nginx-debug # 編碼轉換的映射文件 /etc/nginx/koi-utf /etc/nginx/koi-win /etc/nginx/win-utf # 配置CentOS守護進程對Nginx的管理方式 /usr/lib/systemd/system/nginx-debug.service /usr/lib/systemd/system/nginx.service /etc/sysconfig/nginx /etc/sysconfig/nginx-debug # Nginx的文檔 /usr/share/doc/nginx-1.16.0 /usr/share/doc/nginx-1.16.0/COPYRIGHT /usr/share/man/man8/nginx.8.gz # Nginx檢測更新命令 /usr/libexec/initscripts/legacy-actions/nginx /usr/libexec/initscripts/legacy-actions/nginx/check-reload /usr/libexec/initscripts/legacy-actions/nginx/upgrade ```2.3.默認配置
配置語法檢查:nginx -t -c /etc/nginx/nginx.conf
PS:不重啟的方式載入配置:
Nginx -s reload -c /etc/nginx/nginx.conf
全局以及服務級別的配置:
| 參數 | 說明 |
|---|---|
user | 使用用戶來運行nginx |
worker_processes | 工作進程數 |
error_log | nginx的錯誤日記 |
| pid | nginx啟動時的pid |
events相關配置:
| 參數 | 說明 |
|---|---|
worker_connections | 每個進程的最大連接數 |
use | 工作進程數 |
常用中間件配置:
http { ...... server { listen 80; # 埠號 server_name localhost; # 域名 # 路徑訪問控制(默認訪問路徑,eg:/ ==> 根目錄) location / { root /usr/share/nginx/html; # 網站根目錄 index index.html index.htm index.py; # 首頁配置 } error_page 500 502 503 504 /50x.html; # 錯誤頁面(可以自定義添404頁面,error_page 404 /404.html;...) # 訪問xxx/50x.html的時候去指定目錄找 location = /50x.html { root /usr/share/nginx/html; # 錯誤頁面所在路徑 } } # 一個server配置一個虛擬 or 獨立的站點(通過listen和server_name來區別多個server) server { ...... } } 2.4.systemctl配置
nginx:(等會編譯安裝的時候可以參考)
[root@localhost dnt]# cat /usr/lib/systemd/system/nginx.service [Unit] Description=nginx - high performance web server Documentation=http://nginx.org/en/docs/ After=network-online.target remote-fs.target nss-lookup.target Wants=network-online.target [Service] Type=forking PIDFile=/var/run/nginx.pid ExecStart=/usr/sbin/nginx -c /etc/nginx/nginx.conf ExecReload=/bin/kill -s HUP $MAINPID ExecStop=/bin/kill -s TERM $MAINPID [Install] WantedBy=multi-user.target nginx-debug:
[root@localhost dnt]# cat /usr/lib/systemd/system/nginx-debug.service [Unit] Description=nginx - high performance web server Documentation=http://nginx.org/en/docs/ After=network-online.target remote-fs.target nss-lookup.target Wants=network-online.target [Service] Type=forking PIDFile=/var/run/nginx.pid ExecStart=/usr/sbin/nginx-debug -c /etc/nginx/nginx.conf ExecReload=/bin/kill -s HUP $MAINPID ExecStop=/bin/kill -s TERM $MAINPID [Install] WantedBy=multi-user.target 3.編譯安裝
3.1.安裝編譯環境
一步到位:yum install gcc-c++ pcre pcre-devel zlib zlib-devel openssl openssl-devel -y

簡單拆分解析一下:
- Nginx使用
C/C++編寫的,安裝一下依賴:yum install gcc-c++ -y - Nginx需要使用PCRE來進行正則解析:
yum install pcre pcre-devel -y - 現在伺服器和瀏覽器一般都是使用gzip:
yum install -y zlib zlib-devel -y - 讓Nginx支援https:
yum install openssl openssl-devel -y
3.2.Nginx編譯安裝
3.2.1.下載解壓
先編譯安裝一下,後面說lua模組的時候再重新編譯下就行了
下載:curl -o nginx.tar.gz http://nginx.org/download/nginx-1.16.0.tar.gz
解壓:tar -zxvf nginx.tar.gz
3.2.2.配置編譯參數
參考前面說的在線版Nginx來設置編譯參數的配置:
PS:
nginx -V
切換到nginx的解壓目錄:cd nginx-1.16.0 然後執行下面命令
PS:root許可權編譯哦~
./configure --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 --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 --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' 3.2.3.進行編譯安裝
接著編譯安裝:make && make install
PS:提速:
make -j 4 && make install

3.2.4.配置systemctl
利用systemctl添加自定義系統服務

# vi /usr/lib/systemd/system/nginx.service [Unit] Description=nginx - high performance web server Documentation=http://nginx.org/en/docs/ After=network-online.target remote-fs.target nss-lookup.target Wants=network-online.target [Service] Type=forking PIDFile=/var/run/nginx.pid ExecStart=/usr/sbin/nginx -c /etc/nginx/nginx.conf ExecReload=/bin/kill -s HUP $MAINPID ExecStop=/bin/kill -s TERM $MAINPID [Install] WantedBy=multi-user.target PS:如果不生效可以重載下systemctl:systemctl daemon-reload
3.2.5.埠放行
放行80埠:firewall-cmd --zone=public --add-port=80/tcp --permanent
PS:規則生效:
firewall-cmd --reload

3.2.6.驗證

運行的時候如果出現nginx: [emerg] getpwnam("nginx") failed的錯誤可以參考我寫這篇文章:https://www.cnblogs.com/dotnetcrazy/p/11304783.html
PS:核心:
useradd -s /sbin/nologin -M nginx
3.3.編譯安裝Lua模組
大體思路
默認是不支援Lua的,所以需要自己編譯安裝下
PS:記得安裝下Lua庫:
yum install lua lua-devel -y
主要就3步走:
- 安裝Lua即時編譯器:
LuaJIT - 安裝Nginx模組:
ngx_devel_kitandlua-nginx-module - 重新編譯Nginx:複製在線安裝的編譯參數(
nginx -V)然後添加兩個參數--add-module=../ngx_devel_kit-0.3.1--add-module=../lua-nginx-module-0.10.15
3.3.1.編譯安裝luajit並導入環境變數
解壓縮

# 編譯安裝 make install PREFIX=/usr/local/LuaJIT # 導入環境變數 export LUAJIT_LIB=/usr/local/LuaJIT/lib export LUAJIT_INC=/usr/local/LuaJIT/include/luajit-2.0 
3.3.2.共享lua動態庫
載入lua庫到ld.so.conf文件
echo "/usr/local/LuaJIT/lib" >> /etc/ld.so.conf

執行ldconfig讓動態函式庫載入到快取中

3.3.3.配置nginx的編譯參數

完整參數附錄:
./configure --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 --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 --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' --add-module=../ngx_devel_kit-0.3.1 --add-module=../lua-nginx-module-0.10.15 3.3.4.重新編譯安裝nginx
編譯安裝:make && make install

3.3.5.驗證Lua模組
驗證下Lua是否已經可用:
在nginx.config的server節點下添加:
PS:
vi /etc/nginx/nginx.conf

server { listen 80; server_name localhost; charset utf-8; # 默認編碼為utf-8 location / { root html; index index.html index.htm; } ... # 測試Nginx的Lua(添加這一段) location /hello { default_type 'text/plain'; content_by_lua 'ngx.say("歡迎訪問逸鵬說道公眾號~")'; } ... } 檢查配置:nginx -t -c /etc/nginx/nginx.conf
PS:配置生效:
nginx -s reload -c /etc/nginx/nginx.conf

看看效果:

擴展:你可以試試獲取ip哦~
# 獲取客戶端ip location /myip { default_type 'text/plain'; content_by_lua ' clientIP = ngx.req.get_headers()["x_forwarded_for"] ngx.say("IP:",clientIP) '; } 4.Nginx+Lua搭建WAF防火牆
市面上比較常用一塊開源項目:ngx_lua_waf
- 攔截Cookie類型工具
- 攔截異常post請求
- 攔截CC洪水攻擊
- 攔截URL
- 攔截arg(提交的參數)

4.1.環境
clone程式碼並移動到nginx的waf目錄下

簡單說下裡面的規則分別有啥用:
- args裡面的規則get參數進行過濾的
- url是只在get請求url過濾的規則
- post是只在post請求過濾的規則
- whitelist是白名單,裡面的url匹配到不做過濾
- user-agent是對user-agent的過濾規則
4.2.配置
修改必要配置

詳細說明我引用一下我的上篇文章:
參數簡單說明下:紅色字體部分需要修改
nginx.config的http下添加如下內容:

lua_package_path "/etc/nginx/waf/?.lua"; lua_shared_dict limit 10m; init_by_lua_file /etc/nginx/waf/init.lua; access_by_lua_file /etc/nginx/waf/waf.lua; 4.3.生效
配置語法檢查:nginx -t -c /etc/nginx/nginx.conf
PS:不重啟的方式載入配置:
Nginx -s reload -c /etc/nginx/nginx.conf

4.4.簡單驗證

PS:其實繞過很簡單,看看他默認規則即可,這款WAF的強大之處在於輕量級,而且規則可以自定化
過濾規則在wafconf下,可根據需求自行調整,每條規則需換行,或者用|分割
舉個例子:http://192.168.0.10/hello?id=1 or 1=1
PS:默認規則沒有這點的防護

那麼我們可以在args規則中添加比如sors+,然後nginx -s reload一下就行了
PS:如果是從post進行注入,或者cookie中轉注入,那麼在對應規則裡面添加就行,我這邊只是演示下防火牆被繞過該怎麼解決~(多看看日誌)

4.5.CC驗證
留個課後作業:使用ab來測試下nginx+lua的waf對cc的防禦效果
提示:可以使用ab -n 2000 -c 200 http://192.168.0.10來簡單測試
PS:測試前curl http://192.168.0.10/hello 看看返回內容,測試後再curl看看返回內容
擴展:隱藏Nginx版本資訊
防止被黑客進行針對性滲透,隱藏下版本資訊
PS:其他配置今天就不詳細講解了,下次講Nginx的時候會說的
原來:

配置下:vi /etc/nginx/nginx.conf
http下添加:
server_tokens off;

檢查下語法:nginx -t
不重啟的方式載入配置文件:nginx -s reload

現在效果:

