我在提供 MySQL 服务的服务器上有一个相当简单的 iptables 防火墙,但是 iptables 似乎给了我非常不一致的结果。
脚本上的默认策略如下:
iptables -P INPUT DROP
然后我可以使用以下规则将 MySQL 公开:
iptables -A INPUT -p tcp --dport 3306 -j ACCEPT
有了这条规则,我可以从服务器上的任何源 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
一旦上述规则生效,就会发生以下情况:
我能只要使用默认 IP 地址连接到 MySQL 服务器,就可以从 .184、.196 和 .251 主机连接到 MySQL 服务器或者与默认 IP 地址位于同一子网中的 IP 别名。
我是无法当我从 .184 或 .196 主机访问时,使用分配给服务器的 IP 别名(与服务器的默认 IP 位于不同的子网)连接到 MySQL,但 .251 工作正常。从 .184 或 .196 主机访问时,telnet 尝试会挂起...
# telnet 209.xxx.xxx.22 3306 Trying 209.xxx.xxx.22...
如果我删除 .251 行(使 .196 成为最后添加的规则),.196 主机仍然无法使用 IP 别名连接到 MySQL(因此,导致不一致行为的不是规则的顺序)。我知道,这个特定的测试很愚蠢,因为这三个规则的添加顺序并不重要,但我想有人可能会问。
如果我切换回“公共”规则,则所有主机都可以使用默认或别名 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
有什么想法吗?提前谢谢。:-)
答案1
.184 或 .196 主机客户端主机在其他子网中是否也有额外的 IP 地址?
如果您执行tcpdump -qn port 3306
并尝试从其中一个系统进行连接,您会看到什么?您是否看到了您期望的源地址?这可能是一个简单的路由问题。
当系统做出路由决定时,它会查阅路由表。路由表是一个始终按特定顺序查阅的列表。本地网络的链接路由几乎总是最优先的路由,并将在使用网关(路由器)的路由之前使用。默认网关始终是当没有其他路由适用时使用的路由。如果给定路由已定义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.0/24
都将来自10.2.13.1
,而任何发往 的邮件10.2.4.0/23
都将来自10.2.4.245
。