我尝试将流量从一台服务器转发到另一台服务器,同时保留原始请求者 IP。因此,我无法使用 SNAT 或 MASQUERADE。
服务器A:
公网IP:111.111.111.111
私网IP:10.0.0.1
服务器B:
公网IP:222.222.222.222
私网IP:10.0.0.2
我想将流量从服务器 A(111.111.111.111)转发到服务器 B(10.0.0.2)。
这很好用:
iptables -t nat -A PREROUTING -d 111.111.111.111 -p tcp --dport 80 -j DNAT --to-destination 10.0.0.2:80
iptables -t nat -A POSTROUTING -j MASQUERADE
但是,由于我在本例中使用了 MASQUERADE,因此目标服务器 (10.0.0.2) 会看到所有流量都来自 111.111.111.111,即 apache-logs 和其他服务器会显示所有请求都来自 111.111.111.111
我该如何设置它,以便保留原始源 IP 地址,就像家庭路由器在使用端口转发时所做的那样。
我认为我需要以某种方式设置一个“路由”,以便来自 10.0.0.2 的传出流量通过服务器 A 出去,而不是尝试在服务器 B 的公共 IP 上做出响应?
答案1
看来您对网络感到困惑。
您在 NAT 级别上想要的东西根本没有意义。
地址必须在第 3 层网络数据包中重写,NAT 才能正常工作。
而且私有 IP 空间首先是不可路由的(在互联网上,内部网可能表现不同)。
您想要查看原始 IP 地址的地方是第 4 层:应用层。(日志等)那里的信息完全不受 NAT 的影响。您可能会看到 NAT 路由器的 IP 地址,但 Apache 日志仍应根据 HTPP 标头信息指示 NAT 后面的哪台机器/主机名/用户请求了该信息。
您混淆了不相关的不同事物。
答案2
您的DNAT
规则本身就足以进行地址转换,无需添加任何内容MASQUERADE
,POSTROUTING
您只需要告诉防火墙接受转换后的数据包。
例如我的进站路线:
/sbin/iptables -t nat -A PREROUTING -p tcp -d $EXTERNALIP --dport 22 -j DNAT --to $INTERNALTARGET:22
/sbin/iptables -A FORWARD -p tcp -d $INTERNALTARGET --dport 22 -j ACCEPT
从问题的措辞来看,您似乎试图将公共请求路由到一个私有子网,然后再路由到另一个子网 - 如果是这种情况,那么您可能需要进行路由调整,以便返回数据包知道要去哪里。在上面的例子中,我将公共接口 ($EXTERNALIP) 上的请求传递到与路由器直接连接的一个私有网络支路相连的机器 ($INTERNALTARGET),并且该路由器是默认路由,因此返回数据包无需额外帮助就知道要去哪里。
答案3
Iptables 很棒,但是如果你把所有东西都放在 nginx 中,那么它就可以完成它设计的任务。可以使用 iptables 执行其他高级技巧,例如日志记录和数据包标记,但是如果你没有理由在 nginx 之外执行这些操作,则应该通过 nginx。这样,如果你移动到不同的系统(例如 (Ugly)windows 服务器或 FreeBSD),则配置将在 nginx 中完成,而不是在系统相关级别完成。如果你担心速度,这就是 nginx 的设计目的,因此如果你使用一些预制的或开发自己的日志监视器,那么在你使用的每个系统上都是相同的。Linux 很棒,没有理由放弃它,但是如果你必须在其他环境中实现更多服务器,则你的所有配置都是独立于环境的。