业务需要通过nginx来前置识别ip跳转到不同的网站,当然也可以跳转到不同的后端接口,记录一下实现过程
Nginx的geo
模块允许你根据客户端的IP地址或其他变量的值来执行一些条件分支逻辑。该模块用于根据客户端的地理位置信息执行不同的操作。以下是geo
模块的一些基本介绍和使用方式:
geo $variable {
default value;
192.168.1.0/24 variable_value;
10.0.0.0/8 variable_value;
...
}
$variable
是一个自定义变量,用于存储与匹配的值。default value;
设置变量的默认值。192.168.1.0/24
或 10.0.0.0/8
行都指定了一个地址段,并设置了相应的variable_value
。geo $local_network {
default 0;
192.168.1.0/24 1;
10.0.0.0/8 1;
}
server {
if ($local_network) {
# 当客户端IP在局域网范围内时执行此处的操作
}
# 其他服务器配置...
}
上述例子中,如果客户端的IP地址在192.168.1.0/24或10.0.0.0/8的范围内,$local_network
变量的值将被设置为1,然后可以在server
块内根据这个变量执行相应的条件操作。
限制访问: 根据客户端的地理位置限制对某些资源的访问。
geo $allowed_country {
default no;
US yes;
CA yes;
}
server {
location /restricted {
if ($allowed_country = no) {
return 403;
}
# 允许的国家执行相应的操作
}
# 其他服务器配置...
}
日志分析: 根据客户端的地理位置信息记录访问日志。
geo $log_country {
default "Unknown";
US "United States";
CA "Canada";
}
log_format main '$remote_addr - $log_country - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
server {
access_log /var/log/nginx/access.log main;
# 其他服务器配置...
}
选择不同的后端服务器: 根据客户端的地理位置信息选择不同的后端服务器。
geo $backend_server {
default "default_server";
US "us_server";
CA "ca_server";
}
upstream backend {
server default_server;
server us_server;
server ca_server;
}
server {
location / {
proxy_pass http://backend;
}
# 其他服务器配置...
}
nginx.conf
中添加geo配置文件指向 geo $country {
default CN;
include /etc/nginx/conf/ipv4geo.conf;
}
ipv4geo.conf
文件里面内容# 这里面只是一个示例,具体全球ip列表需要自己整理,后续会专门出一篇博客来介绍,实现从全球五大机构获取ip的国家
124.246.0.0/21 AU;
124.246.8.0/21 AU;
124.246.16.0/21 AU;
124.246.24.0/21 AU;
124.246.32.0/19 AU;
124.246.64.0/18 SG;
124.246.128.0/17 JP;
124.247.0.0/17 JP;
124.247.128.0/18 JP;
124.247.192.0/18 IN;
124.248.0.0/17 CN;
124.248.128.0/20 NZ;
124.248.144.0/20 JP;
124.248.160.0/19 KH;
124.248.192.0/18 HK;
124.249.0.0/16 CN;
124.250.0.0/15 CN;
124.252.0.0/16 GB;
124.253.0.0/16 IN;
server
模块server {
listen 9090;
server_name 47.103.131.5;
location / {
if ($country = "CN"){
rewrite ^(.*) https://www.csdn.com$1 permanent;
}
if ($country = "US"){
rewrite ^(.*) https://www.baidu.com$1 permanent;
}
add_header Content-Type text/plain;
return 200 '$remote_addr\n$country';
}
}
请注意,geo
模块的使用需要谨慎,尤其是在复杂的应用场景中,因为在if
语句内使用它可能会导致性能问题。在实际使用中,建议考虑使用其他更高效的Nginx模块或者将相关逻辑移到应用层处理。