如何在兩層伺服器的第二層Nginx上取得使用者IP
一.之前在做nginx的伺服器設定的時候遇到了一個問題,在之前伺服器有用到一個限制客戶端最大並發連線的功能,而且這個功能的實作是依靠在伺服器中做
$remote-addr
這樣的設定來達到的。但在增加了前端一層(負載、CDN、防火牆、安全服務)伺服器之後,拿到的客戶端IP就都變成了前端伺服器的IP,但並非真是真是的用戶IP位址。
二.這樣的問題下,我又重新看了幾次nginx官網的介紹,也發現其中另外一個特別重要的變數
$proxy_add_x_forwarded_for
這個變數是客戶端存取請求中的X-forwarded-for 欄位的值,如果請求中不包含這個字段,則自動用這個變數會等價於remote-addr這個變數。這允許我們獲取HTTP請求中通常情況下前端伺服器保存的客戶真實IP位址的字段,通常就是我們說的X_FORWARDED_FOR字段,然後透過這樣的方法,我們就可以實現各種各樣的功能了。
三.下面我來實際為大家做一個簡單示範。諸多不足,歡迎指正。
首先我們先搭建好Nginx的環境,這裡我們使用1.7 系列的最新版本1.7.9為例,(關於版本的問題請參考FAQ 1)
下載、WGET所需網址http://nginx.org/ download/nginx-1.7.9.tar.gz
1. 下載Nginx
[lugt@localhostmysql]$ wget http://nginx.org/download/nginx-1.7.9.g
[lugt@localhostmysql]$ tar zxvf nginx-1.7.9.tar.gz
3. 直接編譯(需考慮是否需要openssl等外掛程式的支援)
[mydft點🕎 9
[lugt@localhost nginx-1.7.9]$ ./configure
[lugt@localhost nginx-1.7.9]$ make
[lugt@localhost nginx-1.7.9]$ su localhostnginx-1.7.9]$ make install
4. 接著接下來修改nginx.conf設定檔
[lugt@localhost nginx-1.7.9]$ su
[lugt@localhost nginx-1.7.9]$ suhost
/usr/local/nginx[lugt@localhostnginx]$ vi conf/nginx.conf然後在nginx.conf 中找到這裡,加入來設定負載均衡,模仿CDNupstream dnsnginx1 { server[*.*.*.*/yourhostname]:8080 weight=10000; #填IP、域名 } server { listen 80; server_name #access_log logs/host.access.log main location /{ proxy_pass http://dnsnginx1; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header HTTP_X_FORWARDED_FOR $remote_addr; proxy_redirect default; } }
在設定一個虛擬伺服器在8080端口,
limit_conn_zone $proxy_add_x_forwarded_for zone=addr:10m; # 并发设置 空间10M server { listen 8080; server_name [*.*.*.*/yourhostname]:8080 weight=10000; #填IP、域名 limit_conn addr 1; #限制客户端最大并发连接数为 1 location / { root html; index index.html index.htm; } }保存。接著測試設定檔語法
[lugt@localhostnginx]$ ./sbin/nginx –t啟動伺服器 [lugt@localhostnginx]$
使用ab 工具查看效果。
[lugt@localhost nginx]$ ab –c 10 –n 100 –v 4 http://127.0.0.1/ | grep HTTP/1.1
這行的意思:透過AB測試工具存取位址,並發連線數為30,總測試300次,顯示HTTP返回頭資訊
透過ab 工具可以測出無論同時發送多少連接,最後成功返回200的只有之前限制nginx的最大並發連接數,所以可以證明對於IP的限制功能已經可以使用了。參考資料請見FAQ2
FAQ 1 版本問題
如果目前正在使用的Nginx版本沒有達到1.7.1版本,很可能nginx還不支援這個功能,
這時候就需要透過一段程式碼夾在limit_conn_handler函數中來從request取得x_forwarded_for 的值。
以1.6.1版本為例,程式碼增加如下。 src/http/modules/ngx_http_limit_conn.c 第184行
hash =ngx_crc32_short(key.data, key.len); If(“” == &ctx->key){ <span style="white-space:pre"> </span>If(NULL!= r->main->headers_in->x_forwarded_for->elts){ key.data= *(char*)r->main->headers_in->x_forwarded_for->elts; key.len = 4; hash =ngx_crc32_short(key.data, key.len); <span style="white-space:pre"> </span>} }FAQ 2 參考數據
這裡是一份參考數據, 獲取
[lugt@localhost~]$ ab -c 10 -n 100 -v 4 http://127.0.0.1/ | grep HTTP/1.1
HTTP/1.1503 Service Temporarily Unavailable
HTTP/1.1503 Service Temporarily Unavailable
HTTP/1.1503 Service Temporarily Unavailable
HTTP/1.1503 Service Temporarily Unavailable
HTTP/1.1503 Service Temporarily Unavailable
HTTP/1.1503 Service Temporarily Unavailable
HTTP/1.1503 Service Temporarily Unavailable
503 Service Temporarily UnavailableHTTP/1.1 200 OKHTTP/ 1.1503 Service Temporarily UnavailableHTTP/1.1503 Service Temporarily UnavailableHTTP/1.1503 Service Temporarily Unavailable
HTTP/1.1503 Service Temporarily Unavailable
HTTP/1.1503 Service Temporarily Unavailable
HTTP/1.1503 Service Temporarily Unavailable
HTTP/1.1503 Service Temporarily Unavailable
HTTP/1.1503 Service Temporarily Unavailable
HTTP/1.1503 Service Temporarily Unavailable
HTTP/1.1 200 OK
English Version
How to retrievethe true ip of the client user if there are two layers of servers
Days before, wehave been faced such a difficulty which is we can’t use the variable $remote_addr for gathering the clients’ip address. This problem surfaces when we used a proxy server between the trueserver and client, which is actually a cdn. And that makes our functions oflimiting the maximum connections a client can make to a server at a time. Thissituation can also found if the load balance or any anti-spam service are inuse. So that’s why we can’t use remote_addr variable further.
After I did someresearch on the documentation and the code , I found out that this problem canbe solved by replacing the
$remote_addr
variable with the
$proxy_add_x_forwarded_forvariable. As this variable allows to retrievethe data from the column X_forwarded_for from the request, we can use thisvariable functioning in many ways.
And now I shall makean easy example to practically use this method.
First of all,build up a Nginx server.
Here, I will usethe 1.7.9 version (latest to the written time) for instance, therefore, thereexist some differences between older versions than 1.7.1 (see FAQ 1)
1. Download A Nginx Copy:
[lugt@localhostmysql]$ wget http://nginx.org/download/nginx-1.7.9.tar.gz
2. Decompress the file
[lugt@localhostmysql]$ tar zxvf nginx-1.7.9.tar.gz
3. Compile The Code
[lugt@localhostmysql]$ cd nginx-1.7.9
[lugt@localhostnginx-1.7.9]$ ./configure
[lugt@localhostnginx-1.7.9]$ make
[lugt@localhostnginx-1.7.9]$ su
[lugt@localhostnginx-1.7.9]$ make install
4. And edit the config file nginx.conf
[lugt@localhost nginx-1.7.9]$ su
[lugt@localhostnginx-1.7.9]$ cd /usr/local/nginx
[lugt@localhostnginx]$ vi conf/nginx.conf
There add suchdirectives to the server1 for emulate for an CDN server
upstream dnsnginx1 { server[*.*.*.*/yourhostname]:8080 weight=1000; #fill in your ip/hostname } server { listen 80; server_name [hostname] #fill your ip/ hostname here #access_log logs/host.access.log main location /{ proxy_pass http://dnsnginx1; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header HTTP_X_FORWARDED_FOR $remote_addr; proxy_redirect default; } }
After the end ofone server directive, and in the http directive, add so to function the sever2
limit_conn_zone $proxy_add_x_forwarded_for zone=addr:10m; # sample setting server { listen 8080; server_name [*.*.*.*/hostname]:8080 weight=10000; #fill in ip/hostname here limit_conn addr 1; # Enablethe limitation of connection per ip at a time to 1. location / { root html; index index.html index.htm; } }
And then you cansave , test the config file and run nginx
Test your configfile:
[lugt@localhostnginx]$ ./sbin/nginx –t
Start the nginx server
[lugt@localhostnginx]$ ./sbin/nginx
Now, the serverhas been set and you can run a test at instance.
/* This CommandMeans to run a tool to connect to server as 10conn/once and 10 conns in total*/
[lugt@localhost~]$ ab -c 10 -n 100 -v 4 http://127.0.0.1/ | grep HTTP/1.1
FAQ 1
There is actuallysome little malfunctions when using elder versions than 1.7.1 (Probably the newversion has it for a new feature).So to use this directive in earlier versions,some code need to be added.
As a Example inthe version 1.6.1
In filesrc/http/modules/ngx_http_limit_conn.c Line around 184
hash =ngx_crc32_short(key.data, key.len); If("" == &ctx->key){ If(NULL!= r->main->headers_in->x_forwarded_for->elts){ key.data= *(char*)r->main->headers_in->x_forwarded_for->elts; key.len = 4; hash =ngx_crc32_short(key.data, key.len); }
}<span style="font-family: Arial, Helvetica, sans-serif;"> </span>
FAQ 2 TestingResults
[lugt@localhost~]$ ab -c 10 -n 100 -v 4 http://127.0.0.1/ | grep HTTP/1.1
HTTP/1.1503 Service Temporarily Unavailable
HTTP/1.1503 Service Temporarily Unavailable
HTTP/1.1503 Service Temporarily Unavailable
HTTP/1.1503 Service Temporarily Unavailable
HTTP/1.1503 Service Temporarily Unavailable
HTTP/1.1503 Service Temporarily Unavailable
HTTP/1.1503 Service Temporarily Unavailable
HTTP/1.1503 Service Temporarily Unavailable
HTTP/1.1503 Service Temporarily Unavailable
HTTP/1.1 200 OK
HTTP/1.1503 Service Temporarily Unavailable
HTTP/1.1503 Service Temporarily Unavailable
HTTP/1.1503 Service Temporarily Unavailable
HTTP/1.1503 Service Temporarily Unavailable
503 Service Temporarily UnavailableHTTP/1.1503 Service Temporarily UnavailableHTTP /1.1503 Service Temporarily UnavailableHTTP/1.1503 Service Temporarily UnavailableHTTP/1.1503 Service Temporarily UnavailableHTTP/1.1503 Service Temporarily UnavailableHTTP/1。 time of HTTP/200 and so on>以上就介紹如何在兩層伺服器的第二層Nginx上取得使用者IP,包含了方面的內容,希望對PHP教學有興趣的朋友有所幫助。

PHP和Python各有優勢,選擇應基於項目需求。 1.PHP適合web開發,語法簡單,執行效率高。 2.Python適用於數據科學和機器學習,語法簡潔,庫豐富。

PHP不是在消亡,而是在不斷適應和進化。 1)PHP從1994年起經歷多次版本迭代,適應新技術趨勢。 2)目前廣泛應用於電子商務、內容管理系統等領域。 3)PHP8引入JIT編譯器等功能,提升性能和現代化。 4)使用OPcache和遵循PSR-12標準可優化性能和代碼質量。

PHP的未來將通過適應新技術趨勢和引入創新特性來實現:1)適應云計算、容器化和微服務架構,支持Docker和Kubernetes;2)引入JIT編譯器和枚舉類型,提升性能和數據處理效率;3)持續優化性能和推廣最佳實踐。

在PHP中,trait適用於需要方法復用但不適合使用繼承的情況。 1)trait允許在類中復用方法,避免多重繼承複雜性。 2)使用trait時需注意方法衝突,可通過insteadof和as關鍵字解決。 3)應避免過度使用trait,保持其單一職責,以優化性能和提高代碼可維護性。

依賴注入容器(DIC)是一種管理和提供對象依賴關係的工具,用於PHP項目中。 DIC的主要好處包括:1.解耦,使組件獨立,代碼易維護和測試;2.靈活性,易替換或修改依賴關係;3.可測試性,方便注入mock對象進行單元測試。

SplFixedArray在PHP中是一種固定大小的數組,適用於需要高性能和低內存使用量的場景。 1)它在創建時需指定大小,避免動態調整帶來的開銷。 2)基於C語言數組,直接操作內存,訪問速度快。 3)適合大規模數據處理和內存敏感環境,但需謹慎使用,因其大小固定。

PHP通過$\_FILES變量處理文件上傳,確保安全性的方法包括:1.檢查上傳錯誤,2.驗證文件類型和大小,3.防止文件覆蓋,4.移動文件到永久存儲位置。

JavaScript中處理空值可以使用NullCoalescingOperator(??)和NullCoalescingAssignmentOperator(??=)。 1.??返回第一個非null或非undefined的操作數。 2.??=將變量賦值為右操作數的值,但前提是該變量為null或undefined。這些操作符簡化了代碼邏輯,提高了可讀性和性能。


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

VSCode Windows 64位元 下載
微軟推出的免費、功能強大的一款IDE編輯器

SublimeText3 英文版
推薦:為Win版本,支援程式碼提示!

禪工作室 13.0.1
強大的PHP整合開發環境

mPDF
mPDF是一個PHP庫,可以從UTF-8編碼的HTML產生PDF檔案。原作者Ian Back編寫mPDF以從他的網站上「即時」輸出PDF文件,並處理不同的語言。與原始腳本如HTML2FPDF相比,它的速度較慢,並且在使用Unicode字體時產生的檔案較大,但支援CSS樣式等,並進行了大量增強。支援幾乎所有語言,包括RTL(阿拉伯語和希伯來語)和CJK(中日韓)。支援嵌套的區塊級元素(如P、DIV),

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)