用 iptables 把来自某个国家的 IP 重定向到预定页面

昨天有位客户想在他网站上阻止所有来自中国的 IP 并且把来自中国的访问重定向到某个预定的页面(或网站)。正统的做法应该是用 apache + mod_geoip 或者 nginx + http_geoip_module 来做,但是发现这位客户使用了 apache/directAdmin/suexec,suexec 好像和 mod_geoip 在一起有问题,VPSee 不想大动客户的配置,所以打算用 iptables 来实现这个要求。想法是这样的,用 iptables 把来自中国的流量全部导向到网站的 81 端口,并在 apache 上启动监听81端口,放上预定的页面(或网站)。

先到 IPdeny 下载以国家代码编制好的 IP 地址列表,比如下载 cn.zone:

# wget http://www.ipdeny.com/ipblocks/data/countries/cn.zone

得到需要的所有 IP 地址后,用下面的脚本逐行读取 cn.zone 文件并加入到 iptables 中:

#!/bin/bash
# Redirect traffic from a specific country to a specific page
# written by vpsee.com

COUNTRY="cn"
YOURIP="1.2.3.4"

if [ "$(id -u)" != "0" ]; then
   echo "you must be root" 1>&2
   exit 1
fi

iptables -F
iptables -X
iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT
iptables -A INPUT -i eth0 -j ACCEPT
iptables -A OUTPUT -o eth0 -j ACCEPT

# Redirect incoming http (80) from China to 81
for c in $COUNTRY
do
        country_file=$c.zone

        IPS=$(egrep -v "^#|^$" $country_file)
        for ip in $IPS
        do
           echo "redirecting $ip"
           iptables -t nat -I PREROUTING -p tcp --dport 80 -s $ip -j DNAT \
                   --to-destination $YOURIP:81
        done
done

iptables-save > /etc/sysconfig/iptables
chmod go-r /etc/sysconfig/iptables
service iptables restart

这样来自中国的 IP 访问 YOURIP 这个网站后就会自动导向到 YOURIP:81 这个端口,然后我们修改 apache 的配置,增加一个 Listen 81 和 以及在 DocumentRoot 里面放上预定的页面(或网站)就可以了

2 comments »

  1. tort said,
    26 11 月, 2011 @ 下午 5:05

    linux iptables 如何封单个IP 以及各种IP段(例子)

    封单个IP的命令是:
    iptables -I INPUT -s 211.1.0.0 -j DROP
    封IP段的命令是:
    iptables -I INPUT -s 211.1.0.0/16 -j DROP
    iptables -I INPUT -s 211.2.0.0/16 -j DROP
    iptables -I INPUT -s 211.3.0.0/16 -j DROP
    封整个段的命令是:
    iptables -I INPUT -s 211.0.0.0/8 -j DROP
    封几个段的命令是:
    iptables -I INPUT -s 61.37.80.0/24 -j DROP
    iptables -I INPUT -s 61.37.81.0/24 -j DROP
    【解封】
    iptables -D INPUT -s IP地址 -j REJECT

    如果发现input连接 命令不起作用,则可以 路由连接参数 使用下面命令
    iptables -A FORWARD -s 1.202.0.0/16 -j DROP

    在unix中IP子网掩码可用16,24,32等数字来表示,意思是:16表示子网掩码的前16位是全1,24、32以此类推。

    iptables -A FORWARD -s 61.172.0.0/16 -i 网卡名称 -j DROP

    ——–有人说这种方法比较好用,这句比你防火墙管用——–

    那句只能禁止一个ip路由 #route add 61.172.0.0/16 reject
    这句可以封整段 #route add -net 61.172.0.0 netmask 255.255.0.0 reject

    下面看些实际例子,设计封第几个IP段的问题:

    ——如果要封的内容是 061.037.080.000->061.037.081.255 —–
    iptables -I INPUT -s 61.37.80.0/24 -j DROP
    iptables -I INPUT -s 61.37.81.0/24 -j DROP

    —–用什么命令可以让iptables 封了 211.1.0.0 到 211.10.0.0 IP段?———–
    platinum 回复于:2004-01-01 01:14:13
    iptables -I INPUT -s 211.1.0.0/16 -j DROP
    iptables -I INPUT -s 211.2.0.0/16 -j DROP
    iptables -I INPUT -s 211.3.0.0/16 -j DROP

    ——如果要封的内容是整段的 比如 211.0.0.0 – 211.255.255.255 ————-
    iptables -I INPUT -s 211.0.0.0/8 -j DROP

  2. tort said,
    22 12 月, 2011 @ 下午 12:21

    再补个人觉得不错的三条规则。
    -A FORWARD -p tcp –syn -m limit –limit 1/s –limit-burst 5 -j ACCEPT
    -A FORWARD -p tcp –tcp-flags SYN,ACK,FIN,RST RST -m limit –limit 1/s -j ACCEPT
    -A FORWARD -p icmp –icmp-type echo-request -m limit –limit 1/s -j ACCEPT

    说明:
    第一行:每秒中最多允许5个新连接
    第二行:防止各种端口扫描
    第三行:Ping洪水攻击(Ping of Death)

Leave a Comment