NGINX安全配置和限制訪問

提及網絡***,可能不少人只知道大名鼎鼎的DDOS***,這種***廉價且效果出衆,直接經過第四層網絡協議用他的帶寬把你的帶寬頂掉,形成網路阻塞,防不勝防,就連騰訊這種大鱷公司也被大流量DDOS搞過焦頭爛額。暫時的解決方法只有三種,第一種就是你要夠有錢,買強大的高級防火牆,或者使用的帶寬足夠大,無視這些網絡流量。第二種是技術足夠強,例如個別有技術的大牛公司(阿里),用類如DPDK的高效數據包處理驅動,開發出流量清洗服務,把垃圾網絡包過濾掉,不過同時也會影響正常的網絡包,增長延時。第三種就是錢很少的公司多數使用的方案,換ip(廢話)。不過,如今有不少公司推出本身的流量清洗服務,細化到按小時收費,也是至關靈活了,按需購買。javascript

不過還有一種網絡***其實比起DDOS更頻繁出現,就是CC(Challenge Collapsar)***,通常來講是利用網站代碼漏洞,不停地發大量數據包請求,形成對方服務器迴應這些請求致使資源耗盡,一直到宕機崩潰。這種***屬於第七層的網絡協議,一方面在服務器層面是正常的請求,因此這種狀況想根本解決問題,只能從代碼入手。可是另外一方面,也就能夠用其餘來限制他訪問,例如nginx的配置上也是能稍微防一下。php


nginx基本安全配置css

先說一些基本安全設置,由開始發展到如今,其實nginx的安全作得比之前已經好很多,不過有些仍是要強調一下。html

Nginx默認是不容許列出整個目錄的,不過,咱們爲了安全,最好仍是確認這個真的關閉了,否則代碼被拉走了就悲劇了。java

http {
autoindex off;
}

nginx默認是會在返回的數據包中顯示版本號,本來這個並非大問題,可是被別有用心的人專門***這個版本的話,那就很差了,因此,咱們仍是隱藏好一點。node

http {
server_tokens off;
}

其餘限制訪問請求參數nginx

http {
#設置客戶端請求頭讀取超時時間,超過這個時間尚未發送任何數據,Nginx將返回「Request time out(408)」錯誤
client_header_timeout 15;
#設置客戶端請求主體讀取超時時間,超過這個時間尚未發送任何數據,Nginx將返回「Request time out(408)」錯誤
client_body_timeout 15;   
#上傳文件大小限制
client_max_body_size 100m;
#指定響應客戶端的超時時間。這個超過僅限於兩個鏈接活動之間的時間,若是超過這個時間,客戶端沒有任何活動,Nginx將會關閉鏈接。
send_timeout    600;
#設置客戶端鏈接保持會話的超時時間,超過這個時間,服務器會關閉該鏈接。
keepalive_timeout 60;
}

毫無疑問,nginx是能夠作訪問限制的,allow就是容許訪問的ip和ip段,deny就是禁止訪問的ip和ip段,不過這個須要看你網站的需求,如今滿天飛的家用寬帶IP,誰敢說IP一直是那一個。web

#設置網站根目錄的訪問權限
location / {
    allow 192.168.1.1/24;
    allow 120.76.147.159;
    deny 119.23.19.240;
    deny 192.168.3.1/24;
    deny all;
}

因此,咱們再細化一點,限制訪問個別目錄或文件後綴名。算法

#在訪問uploads、p_w_picpaths目錄時,訪問php|php5|jsp後綴的文件會返回403代碼,也就是不給執行代碼了
location ~ ^/(uploads|p_w_picpaths)/.*\.(php|php5|jsp)$ {
    allow 192.168.1.1/24;
    return 403;
}
#禁止訪問全部目錄下的sql|log|txt|jar|war|sh|py後綴的文件,這些是什麼文件就不詳細說了。
location ~.*\.(sql|log|txt|jar|war|sh|py) {
    deny all;
}
#有時候,有些訪問記錄不想保存到日誌裏面,例如靜態圖片
location ~ .*\.(js|jpg|JPG|jpeg|JPEG|css|bmp|gif|GIF|png)$ {
    access_log off;
}
#若是想用戶體驗好一點,能夠創建一個報錯頁面,而後讓這個頁面跳轉到其餘頁面
error_page 403 http://www.example.com/errorfile/404.html;

再高級一點,判斷特定條件,而後拒絕服務sql

#判斷當http_user_agent返回的結果中包含UNAVAILABLE關鍵字,則返回403錯誤。
location / {
    if ($http_user_agent ~ UNAVAILABLE) {
    return 403;
    }
}

再次強調,這些要跟網站實際狀況相結合,要否則影響範圍被擴大,形成一些莫名其妙的事,那可不是好事,不過通常403都是本身控制,比較好判斷,因此最好別直接deny all。


nginx高級安全配置

訪問權限控制:

想更精準控制訪問權限,其實還有auth_basic指令,用戶必須輸入有效的用戶名和密碼才能訪問站點。而用戶名和密碼應該列在 auth_basic_user_file指令設置的文件中。

server {
    ...
    auth_basic "closed website";
    auth_basic_user_file conf/htpasswd;
}

auth_basic的off參數能夠取消驗證,好比對於一些公共資源,則能夠取消驗證。

server {
    ...
    auth_basic "closed website";
    auth_basic_user_file conf/htpasswd;
    location /public/ {
        auth_basic off;
    }
}

咱們還需使用satisfy指令來組合來使用IP訪問和Http驗證。 其默認設置爲all,即IP訪問和HTTP驗證同時經過時才容許用戶訪問,若設置爲any,即IP訪問和HTTP驗證其一經過就容許用戶訪問

location / {
    satisfy any;
    allow 192.168.1.0/24;
    deny  all;
    auth_basic           "closed site";
    auth_basic_user_file conf/htpasswd;
}

這樣弄好像變得有點複雜,因此仍是得看需求。

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

鏈接權限控制:

實際上nginx的最大鏈接數是worker_processes乘以worker_connections的總數。

也就是說,下面的這個配置,就是4X65535,通常來講,咱們會強調worker_processes設置成和核數相等,worker_connections並無要求。可是同時這個設置其實給了***者空間,***者是能夠同時發起這麼多個鏈接,把你服務器搞跨。因此,咱們應該更合理的配置這兩個參數。

user  www;
worker_processes  4;
error_log  /data/logs/nginx_error.log  crit;
pid        /usr/local/nginx/nginx.pid;
events {
        use epoll;
        worker_connections 65535;
}

不過,也不是徹底沒有辦法限制,在nginx0.7開始,出了兩個新的模塊:

HttpLimitReqModul:    限制單個 IP 每秒請求數

HttpLimitZoneModule:     限制單個 IP 的鏈接數

這兩個模塊,要先在http層定義,而後在 location, server, http上下文中做限制,他們用的是限制單ip訪問的漏桶算法,也就是說超過定義的限制會報503錯誤,這樣爆發的cc***就所有被限制住了。固然,有些時候多是某個公司同一個ip有幾十人一塊兒訪問網站,這是有可能被誤傷的,作好503報錯回調是頗有必要的。

先看HttpLimitReqModul:

http {
    limit_req_zone $binary_remote_addr zone=test_req:10m rate=20r/s;
     …
     server {
         …
         location /download/ {
            limit_req zone=test_req burst=5 nodelay;
         }
     }
}

上面http層的就是定義,這是一個名爲test_req的limit_req_zone空間,用來存儲session數據,大小是10M內存,1M大約能夠存16000個ip回話,看你訪問量有多少就設多少。以$binary_remote_addr 爲key,這個定義是客戶端IP,能夠改爲$server_name等其餘,限制平均每秒的請求爲20個,寫成20r/m就是每分鐘了,也是看你訪問量。

下面location層就是應用這個限制了,對應上面的定義,對訪問download文件夾的請求,限制每一個ip每秒不超過20個請求,漏桶數burst爲5,brust的意思就是,若是第1,2,3,4秒請求爲19個,第5秒的請求爲25個是被容許的。可是若是你第1秒就25個請求,第2秒超過20的請求返回503錯誤。nodelay,若是不設置該選項,第1秒25個請求時,5個請求放到第2秒執行,設置nodelay,25個請求將在第1秒執行。

就這個限制定義而言,把每一個IP限制了請求數,對於海量的cc請求***,效果明顯,例如限制到1r/s每秒一次請求,那就更明顯了,不過也正如開頭所說,對於大公司多人統一IP同時訪問,不免出現誤傷,因此仍是得多考慮。

而後再看HttpLimitZoneModule:

http {
  limit_conn_zone test_zone $binary_remote_addr 10m;
   server {
    location /download/ {
      limit_conn test_zone 10;
      limit_rate 500k;
    }
  }
}

和上面的相似,上面http層就是總定義,這是一個名爲test_zone的limit_conn_zone空間,大小也是10M,key仍是客戶端IP地址,不過這個沒有限制次數,改下面定義去了。

下面location層就是真正定義了,由於key定義是客戶端ip,因此limit_conn就是一個IP限制了10個鏈接,若是是$server_name,那就是一個域名10個鏈接。而後下面limit_rate就是限制一個鏈接的帶寬,若是一個ip兩個鏈接,就是500x2k,這裏是10,那就是最多能夠有5000K速度給到這個ip了。

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

嫌棄503用戶體驗很差,也能夠加個返回頁面:
error_page   503   /errpage/503.html;
503頁面的源代碼:

<html>
<head>
<title>頁面即將載入….</title>
<meta http-equiv=content-type c>
<META NAME=」ROBOTS」 C>
</head>
<body bgcolor=」#FFFFFF」>
<table cellpadding=」0″ cellspacing=」0″ border=」0″ width=」700″ align=」center」 height=」85%」>
  <tr align=」center」 valign=」middle」>
    <td>
    <table cellpadding=」10″ cellspacing=」0″ border=」0″ width=」80%」 align=」center」 style=」font-family:
Verdana, Tahoma; color: #666666; font-size: 11px」>
    <tr>
      <td valign=」middle」 align=」center」 bgcolor=」#EBEBEB」>
        <br /><b style=」font-size: 16px」>頁面即將載入</b>
        <br /><br />你刷新頁面的速度過快。請少安毋躁,頁面即將載入…
        <br /><br />[<a href="JavaScript:window.location.reload();"><font color=#666666>當即從新載入</font></a>]
        <br /><br />
      </td>
    </tr>
    </table>
    </td>
  </tr>
</table>
</body>
</html>
<SCRIPT language=javascript>
function update()
{
  window.location.reload();
}
setTimeout(「update()」,2000);
</script>

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

上述的配置,是全網通用得,有時候不免有誤傷,那怎麼辦呢,能夠設置白名單制度。

#geo指令定義了一個白名單$whiteiplist變量,默認值爲1,
#若是客戶端ip在上面的範圍內,$whiteiplist的值爲0。
geo $whiteiplist  {
    default 1;
    10.11.15.161 0;
    127.0.0.1/32 0;
    }
#使用map指令映射上面geo匹配的客戶端的ip爲空串,若是不是就顯示自己真實的ip,
#這樣匹配的ip就不能存到limit_req_zone內存session中,因此不會被限制訪問    
map $whiteiplist  $limit {
    1 $binary_remote_addr;
    0 "";
    }
#而後再製定這個$limit變量來設置規則,白名單制度就創建起來了
limit_req_zone $limit zone=one:10m rate=10r/s;
limit_conn_zone $limit zone=addr:10m;
相關文章
相關標籤/搜索