通路控制
通路控制是網絡安全防範和保護的主要政策,其任務是保證網絡資源不被非法通路。Nginx作為Web伺服器的後起之秀,也提供了通路控制的功能。它可以根據實際需求,對使用者可以通路和禁止的目錄進行限制。下面将對Nginx提供的權限控制指令以及典型的應用進行詳細講解。
權限控制指令
Nginx中提供了兩個用于配置通路權限控制的指令,分别為
allow和deny
。從其名稱就可以看出,allow用于設定允許通路的權限deny用于設定禁止通路的權限。在使用時,權限指令後隻需跟上允許或禁止的IP、IP段或all即可。其中,all表示所有的。
權限控制指令的使用雖然簡單,但是在設定的過程中,還需要特别注意以下幾個點。
- 單個IP指定作用範圍最小,all指定作用範圍最大。
- 同一塊下,若同時存在多個權限指令(deny、allow),則先出現的通路權限設定生效,并且會對後出現的設定進行覆寫,未覆寫的範圍依然生效,否則以先出現的設定用古好為準。
- 當多個塊(如http、server、location)中都出現了權限設定指令,則内層塊中的權限級别要比外層塊中設定的權限級别高。
1. 禁止所有使用者通路:
需要注意的是,在server塊下設定deny all後,伺服器内的用戶端軟體在通路自己時也會出現403Forbidden。是以,在設定時需要慎重考慮。
2. 隻允許指定使用者通路:
allow 192.158.78.128
deny all;
上述指令表示隻允許192.168.78.128用戶端通路,其他所有用戶端都不能通路。利用之前準備的兩個用戶端可以進行測試。需要注意的是,若省略此處的denyall,則會允許所有用戶端通路;若将deny all 移動到allow 192. 168. 78. 128之後,則會阻止所有用戶端.通路。
從上述規律看出,同一個塊下的兩個權限指令,先出現的設定會覆寫後出現的設定,使得allow 192. 168. 78. 128的配置優先生效;同時deny指令設定的通路範圍all 較大,未被allow覆寫的範圍配置依然生效,達到除了IP為192. 168. 78. 128的使用者外,禁止其他使用者對伺服器通路的效果。
3. 不同塊間的全下指令優先級:
http{
...
deny all;
server{
listen 80;
server_name localhost;
root html;
index index.tml index.html;
}
}
此時,會禁止所有使用者對http塊的通路。
在server塊中加入
allow all;
http{
...
deny all;
server{
listen 80;
server_name localhost;
root html;
index index.tml index.html;
allow all;
}
}
修改後,所有使用者都可以通路server塊。這是由于Nginx配置檔案中的各個塊在嵌套的情況下,内層塊内的指令比外層塊内的指令執行優先級高。是以,當内外層塊中同時出現權限指令時,則内層塊中的allow all 會覆寫外層塊中的deny all 的設定。
通路控制典型應用
在實際應用中,權限控制的需求更加複雜。例如,對于網站下的img目錄允許所有使用者通路,但對于網站下的admin目錄則僅允許管理者身份的使用者通路。此時,僅靠deny和allow這兩個權限指令不能滿足使用者的需求,還需要使用location塊來完成相關需求的比對。
在此之前,首先要簡單了解一下location 的相關文法及規定,具體如下:
#文法類型1
location [= | ~ | ~ * | ^~] URI {...}
#文法類型2
location @name {...}
在上述文法中,
=、~、~ *、^~和@
都是location 用于實作通路控制的字首,且在使用時隻能選擇一種,當然也可以不設定字首。其中,關于location字首的含義如下圖所示。
URI
表示URL位址中從域名到參數之間的部分,
{ ... }
表示指令塊,用于滿足location 比對條件後需要執行的指令。
1. 精準比對:
所謂精準比對指的就是使用者通路的URI與指定的URI完全一緻的情況,才會執行其後的指令塊,示例配置如下:
server{
listen 80;
server_name localhost;
root html;
index index.html index.htm;
location =/js{ ###6
allow 192.168.78.128;
}
location =/admin/auth { ###9
allow 192.168.78.200;
}
deny all;
}
的上述第
6~8行和第9~11
行配置設定了兩個精準比對,第12行用于禁止所有使用者的通路。當上述配置中允許通路的兩個用戶端,請求網站根目錄下不存在的檔案或目錄時,如果符合比對規則,網頁顯示404NotFound,不符合時顯示403Forbidden。
假設網站根目錄下沒有任何檔案,下面使用IP為192. 168. 78.128的A使用者和IP為192. 168. 78. 200的B使用者通過不同的URL進行通路測試,其對應的響應結果如下所示。
精準比對是隻有使用者請求的URI與location中定義的比對模式完全一緻的情況下,才會執行其後的指令塊,否則比對不成功。
2. 正則比對:
Nginx配置檔案中,多個正則location之間按照正則location在配置檔案中的書寫順序進行比對,且隻要比對成功就不會繼續比對後面定義的正則location。下面在IP為192.168.78.3的虛拟機中,設定以下兩個正則location通路控制,具體如下:
location ~\.html$ {
allow all;
}
location ~^/aaa/.*\.html$ {
deny all;
}
在上述配置中,第1行表示比對網站根目錄下以.html結尾的檔案,第4行表示比對網站根目錄下aaa目錄中以.html結尾的檔案。
下面使用IP為192.168.78.128的使用者通過不同的URL進行通路測試,其對應的響應結果如下:
當location中的URI與使用者請求中以
.html
為結尾的檔案比對上時,正則location停止了繼續比對,是以顯示結果都為404NotFound。
接下來,
調換第1~3行與第4~6行代碼的編寫順序
,再次通路http://192.168.78.3/test. html結果依然為404 Not Found,而通路http://192. 168. 78. 3/aaa/test. html的結果為403 Forbidden。
從上述兩組測試對比可總結出,
正則location的編寫順序不同,則結果不同,且隻有前面定義的正則location比對不成功的情況下,才會繼續比對後面的正則location
。是以,讀者在實際應用中要注意正則location在配置檔案中的書寫順序。
3. 最大字首比對:
由于location可以同時定義多個,當一個配置檔案中同時出現多個location 時,普通location之間遵循“最大字首比對"原則。通俗地講就是,比對度最高的location将會執行,示例如下:
location /ng.test {
allow all;
}
location /ng.test/log {
deny all;
}
注意:
當最大字首location與正則location同時存在時,如果正則location比對成功,則不會執行最大字首location。具體示例如下。
location / {
deny all;
}
location ~\.html$ {
allow all;
}
location / {}
與
location =/ {}
的差別:
location/ {}遵守普通location 的最大字首比對,由于任何URI都必然以“/”根開頭,是以對于一個URI ,若配置檔案中有更合适的比對則會将其替代,否則傳回location/ {}比對到的結果,它相當于站點預設配置。
而location=/ {}遵守的是精準比對,也就是隻能比對該站點根目錄,同時會禁止繼續搜尋正則location,效率比location/ {}要高。是以,若在開發中能确定精準比對的情況,可以采用location =/ {}的方式,提升比對效率。
4. 禁用正則比對:
利用=精準比對或^~非正則比對可以在正則比對之前優先比對,進而禁止執行原有的正則比對。下面在server塊中添加以下幾條location比對規則,具體如下:
location =/aaa/test.html {
allow all;
}
location ^~/ {
deny all;
}
location ~\.html$ {
allow all;
}
在上述配置中,第1行僅用于精準比對網站根目錄下的1aaa/test.html,第4行用于非.正則比對網站根目錄下的檔案,第7行用于正則比對網站根目錄下以. html為結尾的檔案。
接下來通過不同URL進行通路測試,具體如上表所示。從表中的響應結果可以看出,在使用了“=”或“^~”字首時,普通location比對後将不再執行正則location的比對。
值得一提的是,
字首“一”和“^~”雖然都能阻止繼續搜尋正則location,不同的地方是它們遵循的規則不同,“^~”依然遵循最大字首比對規則,而=則嚴格按照精準比對執行
。亦i是以,當多種類型的location比對同時出現時,最終執行結果為“=”比對優先于
“^~”
比對,
“^~”
比對優先于正則比對,正則比對優先于普通的最大字首比對。隻要優先的location比對成功,就不會執行其他的location。
root 與 alias的差別:
在location中指定目錄時,除了可以使用root 指令外,還可以使用alias 指令完成。兩者在使用時有一定的差別,具體示例如下:
#當收到"/img/ithemima.png"請求時,将請求映射為"/var/www/image/itheima.png"
location /img/ {
alias /var/www/image/;
}
#當收到"/img/ithemima.png"請求時,将請求映射為"/var/www/image/img/itheima.png"
location /img/ {
root /var/www/image;
}
從上述示例可以看出,alias在映射路徑時不會追加location 比對到的部分,而root 追加了location比對到的部分。