天天看點

談談我對nginx的一些了解

NGINX是什麼?

          Nginx (engine x) 是一個高性能的HTTP和反向代理服務,也是一個IMAP/POP3/SMTP服務。

          反向代理又是什麼?和正向代理有什麼差別呢?其實這兩種代理方式主要差別是代理對象不同:正向代理代理對象是用戶端;而反向代理代理對象是伺服器。

NGINX可以做什麼?

          場景:

              nginx為高并發而生,是以nginx首先應用場景一定是高并發負載較高的場景下。

          用途:

             nginx很多時候被用來做前置負載均衡。

             同時由于nginx對靜态資源有較好的支援,中小型網站也可以用來做動靜分離。

NGINX安裝使用

             參考:http://www.runoob.com/linux/nginx-install-setup.html

NGINX基本配置       

#nginx程序,一般設定為和cpu核數一樣

worker_processes 4;                        

#錯誤日志存放目錄 

error_log  /data1/logs/error.log  crit;  

#運作使用者,預設即是nginx,可不設定

user nginx       

#程序pid存放位置

pid        /application/nginx/nginx.pid;        

#Specifies the value for maximum file descriptors that can be opened by this process. 

#最大檔案打開數(連接配接),可設定為系統優化後的ulimit -HSn的結果

worker_rlimit_nofile 51200;

#cpu親和力配置,讓不同的程序使用不同的cpu

worker_cpu_affinity 0001 0010 0100 1000 0001 00100100 1000;

#工作模式及連接配接數上限

events 

{

  use epoll;       #epoll是多路複用IO(I/O Multiplexing)中的一種方式,但是僅用于linux2.6以上核心,可以大大提高nginx的性能

  worker_connections 1024;  #;單個背景worker process程序的最大并發連結數

}

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

http 

{

include mime.types; #檔案擴充名與類型映射表

default_type application/octet-stream; #預設檔案類型

#limit子產品,可防範一定量的DDOS攻擊

#用來存儲session會話的狀态,如下是為session配置設定一個名為one的10M的記憶體存儲區,限制了每秒隻接受一個ip的一次請求 1r/s

  limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s;

  limit_conn_zone $binary_remote_addr zone=addr:10m;

  include       mime.types;

  default_type  application/octet-stream;

#第三方子產品lua防火牆

    lua_need_request_body on;

    #lua_shared_dict limit 50m;

    lua_package_path "/application/nginx/conf/waf/?.lua";

    init_by_lua_file "/application/nginx/conf/waf/init.lua";

    access_by_lua_file "/application/nginx/conf/waf/access.lua";

 #設定請求緩存    

  server_names_hash_bucket_size 128;

  client_header_buffer_size 512k;

  large_client_header_buffers 4 512k;

  client_max_body_size 100m;

  #隐藏響應header和錯誤通知中的版本号

  server_tokens off;

  #開啟高效傳輸模式   

  sendfile on;

-------------------------------------------------------------------------------------------------

  #激活tcp_nopush參數可以允許把httpresponse header和檔案的開始放在一個檔案裡釋出,

  積極的作用是減少網絡封包段的數量

  tcp_nopush     on;

  #激活tcp_nodelay,核心會等待将更多的位元組組成一個資料包,進而提高I/O性能

  tcp_nodelay on;

tcp_nopush

官方:

tcp_nopush

Syntax: tcp_nopush on | off

Default: off

Context: http

server

location

Reference: tcp_nopush

This directive permits or forbids the use of thesocket options TCP_NOPUSH on FreeBSD or TCP_CORK on Linux. This option is onlyavailable when using sendfile.

Setting this option causes nginx to attempt to sendit’s HTTP response headers in one packet on Linux and FreeBSD 4.x

You can read more about the TCP_NOPUSH and TCP_CORKsocket options here.

linux 下是tcp_cork,上面的意思就是說,當使用sendfile函數時,tcp_nopush才起作用,它和指令tcp_nodelay是互斥的。tcp_cork是linux下tcp/ip傳輸的一個标準了,這個标準的大概的意思是,一般情況下,在tcp互動的過程中,當應用程式接收到資料包後馬上傳送出去,不等待,而tcp_cork選項是資料包不會馬上傳送出去,等到資料包最大時,一次性的傳輸出去,這樣有助于解決網絡堵塞,已經是預設了。

也就是說tcp_nopush = on 會設定調用tcp_cork方法,這個也是預設的,結果就是資料包不會馬上傳送出去,等到資料包最大時,一次性的傳輸出去,這樣有助于解決網絡堵塞。

以快遞投遞舉例說明一下(以下是我的了解,也許是不正确的),當快遞東西時,快遞員收到一個包裹,馬上投遞,這樣保證了即時性,但是會耗費大量的人力物力,在網絡上表現就是會引起網絡堵塞,而當快遞收到一個包裹,把包裹放到集散地,等一定數量後統一投遞,這樣就是tcp_cork的選項幹的事情,這樣的話,會最大化的利用網絡資源,雖然有一點點延遲。

對于nginx配置檔案中的tcp_nopush,預設就是tcp_nopush,不需要特别指定,這個選項對于www,ftp等大檔案很有幫助      

tcp_nodelay

TCP_NODELAY和TCP_CORK基本上控制了包的“Nagle化”,Nagle化在這裡的含義是采用Nagle算法把較小的包組裝為更大的幀。 John Nagle是Nagle算法的發明人,後者就是用他的名字來命名的,他在1984年首次用這種方法來嘗試解決福特汽車公司的網絡擁塞問題(欲了解詳情請參看IETF RFC 896)。他解決的問題就是所謂的silly window syndrome,中文稱“愚蠢視窗症候群”,具體含義是,因為普遍終端應用程式每産生一次擊鍵操作就會發送一個包,而典型情況下一個包會擁有一個位元組的資料載荷以及40個位元組長的標頭,于是産生4000%的過載,很輕易地就能令網絡發生擁塞,。 Nagle化後來成了一種标準并且立即在網際網路上得以實作。它現在已經成為預設配置了,但在我們看來,有些場合下把這一選項關掉也是合乎需要的。

       現在讓我們假設某個應用程式發出了一個請求,希望發送小塊資料。我們可以選擇立即發送資料或者等待産生更多的資料然後再一次發送兩種政策。如果我們馬上發送資料,那麼互動性的以及客戶/伺服器型的應用程式将極大地受益。如果請求立即發出那麼響應時間也會快一些。以上操作可以通過設定套接字的TCP_NODELAY = on 選項來完成,這樣就禁用了Nagle 算法。

       另外一種情況則需要我們等到資料量達到最大時才通過網絡一次發送全部資料,這種資料傳輸方式有益于大量資料的通信性能,典型的應用就是檔案伺服器。應用 Nagle算法在這種情況下就會産生問題。但是,如果你正在發送大量資料,你可以設定TCP_CORK選項禁用Nagle化,其方式正好同 TCP_NODELAY相反(TCP_CORK和 TCP_NODELAY是互相排斥的)。      

-------------------------------------------------------------------------------------

 #FastCGI相關參數:為了改善網站性能:減少資源占用,提高通路速度

fastcgi_connect_timeout 300;

fastcgi_send_timeout 300;

fastcgi_read_timeout 300;

fastcgi_buffer_size 64k;

fastcgi_buffers 4 64k;

fastcgi_busy_buffers_size 128k;

fastcgi_temp_file_write_size 128k;

----------------------------------------------

#連接配接逾時時間,機關是秒

  keepalive_timeout 60;

  #開啟gzip壓縮功能

    gzip on;

 #設定允許壓縮的頁面最小位元組數,頁面位元組數從header頭的Content-Length中擷取。預設值是0,表示不管頁面多大都進行壓縮。建議設定成大于1K。如果小于1K可能會越壓越大。

  gzip_min_length  1k;

#壓縮緩沖區大小。表示申請4個機關為16K的記憶體作為壓縮結果流緩存,預設值是申請與原始資料大小相同的記憶體空間來存儲gzip壓縮結果。

  gzip_buffers     4 16k;

#壓縮版本(預設1.1,前端為squid2.5時使用1.0)用于設定識别HTTP協定版本,預設是1.1,目前大部分浏覽器已經支援GZIP解壓,使用預設即可。

  gzip_http_version 1.0;

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

  gzip_comp_level 9;

#用來指定壓縮的類型,“text/html”類型總是會被壓縮

  gzip_types       text/plain application/x-javascript text/css application/xml;

  #vary header支援。該選項可以讓前端的緩存伺服器緩存經過GZIP壓縮的頁面,例如用

Squid緩存經過Nginx壓縮的資料。

gzip_vary off;

#開啟ssi支援,預設是off

  ssi on;

  ssi_silent_errors on;

#設定日志模式

    log_format  access  '$remote_addr - $remote_user [$time_local] "$request" '

                        '$status $body_bytes_sent "$http_referer" '

                        '"$http_user_agent" $http_x_forwarded_for';

#反向代理負載均衡設定部分

#upstream表示負載伺服器池,定義名字為backend_server的伺服器池

upstream backend_server {

    server   10.254.244.20:81 weight=1 max_fails=2 fail_timeout=30s;

    server   10.254.242.40:81 weight=1 max_fails=2 fail_timeout=30s;

    server   10.254.245.19:81 weight=1 max_fails=2 fail_timeout=30s;

    server   10.254.243.39:81 weight=1 max_fails=2 fail_timeout=30s;

  #設定由 fail_timeout 定義的時間段内連接配接該主機的失敗次數,以此來斷定 fail_timeout 定義的時間段内該主機是否可用。預設情況下這個數值設定為 1。零值的話禁用這個數量的嘗試。

設定在指定時間内連接配接到主機的失敗次數,超過該次數該主機被認為不可用。

#這裡是在30s内嘗試2次失敗即認為主機不可用!

  }

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

#基于域名的虛拟主機

  server

  {

#監聽端口

    listen       80;

    server_name  www.abc.com abc.com;    

    index index.html index.htm index.php;    #首頁排序

    root  /data0/abc;                            #站點根目錄,即網站程式存放目錄 

    error_page 500 502 404 /templates/kumi/phpcms/404.html;   #錯誤頁面

#僞靜态   将www.abc.com/list....html的檔案轉發到index.php。。。

#rewrite ^/list-([0-9]+)-([0-9]+)-([0-9]+)-([0-9]+)-([0-9]+)-([0-9]+)-([0-9]+)-([0-9]+)-([0-9]+)\.html$ /index.php?m=content&c=index&a=lists&catid=$1&types=$2&country=$3&language=$4&age=$5&startDate=$6&typeLetter=$7&type=$8&page=$9 last;

#location 标簽,根目錄下的.svn目錄禁止通路

    location ~ /.svn/ {

     deny all;

    }

            location ~ \.php$   

             {  #符合php擴充名的請求排程到fcgi server  

              fastcgi_pass  127.0.0.1:9000;  #抛給本機的9000端口

              fastcgi_index index.php;    #設定動态首頁

              include fcgi.conf;

             }

            allow   219.237.222.30 ;  #允許通路的ip

            allow   219.237.222.31 ;

            allow   219.237.222.32 ;

            allow   219.237.222.33 ;

            allow   219.237.222.34 ;

            allow   219.237.222.35 ;

            allow   219.237.222.61 ;

            allow   219.237.222.28 ;

            deny    all;            #禁止其他ip通路

            }

    location ~ ^/admin.php

         {

            location ~ \.php$

             {

              fastcgi_pass  127.0.0.1:9000;

              fastcgi_index index.php;

              include fcgi.conf;

             }

            allow   219.237.222.30 ;

            allow   219.237.222.31 ;

            allow   219.237.222.32 ;

            allow   219.237.222.33 ;

            allow   219.237.222.34 ;

            allow   219.237.222.35 ;

            allow   219.237.222.61;

            allow   219.237.222.28;

         deny    all;

            }

#将符合js,css檔案的等設定expries緩存參數,要求浏覽器緩存。

location~ .*\.(js|css)?$ {

       expires      30d; #用戶端緩存上述js,css資料30天

    }

     location ~ ^/list {

         #如果後端的伺服器傳回502、504、執行逾時等錯誤,自動将請求轉發到upstream負載均衡池中的另一台伺服器,實作故障轉移。

         proxy_next_upstream http_502 http_504 error timeout invalid_header;

         proxy_cache cache_one;

         #對不同的HTTP狀态碼設定不同的緩存時間

         proxy_cache_valid  200 301 302 304 1d;

         #proxy_cache_valid  any 1d;

         #以域名、URI、參數組合成Web緩存的Key值,Nginx根據Key值哈希,存儲緩存内容到二級緩存目錄内

         proxy_cache_key $host$uri$is_args$args;

         proxy_set_header Host  $host;

         proxy_set_header X-Forwarded-For  $remote_addr;

         proxy_ignore_headers "Cache-Control" "Expires" "Set-Cookie";

         #proxy_ignore_headers Set-Cookie;

         #proxy_hide_header Set-Cookie;

         proxy_pass http://backend_server;

         add_header      Nginx-Cache     "$upstream_cache_status  from  km";

          expires      1d;

        }

    access_log  /data1/logs/abc.com.log access;    #nginx通路日志

  }

-----------------------ssl(https)相關------------------------------------

server {

  listen 13820; #監聽端口

  server_name localhost;

  charset utf-8; #gbk,utf-8,gb2312,gb18030 可以實作多種編碼識别

  ssl on; #開啟ssl

  ssl_certificate /ls/app/nginx/conf/mgmtxiangqiankeys/server.crt; #服務的證書

  ssl_certificate_key /ls/app/nginx/conf/mgmtxiangqiankeys/server.key; #服務端key

  ssl_client_certificate /ls/app/nginx/conf/mgmtxiangqiankeys/ca.crt; #用戶端證書

  ssl_session_timeout 5m; #session逾時時間

  ssl_verify_client on; # 開戶用戶端證書驗證 

  ssl_protocols SSLv2 SSLv3 TLSv1; #允許SSL協定 

  ssl_ciphers ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP; #加密算法

  ssl_prefer_server_ciphers on; #啟動加密算法

  access_log /lw/logs/nginx/dataadmin.test.com.ssl.access.log access ; #日志格式及日志存放路徑

  error_log /lw/logs/nginx/dataadmin.test.com.ssl.error.log; #錯誤日志存放路徑

}

}

##add by 20140321#######nginx防sql注入##########

###start####

if ( $query_string ~* ".*[\;'\<\>].*" ){

    return 444;

    }

if ($query_string  ~* ".*(insert|select|delete|update|count|\*|%|master|truncate|declare|\'|\;|and|or|\(|\)|exec).* ") 

    {  

    return 444; 

    }

if ($request_uri ~* "(cost\()|(concat\()") {

                 return 444;

    }

if ($request_uri ~* "[+|(%20)]union[+|(%20)]") {

                 return 444;

    }

if ($request_uri ~* "[+|(%20)]and[+|(%20)]") {

                 return 444;

    }

if ($request_uri ~* "[+|(%20)]select[+|(%20)]") {

                 return 444;

    }

set $block_file_injections 0;

if ($query_string ~ "[a-zA-Z0-9_]=(\.\.//?)+") {

set $block_file_injections 1;

}

if ($query_string ~ "[a-zA-Z0-9_]=/([a-z0-9_.]//?)+") {

set $block_file_injections 1;

}

if ($block_file_injections = 1) {

return 448;

}

set $block_common_exploits 0;

if ($query_string ~ "(<|%3C).*script.*(>|%3E)") {

set $block_common_exploits 1;

}

if ($query_string ~ "GLOBALS(=|\[|\%[0-9A-Z]{0,2})") {

set $block_common_exploits 1;

}

if ($query_string ~ "_REQUEST(=|\[|\%[0-9A-Z]{0,2})") {

set $block_common_exploits 1;

}

if ($query_string ~ "proc/self/environ") {

set $block_common_exploits 1;

}

if ($query_string ~ "mosConfig_[a-zA-Z_]{1,21}(=|\%3D)") {

set $block_common_exploits 1;

}

if ($query_string ~ "base64_(en|de)code\(.*\)") {

set $block_common_exploits 1;

}

if ($block_common_exploits = 1) {

return 444;

}

set $block_spam 0;

if ($query_string ~ "\b(ultram|unicauca|valium|viagra|vicodin|xanax|ypxaieo)\b") {

set $block_spam 1;

}

if ($query_string ~ "\b(erections|hoodia|huronriveracres|impotence|levitra|libido)\b") {

set $block_spam 1;

}

if ($query_string ~ "\b(ambien|blue\spill|cialis|cocaine|ejaculation|erectile)\b") {

set $block_spam 1;

}

if ($query_string ~ "\b(lipitor|phentermin|pro[sz]ac|sandyauer|tramadol|troyhamby)\b") {

set $block_spam 1;

}

if ($block_spam = 1) {

return 444;

}

set $block_user_agents 0;

if ($http_user_agent ~ "Wget") {

 set $block_user_agents 1;

}

# Disable Akeeba Remote Control 2.5 and earlier

if ($http_user_agent ~ "Indy Library") {

set $block_user_agents 1;

}

# Common bandwidth hoggers and hacking tools.

if ($http_user_agent ~ "libwww-perl") {

set $block_user_agents 1;

}

if ($http_user_agent ~ "GetRight") {

set $block_user_agents 1;

}

if ($http_user_agent ~ "GetWeb!") {

set $block_user_agents 1;

}

if ($http_user_agent ~ "Go!Zilla") {

set $block_user_agents 1;

}

if ($http_user_agent ~ "Download Demon") {

set $block_user_agents 1;

}

if ($http_user_agent ~ "Go-Ahead-Got-It") {

set $block_user_agents 1;

}

if ($http_user_agent ~ "TurnitinBot") {

set $block_user_agents 1;

}

if ($http_user_agent ~ "GrabNet") {

set $block_user_agents 1;

}

if ($block_user_agents = 1) {

return 444;

}

###end####