Iptables不会将ssh访问转发到公有子网下的实例

我有以下情况:

1 – 一个堡垒(NAT)的实例,我用它作为网关来转发ssh访问所有我的私人实例(使用iptables)[私有IP:10.10.1.10公共IP:200.147.160.24]

2 – 在我的堡垒实例(使用互联网网关)相同vpc (但不在同一子网下)的公共实例[私有IP:10.10.9.23公共IP:186.192.90.5]

我想通过在堡垒(1)中的iptables向前访问我的公共实例(2),但我可以。 它导致超时。 (所有其他转发到私人实例的作品)。

这是有趣的,因为: – 如果我通过使用公共IP直接ssh公共实例工作正常。

  • 如果我SSH入堡垒,然后ssh使用其私有IP的公共实例,它也可以正常工作。

这是我在我的堡垒中使用的iptables规则:

iptables -t nat -A PREROUTING -d 0.0.0.0/0 -p tcp --dport 1500 -j DNAT --to-destination 10.10.9.23:22

这工作: ssh [email protected]

这工作(内部堡垒(1)): ssh [email protected]

这不起作用(超时): ssh -p 1500 [email protected]

  • 所有使用的端口都在安全组中打开。
  • 公共ips不是真实的,只是例如

任何想法表示赞赏。

这里有一个涉及NAT的非对称路由情况,这是行不通的。

当然,如果你的目标实例拥有公有IP,那么似乎堡垒主机没有太多的堡垒效应……但是假设你有一个合乎逻辑的理由,这里是我对这个问题的看法:

我们调用客户机C ,堡垒B和目标实例T

stream量到达:源IP = C,目的IP = B

B转换:源IP = C,目标IP = T。发送到T.

T收到:源IP = C,目的IP = T.

T回复:来源IP = T,目标IP = C

回复stream量在哪里? 没有到堡垒 – 它进入互联网网关…一个回应数据包的TCPstream量网关从来没有听说过。 网关,所有的权利,应该放弃它或发送一个TCP RST的发送实例T拆除这个无效的连接。

客户端C不应该看到这个回应,但即使这样做,客户现在看到…

来源IP = T,目标IP = C

客户端或任何中间有状态的防火墙都不会期望这种情况,所以stream量被丢弃或被拒绝。

使用你的私人地址的机器,默认的VPC路由(我假设)指向堡垒主机,所以这里没有不对称的情况。 堡垒可以在返回到C的路上将相反方向的地址翻译出来,一切正常。

现在,理论上来说,你应该可以通过在堡垒中join第二条规则来使这个设置工作,以便这些ssh连接采用堡垒主机的IP地址作为其地址。

留下DNAT规则,你需要这样的东西…

 iptables -t nat -A POSTROUTING -d 10.10.9.23/32 -p tcp --dport 22 -j SNAT 

当然,我只是做了这件事,因为我从来没有这样做过,但至less它的逻辑是正确的。

现在,假设这个(或类似的东西)有效,你已经解决了你的可达性问题,并且创build了一个新的问题:源IP地址(在服务器内部的日志中)将永远是堡垒主机。 我们没有太多的select,但要做到这一点,要使翻译连接可路由回到互联网……但是您最好只是使用公共地址访问机器。

另一种方法是在堡垒上使用HAProxy。 T服务器看到的源地址仍然是堡垒主机的内部地址…但是现在在堡垒主机上有很好的日志文件用于IP地址跟踪。 在需要将内部TCP服务公开给Internet的情况下,由于日志,访问控制和代理服务器提供的连接统计信息,这是我首选的DNAT方法。 (HAProxy既是一个http感知的负载均衡器,也是一个与负载无关的TCP负载均衡器,我不是这个产品的附属产品,只是一个粉丝)。

我不知道发生了什么,但怀疑路由问题/不匹配是一种可能性。 你有没有尝试使用像tcpdump这样的工具来检查数据包使它和路线?