服务器屏蔽所有境外(国外)IP段

作者: Darren 分类: 收藏 发布时间: 2019-05-18 10:56

以下是针对WEB优化的的脚本

有不少人希望让自己的网站仅让某一个国家的IP访问,其它的则禁止访问,这时我们就可以使用以下命令了:

wget https://www.321dz.com/shell/block-any.sh
chmod +x block-any.sh
./block-any.sh

上面的代码仅允许国内的IP访问,并会在:/etc/rc.d/rc.local写入规则,每次系统重启后都会重新导入iptables规则,如果你调整了iptables规则,需要编辑:/etc/rc.d/rc.local删除相应的启动自运行代码。block-any.sh代码如下:

#! /bin/bash
#判断本次运行时间
#判断是否具有root权限
root_need() {
    if [[ $EUID -ne 0 ]]; then
        echo "Error:This script must be run as root!" 1>&2
        exit 1
    fi
}
#检查系统分支及版本(主要是:分支->>版本>>决定命令格式)
check_release() {
    if uname -a | grep el7  ; then
        release="centos7"
    elif uname -a | grep el6 ; then
        release="centos6"
        yum install ipset -y
    elif cat /etc/issue |grep -i ubuntu ; then
        release="ubuntu"
        apt install ipset -y
    fi
}
#安装必要的软件(wget),并下载中国IP网段文件(最后将局域网地址也放进去)
get_china_ip() {
  #安装必要的软件(wget)
  rpm --help >/dev/null 2>&1 && rpm -qa |grep wget >/dev/null 2>&1 ||yum install -y wget ipset >/dev/null 2>&1 
  dpkg --help >/dev/null 2>&1 && dpkg -l |grep wget >/dev/null 2>&1 ||apt-get install wget ipset -y >/dev/null 2>&1
  #该文件由IPIP维护更新,大约一月一次更新(也可以用我放在国内的存储的版本,2019-05-18日版)
  [ -f china_ip_list.txt ] && mv china_ip_list.txt china_ip_list.txt.old
  wget https://github.com/17mon/china_ip_list/blob/master/china_ip_list.txt
  cat china_ip_list.txt |grep 'js-file-line">' |awk -F'js-file-line">' '{print $2}' |awk -F'<' '{print $1}' >> china_ip.txt
  rm -rf china_ip_list.txt
  #wget https://www.321dz.com/shell/china_ip.txt
  #放行局域网地址
  echo "192.168.0.0/18" >> china_ip.txt
  echo "10.0.0.0/8" >> china_ip.txt
  echo "172.16.0.0/12" >> china_ip.txt
}
#只允许国内IP访问
ipset_only_china() {
  echo "ipset create whitelist-china hash:net hashsize 10000 maxelem 1000000" > /etc/ip-black.sh
  for i in $( cat china_ip.txt )
  do
          echo "ipset add whitelist-china $i" >> /etc/ip-black.sh
  done
  echo "iptables -I INPUT -m set --match-set whitelist-china src -j ACCEPT" >> /etc/ip-black.sh
  #拒绝非国内和内网地址发起的tcp连接请求(tcp syn 包)(注意,只是屏蔽了入向的tcp syn包,该主机主动访问国外资源不用影响)
  echo "iptables  -A INPUT -p tcp --syn -m connlimit --connlimit-above 0 -j DROP" >> /etc/ip-black.sh
  #拒绝非国内和内网发起的ping探测(不影响本机ping外部主机)
  echo "iptables  -A INPUT -p icmp -m icmp --icmp-type 8 -j DROP" >> /etc/ip-black.sh
  #echo "iptables -A INPUT -j DROP" >> /etc/ip-black.sh
  rm -rf china_ip.txt
}
run_setup() {
  chmod +x /etc/rc.local
  sh /etc/ip-black.sh
  rm -rf /etc/ip-black.sh
  #下面这句主要是兼容centos6不能使用"-f"参数
  ipset save whitelist-china -f /etc/ipset.conf || ipset save whitelist-china > /etc/ipset.conf
  [ $release = centos7 ] && echo "ipset restore -f /etc/ipset.conf" >> /etc/rc.local
  [ $release = centos6 ] && echo "ipset restore < /etc/ipset.conf" >> /etc/rc.local
  echo "iptables -I INPUT -m set --match-set whitelist-china src -j ACCEPT" >> /etc/rc.local
  echo "iptables  -A INPUT -p tcp --syn -m connlimit --connlimit-above 0 -j DROP" >> /etc/rc.local
  echo "iptables  -A INPUT -p icmp -m icmp --icmp-type 8 -j DROP" >> /etc/rc.local
  #echo "iptables -A INPUT -j DROP" >> /etc/rc.local
}
main() {
  check_release
  get_china_ip
  ipset_only_china
case "$release" in
centos6)
  run_setup
  ;;
centos7)
  chmod +x /etc/rc.d/rc.local
  run_setup
  ;;
ubuntu)
  sed -i '/exit 0/d' /etc/rc.local
  run_setup
  echo "exit 0" >> /etc/rc.local
  ;;
esac
}
main

如果你要排除一些IP,允许这些IP作为例外继续访问,可以使用iptables -I命令新增iptables规则,或者手动添加iptables规则,注意要将规则放在最上面,因为iptables执行顺序是从上往下。

如果在设置过程中出现了任何问题,或者导致某些服务用不了,那么你可以先抢救一下,输入一下命令:

iptables -P INPUT ACCEPT
iptables -F

第二种不关闭端口与屏蔽端口,只屏蔽IP

1、安装ipset

#Debian/Ubuntu系统
apt-get -y install ipset

#CentOS系统
yum -y install ipset

CentOS 7还需要关闭firewall防火墙:

systemctl stop firewalld.service
systemctl disable firewalld.service

2、清空之前的规则

#防止设置不生效,建议清空下之前的防火墙规则
iptables -P INPUT ACCEPT
iptables -F

3、创建新规则

#创建一个名为cnip的规则
ipset -N cnip hash:net
#下载国家IP段,这里以中国为例
wget -P . http://www.ipdeny.com/ipblocks/data/countries/cn.zone
#将IP段添加到cnip规则中
for i in $(cat /root/cn.zone ); do ipset -A cnip $i; done

4、设置IP段白名单

#放行IP段
iptables -A INPUT -p tcp -m set --match-set cnip src -j ACCEPT
#关掉所有端口
iptables -P INPUT DROP

这时候就只有指定国家的IP能访问服务器了。

如果你在国内,网站不允许被国内人访问,建议别关所有端口,这样你的SSH会上不去,我们可以只关闭80/443端口。

#关闭指定端口,比如80/443
iptables -A INPUT -p tcp --dport 80 -j DROP
iptables -A INPUT -p tcp --dport 443 -j DROP

这时候其他国家的IP是无法访问你服务器的80/443端口,等于无法访问你的网站,其它端口还是可以访问的。

5、删除规则

#将参数里的-A改成-D就是删除规则了,如
iptables -D INPUT -p tcp -m set --match-set cnip src -j ACCEPT
iptables -D INPUT -p tcp --dport 443 -j DROP

说明

设置防火墙后,可能有些服务器重启系统后会清空防火墙规则,导致设置的失效,所以我们设置规则后,需要使用iptables命令保存下,保存命令可能在很多系统中都不通用,这里就不说了,需要各位自行搜索解决了,有耐心的也可以每次重启的时候都重新设置一下防火墙。