Nginx range filter模組數字錯誤漏洞修復 (Nginx平滑升級)

散盡浮華發表於2018-11-15

 

對線上生產環境伺服器進行漏洞掃描, 發現有兩臺前置機器存在Nginx range filter模組數字錯誤漏洞, 當使用nginx標準模組時,攻擊者可以通過傳送包含惡意構造range域的header 請求,來獲取響應中的快取檔案頭部資訊。該漏洞存在於Nginx 1.13.3以下版本中只要Ningx開啟了快取功能, 攻擊者即可傳送惡意請求進行遠端攻擊造成資訊洩露。也就是說當Nginx伺服器使用代理快取的情況下, 快取檔案頭可能包含後端伺服器的真實IP地址或其它敏感資訊,攻擊者就可以利用該漏洞拿到這些敏感資訊,從而導致資訊洩露。故此漏洞存在安全隱患, 需要儘快修復. 

該漏洞修復方案一:

找到nginx的原始碼解壓包, 在nginx的原始碼包中找到ngx_http_range_filter_module.c
[root@dtin ~]# cd /data/software/nginx-1.12.2
[root@dtin nginx-1.12.2]# vim ./src/http/modules/ngx_http_range_filter_module.c
.......
        if (suffix) {
            start = content_length - end;
            end = content_length - 1;
        }
.......

將上面ngx_http_range_filter_module.c原始碼檔案中的"start = content_length - end;"改為“start = (end < content_length) ? content_length - end : 0;"
即改為:
[root@dtin nginx-1.12.2]# vim ./src/http/modules/ngx_http_range_filter_module.c
.......
        if (suffix) {
            start = (end < content_length) ? content_length - end : 0;
            end = content_length - 1;
        }
.......

接著重新編譯nginx,並進行替換即可。

該漏洞修復方案一 (推薦這一種)

由於是生產環境, 線上業務不能停, 故需要進行Nginx平滑升級, 升級過程中服務不能中斷. Nginx平滑升級原理如下介紹:
多程式模式下的請求分配方式
Nginx預設工作在多程式模式下,即主程式(master process)啟動後完成配置載入和埠繫結等動作,fork出指定數量的工作程式(worker process),這些子程式會持有監聽埠的檔案描述符(fd),並通過在該描述符上新增監聽事件來接受連線(accept)。

訊號的接收和處理
Nginx主程式在啟動完成後會進入等待狀態,負責響應各類系統訊息,如SIGCHLD、SIGHUP、SIGUSR2等。

Nginx訊號
主程式支援的訊號
- TERM, INT: 立刻退出
- QUIT: 等待工作程式結束後再退出
- KILL: 強制終止程式
- HUP: 重新載入配置檔案,使用新的配置啟動工作程式,並逐步關閉舊程式。
- USR1: 重新開啟日誌檔案
- USR2: 啟動新的主程式,實現熱升級
- WINCH: 逐步關閉工作程式

工作程式支援的訊號
- TERM, INT: 立刻退出
- QUIT: 等待請求處理結束後再退出
- USR1: 重新開啟日誌檔案

=================nginx平滑升級操作記錄====================

[app@web-node01 ~]# /data/nginx/sbin/nginx -v
nginx version: nginx/1.12.2

備份之前安裝的nginx (其實主要備份的是sbin/nginx  和 conf配置目錄, 這裡我全部備份)
[app@web-node01 ~]# cp -r /data/nginx /data/nginx.old
[app@web-node01 ~]# ll /data/
total 0
drwxr-xr-x 10 app app 133 Sep 15 22:31 nginx
drwxr-xr-x 10 app app 133 Nov 15 15:21 nginx.old

下載nginx1.14.1的安裝包, 解壓並進行編譯安裝. 安裝路徑需與舊版一致
[app@web-node01 software]# ll nginx-1.14.1.tar.gz 
-rw-rw-r-- 1 app app 1014040 Nov 15 11:04 nginx-1.14.1.tar.gz
[app@web-node01 software]# tar -zvxf nginx-1.14.1.tar.gz
[app@web-node01 software]# cd nginx-1.14.1/
[app@web-node01 nginx-1.14.1]# ./configure --prefix=/data/nginx --user=app --group=app --with-http_ssl_module --with-http_flv_module --with-http_stub_status_module --with-http_gzip_static_module --with-pcre --with-stream 
[app@web-node01 nginx-1.14.1]# make && make install

傳送USR2訊號
向主程式傳送USR2訊號,Nginx會啟動一個新版本的master程式和工作程式,和舊版一起處理請求
[app@web-node01 nginx-1.14.1]# ps -ef|grep nginx
app       1899 30168  0 15:25 pts/0    00:00:00 grep --color=auto nginx
app      19233 22333  0 Sep21 ?        00:00:00 nginx: worker process
app      19234 22333  0 Sep21 ?        00:00:00 nginx: worker process
app      19235 22333  0 Sep21 ?        00:00:00 nginx: worker process
app      19236 22333  0 Sep21 ?        00:00:01 nginx: worker process
app      19237 22333  0 Sep21 ?        00:00:00 nginx: worker process
app      19238 22333  0 Sep21 ?        00:00:01 nginx: worker process
app      19239 22333  0 Sep21 ?        00:00:05 nginx: worker process
app      19240 22333  0 Sep21 ?        00:00:01 nginx: worker process
app      19241 22333  0 Sep21 ?        00:00:27 nginx: cache manager process
root     22333     1  0 Sep15 ?        00:00:00 nginx: master process /data/nginx/sbin/nginx

[app@web-node01 nginx-1.14.1]# kill -USR2 22333            

[app@web-node01 nginx-1.14.1]# ps -ef|grep nginx    
root      1911 22333  0 15:26 ?        00:00:00 nginx: master process /data/nginx/sbin/nginx
app       1912  1911  0 15:26 ?        00:00:00 nginx: worker process
app       1913  1911  0 15:26 ?        00:00:00 nginx: worker process
app       1914  1911  0 15:26 ?        00:00:00 nginx: worker process
app       1915  1911  0 15:26 ?        00:00:00 nginx: worker process
app       1916  1911  0 15:26 ?        00:00:00 nginx: worker process
app       1917  1911  0 15:26 ?        00:00:00 nginx: worker process
app       1918  1911  0 15:26 ?        00:00:00 nginx: worker process
app       1919  1911  0 15:26 ?        00:00:00 nginx: worker process
app       1920  1911  0 15:26 ?        00:00:00 nginx: cache manager process
app       1921  1911  0 15:26 ?        00:00:00 nginx: cache loader process
app       1923 30168  0 15:26 pts/0    00:00:00 grep --color=auto nginx
app      19233 22333  0 Sep21 ?        00:00:00 nginx: worker process
app      19234 22333  0 Sep21 ?        00:00:00 nginx: worker process
app      19235 22333  0 Sep21 ?        00:00:00 nginx: worker process
app      19236 22333  0 Sep21 ?        00:00:01 nginx: worker process
app      19237 22333  0 Sep21 ?        00:00:00 nginx: worker process
app      19238 22333  0 Sep21 ?        00:00:01 nginx: worker process
app      19239 22333  0 Sep21 ?        00:00:05 nginx: worker process
app      19240 22333  0 Sep21 ?        00:00:01 nginx: worker process
app      19241 22333  0 Sep21 ?        00:00:27 nginx: cache manager process
root     22333     1  0 Sep15 ?        00:00:00 nginx: master process /data/nginx/sbin/nginx

傳送WITCH訊號
向原Nginx主程式傳送WINCH訊號,它會逐步關閉其下的工作程式(主程式不退出),這時所有請求都會由新版Nginx處理. 
[app@web-node01 nginx-1.14.1]# kill -WITCH 22333         //如果這個命令報錯,則可以忽略, 在最後一步直接kill掉原來Nginx主程式的pid即可.

傳送HUP訊號 (特別注意: 這一步是回退, 如果不回退, 則直接忽略這一步即可)
如果這時需要回退,可向原Nginx主程式傳送HUP訊號,它會重新啟動工作程式, 仍使用舊版配置檔案 。
然後可以將新版Nginx程式殺死(使用QUIT、TERM、或者KILL)
[app@web-node01 nginx-1.14.1]# kill -HUP 22333

升級完畢
如果不需要回滾,可以將原Nginx主程式殺死(使用QUIT、TERM、或者KILL),至此完成熱升級。

[app@web-node01 nginx-1.14.1]# ps -ef|grep nginx
root      1911 22333  0 15:26 ?        00:00:00 nginx: master process /data/nginx/sbin/nginx
app       1912  1911  0 15:26 ?        00:00:00 nginx: worker process
app       1913  1911  0 15:26 ?        00:00:00 nginx: worker process
app       1914  1911  0 15:26 ?        00:00:00 nginx: worker process
app       1915  1911  0 15:26 ?        00:00:00 nginx: worker process
app       1916  1911  0 15:26 ?        00:00:00 nginx: worker process
app       1917  1911  0 15:26 ?        00:00:00 nginx: worker process
app       1918  1911  0 15:26 ?        00:00:00 nginx: worker process
app       1919  1911  0 15:26 ?        00:00:00 nginx: worker process
app       1920  1911  0 15:26 ?        00:00:00 nginx: cache manager process
app       2394 30168  0 15:33 pts/0    00:00:00 grep --color=auto nginx
app      19233 22333  0 Sep21 ?        00:00:00 nginx: worker process
app      19234 22333  0 Sep21 ?        00:00:00 nginx: worker process
app      19235 22333  0 Sep21 ?        00:00:00 nginx: worker process
app      19236 22333  0 Sep21 ?        00:00:01 nginx: worker process
app      19237 22333  0 Sep21 ?        00:00:00 nginx: worker process
app      19238 22333  0 Sep21 ?        00:00:01 nginx: worker process
app      19239 22333  0 Sep21 ?        00:00:05 nginx: worker process
app      19240 22333  0 Sep21 ?        00:00:01 nginx: worker process
app      19241 22333  0 Sep21 ?        00:00:27 nginx: cache manager process
root     22333     1  0 Sep15 ?        00:00:00 nginx: master process /data/nginx/sbin/nginx

[app@web-node01 nginx-1.14.1]# sudo kill -9 19233 19234 19235 19236 19237 19238 19239 19240 19241 22333

[app@web-node01 nginx-1.14.1]# ps -ef|grep nginx
root      1911     1  0 15:26 ?        00:00:00 nginx: master process /data/nginx/sbin/nginx
app       1912  1911  0 15:26 ?        00:00:00 nginx: worker process
app       1913  1911  0 15:26 ?        00:00:00 nginx: worker process
app       1914  1911  0 15:26 ?        00:00:00 nginx: worker process
app       1915  1911  0 15:26 ?        00:00:00 nginx: worker process
app       1916  1911  0 15:26 ?        00:00:00 nginx: worker process
app       1917  1911  0 15:26 ?        00:00:00 nginx: worker process
app       1918  1911  0 15:26 ?        00:00:00 nginx: worker process
app       1919  1911  0 15:26 ?        00:00:00 nginx: worker process
app       1920  1911  0 15:26 ?        00:00:00 nginx: cache manager process
app       2496 30168  0 15:35 pts/0    00:00:00 grep --color=auto nginx

[app@web-node01 ~]# /data/nginx/sbin/nginx -v
nginx version: nginx/1.14.1

相關文章