我们在 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
但是,当我尝试以虚拟 IP 登录 MySql 时,从源(172.31.0.151)服务器有了这两个规则:
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, options [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, options [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, options [mss 8961,sackOK,TS val 2723447030 ecr 0,nop,wscale 7], 长度 0
PREROUTING 规则不生效,登录尝试仍在寻找 6.6.6.6 的服务器,而不是 NAT 到实际 IP 地址 172.31.6.173。
任何建议将被认真考虑。谢谢你。
我假设 OP 的规则已添加到 IP 地址为 172.31.0.151 的 Ubuntu 系统中,该系统随后将启动 mysql 连接到一个虚拟地址。
从这个Netfilter 和通用网络示意图 中可以看出:
所以 nat/PREROUTING 对重定向本地发起的连接没有影响。这应该在 nat/OUTPUT 中完成。因为这甚至可能改变要使用的接口(可能不是在 OP 的情况下),这会触发稍后的重新路由检查以处理这种情况。
最后,您的规则应添加:
如果系统只有一个 IP 地址:172.31.0.151,
-s 172.31.0.151
就变得多余了: