1. 程式人生 > >Nginx服務優化

Nginx服務優化

顯示 目前 doc 情況 為什麽 可能 wait erer partner


1.1Nginx.conf配置文件基本參數優化

1.1.1 隱藏nginx header內版本號信息

一些特定的系統及服務漏洞一般都和特定的軟件及版本號有關,我們應盡量隱藏服務器的敏感信息(軟件名稱及版本等信息)這樣黑客無法猜到有漏洞的服務是否是對應服務的版本,從而確保web服務器最大的安全。

徹底修改nginx錯誤返回頁面,在編譯安裝之前修改nginx.h文件

sed -n ‘13,17p‘ src/core/nginx.h

#define NGINX_VERSION "1.6.3" #將版本隨便修改為"8.8.8"

#define NGINX_VER "nginx/" NGINX_VERSION

#define NGINX_VAR "NGINX" #NGINX更改為XuLiangWei

#define NGX_OLDPID_EXT ".oldbin"

sed -n ‘49p‘ src/http/ngx_http_header_filter_module.c

static char ngx_http_server_string[] = "Server: nginx" CRLF; #將nginx更改為XuLiangWei

sed -i ‘s#Server: nginx#Server: OWS#g‘ ngx_http_header_filter_module.c #sed

替換方法

sed -n ‘21,29p‘ src/http/ngx_http_special_response.c

static u_char ngx_http_error_full_tail[] =

"<hr><center>" NGINX_VER "</center>" CRLF #將nginx修改為"xuliangwei.com"

"</body>" CRLF

"</html>" CRLF

http

{

......

server_tokens off; #在nginx.conf配置文件中,直接使用,網站的錯誤頁面還是會顯示版本號信息

......

}

通過瀏覽器訪問也沒有nginx的版本號,這樣才能確保nginx版本號不被黑客知道。

說明:

q 提升網站安全,要從最簡單、最短板、最低點入手解決問題,門大開著,窗戶安裝再結實也沒有意義

q 向有經驗的人及優秀的網站公司學習

q 學習看官方聞到那股,根據一手資料去分析

q 命令行輸出結果中含有需要過濾掉或者保留的內容時,命令自身可能有參數直接實現。

q 掌握技術思想比解決問題本身更重要:http://oldboy.blog.51cto.com/2561410/1196298

1.1.2 更改nginx默認用戶及用戶組

為了web服務更安全,我們要盡可能的改掉所有軟件默認的配置,包括端口,用戶等。例如:前面的linux基礎安全,我們就更改過ssh服務的22端口以及禁止root ssh連接等。

更改nginx的用戶和用戶組的操作方法和步驟如下:

[root@Nginx conf]# pwd #查看當前路徑

/application/nginx/conf

[root@Nginx conf]# grep "#user" nginx.conf.default #過濾出默認用戶

#user nobody; #1.一般情況,nginx服務啟動,使用的用戶和組默認都是nobody,查看默認配置如下

為了防止黑客猜到這個web服務的用戶,我們需要更改特殊的用戶名例如:nginx或者特殊點xuliangwei,但是這個用戶必須是系統裏存在的。

[root@Nginx conf]# useradd nginx -s /sbin/nologin –M #2.建立nginx用戶不需要有系統登錄權限,應當禁止其登錄能力

[root@Nginx conf]# id nginx #檢查用戶用戶是否創建成功

uid=500(nginx) gid=500(nginx) groups=500(nginx)

user nginx nginx; ?3.更改nginx服務默認用戶和組的方法有兩種,第一種為直接更改配置文件參數:

如果註釋或不設置上述參數,默認即是nobody用戶和組,不推薦使用nobody用戶名稱,最好采用一個普通用戶,如nginx或特殊點的xuliangwei

[root@Nginx conf]# ../sbin/nginx -V ?4.更改默認用戶的第二種方法:直接在編譯nginx軟件時指定編譯的用戶和組

nginx version: nginx/1.6.3

built by gcc 4.4.7 20120313 (Red Hat 4.4.7-16) (GCC)

TLS SNI support enabled

configure arguments: --prefix=/application/nginx-1.6.3 --user=nginx --group=nginx --with-http_ssl_module --with-http_stub_status_module

提示:其實,在前面編譯nginx服務時,我們就是這樣呆著參數編譯的。

5.最後檢查nginx進程的對應用戶如下

[root@Nginx conf]# ps aux|grep nginx|grep -v grep ?

root3999 0.0 0.244556 1044 ? Ss07:56 0:00 nginx: master process /application/nginx/sbin/nginx

nginx4001 0.0 0.344988 1624 ? S07:56 0:00 nginx: worker process

6.更改nginx默認用戶及用戶組結論

通過查看杉樹更改後的nginx進程,我們看到了worker processes的進程對應用戶都變成了nginx了。所以,我們有理由得出結論,上述的兩種方法都是設置Nginx的worker進程運行的用戶的,Nginx的主進程還是以root身份運行的,當然,後文也會有不用root起主進程服務的技巧。

1.1.3 配置nginx worker進程個數

在高並發場景,我們需要事先啟動更多的nginx進程以保證快速響應並且處理用戶的請求。具體的配置參數如下:

worker_processes8; ?指定了Nginx要開啟的進程數。建議指定的CPU的數量相等或乘2的進程數。

worker_processes參數開始的設置可以等於cpu的個數或核數(worker_cpu_affinity參數中的配置可以指定第一個到最後一個進程分別使用的哪個cpu),進程數多一些,起始提供服務時就不會臨時啟動新進程提供服務,減少額系統開銷,提升了服務速度。特殊場合也可以考慮提高至CPU*2的進程數,具體情況要根據實際的業務來選擇,因為這個參數除了CPU盒數影響外,和硬盤存儲的數據以及負載也有關。

[root@Nginx conf]# grep "physical id" /proc/cpuinfo ?1.查看Linux服務器的盒數的方法

physical id: 0

[root@Nginx conf]# grep "worker_processes" nginx.conf ?2.查看默認的nginx.conf裏worker_processes數

worker_processes2;

這裏我們修改參數值為4,然後重新加載nginx服務,操作過程及結果:

[root@Nginx conf]# sed -i ‘s#worker_processes2;#worker_processes 4;#g‘ nginx.conf ?1.修改配置

[root@Nginx conf]# grep "worker_processes" nginx.conf ?2.檢查修改結果

worker_processes4;

[root@Nginx conf]# /application/nginx/sbin/nginx -t ?3.nginx程序測試是否正確

nginx: the configuration file /application/nginx-1.6.3/conf/nginx.conf syntax is ok

nginx: configuration file /application/nginx-1.6.3/conf/nginx.conf test is successful

[root@Nginx conf]# /application/nginx/sbin/nginx -s reload ?4.優雅重啟nginx

[root@Nginx conf]# ps aux|grep "nginx"|grep -v "grep" ?5.檢查進程數

root3999 0.0 0.344556 1704 ? Ss07:56 0:00 nginx: master process /application/nginx/sbin/nginx

nginx4197 0.0 0.345008 1740 ? S08:32 0:00 nginx: worker process

nginx4198 0.0 0.345008 1668 ? S08:32 0:00 nginx: worker process

nginx4199 0.0 0.345008 1740 ? S08:32 0:00 nginx: worker process

nginx4200 0.0 0.345008 1740 ? S08:32 0:00 nginx: worker process

提示:可以看到,當worker_processes 4;worker進程數為4個。Master主進程不包含在內。

1.1.4 根據cpu核數進行nginx進程優化

默認情況nginx的多個進程可能更多的跑在一顆cpu上,本節是分配不同的進程給不同的cpu處理,達到充分利用硬件多核多CPU的目的。

不同的cpu對用配置如下:

worker_cpu_affinity 0001 0010 0100 1000; ?四核cpu服務器:

?nginx進程CPU親和力,即把不同的進程分給不同的CPU處理。

1.1.5 時間處理模型優化

Nginx的連接處理機制在於不同的操作系統采用不同的IO模型,在linux使用epoll的IO多路復用模型,在freed使用kqueue的IO多路復用模型,在solaris使用/dev/poll方式的IO多路復用模型,在windows使用的是icop等等。

根據系統類型不同選擇不同use [ kqueue| rtsig | epoll | /dev/poll |select |poll];該參數結合系統使用,不同系統使用參數不同,我們使用的是Centos6.7,因此我們調整為epoll模型。

1.具體的配置參數如下:

events ?events指令是設定Nginx的工作模式及連接數上限。

{

use epoll; ?use是個事件模塊指令,用來指定Nginx的工作模式。Nginx支持的工作模式有select、poll、kqueue、epoll、rtsig和/dev/poll。其中select和poll都是標準的工作模式,kqueue和epoll是高效的工作模式,不同的是epoll用在Linux平臺上,而kqueue用BSD系統中。對於Linux系統Linux2.6的內核,推薦選擇epoll工作模式,這是高性能高並發的設置。

}

1.1.6 調整單個進程允許的客戶端最大連接數

這個值根據具體服務器性能和程序的內存使用量來指定(一個進程啟動使用額內存根據程序確定)

events ?events指令是設定Nginx的工作模式及連接數上限。

{

worker_connections 20480; ?worker_connections也是個事件模塊指令,用於定義Nginx每個進程的最大連接數,默認是1024.最大客戶端連接數有worker_processes和worker_connections決定,即Max_client=worker_processes*worker_connections。進程的最大連接數受Linux系統進程的最大打開文件數限制,在執行操作系統命令 “ulimit –HSn 65535”或配置相應文件後worker_connections的設置才能生效。

}

1.1.7 配置每個進程最大文件打開數

worker_rlimit_nofile 65535; #放置最上面。每個進程打開的最大文件數,可設置為系統優化後的ulimit –HSn的結果,在第一章系統安裝時,調整文件描述符和這個處理的一個問題。

1.1.8 優化服務器名字的hash表大小

確切名字和通配符名字存儲在哈希表中。哈希表和監聽端口關聯,每個端口都最多關聯到三張表;確切名字的哈希表,以星號起始的通配符名字的哈希表和以星號結束的通配符名字的哈希表。哈希表的尺寸在配置階段進行了優化,可以以最小的CPU緩存命中失敗來找到名字。Nginx首選搜索確切名字的哈希表,如果沒有找到,搜索以星號起始的通配符名字的哈希表,如果還是沒有找到,繼續搜索以星號結束的通配符名字的哈希表。因為名字是按照域名的節來搜索的,所以搜索通配符名字的哈希表比搜索確切名字的哈希表慢。註意nginx.org存儲在通配符名字的哈希表中,而不在確切名字的哈希表中。正則表達式是一個一個串行的測試,所以是最慢的,而且不可擴展。

鑒於以上原因,請盡可能使用確切的名字。舉個例子,如果使用nginx.org和www.nginx.org來訪問服務器時最頻繁的,那麽將他們明確的出來就更為有效

下面這種方法相比更簡單,但是效率也更低:

server {

listen 80;

server_name nginx.org ;

….

}

server {

listen 80;

server_name nginx.org *.nginx.org;

….

}

1.1.9 開啟高效文件傳輸模式

sendfile on; #sendfile參數用於開啟文件高效傳輸模式。同時將tcp_nopush和tcp_nodelay兩個指令設置為on用於防止網絡阻塞。

tcp_nopush on; #打開linux下TCP_CORK,sendfile參數打開時才有效,減少報文段的數量之用。

建議:在http段開啟上述功能。

1.1.10設置連接超時時間

keepalive_timeout 60; #設置客戶端連接保持會話的超時時間。超過這個時間,服務器會關閉該連接。

tcp_nodelay on; #打開tcp_nodelay,在包含了keepalive參數才有效

client_header_timeout 15; #設置客戶端其你去頭讀取超時時間。如果超過這個時間,客戶端還沒有發送任何數據,Nginx將返回”Request timeout(408)”錯誤

client_body_timeout 15; #設置客戶端請求主體讀取超時時間。如超過這個時間,客戶端還沒有發送任何數據,Nginx將返回”Request timeout(408)”錯誤 默認值是60.

send_timeout 15; #指定響應客戶端的超時時間。這個超時僅限於兩個鏈接活動之間的時間,如果超過這個時間,客戶端沒有任何活動,Nginx將會關閉連接。

1.1.11上傳文件大小限制(動態應用)

主配置文件裏加入如下參數,具體大小根據你自己的業務做調整。

client_max_body_size 10m;

1.1.12fastcgi調優(配合PHP引擎動態服務)

技術分享圖片

讀磁盤寫入buffer緩沖區

fastcgi_connect_timeout 120; #指定連接到後端FastCGI的超時時間,默認60s。

fastcgi_send_timeout 120; #向FastCGI傳送請求的超時時間,這個值是指已經完成兩次握手後向FastCGI傳送請求的超時時間,默認60s。

fastcgi_read_timeout 120; #指定接受FastCGI應答的超時時間,這個值是指已經完成兩次握手後接受FastCGI應答的超時時間。

fastcgi_buffer_size 64k; #指定讀取astCGI應答第一部分需要用多大的緩沖區,這個值表示將使用1個64KB的緩沖區讀取應答的第一部分(應答頭),可以設置為fastcgi_buffers現象指定的緩沖區大小。

fastcgi_buffers 4 64k; #指定本地需要用多少盒多大的緩沖區來緩存FastCGI的應答請求。如果一個PHP腳本所產生的頁面大小為256KB,那麽會為其分配4個64KB的緩沖區來緩存:如果頁面大小大於256KB,那麽大於256KB的部分會緩存到fastcgi_temp指定的路徑中,但是這並不是好方法,因為內存中的數據處理熟讀要快於硬盤。一般這個值應該為站點中PHP腳本所產生的頁面大小的中間值,如果站點大部分腳本所產生的頁面大小為256KB,那麽可以把這個值設置為16 16k、“4 64k”等。

fastcgi_busy_buffers_size 128k; #建議為fastcgi_vuffers的兩倍

fastcgi_temp_file_write_size 128k; #在寫入fastcgi_temp_path時將用多大的數據庫,默認值是fastcgi_buffers的兩倍,設置上述數值設置太小時,若負載上來時可能報502 Bod Gateway

#fastcgi_cache oldboy_nginx; #表示開啟FastCGI緩存並未其指定一個名詞。開啟緩存非常有用,可以有效降低CPU的負載,並且防止502錯誤的發生,但是開啟緩存也可能會引起其他問題,要根據具體情況選擇。

用戶讀取cache緩存區

fastcgi_cache_valid 200 302 1h; #用來指定應答代碼的緩存時間,實例中的值表示將200和302應答緩存一個小時

fastcgi_cache_valid 301 1d; #將301應答緩存1天

fastcgi_cache_valid any 1m; #將其他應答緩存為1分鐘

fastcgi_cache_min_uses 1; #緩存在fastcgi_cache_path指令inactive參數值時間內的最少使用次數

1.1.13配置nginx gzip壓縮功能

Nginx gzip壓縮模塊提供了對文件內容壓縮的功能,允許nginx服務器將輸出內容在發送到客戶端之前根據具體的策略進行壓縮,以節約網站帶寬,同時提升用戶訪問體驗。此功能同apache的mod_deflate壓縮功能,依賴ngx_http_gzip_module模塊,默認已安裝我們已經詳細講解過了壓縮的功能。(一般配置在http標簽全局生效)

gzip on; #開啟gzip壓縮功能

gzip_min_length 1k; #設置允許壓縮的頁面最小字節數,頁面字節數從header頭的Content-Length中獲取。默認值是0,不管頁面多大都進行壓縮。建議設置成大於1k。如果小於1k可能會越壓越大。

gzip_buffers 4 32k; #壓縮緩存區大小。表示申請4個單位為16k的內存作為壓縮結果流緩存,默認值是申請與原始數據大小相同的內存空間來存儲gzip壓縮結果。

#gzip_http_version 1.1; #壓縮版本(默認1.1,前端為squid2.5時使用1.0)用於設置識別HTTP協議版本,默認是1.1,目前大部分瀏覽器已經支持GZIP解壓,使用默認即可(可以不用配置)。

gzip_comp_level 9; #壓縮比率。用來指定GZIP壓縮比,1壓縮比最小,處理速度最快;9壓縮比最大,傳輸速度快, 處理最慢,也比較消耗cpu資源。

gzip_types text/plain application/x-javascript text/css application/xml; ?用來指定壓縮的類型,“text/html”類型總是會被壓縮。

gzip_vary on; ?vary header支持。該選項可以讓前端的緩存服務器緩存經過GZIP壓縮的頁面,例如用Sqiud緩存經過Nginx壓縮的數據。

提示:gzip_types類型不同的版本可能會有不同,上述是適合1.6.3的nginx。對用的文件類型查看安裝目錄下的mime.types文件。

建議:大於1k的純文件文件html,js,css,xmlshtml。圖片,視頻等不要壓縮。因為不但不會減小,在壓縮時消耗CPU,MEM資源。

1.1.14配置nginx expires緩存功能

在網站開發和運營中,對於圖片,CSS,JS,html等代碼緩存10天,這樣用戶第一次打開頁面後,會在本地的瀏覽器緩存相應的上述內容,這樣的緩存可以提高下次用戶打開類似頁面的加載速度,並節省服務器端大量的帶寬。此功能同apache的expires,我們已經詳細講解過了。這裏通過location的功能,昂需要緩存的擴展名列出來,然後指定緩存時間。

Expire功能優點:

Expires可以降低網站購買的帶寬,節約成本,同時提升了用戶訪問體驗,是web服務非常重要的功能。

Expire功能缺點:

被緩存的頁面或數據更新了,用戶看到的可能還是舊的內容,反而影響用戶體驗。

解決辦法:

第一個:縮短緩存時間,例如:1天,不徹底,除非更新頻繁率大於1天。

第二個:對緩存的對象改名。

圖片,附件一般不會被用戶修改,如果用戶修改了,實際上也都是更改文件名重新傳了而已。

網站升級對於js,css元素,一般可以改名。

location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$

{

expires 3650d; ?一年(以gif|jpg|jpeg|png|bmp|swf結尾的)

}

location ~.*\.(js|css)?&

{

expires 30d; ?一月

}

特別註意:location內容一般防到虛擬主機配置中,即server標簽中。

根據目錄進行判斷,添加expires功能範例

location ~ ^/(images|javascript|js|flash|media|static)/ {

expires 360d;

}

單個文件添加expires功能範例(給robots.txt設置過期時間;這裏為robots.txt為7天並不記錄404錯誤日誌)

location ~(robots.txt) {

log_not_found off;

expires 7d;

break;

}

1.1.15使用tmpts文件系統替代頻繁訪問的目錄

[root@Nginx ~]# mkdir /opt/tmp

[root@Nginx ~]# cd /tmp

[root@Nginx tmp]# mv * /opt/tmp/

[root@Nginx tmp]# mount -t tmpfs -o size=16m tmpfs /tmp

[root@Nginx tmp]# df -h

FilesystemSize Used Avail Use% Mounted on

/dev/sda362G 4.2G 55G8% /

tmpfs244M 0 244M0% /dev/shm

/dev/sda1190M 36M 145M20% /boot

tmpfs16M 0 16M0% /tmp

想要永久生效,可以放在/etc/rc.local 或者是 /etc/fstab

1.1.16最小化目錄及文件權限設置

為了保證網站不遭受目錄入侵上傳及修改文件。

安全的權限:

所有站點目錄的用戶和組都應該為root

所有目錄權限是默認的755

所有文件權限是默認的644

註意:網站服務的用戶不能用root

以上的權限設置可以做到防止黑客上傳目錄,以及修改站點文件,但是,合理的用戶上傳的內容也被拒之門外了。那麽如何解決可以讓合法的用戶傳文件又不至於被黑客利用攻擊呢?

這就是對業務進行分離,在比較好的網站額外架構中,應把資源文件,包括用戶上傳的圖片,附件等的服務和程序服務分離,最好把上傳程序服務也分離,這樣可以從容按照前面的標準授權了。

大多數公司的不安全授權如下:

chmod –R 777 /sitedir

chown –R nginx.nginx /sitedir

1.1.17Nginx限制HTTP請求方法

我們可以通過Nginx限制Http請求的方法來達到提升服務器安全的目的,例如讓Http只能使用GET、HEAD和POST方法的配置如下:

#Only allow these request methods

if ($request_method !~ ^(GET|HEAD|POST)$ ) {

return 501;

}

#Only allow these request methods

if ($request_method ~* ^(GET)$ ) {

return 501;

}

1.1.18Nginx圖片及目錄防止盜鏈

a.根據http referer實現防盜鏈

在http協議中,有一個表頭叫referer,使用URL格式來表示從那裏來的連接到當前的網頁資源。通過referer可以檢測目標訪問的來源網頁,如果是資源文件,可以跟蹤到顯示它的網頁地址,一旦檢測出來來源不是本站的,就進行阻止或者返回到指定的頁面,Apache,nginx,lighttpd三者都支持防盜鏈

b.根據cookies處理

c.通過加密變換路徑實現防盜鏈

利用瀏覽器的referer並且針對擴展名rewrite重定向

location ~ .*\.(jpg|gif|png|swf|flv|wma|wmv|asf|mp3|mmf|zip|rar)?$ {

valid_referers none blocked *.etiantian.org etiantian.org;

if ($invalid_referer) {

rewrite ^/ http://www.etiantian.org/img/nolink.jpg;

}

}

http://oldboy.blog.51cto.com/2561410/909696 流量暴漲

nginx實現下載防盜鏈模塊

http://nginx.org/en/docs/http/ngx_http_secure_link_module.html

1.1.19禁止不同瀏覽器軟件訪問

if ($http_user-agent ~* "Firefox|MSIE 8.0"){

#return 403;

rewrite ^(.*) http://www.xuliangwei.com/$1 permanent;

}

#如果客戶端瀏覽器是firefox或者ie則跳轉到www.xuliangwei.com域名,或者也可以給出403錯誤

1.1.20防止網站惡意解析

案例:你的網站權重比較高,為了提高權重,然後有人惡意解析域名到你的服務器ip地址

方法一:

server {

listen 80 default;

return 500;

}

第二種方式:

server {

listen 80 default_server;

server_name _;

return 501;

}

方法二:301跳轉到本域名,但是還是有非法解析(不推薦)

if ($host !~ ^www/.eduoldboy/.com$){

rewrite ^(.*) http://www. eduoldboy.com$1 permanent;

}

1.1.21Nginx防爬蟲

if ($http_user_agent ~* "qihoobot|Baiduspider|Googlebot|Googlebot-Mobile|Googlebot-Image|Mediapartners-Google|Adsbot-Google|Yahoo! Slurp China|YoudaoBot|Sosospider|Sogou spider|Sogou web spider|MSNBot") {

return 403;

}

1.2Nginx日誌相關優化與安全

Nginx沒有類似Apache的cronolog日誌分割處理的功能,但是可以通過Nginx的信號控制功能或者reload重新加載,然後利用腳本來實現日誌的自動切割。

向 Nginx 主進程發送 USR1 信號。USR1 信號是重新打開日誌文件(不需要重啟服務可能是更好的選擇)

[root@LNMP scripts]# cat cut_log.sh

#!/bin/sh

date=`date +%Y%m%d`

bashdir="/application/nginx"

log_dir="$bashdir/logs"

logname="access_www"

nginxpid=`cat /application/nginx/logs/nginx.pid`

#nginxpid=`ps aux | grep nginx |awk ‘NR==1{print $2}‘`

[ -d $log_dir ] && cd $log_dir || exit 1

if [ -f ${logname}.log ];then

/bin/mv ${logname}.log ${date}_${logname}.log && \

kill -USR1 $nginxpid

else

echo "plese touch $logname.log"

exit 2

fi

每天淩晨切割

[root@LNMP scripts]# crontab -l

#################

00 00 * * * /bin/sh /server/scripts/cut_log.sh >/dev/null 2>&1

1.2.1 不記錄不需要的訪問日誌

對於健康檢查或某些(圖片,js,css)的日誌,一般不需要記錄,因為在統計PV時是按照頁面計算。而且日誌寫入頻繁會消耗磁盤IO,降低服務性能。

location ~ .*\.(js|jpg|JPG|jpeg|JPEG|css|bmp|gif|GIF)$ {

access_log off;

}

1.2.2 訪問日誌的權限設置

假如日誌目錄為/app/logs,則授權方法

[root@Nginx ~]# mkdir /app/logs –p #創建/app/logs目錄

[root@Nginx ~]# chown -R root.root /app/logs/ #授權/app/logs目錄的屬主屬組為root

[root@Nginx ~]# chmod 700 /app/logs/ #賦予屬主讀寫執行權限

[root@Nginx ~]# ll -d /app/logs/ #查看權限是否ok

drwx------ 2 root root 4096 Oct 10 10:02 /app/logs/

提示:不需要在日誌目錄上給nginx用戶讀或者寫的許可,否則會有安全隱患,所以不適用nginx用戶,只所以設置root也能寫入日誌,因為nginx的主進程是root用戶,所以能夠寫入。

1.3Nginx站點目錄及文件URL訪問控制

1.3.1 根據擴展名限制程序和文件訪問

Nginx下禁止訪問資源目錄下的php程序文件,(配置在server標簽下)寫在php解析前面配置方法如下:

location ~^/images/.*\.(php|php5)$

{

deny all;

}

location ~ ^/static/.*\.(php|php5|.sh|.pl|.py)$

{

deny all;

}

location ~ ^/data/(attachment|avatar)/.*\.(php|php5)$

{

deny all;

}

Nginx下配置禁止訪問單目錄或多目錄(配置在server標簽下)配置方法如下:

location ~^/(static)/{

deny all;

}

location ~^/static{

deny all;

}

location ~^/(static|js){

deny all;

}

1.3.2 限制來源IP訪問

使用nginx_http_access_module模塊限制ip訪問

範例1:禁止目錄讓外界訪問,但允許某IP訪問該目錄,且支持PHP解析

location ~ ^/oldboy/ {

allow 202.111.12.211;

deny all;

}

location ~ ^/oldboy/ {

deny 192.168.1.1;

allow 192.168.1.0/24;

allow 10.1.1.0/16;

deny all;

}

企業安利:Nginx做反向代理的時候可以限制客戶端IP嗎?

使用if來控制

if ( $remote_addr = 10.0.0.8 ){

return 403;

}

if ( $remote_addr = 208.247.17.130 ) {

set $allow_access_root ‘true’;

}

1.4Nginx錯誤頁面優雅顯示

1.4.1 生產環境常見的HTTP狀態碼列表

生產環境常見的HTTP狀態碼列表(List of HTTP status codes)為:
說明:求精不求多,有舍才有得 不一樣的思維不一樣的精彩。《老男孩linux實戰培訓》也是這個原則。

200 - OK,服務器成功返回網頁
- Standard response for successful HTTP requests.

301 - Moved Permanently(永久跳轉),請求的網頁已永久跳轉到新位置。
- This and all future requests should be directed to the given.

403 - Forbidden(禁止訪問),服務器拒絕請求
- forbidden request (matches a deny filter) => HTTP 403
- The request was a legal request, but the server is refusing to respond to it.

404 - Not Found,服務器找不到請求的頁面。
- The requested resource could not be found but may be available again in the future.

500 - Internal Server Error(內部服務器錯誤)
- internal error in haproxy => HTTP 500
- A generic error message, given when no more specific message is suitable.

502 - Bad Gateway(壞的網關),一般是網關服務器請求後端服務時,後端服務沒有按照http協議正確返回結果。
- the server returned an invalid or incomplete response => HTTP 502
- The server was acting as a gateway or proxy and received an invalid response from the upstream server.

503 - Service Unavailable(服務當前不可用),可能因為超載或停機維護。
- no server was available to handle the request => HTTP 503
- The server is currently unavailable (because it is overloaded or down for maintenance).

504 - Gateway Timeout(網關超時),一般是網關服務器請求後端服務時,後端服務沒有在特定的時間內完成服務。
- the server failed to reply in time => HTTP 504
- The server was acting as a gateway or proxy and did not receive a timely response from the upstream server.

1.4.2 為什麽要配置錯誤頁面優雅顯示

error_page 404http://oldboy.blog.51cto.com;

阿裏門戶網站天貓的Nginx優雅顯示配置案例如下:

error_page500 501 502 503 504 http://xuliangwei.com/error2.html;

error_page 400 403 404 405 408 410 411 412 413 414 415 http://xuliangwei.com/error1.html;

1.5系統內核參數優化

kernel.shmall = 4294967296

net.ipv4.tcp_fin_timeout = 2

net.ipv4.tcp_tw_reuse = 1

net.ipv4.tcp_tw_recycle = 1

net.ipv4.tcp_syncookies = 1

net.ipv4.tcp_keepalive_time = 600

net.ipv4.ip_local_port_range = 4000 65000

net.ipv4.tcp_max_syn_backlog = 16384

net.ipv4.tcp_max_tw_buckets = 36000

net.ipv4.route.gc_timeout = 100

net.ipv4.tcp_syn_retries = 1

net.ipv4.tcp_synack_retries = 1

net.core.somaxconn = 16384

net.core.netdev_max_backlog = 16384

net.ipv4.tcp_max_orphans = 16384

net.ipv4.tcp_fin_timeout = 2

net.ipv4.tcp_tw_reuse = 1

net.ipv4.tcp_tw_recycle = 1

net.ipv4.tcp_syncookies = 1

net.ipv4.tcp_keepalive_time =600

net.ipv4.ip_local_port_range = 4000 65000

net.ipv4.tcp_max_syn_backlog = 16384

net.ipv4.tcp_max_tw_buckets = 36000

net.ipv4.route.gc_timeout = 100

net.ipv4.tcp_syn_retries = 1

net.ipv4.tcp_synack_retries = 1

net.core.somaxconn = 16384

net.core.netdev_max_backlog = 16384

net.ipv4.tcp_max_orphans = 16384

#for iptables

net.nf_conntrack_max = 25000000

net.netfilter.nf_conntrack_max = 25000000

net.netfilter.nf_conntrack_tcp_timeout_established = 180

net.netfilter.nf_conntrack_tcp_timeout_time_wait = 120

net.netfilter.nf_conntrack_tcp_timeout_close_wait = 60

net.netfilter.nf_conntrack_tcp_timeout_fin_wait = 120

#以下參數是對iptables防火墻的優化,防火墻不開會提示,可以忽略不理。

##net.nf_conntrack_max = 25000000

##net.netfilter.nf_conntrack_max = 25000000

##net.netfilter.nf_conntrack_tcp_timeout_established = 180

##net.netfilter.nf_conntrack_tcp_timeout_time_wait = 120

系統內核參數詳解:

1.6Include優化配置文件

Include包含文件或目錄

Nginx的主配置文件為nginx.conf,主配置文件包含的所有虛擬主機統一放入extra目錄中,虛擬主機的配置文件按照網站的域名或功能取名例如:bbs.conf blog.conf等。

如果虛擬主機的數量不是很多,也可以生成一個單獨的配置文件,僅僅和Nginx的主配置文件nginx.conf分離開

規範配置文件,它可以放置Nginx配置中任何位置。

http {

…….

include vhosts/*.conf; ?包含vhosts下所有以conf結尾的文件

include extra/www.conf; ?包含www網站虛擬主機配置文件

include extra/bbs.conf; ?包含bbs網站虛擬主機配置文件

include extra/blog.conf; ?包含blog網站虛擬主機配置文件

.......

}

1.7NGINX監牢模式

1.7.1 Nginx服務使用普通用戶

默認情況下,Nginx的Master進程使用的是root用戶,worker進程使用的是Nginx指定的普通用戶,使用root用戶跑Nginx的Master進程有兩個最大的問題。

管理權限必須是root,這就使得最小化分配權限原則遇到難題。

使用root跑Nginx服務,一旦網站出現漏洞,用戶就可以很容易地獲得服務器的root權限。

因此,不用給開發人員,甚至普通運維人員管理權限,就可以很好的管理Nginx服務。

1.7.2 Nginx服務降權解決方案

q 給Nginx服務降權,用inca用戶跑Nginx服務,給開發及運維設置普通賬戶,只要和inca同組即可管理Nginx,該方案解決了Nginx管理問題,防止root分配權限過大。

q 開發人員使用普通賬戶即可管理nginx服務以及站點下的程序、看日誌。

q 采取項目負責制度,即誰服務項目維護出題就是誰負責。

很多公司開發和運維為爭root權限不可開交,甚至大打出手的也有。

參考資料:到底要不要給開發人員管理服務器的權限?http://down.51cto.com/data/844517

[root@web-node1 ~]# useradd inca

[root@web-node1 ~]# su - inca

[inca@web-node1 ~]$ mkdir conf logs www

[inca@web-node1 ~]$ cp /application/nginx/conf/mime.types ./conf/

[inca@web-node1 ~]$ echo inca > www/index.html

[inca@web-node1 ~]$ cat conf/nginx.conf

worker_processes4;

worker_cpu_affinity 0001 0010 0100 1000;

worker_rlimit_nofile 65535;

error_log/home/inca/logs/error.log;

user inca inca;

pid/home/inca/logs/nginx.pid;

events {

use epoll;

worker_connections 10240;

}

http {

include/home/inca/conf/mime.types;

default_typeapplication/octet-stream;

sendfile on;

keepalive_timeout 65;

log_format main ‘$remote_addr - $remote_user [$time_local] "$request" ‘

‘$status $body_bytes_sent "$http_referer" ‘

‘"$http_user_agent" "$http_x_forwarded_for"‘;

server {

listen 8080;

server_name www.etiantian.org;

root /home/inca/www;

location / {

index index.php index.html index.htm;

}

access_log/home/inca/logs/www_log_access.logmain;

}

}

[inca@web-node1 ~]$ /application/nginx/sbin/nginx -c /home/inca/conf/nginx.conf &>/dev/null

[inca@web-node1 ~]$ ps aux|grep nginx

inca1619 0.0 0.242452 1032 ? Ss21:07 0:00 nginx: master process /application/nginx/sbin/nginx -c /home/inca/conf/nginx.conf

inca1620 0.0 1.046704 5296 ? S21:07 0:00 nginx: worker process

inca1621 0.0 1.046704 5416 ? S21:07 0:00 nginx: worker process

inca1622 0.0 1.046704 5416 ? S21:07 0:00 nginx: worker process

inca1623 0.0 1.046704 5404 ? S21:07 0:00 nginx: worker process

本解決方案的優點如下:

q 給Nginx服務降權,讓網站更安全。

q 按用戶設置站點權限,使站點更獨立(無需虛擬化隔離)

q 開發不需要用root即可完整管理服務及站點。

q 可實現對責任劃分:網絡問題屬於運維的責任,網站打不開就是開發責任或共同承擔。

1.9Nginx程序架構優化

為網站程序解藕

解耦是開發人員中流行的一個名詞,簡單地說就是把一堆程序代碼按照業務用途分開,然年後提供服務,例如:註冊、登陸、上傳、下載、用戶中心、搜索、商品、價格、購物車、結算、物流、訂單、評價、積分、積分抽獎、等應該是獨立的程序服務,只不過在客戶端看來是一個整體而已,如果中小公司做不到上述細致的解耦,起碼也要讓下面的幾個程序模塊獨立。

q 網頁頁面服務。

q 圖片附件及下載服務。

q 上傳圖片服務。

上述三者的功能盡量分離。

Nginx服務優化