我在提供MySQL服务的服务器上有一个相当简单的iptables防火墙,但是iptables似乎给了我非常不一致的结果。
脚本的默认策略如下所示:
iptables -P INPUT DROP
然后我可以使用以下规则公开MySQL:
iptables -A INPUT -p tcp --dport 3306 -j ACCEPT
有了这个规则,我可以连接到MySQL从任何源IP到服务器上的任何目标IP没有问题。 但是,当我尝试通过用以下代替上面的行来限制对三个IP的访问时,我遇到了麻烦(xxx = masked octect):
iptables -A INPUT -p tcp --dport 3306 -m state --state NEW -s 208.XXX.XXX.184 -j ACCEPT iptables -A INPUT -p tcp --dport 3306 -m state --state NEW -s 208.XXX.XXX.196 -j ACCEPT iptables -A INPUT -p tcp --dport 3306 -m state --state NEW -s 208.XXX.XXX.251 -j ACCEPT
一旦上述规定到位,会发生以下情况:
我可以从.184,.196和.251主机连接到MySQL服务器,只要连接到MySQL服务器,使用默认的IP地址或 IP别名与默认IP地址相同的子网即可。
当我来自.184或.196主机时,我无法使用从服务器的默认IP分配给服务器的IP别名连接到MySQL,但.251工作得很好。 从.184或.196主机,远程login尝试只是挂起…
# telnet 209.xxx.xxx.22 3306 Trying 209.xxx.xxx.22...
如果我删除了.251行(使.196添加了最后一个规则),那么.196主机仍然无法使用IP别名连接到MySQL(所以这不是造成不一致行为的规则的顺序)。 我知道,这个特别的testing是愚蠢的,因为这三个规则的顺序应该是什么顺序都不重要,但是我想有人会问。
如果我切换回“公共”规则,则所有主机都可以使用默认或别名IP(在任一子网中)连接到MySQL服务器:
iptables -A INPUT -p tcp --dport 3306 -j ACCEPT
服务器运行在CentOS 5.4 OpenVZ / Proxmox容器(2.6.32-4-pve)中。
而且,如果你喜欢在iptables脚本的上下文中看到问题规则,这里是(xxx = masked octect):
# Flush old rules, old custom tables /sbin/iptables --flush /sbin/iptables --delete-chain # Set default policies for all three default chains /sbin/iptables -P INPUT DROP /sbin/iptables -P FORWARD DROP /sbin/iptables -P OUTPUT ACCEPT # Enable free use of loopback interfaces /sbin/iptables -A INPUT -i lo -j ACCEPT /sbin/iptables -A OUTPUT -o lo -j ACCEPT # All TCP sessions should begin with SYN /sbin/iptables -A INPUT -p tcp ! --syn -m state --state NEW -j DROP # Accept inbound TCP packets (Do this *before* adding the 'blocked' chain) /sbin/iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT # Allow the server's own IP to connect to itself /sbin/iptables -A INPUT -i eth0 -s 208.xxx.xxx.178 -j ACCEPT # Add the 'blocked' chain *after* we've accepted established/related connections # so we remain efficient and only evaluate new/inbound connections /sbin/iptables -N BLOCKED /sbin/iptables -A INPUT -j BLOCKED # Accept inbound ICMP messages /sbin/iptables -A INPUT -p ICMP --icmp-type 8 -j ACCEPT /sbin/iptables -A INPUT -p ICMP --icmp-type 11 -j ACCEPT # ssh (private) /sbin/iptables -A INPUT -p tcp --dport 22 -m state --state NEW -s xxx.xxx.xxx.xxx -j ACCEPT # ftp (private) /sbin/iptables -A INPUT -p tcp --dport 21 -m state --state NEW -s xxx.xxx.xxx.xxx -j ACCEPT # www (public) /sbin/iptables -A INPUT -p tcp --dport 80 -j ACCEPT /sbin/iptables -A INPUT -p tcp --dport 443 -j ACCEPT # smtp (public) /sbin/iptables -A INPUT -p tcp --dport 25 -j ACCEPT /sbin/iptables -A INPUT -p tcp --dport 2525 -j ACCEPT # pop (public) /sbin/iptables -A INPUT -p tcp --dport 110 -j ACCEPT # mysql (private) /sbin/iptables -A INPUT -p tcp --dport 3306 -m state --state NEW -s 208.xxx.xxx.184 -j ACCEPT /sbin/iptables -A INPUT -p tcp --dport 3306 -m state --state NEW -s 208.xxx.xxx.196 -j ACCEPT /sbin/iptables -A INPUT -p tcp --dport 3306 -m state --state NEW -s 208.xxx.xxx.251 -j ACCEPT
有任何想法吗? 提前致谢。 🙂
.184或.196主机客户端主机在另一个子网中是否还有其他IP地址?
如果你做了一个tcpdump -qn port 3306并试图从这些系统之一连接,你看到了什么? 你看到你期望的源地址吗? 这可能是一个简单的路由问题。
当一个系统做出路由决定时,它查阅路由表。 路由表是一个总是以特定顺序查询的列表。 本地networking的链路路由几乎总是最优选的路由,并将在使用网关(路由器)的路由之前使用。 默认网关始终是没有其他路由将应用时使用的路由。 如果给定的路由有一个src定义的路由,那么该地址将是首选的,并且最有可能在该路由被使用时使用。
10.2.13.0/24 dev eth1 proto kernel scope link src 10.2.13.1 10.2.4.0/23 dev eth0 proto kernel scope link src 10.2.4.245 default via 10.2.4.1 dev eth0
因此,考虑到多宿主系统的这个路由表,来自10.2.13.1任何东西将来自10.2.13.1 ,而去往10.2.4.0/23任何东西将来自10.2.4.245 。