海运的博客

Nginx模块GeoIP匹配处理IP所在国家、城市

发布时间:July 1, 2012 // 分类:Nginx // 5 Comments

Nginx可配合GeoIP模块定位IP所在物理位置并做相应处理,支持多个条件匹配:

$geoip_country_code #国家代码2位,如CN
$geoip_country_code3 #国家代码3位,如CHN
$geoip_country_name #国家完整名称,如China
$geoip_region #所在地区
$geoip_city #所在城市,如BeiJing
$geoip_postal_code #邮政编码
$geoip_city_continent_code #所在洲,如AS
$geoip_latitude #纬度
$geoip_longitude #经度

编译安装Nginx并添加GeoIP模块:

yum install geoip-devel #安装GeoIP解析库
wget http://nginx.org/download/nginx-1.0.15.tar.gz
tar zxvf nginx-1.0.15.tar.gz 
cd nginx-1.0.15
 ./configure --user=www --group=www --prefix=/usr/local/nginx --with-http_stub_status_module \
--with-http_ssl_module --with-http_gzip_static_module --with-ipv6 --with-http_geoip_module
make 
make install

下载GeoIP城市国家数据库:

mkdir -p /usr/local/nginx/geoip
cd /usr/local/nginx/geoip
wget http://www.maxmind.com/download/geoip/database/GeoLiteCountry/GeoIP.dat.gz
wget http://geolite.maxmind.com/download/geoip/database/GeoLiteCity.dat.gz
gunzip GeoIP.dat.gz 
gunzip GeoLiteCity.dat.gz 

编辑Nginx配置文件加载GeoIP数据库:

http
[...]
geoip_country  /usr/local/nginx/geoip/GeoIP.dat; #国家数据库
geoip_city     /usr/local/nginx/geoip/GeoLiteCity.dat; #城市数据库
[...]

如需Nginx传递变量给PHP,编辑fastcgi_params添加:

fastcgi_param GEOIP_CITY_COUNTRY_CODE $geoip_city_country_code;
fastcgi_param GEOIP_CITY_COUNTRY_CODE3 $geoip_city_country_code3;
fastcgi_param GEOIP_CITY_COUNTRY_NAME $geoip_city_country_name;
fastcgi_param GEOIP_REGION $geoip_region;
fastcgi_param GEOIP_CITY $geoip_city;
fastcgi_param GEOIP_POSTAL_CODE $geoip_postal_code;
fastcgi_param GEOIP_CITY_CONTINENT_CODE $geoip_city_continent_code;
fastcgi_param GEOIP_LATITUDE $geoip_latitude;
fastcgi_param GEOIP_LONGITUDE $geoip_longitude;

应用示例,Nginx判断如果访问者IP所在国家为美国或中国,返回404错误

map $geoip_country_code $allowed_country {
    default yes;
    CN no;
}
server
    [...]
    if ($geoip_country_code ~* (US|CN)) {
      return 404;
    }

    if ($allowed_country = no) {
        return 404;
    }
    [...]

新建PHP程序测试GeoIP:

<html>
<head>
 <title>IP地址检测,我的IP地址是多少?</title>
 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
</head>
<body>
<?php
    if (getenv(HTTP_X_FORWARDED_FOR)) {
        $pipaddress = getenv(HTTP_X_FORWARDED_FOR);
        $ipaddress = getenv(REMOTE_ADDR);
        echo "<br>您的代理IP地址是: ".$pipaddress. " (via $ipaddress) " ;
    } else {
        $ipaddress = getenv(REMOTE_ADDR);
        echo "<br>您的IP地址是 : $ipaddress";
    }
  $geoip_city_country_code = getenv(GEOIP_CITY_COUNTRY_CODE);
  $geoip_city_country_code3 = getenv(GEOIP_CITY_COUNTRY_CODE3);
  $geoip_city_country_name = getenv(GEOIP_CITY_COUNTRY_NAME);
  $geoip_region = getenv(GEOIP_REGION);
  $geoip_city = getenv(GEOIP_CITY);
  $geoip_postal_code = getenv(GEOIP_POSTAL_CODE);
  $geoip_city_continent_code = getenv(GEOIP_CITY_CONTINENT_CODE);
  $geoip_latitude = getenv(GEOIP_LATITUDE);
  $geoip_longitude = getenv(GEOIP_LONGITUDE);
  echo "<br>国家 : $geoip_city_country_name ( $geoip_city_country_code3 , $geoip_city_country_code ) ";
  echo "<br>地区 :  $geoip_region";
  echo "<br>城市 :  $geoip_city ";
  echo "<br>邮政编码 :  $geoip_postal_code";
  echo "<br>所在洲 :  $geoip_city_continent_code";
  echo "<br>纬度 :  $geoip_latitude ";
  echo "<br>经度 :   $geoip_longitude ";

?>
</body>
</html>

debian下:

apt install libnginx-mod-http-geoip geoip-database

https://mailfud.org/geoip-legacy/

Nginx与PHP变量传递fastcgi_params

发布时间:July 1, 2012 // 分类:Nginx,PHP // No Comments

Nginx配置Fastcgi解析PHP时会调用fastcgi_params配置文件来传递服务器变量,默认内容如下:

#参数设定       #传递为PHP变量名    #Nginx自有变量,可自定义
fastcgi_param  QUERY_STRING       $query_string;
fastcgi_param  REQUEST_METHOD     $request_method;
fastcgi_param  CONTENT_TYPE       $content_type;
fastcgi_param  CONTENT_LENGTH     $content_length;

可以修改配置文件设定自定义变量传递到php-cgi端:

fastcgi_param  haiyun      "Hello haiun";

新建php文件通过$_SERVER[""]变量测试:

<?
echo $_SERVER["haiyun"];
?>
curl www.haiyun.me/test.php
Hello haiyun

13-12-25更新,不推荐使用这种方式传递变量,会增加连接开销,可修改PHP-FPM配置文件传递变量:

env[haiyun] = test

HTTP代理级别及检测是否使用代理

发布时间:July 1, 2012 // 分类:PHP // No Comments

透明代理,Transparent Proxies

REMOTE_ADDR = 代理服务器 IP
HTTP_VIA = 代理服务器 IP (补充:这个字段由代理服务器填充,有时会填充网关信息等)
HTTP_X_FORWARDED_FOR = 您的真实 IP

匿名代理,Anonymous Proxies

REMOTE_ADDR = 代理服务器 IP
HTTP_VIA = 代理服务器 IP (补充:这个字段由代理服务器填充,有时会填充网关信息等)
HTTP_X_FORWARDED_FOR = 代理服务器 IP

高匿名代理,High Anonymity Proxies/Elite Proxies
REMOTE_ADDR = 代理服务器 IP
HTTP_VIA = 没数值或不显示
HTTP_X_FORWARDED_FOR = 没数值或不显示
PHP检测客户端是否使用代理:

<?php
header("Content-type: text/html; charset=utf-8");
if(!empty($_SERVER['HTTP_VIA']))    //使用了代理
{
  if(!isset($_SERVER['HTTP_X_FORWARDED_FOR']))
  {
    echo "Anonymous Proxies    普通匿名代理服务器";
    //代理IP地址为 $_SERVER['REMOTE_ADDR']
  }
  else
  {
    echo "Transparent Proxies 透明代理服务器";
    //代理IP地址为 $_SERVER['REMOTE_ADDR']
    //真实ip地址为 $_SERVER['HTTP_X_FORWARDED_FOR']
  }
}
else    
{
  echo "没有代理或者是高匿名代理";
  //真实ip地址为 $_SERVER['REMOTE_ADDR']
}

Iptables拒绝指定国家的IP访问

发布时间:July 1, 2012 // 分类:Iptables // No Comments

有些服务器需拒绝特定国家的IP访问,可使用Iptables配合ipdeny提供的各个国家IP段为源进行过滤操作,由于数目较多会影响iptables性能,也可使用高效率Iptables geoip模块进行匹配操作。
应用示例,以拒绝美国IP为例:

#https://www.haiyun.me
#/bin/bash
wget -O /tmp/us.zone http://www.ipdeny.com/ipblocks/data/countries/us.zone
for ip in `cat /tmp/us.zone`
do
Blocking $ip
iptables -I INPUT -s $ip -j DROP
done

Iptables处理数据包详细流程图

发布时间:June 30, 2012 // 分类:Iptables // No Comments

iptables-Data-flow-diagram.jpg
Iptables包流程如下:

1. 数据包到达网络接口,比如 eth0。
2. 进入 raw 表的 PREROUTING 链,这个链的作用是赶在连接跟踪之前处理数据包。
3. 如果进行了连接跟踪,在此处理。
4. 进入 mangle 表的 PREROUTING 链,在此可以修改数据包,比如 TOS 等。
5. 进入 nat 表的 PREROUTING 链,可以在此做DNAT,但不要做过滤。
6. 决定路由,看是交给本地主机还是转发给其它主机。

到了这里我们就得分两种不同的情况进行讨论了,一种情况就是数据包要转发给其它主机,这时候它会依次经过:
7. 进入 mangle 表的 FORWARD 链,这里也比较特殊,这是在第一次路由决定之后,在进行最后的路由决定之前,我们仍然可以对数据包进行某些修改。
8. 进入 filter 表的 FORWARD 链,在这里我们可以对所有转发的数据包进行过滤。需要注意的是:经过这里的数据包是转发的,方向是双向的。
9. 进入 mangle 表的 POSTROUTING 链,到这里已经做完了所有的路由决定,但数据包仍然在本地主机,我们还可以进行某些修改。
10. 进入 nat 表的 POSTROUTING 链,在这里一般都是用来做 SNAT ,不要在这里进行过滤。
11. 进入出去的网络接口。完毕。

另一种情况是,数据包就是发给本地主机的,那么它会依次穿过:
7. 进入 mangle 表的 INPUT 链,这里是在路由之后,交由本地主机之前,我们也可以进行一些相应的修改。
8. 进入 filter 表的 INPUT 链,在这里我们可以对流入的所有数据包进行过滤,无论它来自哪个网络接口。
9. 交给本地主机的应用程序进行处理。
10. 处理完毕后进行路由决定,看该往那里发出。
11. 进入 raw 表的 OUTPUT 链,这里是在连接跟踪处理本地的数据包之前。
12. 连接跟踪对本地的数据包进行处理。
13. 进入 mangle 表的 OUTPUT 链,在这里我们可以修改数据包,但不要做过滤。
14. 进入 nat 表的 OUTPUT 链,可以对防火墙自己发出的数据做 NAT 。
15. 再次进行路由决定。
16. 进入 filter 表的 OUTPUT 链,可以对本地出去的数据包进行过滤。
17. 进入 mangle 表的 POSTROUTING 链,同上一种情况的第9步。注意,这里不光对经过防火墙的数据包进行处理,还对防火墙自己产生的数据包进行处理。
18. 进入 nat 表的 POSTROUTING 链,同上一种情况的第10步。
19. 进入出去的网络接口。完毕。

转自:http://www.opsers.org/linux-home/security/iptables-related-concepts-and-processes-the-packet-figure.html

分类
最新文章
最近回复
  • 海运: 可能版本问题
  • 海运: 如果运营商限制型号
  • 海运: 没有
  • Mruru: 烽火猫切换rootfs的方法有么大佬?
  • nono: 修改光猫型号是做啥子用的
  • 960: root账号默认密码hg2x0 不对哇
  • rer: 感谢分享!~
  • opnfense: 谢谢博主!!!解决问题了!!!我之前一直以为内置的odhcp6就是唯一管理ipv6的方式
  • liyk: 这个方法获取的IPv6大概20分钟之后就会失效,默认路由先消失,然后Global IPV6再消失
  • 海运: 不好意思,没有。
归档