首頁 > 後端開發 > php教程 > Nginx運作原理與最佳化、漏洞。

Nginx運作原理與最佳化、漏洞。

WBOY
發布: 2016-08-08 09:32:37
原創
948 人瀏覽過


1.  Nginx的模組與工作原理

Nginx由內核和模組組成,其中,內核的設計非常微小和簡潔,完成的工作也非常簡單,僅通過查找配置文件將客戶端請求映射到一個location block(location是Nginx配置中的一個指令,用於URL匹配),而在這個location中所配置的每個指令將會啟動不同的模組去完成相應的工作。

Nginx的模組從結構上分為核心模組、基礎模組和第三方模組:

核心模組:HTTP模組、EVENT模組和MAIL模組

基礎模組:HTTP Access模組、HTTP FastCGI模組、

HTTP模組、HTTP HTTP Proxy模組與HTTP Rewrite模組,

第三方模組:

HTTP Upstream Request Hash模組、Notice模組和HTTP Access Key模組。

用戶根據自己的需求開發的模組都屬於第三方模組。正是有了這麼多模組的支撐,Nginx的功能才會如此強大。

Nginx的模組從功能上分為如下三類。

Handlers(處理器模組)。此類模組直接處理請求,並進行輸出內容和修改headers資訊等操作。 Handlers處理器模組一般只能有一個。

Filters (過濾器模組)。此類模組主要對其他處理器模組輸出的內容進行修改操作,最後由Nginx輸出。

Proxies (代理類別模組)。這類模組是Nginx的HTTP Upstream之類的模組,這些模組主要與後端一些服務例如FastCGI等進行交互,實現服務代理和負載平衡等功能。

圖1-1展示了Nginx模組常規的HTTP請求和回應的過程。


                       圖1-1顯示了Nginx模組中常規的HTTP請求與回應的過程。

Nginx本身所做的工作實際上很少,當它接到一個HTTP請求時,它只是透過查找設定檔將此請求對應到一個location block,而此location中所設定的各個指令則會啟動不同的模組去完成工作,因此模組可以看做Nginx真正的勞動工作者。通常一個location中的指令會涉及一個handler模​​組和多個filter模組(當然,多個location可以重複使用同一個模組)。 handler模​​組負責處理請求,完成回應內容的生成,而filter模組則對回應內容進行處理。

Nginx的模組直接被編譯進Nginx,因此屬於靜態編譯方式。啟動Nginx後,Nginx的模組會自動加載,不像Apache,首先將模組編譯為一個so文件,然後在設定檔中指定是否進行載入。在解析設定檔時,Nginx的每個模組都有可能去處理某個請求,但是同一個處理請求只能由一個模組來完成。 

在運作方式上,Nginx分為單一工作流程和多重工作流程兩種模式。在單一工作進程模式下,除主進程外,還有一個工作進程,工作進程是單執行緒的;在多工作進程模式下,每個工作進程包含多個執行緒。 Nginx預設為單一工作流程模式。

2.  Nginx+FastCGI運作原理

1、什麼是 FastCGI

多數流行的HTTP server都支援FastCGI,包括Apache、Nginx和lighttpd等。同時,FastCGI也被許多腳本語言支持,其中就有PHP。

FastCGI是從CGI發展改良而來的。傳統CGI介面方式的主要缺點是效能很差,因為每次HTTP伺服器遇到動態程式時都需要重新啟動腳本解析器來執行解析,然後將結果傳回HTTP伺服器。這在處理高並發訪問時幾乎是不可用的。另外傳統的CGI介面方式安全性也很差,現在已經很少使用了。

FastCGI介面方式採用C/S結構,可以將HTTP伺服器和腳本解析伺服器分開,同時在腳本解析伺服器上啟動一個或多個腳本解析守護程式。當HTTP伺服器每次遇到動態程式時,可以直接交付給FastCGI進程來執行,然後將得到的結果傳回瀏覽器。這種方式可以讓HTTP伺服器專一地處理靜態請求或將動態腳本伺服器的結果傳回給客戶端,這在很大程度上提高了整個應用系統的效能。

2、Nginx+FastCGI運作原理

Nginx不支援對外部程式的直接呼叫或解析,所有的外部程式(包括PHP)必須透過FastCGI介面來呼叫。 FastCGI介面在Linux下是socket(這個socket可以是檔案socket,也可以是ip socket)。

wrapper:為了呼叫CGI程序,還需要一個FastCGI的wrapper(wrapper可以理解為用於啟動另一個程式的程式),這個wrapper綁定在某個固定socket上,如埠或檔案socket。當Nginx將CGI請求發送給這個socket的時候,透過FastCGI接口,wrapper接收到請求,然後Fork(派生)出一個新的線程,這個線程調用解釋器或者外部程序處理腳本並讀取返回數據;接著, wrapper再將傳回的資料透過FastCGI接口,沿著固定的socket傳遞給Nginx;最後,Nginx將傳回的資料(html頁面或圖片)傳送給客戶端。這就是Nginx+FastCGI的整個運作過程,如圖1-3所示。

       

 和ningx通訊(讀寫socket是fastcgi內部實現的功能,對wrapper是非透明的)

    調度thread,進行fork與kill
  1. 和application(php)進行通訊
  2. 3、spawn-fcgi與PHP-FPM
解析伺服器上啟動一個或多個守護程序對動態腳本進行解析,這些程序就是FastCGI進程管理器,或稱為FastCGI引擎。 spawn-fcgi與PHP-FPM就是支援PHP的兩個FastCGI進程管理器。

因此HTTPServer完全解放出來,可以更好地進行回應和並發處理。

              spawn-fcgi與PHP-FPM的異同:       1)spawn-fcgi是HTTPlightlighttpd的一部分搭配但是ligttpd的spwan-fcgi在高並發存取的時候,會出現記憶體洩漏甚至自動重啟FastCGI的問題。即:PHP腳本處理器當機,這個時候如果使用者造訪的話,可能就會出現白頁(即PHP不能被解析或出錯)。


       2)Nginx是個輕量級的HTTP server,必須藉助第三方的FastCGI處理器才可以對PHP進行解析,因此其實這樣看來nginx是非常靈活的,它可以和任何第三方提供解析的處理器實作連接從而實現對PHP的解析(在nginx.conf中很容易設定)。 nginx也可以使用spwan-fcgi(需要一同安裝lighttpd,但是需要為nginx避開端口,一些較早的blog有這方面安裝的教程),但是由於spawn-fcgi具有上面所述的用戶逐漸發現的缺陷,現在慢慢減少用nginx+spawn-fcgi組合了。

       由於spawn-fcgi的缺陷,現在出現了第三方(目前已經加入到PHP core)的PHP的FastCGI處理器PHP-FPM,它和spawn-fcgi比較起來有一個優點:




🎜由於它是作為PHP的patch補丁來開發的,安裝的時候需要和php源碼一起編譯,也就是說編譯到php core中了,因此在性能方面要優秀一些;🎜🎜🎜🎜同時它在處理高並發方面也優於spawn-fcgi,至少不會自動重啟fastcgi處理器。因此,建議使用Nginx+PHP/PHP-FPM這個組合對PHP進行解析。 🎜🎜🎜🎜      相對Spawn-FCGI,PHP-FPM在CPU和記憶體方面的控制都更勝一籌,而且前者很容易崩潰,必須用crontab進行監控,而PHP-FPM則沒有這種煩惱。 🎜       FastCGI 的主要優點是把動態語言和HTTP Server分開來,所以Nginx與PHP/PHP-FPM經常被部署在不同的伺服器上,以分擔前端Nginx伺服器的壓力,使Nginx專一處理靜態請求和轉發動態請求,而PHP/PHP-FPM伺服器專一解析PHP動態請求。 🎜🎜4、Nginx+PHP-FPM🎜🎜🎜🎜      PHP-FPM是管理FastCGI的一個管理器,它作為PHP的插件存在,在安裝PHP要想使用PHP-FPM時在老php的版本(php5. 3.3之前)就需要把PHP-FPM以補丁的形式安裝到PHP中,而且PHP要與PHP-FPM版本一致,這是必須的)🎜🎜   PHP-FPM其實是PHP原始碼的一個補丁,旨在將FastCGI進程管理整合進PHP包。必須將它patch到你的PHP原始碼中,在編譯安裝PHP後才可以使用。 🎜   PHP5.3.3已經整合php-fpm了,不再是第三方的套件了。 PHP-FPM提供了更好的PHP進程管理方式,可以有效控制記憶體和進程、可以平滑重載PHP配置,比spawn-fcgi有更多優點,所以被PHP官方收錄了。在./configure的時候帶 –enable-fpm參數即可開啟PHP-FPM。 🎜🎜      fastcgi已經在php5.3.5的core中了,不必在configure時加入 --enable-fastcgi了。舊版如php5.2的需要加此項。 🎜🎜      當我們安裝Nginx和PHP-FPM完畢後,設定資訊:🎜🎜

     PHP-FPM的預設設定php-fpm.conf

     listen_address  127.0.0.1:9000gi 的行程 start_servers      min_spare_servers

      

max_spare_servers

      Nginx配置運行php:

 編輯nginx.conf加入如下語句:

root html;   

            fastcgi_pass 127.0.0.1:9000; 

指定了fastcgi進程偵聽的連接埠,nginx就是透過這裡與php互動的

            fastcgi_index index.php;             /usr/local/nginx/html$fastcgi_script_name;    }


    Nginx


透過location    Nginx
通過location指令,將所有以php為後綴的檔案交給127.0.0.1:9000來處理,而這裡的IP位址和埠就是FastCGI進程監聽的IP位址和埠。         其整體工作流程:

     1)、FastCGI進程管理器php-fpm自身,啟動主流程php-fpm和CGI

           主進程php-fpm主要是管理fastcgi子進程,監聽9000埠。

           fastcgi子進程等待來自Web Server的連線。

     2)、當客戶端要求到達Web Server Nginx是時,

Nginx

透過location指令,將所有以php為後綴的檔案都交給127.0.0.1:9000來處理,即 透過location指令,將所有以php為後綴的檔案交給127.0.0.1:9000來處理。       3)FastCGI進程管理器PHP-FPM選擇並連接到一個子進程CGI解釋器。 Web server將CGI環境變數和標準輸入傳送到FastCGI子進程。       4)、FastCGI子進程完成處理後將標準輸出和錯誤訊息從相同連線返回Web Server。當FastCGI子程序關閉連線時,請求便告處理完成。       5)、FastCGI子進程接著等待並處理來自FastCGI進程管理器(運行在 WebServer中)的下一個連線。

3.   Nginx的IO模型

     首先nginx支持的事件模型如下(nginx的wiki):

       Nginx支持如下處理連接的方法(I/O復用方法),這些方法可以透過use指令指定。

  • select – 標準方法。 如果目前平台沒有更有效的方法,它是編譯時預設的方法。你可以使用設定參數 –with-select_module 和 –without-select_module 來啟用或停用這個模組。
  • poll – 標準方法。 如果目前平台沒有更有效的方法,它是編譯時預設的方法。你可以使用設定參數 –with-poll_module 和 –without-poll_module 來啟用或停用這個模組。
  • kqueue – 高效率的方法,使用於 FreeBSD 4.1+, OpenBSD 2.9+, NetBSD 2.0 和 MacOS X. 使用雙處理器的MacOS X系統使用kqueue可能會造成核心崩潰。
  • epoll – 高效率的方法,使用於Linux核心2.6版本及以後的系統。在某些發行版本中,如SuSE 8.2, 有讓2.4版本的核心支援epoll的補丁。
  • rtsig – 可執行的即時訊號,使用於Linux核心版本2.2.19以後的系統。預設整個系統中不能出現大於1024個POSIX即時(排隊)訊號。這種情況 對於高負載的伺服器來說是低效的;所以有必要透過調節核心參數 /proc/sys/kernel/rtsig-max 來增加佇列的大小。可是從Linux核心版本2.6.6-mm2開始, 這個參數就不再使用了,而且對於每個行程有一個獨立的訊號佇列,這個佇列的大小可以用 RLIMIT_SIGPENDING 參數調節。當這個佇列過於擁塞,nginx就放棄它並且開始使用 poll 方法來處理連線直到恢復正常。
  • /dev/poll – 高效率的方法,使用於Solaris 7 11/99+, HP/UX 11.22+ (eventport), IRIX 6.5.15+ 和Tru64 UNIX 5.1A+. 的方法,使用於Solaris 10. 為了防止核心崩潰的問題, 有必要安裝
  • 這個 安全修補程式。
  •         在linux下面,只有epoll是高效率的方法

      

為處理大批量句柄而作了改進的

poll
。 要使用epoll只需要這三個系統呼叫:epoll_create(2), epoll_ctl(2), epoll_wait(2)。它是在2.5.44核心中被引進的(epoll(4) is a new API introduced in Linux kernel 2.5.44),在2.6核心中廣泛應用。         epoll的優點

支援一個行程開啟大數目的

socket

支援一個行程開啟大數目的
  • socket描述lect 最不能忍受的是一個行程所開啟的FD是有一定限制的,由FD_SETSIZE設置,預設值是2048。對於那些需要支援的上萬連線數目的IM伺服器來說顯 然太少了。這時候你一是可以選擇修改這個巨集然後重新編譯內核,不過資料也同時指出這樣會帶來網路效率的下降,二是可以選擇多進程的解決方案(傳統的Apache方案),不過雖然linux上面創建進程的代價比較小,但仍舊是不可忽視的,加上進程間資料同步遠比不上執行緒間同步的高效,所以也不是一種完 美的方案。不過epoll則沒有這個限制,它所支援的FD上限是最大可以開啟檔案的數目,這個數字一般遠大於2048,舉個例子,在1GB記憶體的機器上大約是10萬左右,具體數目可以cat/proc /sys/fs/file-max察看,一般來說這個數目和系統記憶體關係很大。 IO效率不隨FD數目增加而線性下降

        的socket是」活躍」的,但是select/poll每次調用都會線性掃描全部的集合,導致效率呈現線性下降。但epoll不存在這個問題,它只會對」活躍」的socket進行操 作—這是因為在內核實作中epoll是根據每個fd上面的callback函數實現的。那麼,只有」活躍」的socket才會主動的去呼叫 callback函數,其他idle狀態socket則不會,在這點上,epoll實現了一個」偽」AIO,因為這時候推動力在os核心。在一些 在 benchmark中,如果所有的socket基本上都是活躍的—比如一個高速LAN環境,epoll並不比select/poll有什麼效率,相 反,如果過多使用epoll_ctl,效率相比還有稍微的下降。但一旦使用idle connections模擬

    WAN
  • 環境,epoll的效率就遠在select/poll之上了。
    • 使用mmap加速核心與使用者空間的訊息傳遞。

            這 點實際上涉及到epoll的具體實現了。無論是select,poll還是epoll都需要內核把FD訊息通知給用戶空間,如何避免不必要的記憶體拷貝就很 重要,在這點上,epoll是透過核心於用戶空間mmap同一塊記憶體實現的。而如果你想我一樣從2.5核心就關注epoll的話,一定不會忘記手工 mmap這一步的。

    • 內核微調

            也許你可以懷疑linux平台,但你無法迴避linux平台賦予你微調核心的能力。例如,內核TCP/IP協 議棧使用記憶體池來管理sk_buff結構,那麼可以在運行時期動態調整這個記憶體pool(skb_head_pool)的大小— 透過echo XXXX>/proc/sys/net/core/hot_list_length完成。再例如listen函數的第2個參數(TCP完成3次握手 的資料包佇列長度),也可以根據你平台記憶體大小動態調整。更甚至在一個資料包面數目巨大但同時每個資料包本身大小卻很小的特殊系統上嘗試最新的NAPI網卡驅動架構。

        (epoll內容,參考epoll_互動百科全書)

4.   Nginx最佳化

4.   Nginx最佳化

1).減小Nginx編譯後的檔案大小

在編譯Nginx時,預設以debug模式進行,而在debug模式下會插入很多追蹤和ASSERT之類的訊息,編譯完成後,一個Nginx要有好幾兆位元組。而在編譯前取消Nginx的debug模式,編譯完成後Nginx只有幾百千位元組。因此可以在編譯前,修改相關原始碼,取消debug模式。具體方法如下:

在Nginx原始碼檔案被解壓縮後,找到原始碼目錄下的auto/cc/gcc文件,在其中找到如下幾行:

  1. # debug  
  2. CFLAGS=”$CFLAGS -g” 

註解掉或刪除這兩行,即可取消debug模式。

2.為特定的CPU指定CPU類型編譯最佳化

在編譯Nginx時,預設的GCC編譯參數是“-O”,要最佳化GCC編譯,可以使用以下兩個參數:

reee

要決定CPU類型,可以透過以下指令:

  1. --with-cc-opt='-O3' 
  2. --with-cpu-opt=CPU  #为特定的 CPU 编译,有效的值包括:
    pentium, pentiumpro, pentium3, # pentium4, athlon, opteron, amd64, sparc32, sparc64, ppc64 

2. 利用TCMalloc優化Nginx的效能

TCMalloc的全稱為Thread-Caching Malloc,是Google開發的開源工具google-perftools中的一個成員。與標準的glibc庫的Malloc相比,TCMalloc庫在記憶體分配效率和速度上要高得多,這在很大程度上提高了伺服器在高並發情況下的效能,從而降低了系統的負載。以下簡單介紹如何為Nginx加入TCMalloc庫支援。

要安裝TCMalloc函式庫,需要安裝libunwind(32位元作業系統不需要安裝)和google-perftools兩個軟體包,libunwind函式庫為基於64位元CPU和作業系統的程式提供了基本函式呼叫鍊和函式呼叫暫存器功能。以下介紹利用TCMalloc優化Nginx的具體操作流程。

1).安裝libunwind庫

可以從http://download.savannah.gnu.org/releases/libunwind下載對應的libunwind版本,這裡下載的是libunwind-0.99-alpha.tar.gz。安裝流程如下:

  1. [root@localhost home]#cat /proc/cpuinfo | grep "model name" 


2).安裝google-perftools

可以從http://google-perftools..安裝googlecode.com下載對應的google-perftools版本,這裡下載的是google-perftools-1.8. tar.gz。安裝流程如下:

  1. [root@localhost home]#tar zxvf libunwind-0.99-alpha.tar.gz  
  2. [root@localhost home]# cd libunwind-0.99-alpha/  
  3. [root@localhost libunwind-0.99-alpha]#CFLAGS=-fPIC ./configure  
  4. [root@localhost libunwind-0.99-alpha]#make CFLAGS=-fPIC  
  5. [root@localhost libunwind-0.99-alpha]#make CFLAGS=-fPIC install 

至此,google-perftools安裝完成。

3).重新編譯Nginx

為了使Nginx支援google-perftools,需要在安裝過程中加入「–with-google_perftools_module」選項重新編譯Nginx。安裝程式碼如下:

  1. [root@localhost home]#tar zxvf google-perftools-1.8.tar.gz  
  2. [root@localhost home]#cd google-perftools-1.8/  
  3. [root@localhost google-perftools-1.8]# ./configure  
  4. [root@localhost google-perftools-1.8]#make && make install  
  5. [root@localhost google-perftools-1.8]#echo "/usr/
    local/lib" 
    > /etc/ld.so.conf.d/usr_local_lib.conf  
  6. [root@localhost google-perftools-1.8]# ldconfig 

到這裡Nginx安裝完成。

4).為google-perftools新增執行緒目錄

建立一個執行緒目錄,這裡將檔案放在/tmp/tcmalloc下。操作如下:

  1. [root@localhostnginx-0.7.65]#./configure \  
  2. >--with-google_perftools_module --with-http_stub_status_module  --prefix=/opt/nginx  
  3. [root@localhost nginx-0.7.65]#make  
  4. [root@localhost nginx-0.7.65]#make install 

5).修改Nginx主設定檔

修改nginx.conf文件,在pid這行的下面添加如下程式碼:

  1. [root@localhost home]#mkdir /tmp/tcmalloc  
  2. [root@localhost home]#chmod 0777 /tmp/tcmalloc 

接著,重啟Nginxgoogle-perftoolsgoogle-perftoolsgoogle-perftools的載入。

6).驗證運行狀態

為了驗證google-perftools已經正常加載,可透過以下命令查看:

  1. #pid        logs/nginx.pid;  
  2. google_perftools_profiles /tmp/tcmalloc; 

由於在Nginx設定檔中設定worker_processes的值為4,因此開啟了4個執行緒,每個線程會有一行記錄。每個線程檔案後面的數字值就是啟動的Nginx的pid值。

至此,利用TCMalloc優化Nginx的操作完成。

3.Nginx核心參數最佳化

核心參數的最佳化,主要是在Linux系統中針對Nginx應用而進行的系統核心參數最佳化。

下面給出一個最佳化實例以供參考。

  1. [root@ localhost home]# lsof -n | grep tcmalloc  
  2. nginx      2395 nobody   9w  REG    8,8       0    1599440 /tmp/tcmalloc.2395  
  3. nginx      2396 nobody   11w REG   8,8       0    1599443 /tmp/tcmalloc.2396  
  4. nginx      2397 nobody   13w REG  8,8        0    1599441  /tmp/tcmalloc.2397  
  5. nginx     2398 nobody    15w REG  8,8     0    1599442 /tmp/tcmalloc.2398 

將上面的核心參數值加入/etc/sysctl.conf檔案中,然後執行下列指令使其生效:

  1. [root@ localhost home]#/sbin/sysctl -p 

下面对实例中选项的含义进行介绍:

net.ipv4.tcp_max_tw_buckets选项用来设定timewait的数量,默认是180 000,这里设为6000。

net.ipv4.ip_local_port_range选项用来设定允许系统打开的端口范围。

net.ipv4.tcp_tw_recycle选项用于设置启用timewait快速回收。

net.ipv4.tcp_tw_reuse选项用于设置开启重用,允许将TIME-WAIT sockets重新用于新的TCP连接。

net.ipv4.tcp_syncookies选项用于设置开启SYN Cookies,当出现SYN等待队列溢出时,启用cookies进行处理。

net.core.somaxconn选项的默认值是128, 这个参数用于调节系统同时发起的tcp连接数,在高并发的请求中,默认的值可能会导致链接超时或者重传,因此,需要结合并发请求数来调节此值。

net.core.netdev_max_backlog选项表示当每个网络接口接收数据包的速率比内核处理这些包的速率快时,允许发送到队列的数据包的最大数目。

net.ipv4.tcp_max_orphans选项用于设定系统中最多有多少个TCP套接字不被关联到任何一个用户文件句柄上。如果超过这个数字,孤立连接将立即被复位并打印出警告信息。这个限制只是为了防止简单的DoS攻击。不能过分依靠这个限制甚至人为减小这个值,更多的情况下应该增加这个值。

net.ipv4.tcp_max_syn_backlog选项用于记录那些尚未收到客户端确认信息的连接请求的最大值。对于有128MB内存的系统而言,此参数的默认值是1024,对小内存的系统则是128。

net.ipv4.tcp_synack_retries参数的值决定了内核放弃连接之前发送SYN+ACK包的数量。

net.ipv4.tcp_syn_retries选项表示在内核放弃建立连接之前发送SYN包的数量。

net.ipv4.tcp_fin_timeout选项决定了套接字保持在FIN-WAIT-2状态的时间。默认值是60秒。正确设置这个值非常重要,有时即使一个负载很小的Web服务器,也会出现大量的死套接字而产生内存溢出的风险。

net.ipv4.tcp_syn_retries选项表示在内核放弃建立连接之前发送SYN包的数量。

如果发送端要求关闭套接字,net.ipv4.tcp_fin_timeout选项决定了套接字保持在FIN-WAIT-2状态的时间。接收端可以出错并永远不关闭连接,甚至意外宕机。

net.ipv4.tcp_fin_timeout的默认值是60秒。需要注意的是,即使一个负载很小的Web服务器,也会出现因为大量的死套接字而产生内存溢出的风险。FIN-WAIT-2的危险性比FIN-WAIT-1要小,因为它最多只能消耗1.5KB的内存,但是其生存期长些。

net.ipv4.tcp_keepalive_time选项表示当keepalive启用的时候,TCP发送keepalive消息的频度。默认值是2(单位是小时)。

4. PHP-FPM的优化

如果您高负载网站使用PHP-FPMFastCGI,这些技巧也许对您有用:

1)增加FastCGI进程数

PHP FastCGI子进程数调到100或以上,4G内存的服务器上200就可以建议通过压力测试获取最佳值。

2)增加 PHP-FPM打开文件描述符的限制

标签rlimit_files用于设置PHP-FPM对打开文件描述符的限制,默认值为1024。这个标签的值必须和Linux内核打开文件数关联起来,例如,要将此值设置为65 535,就必须在Linux命令行执行“ulimit -HSn 65536”。

       然后 增加 PHP-FPM打开文件描述符的限制:
     # vi /path/to/php-fpm.conf
    找到
1024”
1024更改为 4096或者更高
.
重启 PHP-FPM.

         3)适当增加max_requests

    标签max_requests指明了每个children最多处理多少个请求后便会被关闭,默认的设置是500。

     500

   

5.   Nginx的php漏洞

漏洞介紹:nginx是一款高效能的web伺服器,使用非常廣泛,其不僅經常被用作反向代理,也可以非常好的支援PHP的運作。 80sec發現其中存在一個較為嚴重的安全問題,預設可能導致伺服器錯誤的將任何類型的檔案以PHP的方式進行解析,這將導致嚴重的安全性問題,使得惡意的攻擊者可能攻陷支援php的nginx伺服器.


漏洞分析:nginx預設以cgi的方式支援php的運行,譬如在設定檔當中可以以

<br>location ~ .php$ {<br>root html; 。的關鍵變數SCRIPT_FILENAME由nginx產生的$fastcgi_script_name決定,而透過分析可以看到$fastcgi_script_name是直接由URI環境變數控制的,這裡就是產生問題的點。而為了較好的支援PATH_INFO的提取,在PHP的設定選項裡存在cgi.fix_pathinfo選項,其目的是為了從SCRIPT_FILENAME裡取出真正的腳本名稱。 <br>那麼假設存在一個http://www.80sec.com/80sec.jpg,我們以以下的方式去訪問<br><br><br><br><br>
http://www.80sec.com/80sec.jpg/80sec.php

將會得到一個URI

/80sec.jpg/80sec.php

經過location指令,該請求將交給後端的
/scripts/80sec.jpg/80sec.php
/scripts/80sec.jpg/80sec.php<br><br>而在其他的webserver如lighttpd當中,我們發現其中的SCRIPT_FILENAME被正確的設定為

/scripts/80sec.jpg/80sec.jpg問題。 <br>後端的fastcgi在接受到該選項時,會根據fix_pathinfo配置決定是否對SCRIPT_FILENAME進行額外的處理,一般情況下如果不對fix_pathinfo進行設定將影響使用PATH_INFO進行路由選擇的應用,所以該選項一般開啟配置。 Php將在透過此選項之後尋找其中真正的腳本檔案名字,尋找的方式也是檢視檔案是否存在,而這個時候將分離出SCRIPT_FILENAME和PATH_INFO分別為<br>
/scripts/80sec.jpg和80sec.php
<br>最後,以/scripts/80sec.jpg作為此次請求需要執行的腳本,攻擊者就可以實現讓nginx以php來解析任何類型的檔案了。 <br>POC: 訪問一個nginx來支援php的站點,在一個任何資源的文件如robots.txt後面加上/80sec.php,這個時候你可以看到如下的區別:

訪問http://www. 80sec.com/robots.txt
<br>HTTP/1.1 200 OK<br>Server: nginx/0.6.32Date: Thu, 20 May 2010 10:05:30 GMT
18

Last-Modified: Thu, 20 May 2010 06:26:34 GMT

Connection: keep-alive

Keep-Alive: timeout=20

Accept-Ranges: by f
. com/robots.txt/80sec.php

<br>HTTP/1.1 200 OK<br>Server: nginx/0.6.32
Date: Thu, 20 May 2010 10:06:49 GMT
Encoding: chunked
Connection: keep-alive
Keep-Alive: timeout=20
X-Powered-By: PHP/5.2.6

其中的Content-Type的變化說明了後端負責解析的變化,該網站就可能存在漏洞。
漏洞廠商:http://www.nginx.org<br><br>解決方案:<br><br>我們已經嘗試聯絡官方,但先前你可以透過以下的方式來減少損失<br><br><br>關閉cgi.fix_pathinfo為0<br><br>

if ( $fastcgi_script_name ~ ..*/.*php ) {

return 403;

}


<br>PS: 鳴謝laruence大牛在分析過程中給予的幫助<br> 以上就介紹了Nginx工作原理與最佳化、漏洞。 ,包括了方面的內容,希望對PHP教程有興趣的朋友有所幫助。

相關標籤:
來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板