Nginx -- 根據 IP 匹配指定 URL

業務需求

業務和開發同事須要我這邊作一條規則,全部訪問 ip 爲非上海、廣州 office 外網 ip,url 爲http://test.com/fuck/index.html 的請求都跳轉到 http://test.com/index.html 。而後全部在上海和廣州 office 的外網 IP 訪問 http://test.com/fuck/index.html 依然仍是 http://test.com/fuck/index.html。這樣就能夠在生產上作隔離,不影響其餘用戶的服務。php

注:由於目前生產上的 Nginx 沒有作 lua 支持,因此就沒法經過使用 lua 來實現該需求,也沒有安裝 geoip ,因此也沒法用模塊來支持,只能原生的。css

原始的 nginx 配置html

upstream service_test {
         server 127.0.0.1:8080;
}


server
  {
    listen       80;
    server_name  test.com;

    index index.html index.php;
    root  /tmp/test.com;

    error_page 404  http://test.com/404.html;
    error_page 502  http://test.com/502.html;
    error_page 500  http://test.com/500.html;

    location ~* \.(gif|jpg|jpeg|png|css|js|ico|txt|svg|woff|ttf|eot)$
    {
        rewrite ^(.*)$ /static$1 break;
        root /tmp/test.com; # 
        expires 1d;
    }

    location ~* \.(html|htm)$
    {
        rewrite ^(.*)$ /static$1 break;
        roo  /tmp/test.com; #  
        expires 900s;
    }

    location / {

         proxy_pass http://service_test;

         include /opt/conf/nginx/proxy.conf;
    }

修改後的 Nginx 配置nginx

upstream service_test {
         server 127.0.0.1:8080;
}


server
  {
    listen       80;
    server_name  test.com;

    index index.html index.php;
    root  /tmp/test.com;

    error_page 404  http://test.com/404.html;
    error_page 502  http://test.com/502.html;
    error_page 500  http://test.com/500.html;

    location ~* \.(gif|jpg|jpeg|png|css|js|ico|txt|svg|woff|ttf|eot)$
    {
        rewrite ^(.*)$ /static$1 break;
        root /tmp/test.com; # 
        expires 1d;
    }

    location ~* \.(html|htm)$
    {
        rewrite ^(.*)$ /static$1 break;
        roo  /tmp/test.com; #  
        expires 900s;
    }

   set $flag 0;
   if ($request_uri ~* "^/fuck/\w+\.html$") {
            set $flag "${flag}1";
    }
    if ($remote_addr !~* "192.168.0.50|192.168.0.51|192.168.0.56") {
       set $flag "${flag}2";
    }

    if ($flag = "012") {
        rewrite ^ /index.html permanent;
    }

    location / {

         proxy_pass http://service_test;

         include /opt/conf/nginx/proxy.conf;
    }

在實現需求的過程當中出現的問題

  1. 把 if 指令 和 proxy_pass 都放在 location 下面的話,if 指令裏面的內容不會執行,只會執行 proxy_pass。svg

    location / {
         if ($remote_addr !~* "192.168.0.50|192.168.0.51|192.168.0.56") {
               rewrite ^ /index.html permanent;
         }
         proxy_pass http://service_test;
    
         include /opt/conf/nginx/proxy.conf;
    }
  2. if 指令下面使用 proxy_pass 指令問題lua

像下面這樣使用會報錯,錯誤的方式:url

if ($remote_addr ~* "192.168.0.50|192.168.0.51|192.168.0.56") {
            proxy_pass http://test.com/fuck;
        }

正確的方式:code

if ($remote_addr ~* "192.168.0.50|192.168.0.51|192.168.0.56") {
            proxy_pass http://test.com$request_uri;
        }

或是server

if ($remote_addr ~* "192.168.0.50|192.168.0.51|192.168.0.56") {
            proxy_pass http://test.com;
        }

若是你是直接另外啓動一個 location 的話,好比啓動以下 location :htm

location /fund {
         if ($remote_addr !~* "192.168.0.50|192.168.0.51|192.168.0.56") {
               rewrite ^ /index.html permanent;
         }
    }

這樣的方式也是不支持的,當用 IP 192.168.0.50 訪問的時候,沒有達到咱們的業務需求,會報錯 400

注:各位有其餘好的建議,歡迎探討。

相關文章
相關標籤/搜索