我们在 AWS 中运行 ubuntu 20.04。我们正在尝试设置一条 iptables 规则,以便任何具有虚拟 IP 地址的 MySQL 流量都将被转发到同一 VPC 中 172.31.6.173 处的 MySql 数据库。让我解释一下:
本任务中的 IP 地址:
Ubuntu 服务器(源):172.31.0.151
MySql 服务器(目标):172.31.6.173
MySql 虚拟 IP:6.6.6.6
从 172.31.0.151(源)我们将连接到虚拟 IP(6.6.6.6)上的 mysql,然后它将被 NAT 到目标(172.31.6.173)。
我们使用的规则:
sudo iptables -t nat -A PREROUTING -s 172.31.0.151 -d 6.6.6.6 -j DNAT --to-destination 172.31.6.173
sudo iptables -A FORWARD -p tcp -d 172.31.6.173 -j ACCEPT
第一行指定来自 172.31.0.151 的任何流量,目的地为 6.6.6.6,都将转发到 172.31.6.173
第二行接受所有 tcp 转发到 172.31.6.173。
这些是 iptables 中唯一的规则,如果我运行sudo iptables -t nat -L
,结果是:
Chain PREROUTING (policy ACCEPT)
target prot opt source destination
DNAT all -- 172.31.0.151 6.6.6.6 to:172.31.6.173
Chain INPUT (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
Chain POSTROUTING (policy ACCEPT)
target prot opt source destination
但是,有了这两条规则,当我尝试从源服务器(172.31.0.151)以虚拟 IP 登录 MySql 时:
mysql -h 6.6.6.6 -u username -p
tcpdump 输出:(MySql 服务器是 RDS 实例,这意味着我无法登录运行 tcpdump,因此我只能从源服务器获取 tcpdump):
13:41:41.768171 IP 172.31.0.151.50374 > 6.6.6.6.mysql:标志 [S],seq 3441229166,win 62727,选项 [mss 8961,sackOK,TS val 2723434614 ecr 0,nop,wscale 7],长度 0
13:41:45.992114 IP 172.31.0.151.50374 > 6.6.6.6.mysql:标志 [S],seq 3441229166,win 62727,选项 [mss 8961,sackOK,TS val 2723438838 ecr 0,nop,wscale 7],长度 0
13:41:54.184186 IP 172.31.0.151.50374 > 6.6.6.6.mysql:标志 [S],seq 3441229166,win 62727,选项 [mss 8961,sackOK,TS val 2723447030 ecr 0,nop,wscale 7],长度 0
PREROUTING 规则没有生效,登录尝试仍然在寻找 6.6.6.6 的服务器,而不是通过 NAT 到实际 IP 地址 172.31.6.173。
任何建议都将不胜感激。谢谢。
答案1
我假设 OP 的规则已添加到 IP 地址为 172.31.0.151 的 Ubuntu 系统中,该系统随后启动与虚拟地址的 mysql 连接。
- 本地进程发起的流中第一个数据包不会穿越 nat/PREROUTING,
- 但它确实穿越了 nat/OUTPUT,
- 只有连接的第一个数据包(状态 NEW)才会穿过纳特表(因此,诸如回复之类的进一步的数据包在这里并不重要)。
因此 nat/PREROUTING 对重定向本地发起的连接无效。这应该在 nat/OUTPUT 中完成。由于这可能会改变要使用的接口(在 OP 的情况下可能不会),这会触发重新路由检查稍后处理此类案件。
最后你的规则应该添加:
sudo iptables -t nat -A OUTPUT -s 172.31.0.151 -d 6.6.6.6 -j DNAT --to-destination 172.31.6.173
如果系统只有一个 IP 地址:172.31.0.151,则-s 172.31.0.151
变得多余:
sudo iptables -t nat -A OUTPUT -d 6.6.6.6 -j DNAT --to-destination 172.31.6.173