# 服务器iptables规则配置简单版
参考:https://wiki.archlinux.org/title/iptables_(简体中文) (opens new window)
# 初始配置
下面的操作以Archlinux为例,请事先保证安装了iptables和ipset包。
启动iptables
cp /etc/iptables/empty.rules /etc/iptables/iptables.rules
systemctl start iptables
iptables -nvL --line-numbers
停止iptables
iptables --flush #or iptables -F //清空所有规则
systemctl stop iptables
# 常见操作
删除规则:
参考:http://blog.51yip.com/linux/1404.html (opens new window)
iptables -nvL --line-numbers
iptables -D INPUT 3 //删除input的第3条规则
保存命令行输入的规则到默认规则:
iptables-save > /etc/iptables/iptables.rules
#修改配置文件后,需要重新加载服务:
systemctl reload iptables
#或者通过 iptables 直接加载:
iptables-restore < /etc/iptables/iptables.rules
放行端口:
#例如要放行8080-8089端口
iptables -I INPUT -p tcp --dport 8080-8089 -j ACCEPT
# 最后总结设置
# 先清除所有规则
ipset flush
iptables --flush
#禁用ping,icmp协议
iptables -I INPUT -p icmp -j DROP
#放行ssh端口
iptables -A INPUT -i 网卡设备 -p tcp --dport ssh端口号 -j ACCEPT
#在旧规则前插入新规则(在行首插入)
iptables -I INPUT -p tcp --dport 8080:8089 -j ACCEPT
# 此处可考虑引入anti-portscan防端口扫描脚本,参考[https://github.com/zfhxi/anti-portscan](https://github.com/zfhxi/anti-portscan)
#丢弃规则外的包
iptables -A INPUT -j DROP
****
# 保存命令行规则到默认规则文件中
iptables-save > /etc/iptables/iptables.rules
ipset save > /etc/ipset.conf
查看 扫描服务器非开放端口的入侵者 ip:
watch -n1 ipset list scanner-ip-set
下次开机时:
# 清空规则
ipset flush
iptables --flush
# 首先启动ipset
systemctl start ipset
# 再启动iptables
systemctl start iptables
# 一些操作案例
# 禁止ping
参考:https://www.jianshu.com/p/c1b786ba6b6b (opens new window)
1)默认直接禁ping的问题?
iptables -I INPUT -p icmp -j DROP
//设置完上面的规则后,其他主机确实无法ping本机,但本机也无法ping其他主机
//当本机ping其他主机,其他主机回应也是使用icmp,对方的回应被丢弃
2)禁止其他主机ping本机,允许本机ping其他主机
iptables -A INPUT -p icmp --icmp-type echo-request -j DROP
//仅禁止入站的ping请求,不拒绝入站的ping回应包
# 只允许SSH
参考:https://zhuanlan.zhihu.com/p/413032776 (opens new window)
建议先去/etc/ssh/sshd_config修改默认端口,然后重启ssh服务。
仅允许与此服务器的传入 SSH 连接。您可以从任何地方通过 ssh 连接到此服务器。
iptables -A INPUT -i eth0 -p tcp --dport 22 -j ACCEPT
上面的 iptables 命令有以下 4 个组件。
- “-A INPUT”——这表明我们正在向 INPUT 链追加(或添加)一条新规则。因此,此规则适用于传入流量。
- “-i eth0” – 将根据此规则检查通过接口 eth0 的传入数据包。
- “-p tcp –dport 22” – 此规则适用于 TCP 数据包。这有一个名为“-dport 22”的 tcp 选项,它表示服务器上此规则的目标端口是 22(即 ssh)。
- “-j ACCEPT”——跳转到接受,它只是接受数据包。
简单来说,上述规则可以表述为:所有通过 eth0 for ssh 传入的数据包都将被接受。
# 规则最后—丢弃规则外的其他数据包
参考:https://zhuanlan.zhihu.com/p/413032776 (opens new window)
一旦您指定了接受数据包的自定义规则,您还应该有一个默认规则来丢弃任何其他数据包。
这应该是您在 INPUT 链中的最后一条规则。
要丢弃所有传入的数据包,请执行以下操作。
iptables -A INPUT -j DROP
构建脚本配置规则:
# vi iptables.sh
iptables -A INPUT -i eth0 -p tcp --dport 22 -j ACCEPT
iptables -A INPUT -j DROP
iptables -L INPUT
# 防止端口扫描
见https://github.com/zfhxi/anti-portscan (opens new window)
https://github.com/EtherDream/anti-portscan/blob/master/install.sh (opens new window)
例子:
#!/usr/bin/env bash
#
# 使用 iptables/ipset 阻止端口扫描
#
# 如果有 IP 连接未开放端口,该 IP 将进入扫描者名单,过期时间 IP_DENY_SECOND 秒。
# 如果该 IP 继续连接未开放端口,过期时间不复位,但包计数器会累计,
# 如果累计超过 PORT_SCAN_MAX,该 IP 将无法连接任何端口,直到过期。
IP_DENY_SECOND=60
PORT_SCAN_MAX=3
# 目标网卡
DEV=enp2s0
#INPUT="-A INPUT"
INPUT="-I INPUT"
# INPUT=-t raw -A PREROUTING
# 开放的端口
ipset create pub-port-set bitmap:port range 0-65535
# 如果应用程序端口有变化,需及时更新该 set,否则正常用户会被当成扫描者
ipset add pub-port-set 22-39 # 访问22-39之外的端口,其ip会被加入黑名单
# 名单最大条数
# 例如 100Mbps 网络下 IP_DENY_SECOND 秒能收到多少 SYN 包?(SYN 最小 60B)
IP_SET_MAX=$((100 * 1024 * 1024 / 8 / 60 * $IP_DENY_SECOND))
# 扫描者名单
ipset create scanner-ip-set hash:ip \
timeout $IP_DENY_SECOND \
maxelem $IP_SET_MAX \
counters
## function trap-scan ##
iptables \
-N trap-scan
# 更新扫描者 packets/bytes 计数器
iptables \
-A trap-scan \
-m set --match-set scanner-ip-set src \
-j DROP
# 将 IP 加入扫描者名单(仅首次)
# 使用 iptables 动态改变 ipset,避免了额外的交互。本程序亮点~
iptables \
-A trap-scan \
-j SET \
--add-set scanner-ip-set src
iptables \
-A trap-scan \
-j DROP
## end function ##
# 连接未开放端口,大概率是扫描者,交给 trap-scan 处理
iptables \
-i $DEV \
$INPUT \
-p tcp --syn \
-m set ! --match-set pub-port-set dst \
-j trap-scan
# 连接未开放端口超过 PORT_SCAN_MAX 次的 IP,禁止访问任何服务!
# 此处不更新计数器
# 已建立的 TCP 不影响,因为此处只针对 --syn
iptables \
-i $DEV \
$INPUT \
-p tcp --syn \
-m set ! --update-counters \
--match-set scanner-ip-set src \
--packets-gt $PORT_SCAN_MAX \
-j DROP
# 屏蔽非 SYN 类型的端口扫描
# 例如扫描者发送 ACK,服务器默认会回复 RST,仍有可能暴露端口
# 因此对于非 SYN 包,如果不匹配已建立的连接,则丢弃
iptables \
-i $DEV \
-A INPUT \
-p tcp ! --syn \
-m conntrack ! --ctstate ESTABLISHED,RELATED \
-j DROP