Nginx匹配IP

Nginx 匹配ip

首先,大家如果看到有什么不懂的地方,欢迎吐槽!!!
我会在当天或者第二天及时回复,并且改进~~


定义反向代理

upstream portal.hongxue.com {
server 192.168.0.216:100 weight=1;
}

upstream mobile.hongxue.com {
server 192.168.0.216:200 weight=1;
}

upstream console.hongxue.com {
server 192.168.0.216:300 weight=1;
}

定义Server{}配置

server {
listen 80;
server_name www.hongxue.com;
charset utf8;

location / {
if ( $remote_addr = "10.1.2.6" )
    {
    proxy_pass http://console.hongxue.com;
    break;
    }
if ( $remote_addr = "10.1.2.5" )
    {
    proxy_pass http://portal.hongxue.com;
    break;
    }
if ( $remote_addr = "10.1.2.7" )
    {
    proxy_pass http://mobile.hongxue.com;
    break;
}
    proxy_pass http://192.168.0.223/;
}
}
<think>我们正在处理一个关于Nginx配置的问题,用户希望使用正则表达式来匹配IP和端口。根据引用内容,我们可以找到一些相关的配置示例。引用[2]中提到了通过$remote_addr变量获取客户端IP,并进行条件判断。引用[3]提到了rewrite功能,可以使用正则表达式进行URL重写,并且可以放在server、location、if块中。用户需求:使用正则表达式匹配IP和端口。在Nginx中,我们通常需要匹配请求中的主机头(Host)或者请求的IP和端口。但是,Nginx的server_name指令主要用于匹配域名,而端口是由listen指令指定的。如果我们想根据请求的目标IP和端口进行匹配,实际上可以通过server块中的listen和server_name组合来实现。但是,如果用户是想在配置中根据客户端的IP和端口(即$remote_addr和$remote_port)进行匹配,那么我们可以使用if条件或者map指令结合正则表达式。以下是一些示例:1.匹配特定的客户端IP和端口:我们可以使用if条件,结合正则表达式来匹配客户端的IP和端口。但是注意,Nginx官方不推荐大量使用if,因为效率问题。2.根据目标IP和端口进行路由(即请求到达的IP和端口):这通常通过定义多个server块,每个server块监听不同的端口,或者通过不同的IP地址(通过listen指令指定)来实现。然而,根据用户的问题,我们可能需要根据请求中的Host头(可能包含IP和端口)进行匹配。因为Host头可以是类似“192.168.1.1:8080”的形式。在Nginx中,server_name可以支持正则表达式,但是默认情况下,server_name匹配的是域名(不包括端口),因为端口是由listen指令处理的。所以,如果我们想匹配包含端口的主机头,我们需要在server_name中包括端口?实际上,Nginx匹配server块时,首先根据listen指令的端口(或IP:端口)匹配,然后在同一端口的多个server块中再根据server_name匹配,而server_name是不包含端口的。因此,如果我们想根据请求中的Host头(包含端口)来匹配,我们需要将端口从Host头中提取出来,这可以通过正则表达式捕获组来实现。但是,Nginx的server_name不支持匹配端口,所以我们需要换一种方式。另一种思路:在location中使用正则表达式匹配请求的Host头($host变量包含端口吗?注意,$host变量不包含端口,而$http_host包含端口)。因此,我们可以在location中通过if条件或者直接使用匹配$http_host变量来实现。示例:我们想将Host头为“192.168.1.1:8080”的请求导向特定的上游服务器。配置示例:```server{listen80;#监听80端口,那么请求的端口是80,Host头中的端口可能是80也可能不写(默认80)#但是如果我们监听的端口和Host头中的端口不一致,Nginx会使用listen的端口,而忽略Host头中的端口吗?#实际上,在匹配server块时,端口是由listen决定的,然后server_name匹配的是Host头去掉端口的部分。#所以,如果我们想根据不同的端口(即使同一个listen端口)来区分,我们需要在server块中通过$http_host变量(包含端口)进行判断。}因此,我们可以在server块内部使用location,通过正则表达式匹配$http_host变量。例如,匹配IP为192.168.1.1且端口为8080的Host头:```location/{if($http_host~*"^192\.168\.1\.1:8080$"){#如果匹配成功,则设置proxy_pass到特定的upstreamproxy_passhttp://upstream1;}}```但是,如果我们想要根据目标IP和端口(即服务器监听的IP和端口)来匹配,那么我们可以定义多个server块,每个server块监听不同的IP:端口组合。示例:监听不同端口```server{listen192.168.1.1:80;server_name_;...#配置A}server{listen192.168.1.1:8080;server_name_;...#配置B}```或者同一个端口但不同IP:```server{listen192.168.1.1:80;...}server{listen192.168.1.2:80;...}```因此,我们需要明确用户的需求是匹配客户端的IP和端口($remote_addr和$remote_port)还是匹配请求的目标IP和端口(即服务器监听的IP和端口)或者匹配Host头中的IP和端口?由于用户问题没有明确,我们考虑两种情况:情况1:匹配客户端IP和端口(即来源IP和端口)使用变量$remote_addr(客户端IP)和$remote_port(客户端端口),然后使用正则表达式匹配。示例:只允许特定IP的特定端口的请求(注意:客户端端口通常是随机的,所以这种需求较少)```if($remote_addr~*"192\.168\.1\.100"&&$remote_port="12345"){#满足条件}```情况2:匹配请求的目标IP和端口(即服务器监听的IP和端口)使用多个server块,每个server块监听不同的IP和端口组合。情况3:匹配Host头中的IP和端口(例如反向代理时,根据Host头路由)使用变量$http_host,然后用正则表达式匹配。示例:根据Host头中的IP和端口路由到不同的上游```server{listen80;#监听80端口#当Host头为192.168.1.1:80时(注意,如果浏览器访问80端口,通常不会带:80)set$upstream_endpointdefault_backend;if($http_host~*"^(192\.168\.1\.1):80$"){set$upstream_endpointbackend1;}if($http_host~*"^(192\.168\.1\.1):8080$"){set$upstream_endpointbackend2;}location/{proxy_passhttp://$upstream_endpoint;}}```注意:由于if指令的限制,上述配置可能需要调整以避免if的作用范围问题。另外,当在同一个server块中处理多个不同的Host头时,更推荐使用map指令。使用map指令的示例:```map$http_host$upstream_endpoint{defaultdefault_backend;~*^192\.168\.1\.1:80$backend1;~*^192\.168\.1\.1:8080$backend2;}server{listen80;location/{proxy_passhttp://$upstream_endpoint;}}```这样更高效。总结:根据用户的需求,我们提供了几种匹配IP和端口的方法。用户需要根据自己的实际场景选择。生成相关问题:1.如何在Nginx匹配客户端的IP地址?2.如何配置Nginx监听多个端口?3.如何使用map指令在Nginx中进行复杂的变量匹配?4.在Nginx中,$host变量和$http_host变量有什么区别?</think>### Nginx正则表达式匹配IP与端口配置详解 在Nginx中使用正则表达式匹配IP和端口,主要通过`server`块、`location`块结合正则表达式和内置变量实现。以下是具体配置方法和示例: --- #### 1. **匹配客户端IP地址** 使用`$remote_addr`变量获取客户端IP,通过正则表达式进行匹配: ```nginx server { listen 80; server_name _; # 设置标记变量 set $allow_access false; # 正则匹配IP段:192.168.1.0/24 if ($remote_addr ~* "^192\.168\.1\.\d{1,3}$") { set $allow_access true; } # 允许特定IP:10.0.0.5 if ($remote_addr = "10.0.0.5") { set $allow_access true; } location / { if ($allow_access = false) { return 403; # 拒绝非匹配IP } proxy_pass http://backend; } } ``` > **说明**: > - `~*` 表示不区分大小写的正则匹配 > - `^192\.168\.1\.\d{1,3}$` 匹配整个C类网段 > - 使用`set`定义变量实现复杂逻辑[^2][^3] --- #### 2. **匹配目标端口** 通过`$server_port`变量匹配请求的服务器端口: ```nginx server { listen 80; listen 8080; # 匹配8080端口的请求 if ($server_port = 8080) { rewrite ^/api/(.*)$ /v2/$1; # 重写API路径 } location / { proxy_pass http://upstream_$server_port; # 动态选择upstream } } ``` --- #### 3. **同时匹配IP和端口** 结合`$http_host`变量匹配Host头中的IP:PORT组合: ```nginx map $http_host $backend { ~*^192\.168\.1\.100:8080$ upstream_A; ~*^10\.0\.0\.\d+:80$ upstream_B; default default_backend; } server { listen 80; listen 8080; location / { proxy_pass http://$backend; # 根据Host头路由 } } ``` > **关键点**: > - `map`指令实现高效匹配[^1][^3] > - `~*^192\.168\.1\.100:8080$` 精确匹配IP:PORT > - `10\.0\.0\.\d+` 匹配整个IP段+80端口 --- #### 4. **拒绝非法IP+PORT组合** ```nginx server { listen 80; # 阻止非常规端口访问(如IP:8080通过80端口访问) if ($http_host ~* ":8080$") { return 444; # 强制关闭连接 } location / { # 仅允许标准端口访问 proxy_pass http://safe_backend; } } ``` --- #### ⚠️ **注意事项** 1. **正则表达式语法**: - IP匹配:`^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$` - 端口范围:`:80|:443|:8080$` - 转义点号:`\.`代替`.`[^3][^4] 2. **性能优化**: - 优先使用`map`而非多层`if`[^1] - 简单匹配用`=`精确匹配,复杂逻辑用正则 3. **调试技巧**: ```nginx add_header X-Matched-IP $remote_addr; add_header X-Matched-Port $server_port; ``` > 完整示例见[Nginx官方文档](https://nginx.org/en/docs/)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值