Nginx - 根據IP分配不同的訪問后端


1. 需求分析

為了在線上環境提供測試分支,規定將某IP轉發到測試程序地址。如果是 ngx 直接對外,采用 real_ip 就能夠做限制,但是最前端確實一個7層是負載均衡就需要研究一番了。

 

2. 實踐

業務部署在某雲上,前端上掛着一個7層的負載均衡,通過查看官方可以通過 X-Forwarded-For 來獲取客戶端真實IP,這樣就很簡單了。
通過測試模擬這樣的環境驗證下:

    192.168.118.14 - ngx :該ngx 只是充當負載均衡,開啟 X-Forwarded-For
    192.168.118.15 - ngx:該ngx 為 web服務器,真正的用戶端IP判斷在這里實現
    192.168.118.16 - httpd:充當 測試程序

配置如下:

192.168.118.14(模擬負載均衡):

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # 轉發客戶端真實IP
location / {
    proxy_pass http://192.168.118.15/; # 僅僅用作轉發
    access_log logs/14_access.log main;
    error_log logs/14_error.log;
    #root   html;
    #index  index.html index.htm;
}

 

192.168.118.15(nginx - 用戶端IP判斷在此實現)

upstream back1 {
    server 192.168.118.16:8080;
}
server {
    listen       80;
    server_name  localhost;
    location / {
        if ($http_x_forwarded_for ~* "192.168.118.2") {
            rewrite ^/(.*)$ http://192.168.118.15/back1/$1 break;
        }
        root html;
        index index.html;
        access_log logs/15_access.log main;
        error_log logs/15_error.log;
    }
    location /back1 {
        proxy_pass http://back1/;
    }

 

因為負載均衡可以轉發用戶真實IP,所以在 nginx 中,直接判斷 http_x_forwarded_for 就能做路由。

 

192.168.118.16 開啟 8080 端口

# curl http://192.168.118.16:8080/a.html
<h1>192.168.118.16: a.html</h1>

 

直接訪問 192.168.118.15

# curl http://192.168.118.15/a.html
<h1>192.168.118.15: a.html</h1>

 

定義的規則:當客戶端 192.168.118.2 訪問 192.168.118.14時,則轉發到 192.168.118.16:8080,剩下其他客戶端IP則直接訪問 192.168.118.15

3. 驗證

通過 192.168.118.2 客戶端訪問:

http://192.168.118.14/a.html 地址在瀏覽器已經經過 302 跳轉到新的連接地址了。

 

 

其他客戶端IP訪問:

 

 

4. 后續

通過 rewrite 這種方式實現了條件判斷的跳轉,但是這個跳轉是 HTTP 302 並不支持 head 等信息的轉發,所以在提交 post 請求時,會出現錯誤。

在生產環境中,有這樣一個實例:

 

需求:當IP: 192.168.118.2  訪問 http://192.168.118.15/bbs/ 時,跳轉到 http://192.168.118.16:8080/  uri中不能帶有 /bbs

 

實現:

 

注意:在條件判斷的反向代理中,proxy_pass http://192.168.118.16:8080 后面不得帶 '/' 或者其他路徑,否則 nginx -t 檢測會報錯。報錯信息如下:

 

[root@localhost conf]# nginx -t
nginx: [emerg] "proxy_pass" cannot have URI part in location given by regular expression, or inside named location, or inside "if" statement, or inside "limit_except" block in /usr/local/nginx/conf/nginx.conf:50
nginx: configuration file /usr/local/nginx/conf/nginx.conf test failed

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM