1. 前言
搭建的网站经常受到国外的ip攻击,同时网站本身并不针对国外用户。那么就可以通过配置iptables进行拦截国外ip的访问。
这里我主要基于centos 8 系统进行介绍
1.1. 清理iptables配置
在配置前,如果已经配置比较多的拦截规则了,并且想删除的话。
可以通过命令: iptables -F
清空全部配置的命令。然后再执行:service iptables save
将配置保存。
如果很多命令你想继续保持,并只想删除部分的配置,可以通过:
iptables -L -n --line-number
命令将会列出所有的规则,并且会在每台规则前面添加编号。效果如下:
[root@iZuf6 ~]# iptables -L -n --line-number
Chain INPUT (policy ACCEPT)
num target prot opt source destination
1 DROP all -- 172.104.234.0/24 0.0.0.0/0
2 DROP all -- 157.245.57.0/24 0.0.0.0/0
3 DROP all -- 134.209.124.0/24 0.0.0.0/0
4 DROP all -- 143.42.19.0/24 0.0.0.0/0
5 DROP all -- 172.104.225.0/24 0.0.0.0/0
6 DROP all -- 95.86.208.0/24 0.0.0.0/0
然后,如果想删除哪条,就使用:iptables -D INPUT <num>
命令进行删除即可。
例如删除第6条记录:iptables -D INPUT 6
然后回车就可以了。
原先想了解是否有批量删除的,但是更多的是找到使用shell脚本,然后采用脚本的动态执行进行删除。本身也是调用-D命令进行一条条删除。
最后懒得操作,直接使用 -F全部清空了。
不执行以上清理,也不影响配置。
2. 配置
我们如果想拦截国外ip,单纯依靠iptables还不够。我们需要安装ipset工具。并且获取到所有国外ip集,然后进行统一拦截。
整个拦截过程为:
1.将国内IP地址段整理到ipset中。
2.使用iptables调用ipset进行判断来源ip是否属于国内ip地址。
3.将不属于国内ip地址的访问请求进行拦截。
2.1 安装ipset
关于iptables的安装,这里就不多介绍了。前面文章有介绍过如何安装和使用https://zinyan.com/?p=32
现在需要再安装的是ipset。执行命令如下所示:
[root@iZuf6 ~]# yum -y install ipset
Last metadata expiration check: 1:21:39 ago on Mon 03 Jul 2023 02:11:27 PM CST.
Package ipset-7.1-1.el8.x86_64 is already installed.
Dependencies resolved.
Nothing to do.
Complete!
[root@iZuf6 ~]#
出现了Complete! 就代表安装完毕了。
2.2 配置ipset
当我们安装完毕之后,就可以创建一个ipset了。命令格式为:ipset create xxx hash:net
默认ipset可以存储65536个元素,例如我们创建:ipset create zinyan hash:net
那么这个zinyan规则中默认可以存储的数量就是65536条了。我们如果想存储更多的,可以配置为:
ipset create zinyan hash:net maxelem 1000000
主要就是通过:maxelem
进行指定而已。 其中zinyan是规则名称,我们可以根据自己的想法创建名称。
示例 创建了一个zinyanwhitelist的ipset对象,可以存储的记录数量为1百万:
[root@iZuf6 ~]# ipset create zinyanwhitelist hash:net maxelem 1000000
然后就可以使用ipset list命令进行查看我们创建的对象了:
[root@iZuf6 ~]# ipset list
Name: zinyanwhitelist
Type: hash:net
Revision: 6
Header: family inet hashsize 1024 maxelem 1000000
Size in memory: 376
References: 0
Number of entries: 0
Members:
[root@iZuf6 ~]#
现在,要做的事情就是给这个zinyanwhitelist(zinyan白名单)中添加国内ip记录了。
可以通过apnic公布的亚太地区ip地址,进行查询。获取到国内ip段集合文档。
需要记住自己创建的ipset的对象的名称,例如我上面的名称叫做:zinyanwhitelist。 后面配置脚本时会需要使用到该配置项名称。
2.3 编写自动更新ip获取脚本
首先,创建一个sh脚本文件:
[root@iZuf6 ~]# vim /home/china.sh
在该脚本文件中按I
键进入编辑模式,添加以下内容:
#!/usr/bin/env bash
## 下载国内Ip地址段,并存储到home/china.txt 文本中。
wget --no-check-certificate -O- 'http://ftp.apnic.net/apnic/stats/apnic/delegated-apnic-latest' | awk -F\| '/CN\|ipv4/ { printf("%s/%d\n", $4, 32-log($5)/log(2)) }' > /home/china.txt
##清空 zinyanblack中的记录。(清理老数据)
ipset flush zinyanwhitelist
## 读取china.txt 文件,将国内ip添加到zinyanwhitelist中
ip=$(cat /home/china.txt)
for i in $ip
do
ipset add zinyanwhitelist $i
done
然后按Esc键退出编辑模式,输入:wq
保存并退出。
授予sh脚本可执行权限:chmod +x /home/china.sh
然后手动执行一遍脚本,并检测ip段是否被添加到zinyanwhitelist。示例如下:
[root@iZuf6 ~]# chmod +x /home/china.sh
[root@iZuf6 ~]# sh /home/china.sh
--2023-07-03 16:30:35-- http://ftp.apnic.net/apnic/stats/apnic/delegated-apnic-latest
Resolving ftp.apnic.net (ftp.apnic.net)... 203.119.102.40, 2001:dd8:8:701::40
Connecting to ftp.apnic.net (ftp.apnic.net)|203.119.102.40|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 3738158 (3.6M) [text/plain]
...
一直到文件下载完毕。然后通过ipset list zinyanwhitelist
进行检测,国内ip网段是否添加成功。
[root@iZuf6 ~]# ipset list zinyanwhitelist
Name: zinyanwhitelist
Type: hash:net
Revision: 6
Header: family inet hashsize 4096 maxelem 1000000
Size in memory: 247608
References: 0
Number of entries: 8651
Members:
103.79.240.0/22
203.189.0.0/23
160.202.148.0/22
192.140.128.0/22
43.243.16.0/22
...
然后就会看到,添加了8651条Ip地址。ip添加完毕后,可以通过crontab服务设置定时更新ip集合。
使用命令: 打开crontab配置文件
crontab -e
在打开的文件中按I
进入编辑模式:
0 0 * * 1 /home/china.sh
添加在每周1的凌晨0:0 执行china.sh脚本进行加载数据。 编辑完毕后按Esc键,输入:wq
保存后退出。
定时任务就会创建并激活了。
2.4 配置iptables
配置完ipset之后,我们需要将ipset的相关内容关联到iptables中进行拦截处理。
添加配置:
iptables -A INPUT -m set --match-set zinyanwhitelist src -j ACCEPT # # 匹配 zinyanwhitelist,放行国内ip地址访问
iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A INPUT -i lo -j ACCEPT #允许服务器回环
iptables -A INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT # 放行22端口
iptables -A INPUT -p tcp -m state --state NEW -m tcp --dport 443 -j ACCEPT #放行443 端口
iptables -A INPUT -j REJECT -- reject-with icmp-host-prohibited # 在INPUT表中拒绝所有其他不符合上述任何一条规则的数据包。并且发送一条host prohibited的消息给被拒绝的主机。
iptables -A FORWARD -j REJECT --reject-with icmp-host-prohibited # 在FORWARD表中拒绝所有其他不符合上述任何一条规则的数据包。并且发送一条host prohibited的消息给被拒绝的主机。 也就是拒绝转发
然后执行配置保存(避免关机重启后,需要重新配置iptables的规则。建议执行下面的保存操作。):
[root@iZuf6 ]# service iptables save
iptables: Saving firewall rules to /etc/sysconfig/iptables:[ OK ]
[root@iZuf6 ]#
就配置完毕了。
我们整个配置完毕后的效果可以看到:
[root@iZuf6 n]# iptables -L -n --line-number
Chain INPUT (policy ACCEPT)
num target prot opt source destination
1 ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 match-set zinyanwhitelist src
2 ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED
3 ACCEPT all -- 0.0.0.0/0 0.0.0.0/0
4 ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 state NEW tcp dpt:22
5 ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 state NEW tcp dpt:443
6 REJECT all -- 0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibited
Chain FORWARD (policy ACCEPT)
num target prot opt source destination
1 REJECT all -- 0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibited
在iptables的拦截配置就会多一个DROP的拦截项了。
我上诉的也就是放行了22端口,443端口,以及服务器回环。和白名单中放行的ip地址。其他的请求和地址全部拦截。
评论区