Nginx基礎知識點彙總2

項目中實現對 web 應用程序或 web 應用程序子系統的訪問控制是項目的重要
組成。實現 NGINX 的訪問控制形式多樣,比如從網絡層面實現訪問控制,允許
NGINX 採用身份校驗機制,或 通過 HTTP 響應引導瀏覽器如何操作。本章將討
論使用網絡屬性(network attributes)、身份認證、跨域資源共享(CORS:
Cross-Origin Resource Sharing)原則等安全控制知識。

問題
需要基於客戶端的 IP 地址實現訪問控制功能
解決方案
使用 HTTP 的 access 模塊,實現對受保護資源的訪問控制:

location /admin/ {
	deny 10.0.0.1;
	allow 10.0.0.0/20;
	allow 2001:0db8::/32;
	deny all;
}

給定的 location 塊級指令中配置了允許除 10.0.0.1 外的所有 10.0.0.0/20 IPv4
地址訪問,同時允許 2001:0db8::/32 及其子網的 IPv6 地址訪問,其它 IP 地址
的訪問將會收到 HTTP 狀態爲 403 的響應。allow 和 deny 指令可在 HTTP、server、
location 上下文中使用。控制規則依據配置的順序進行查找,直到匹配到控制規則。

結論
需要控制訪問的資源需要實現分層控制。NGINX 服務器提供對資源進行分層控
制的能力。deny 指令會限制對給定上下文的訪問,allow 指令與 deny 功能
相反,它們的值可以是定值 IP 地址、IPv4 或 IPv6 地址、無類別域間路由(
CIDR: Classless Inter-Domain Routing)、關鍵字或 UNIX 套接字。IP 限制
的常用解決方案是,允許一個內部的 IP 地址訪問資源,拒絕其它所有 IP 地
址的訪問來實現對資源的訪問控制。

問題
項目資源部署在其它域名,允許跨域的訪問請求使用這些資源。
解決方案
通過對不同請求方法設置對應的 HTTP 消息頭實現跨域資源共享:


```java
map $request_method $cors_method {
	OPTIONS 11;
	GET 1;
	POST 1;
	default 0;
}
server {
...
	location / {
		if ($cors_method ~ '1') {
			add_header 'Access-Control-Allow-Methods' 'GET,POST,OPTIONS';
			add_header 'Access-Control-Allow-Origin' '\*.example.com';
			add_header 'Access-Control-Allow-Headers'
						'DNT,
						Keep-Alive,
						User-Agent,
						X-Requested-With,
						If-Modified-Since,Cache-Control,
						Content-Type';
	}
		if ($cors_method = '11') {
			add_header 'Access-Control-Max-Age' 1728000;
			add_header 'Content-Type' 'text/plain; charset=UTF-8';
			add_header 'Content-Length' 0;
			return 204;
		}
	}
}

結論
當請求的資源不屬於當前域名時,就會產生一個跨域的請求,比如 JavaScript 請求其它域名的資源變產生跨域請求。當跨域請求產生,瀏覽器則必須遵守跨域資源共享(CORS)規則,此時瀏覽器便不會引用這些跨域的資源,除非,檢測到給定的允許使用非同源資源的 HTTP 消息頭。爲滿足子域名間能夠跨域使用資源,我們需要使用 add_header 指令設置對應的 CORS 消息頭。如果,一個 HTTP 請求是標準的 GET、POST 或 HEAD 請求且並未設置特定的消息頭,瀏覽器就回對請求和源域名進行檢測。Other request methodswill cause the browser to make the preflight request to check the
terms of the server to which it will obey for that resource.如果沒有實現對特定請求消息頭的配置,瀏覽器在獲取跨域資源時,則會拋出錯誤禁止應用跨域資源。

問題
基於給定的規則如 IP 地址,實現請求連接數。
解決方案
使用 limit_conn_zone 指令構建存儲當前連接數的內存區域;然後,使用 limit_conn 指令設置支持的連接數:

http {
	limit_conn_zone $binary_remote_addr zone=limitbyaddr:10m;
	limit_conn_status 429;
	...
	server {
	...
		limit_conn limitbyaddr 40;
	...
	}
}

配置中創建了一個名爲 limitbyaddr 的存儲容量爲 10 M 的共享內存,鍵名則爲客戶端二進制的 IP 地址。limit_conn 指令接收兩個參數:一個是 limit_conn_zone 創建的名稱 limitbyaddr,和支持的連接數40。limit_conn_status 指令定義了當連接數超過 40 個時的響應狀態碼。limit_conn 和 limit_conn_status 指令能夠在 HTTP、server 和 location 上下文中使用。

結論
合理使用連接數限制,可以是服務器的資源被各個客戶端合理使用。使用的關鍵在於定義一個合理的存儲鍵名。本例中基於 IP 地址作爲存儲鍵名不是一個好的選擇,因爲,一旦有許多用戶通過同一網絡訪問服務,便會限制該 IP地址的所有用戶的訪問連接數,這很不合理。limit_conn_zone 僅在 http 上下文中可用可以使用所有的 NGINX 變量來構建限制鍵名。通過使用能夠識別用戶會話的變量如 cookie,有利於合理使用連接控制功能。limit_conn_status 默認狀態碼是 503 服務不可用。例子中使用 429 因爲服務是可用的,而 500 級的響應碼錶示服務器內部錯誤,而 400 級的響應碼錶示客戶端錯誤。

問題
依據某些規則對用戶請求進行限速,如通過用戶 IP 地址進行限速。
解決方案
利用 rate-limiting 模塊實現對請求限速:

http {
	limit_req_zone $binary_remote_addr zone=limitbyaddr:10m rate=1r/s;
	limit_req_status 429;
...
	server {
...
	limit_req zone=limitbyaddr burst=10 nodelay;
...
	}
}

實例中,創建了一個 10 M 存儲空間的名爲 limitbyaddr 的共享內存,並使用二進制的客戶端 IP 地址作爲鍵名。limit_req_zone 還設置了訪問速度。limit_req 指令主要包含兩個可選參數:zone 和 burst。zone 參數值即爲limit_req_zone 指令中 zone 參數定義的存儲空間名。當用戶請求超出限速設置時,超出的請求將會存儲至 burst 定義的緩衝區,直至也超出請求限速緩衝速率,這是將響應 429 狀態碼給客戶端。burst 參數默認值爲 0。此外,limit_req還有第三個參數 nodelay:它的功能是提供瞬時處理 rate + burst 個請求的能力。limit_req_status 參數用於設置超出速率請求響應給客戶端的狀態碼,默認是 503,示例中設置爲 429。limit_req_status 和 limit_req 指令適用於 HTTP、server 和
location 上下文。limit_req_zone 指令僅能在 HTTP 上下文中使用。

結論
rate-limiting 模塊在項目中非常有用,通過防止瞬間爆發的請求,爲每個用戶提供高質量的服務。使用限速模塊有諸多理由,其一是處於安全方面考慮。如在登錄頁面設置嚴格的限速控制,拒絕暴力攻擊。如果沒有依據用戶實現限速功能,可能會導致其他用戶無法使用服務或浪費了服務器資源。rate-limiting 模塊有點類似上一章節中講解的限制連接模塊。限速設置可以依據每秒限速,也可依據每分鐘進行限速。當用戶請求滿足限速條件時,請求將被記入日誌中。另外,還有一條指令沒有在示例中出:limit_req_log_level 指令設置限速日誌級別,它默認值爲 error級別,您還可以設置爲 info、notice 或 warn 級別。

問題
需要依據客戶端,限制它們下載速度
解決方案
使用 NGINX 服務器的 limit_rate 和 limit_rate_after 指令實現客戶端響應速度:

location /download/ {
	limit_rate_after 10m;
	limit_rate 1m;
}

location 塊級指令設置了對於匹配 /download/ 前綴的 URI 請求,當客戶端下載數據達到 10 M以後,對其下載速度限制在 1 M 以內。不過該帶寬限制功能僅僅是針對單個連接而言,因而,可能實際使用中需要配合使用連接限制和帶寬限制實現下載限速。

結論
limit_rate_after 和 limit_rate 使 NGINX 能夠以您指定的方式在所有客戶端上共享其上傳帶寬。limit_rate 和 limit_rate_after 指令可在幾乎所有的上下文中使用,如 http、server、location、location 指令內的 if 指令,不過 limit_rate 指令還可以通過 $limit_rate 變量來設置帶寬。limit_rate_after 指令表示在客戶端使用多少流量後,將啓用帶寬限制功能。
limit_rate 指令默認限速單位爲字節(byte),還可以設置爲 m (兆字節) 和g (吉字節)。這兩條指令的默認值都是 0,表示不對帶寬進行任何限制。另外,該模塊提供以編碼方式對客戶端帶寬進行限速。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章