【iptables】用iptables实现只允许特定主机访问本机
本机ip: 192.168.0.105
# systemctl stop firewalld
# systemctl disable firewalld
cat gen_iptables.sh
#!/bin/bash
ips="
127.0.0.1
192.168.0.104
192.168.0.107
"
echo "iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT"
echo "iptables -A INPUT -p tcp -m state --state NEW,ESTABLISHED,RELATED --dport 22 -j ACCEPT"
for ip in ${ips[@]}
do
echo "iptables -A INPUT -p tcp -s ${ip} --dport 1:65535 -j ACCEPT"
done
for ip in ${ips[@]}
do
echo "iptables -A INPUT -p udp -s ${ip} --dport 1:65535 -j ACCEPT"
done
echo "iptables -A INPUT -p tcp --dport 1:65535 -j REJECT"
echo "iptables -A INPUT -p udp --dport 1:65535 -j REJECT"
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -p tcp -m state --state NEW,ESTABLISHED,RELATED --dport 22 -j ACCEPT
iptables -A INPUT -p tcp -s 127.0.0.1 --dport 1:65535 -j ACCEPT
iptables -A INPUT -p tcp -s 192.168.0.104 --dport 1:65535 -j ACCEPT
iptables -A INPUT -p tcp -s 192.168.0.107 --dport 1:65535 -j ACCEPT
iptables -A INPUT -p udp -s 127.0.0.1 --dport 1:65535 -j ACCEPT
iptables -A INPUT -p udp -s 192.168.0.104 --dport 1:65535 -j ACCEPT
iptables -A INPUT -p udp -s 192.168.0.107 --dport 1:65535 -j ACCEPT
iptables -A INPUT -p tcp --dport 1:65535 -j REJECT
iptables -A INPUT -p udp --dport 1:65535 -j REJECT
需要首先执行 iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT 是什么原因?
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT 是用来处理已建立的连接以及相关的连接。
这是因为在一个连接建立之后,数据包就会被标记为 ESTABLISHED 状态,而与该连接相关的数据包也会被标记为 RELATED 状态。
通过允许已建立的连接和相关的连接,您的服务器可以正确地处理与已建立连接相关的数据包,确保网络通信的连贯性和正确性。这样可以避免因为阻止已建立的连接或相关连接而导致通信中断或出错的情况发生。
因此,允许 ESTABLISHED 和 RELATED 状态的数据包是一个良好的网络安全实践。
如果没有这句,会导致服务器无法访问其他第三方地址。
为什么这一句不需要 --state NEW ?
在防火墙规则中,--state NEW
选项用于匹配新建立的连接请求,而 --state ESTABLISHED
用于匹配已建立的连接,--state RELATED
用于匹配与已建立连接相关的数据包。
通常情况下,针对入站数据包,我们只需要检查已建立的连接和相关连接,因为入站数据包中的连接建立请求已经被系统内核的连接追踪模块处理过。所以当数据包到达防火墙时,它们被标记为已建立或相关的状态。
--state NEW
主要用于入站数据包中的连接建立请求,而对于已经建立的连接或与之相关的数据包,它们会被标记为已建立或相关状态而不是新状态。
因此,在针对入站数据包的防火墙规则中,通常不需要显式地包含 --state NEW
条件,因为已建立和相关的状态通常足以处理这些数据包,而 --state NEW
更适用于处理连接建立请求的数据包。
# iptables -nvL --line
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
num pkts bytes target prot opt in out source destination
1 52 3684 ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED
2 0 0 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 state NEW,RELATED,ESTABLISHED tcp dpt:22
3 0 0 ACCEPT tcp -- * * 127.0.0.1 0.0.0.0/0 tcp dpts:1:65535
4 0 0 ACCEPT tcp -- * * 192.168.0.104 0.0.0.0/0 tcp dpts:1:65535
5 0 0 ACCEPT tcp -- * * 192.168.0.107 0.0.0.0/0 tcp dpts:1:65535
6 0 0 ACCEPT udp -- * * 127.0.0.1 0.0.0.0/0 udp dpts:1:65535
7 0 0 ACCEPT udp -- * * 192.168.0.104 0.0.0.0/0 udp dpts:1:65535
8 0 0 ACCEPT udp -- * * 192.168.0.107 0.0.0.0/0 udp dpts:1:65535
9 0 0 REJECT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpts:1:65535 reject-with icmp-port-unreachable
10 0 0 REJECT udp -- * * 0.0.0.0/0 0.0.0.0/0 udp dpts:1:65535 reject-with icmp-port-unreachable
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
num pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 21 packets, 1848 bytes)
num pkts bytes target prot opt in out source destination
在 192.168.0.104上测试:
image.png
在 192.168.0.107上测试:
image.png
在 192.168.0.106上测试:
image.png
如果docker容器监听映射到宿主机的端口,要如何限制?
#!/bin/bash
nic="eth0"
ips="
127.0.0.1
192.168.0.104
192.168.0.107
"
echo "iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT"
echo "iptables -A INPUT -p tcp -m state --state NEW,ESTABLISHED,RELATED --dport 22 -j ACCEPT"
echo "iptables -I DOCKER -i ${nic} -p tcp --dport 1:65535 -j DROP"
echo "iptables -I DOCKER -i ${nic} -p udp --dport 1:65535 -j DROP"
for ip in ${ips[@]}
do
echo "iptables -I DOCKER -i ${nic} -s ${ip} -p tcp --dport 1:65535 -j ACCEPT"
done
for ip in ${ips[@]}
do
echo "iptables -I DOCKER -i ${nic} -s ${ip} -p tcp --dport 1:65535 -j ACCEPT"
done
参考
【iptables&docker】对运行docker的服务器开启iptables策略
https://www.jianshu.com/p/a16b07cf3da0
【iptables】关于iptabels的-A与-I参数的区别
https://www.jianshu.com/p/b06e945de464