NAT 倍数服务器

Dar*_*rky 3 networking linux routing iptables reverse-proxy

我需要一个专家来配置NAT重定向(iptables)来维护客户端的源地址。目前我的服务器可以工作,但所有客户端都显示我的 vLAN 的私有 IP。

我的服务器重定向的操作示例:

VPS 1 (Public IP) redirect traffic to VPS 5 (Private IP)
VPS 2 (Public IP) redirect traffic to VPS 5 (Private IP)
VPS 3 (Public IP) redirect traffic to VPS 5 (Private IP)
VPS 4 (Public IP) redirect traffic to VPS 5 (Private IP)
Run Code Online (Sandbox Code Playgroud)

但是在重定向流量时,会将客户端的 IP 更改为客户端访问的公共服务器的私有 IP。

TCPDUMP:

IP 10.0.1.130.61570> 10.0.1.138.85: UDP, length 35
IP 10.0.1.132.63112> 10.0.1.138.85: UDP, length 35
IP 10.0.1.133.63435> 10.0.1.138.85: UDP, length 35
IP 10.0.1.136.63432> 10.0.1.138.85: UDP, length 35
Run Code Online (Sandbox Code Playgroud)

这是重定向完成后所有客户端都分配了私有IP的问题,我需要维护客户端的真实IP。

如果我删除规则“iptables -t nat -A POSTROUTING -j MASQUERADE”

然后维护客户端的 IP,但服务器使用私有 IP 向客户端的 IP 响应数据包。

TCPDUMP:

IP 10.0.1.138.85> client1.isp.net.61570: UDP, length 45
IP 10.0.1.138.85> client2.isp.net.63112: UDP, length 45
IP 10.0.1.138.85> client3.isp.net.63435: UDP, length 45
IP 10.0.1.138.85> client4.isp.net.63432: UDP, length 45
Run Code Online (Sandbox Code Playgroud)

我想保留客户端的真实 IP,但 (VPS 5) 没有将数据包路由回互联网。

Ant*_*lov 5

我知道有两种方法可以解决您的问题:

简单的方法

您可以在DNAT没有SNAT规则的 VPS 主机上使用规则中的其他端口范围。并根据这些端口号VPS-5路由通过正确的主机返回回复。

简短示例:

  • 规划VPS-5其他主机将从客户端转发数据包的其他端口号。让我们猜测VPS-1转发数据包 to VPS-5 tcp/10001, the VPS2- toVPS-5 tcp/10002等等。

  • 在每台VPS主机上,您只需要一条规则即可将流量转发到VPS-5. 所以,在VPS-1规则上看起来像:

# vps-1 host
iptables -t nat -A PREROUTING \
         --dst <vps-1-pub-ip> -p udp --dport <srv-port> \
    -j DNAT --to-destination <vps-5-ip>:10001
Run Code Online (Sandbox Code Playgroud)
  • 关于VPS-5你需要更复杂的配置。诀窍在于,VPS5接收转发请求的端口号也指向 VPS 主机,回复应该通过该主机路由。

  • VPS-5您需要单独的路由表和每个其他VPS主机的路由规则。VPS-1和的示例VPS-2

# vps-5 host
ip route add <connected-subnet> dev <iface> table 1
ip route add 0/0 via <VPS-1-INT-IP> dev <iface> table 1
ip rule add fwmark 1 lookup 1 pref 10001

ip route add <connected-subnet> dev <iface> table 2
ip route add 0/0 via <VPS-2-INT-IP> dev <iface> table 2
ip rule add fwmark 2 lookup 2 pref 10002
Run Code Online (Sandbox Code Playgroud)
  • 标记来自 VPS 主机的传入连接并将其保存到 conntrack 条目中:
# vps-5 host
iptables -t mangle -A PREROUTING \
         -m conntrack --ctstate NEW \
         -p udp --dport 10001 \
    -j CONNMARK --set-mark 0x1
Run Code Online (Sandbox Code Playgroud)
  • 将请求重定向到服务端口:
# vps-5 host
iptables -t nat -A PREROUTING \
         --dst <vps-5-ip> -p udp --dport 10001:10004 \
    -j REDIRECT --to-ports 85
Run Code Online (Sandbox Code Playgroud)
  • 在回复数据包上设置防火墙标记以将它们路由回正确的 VPS 主机:
# vps-5 host
iptables -t mangle -A OUTPUT \
         -m conntrack --ctstate DNAT --ctdir REPLY \
    -j CONNMARK --restore-mark
Run Code Online (Sandbox Code Playgroud)

这种方式仅适用于主机之间直接连接的情况。否则,您应该使用下一种方式。

隧道模式

在某些情况下,服务器之间不是直接连接,而是通过一些路由器连接。在这些情况下,上述方式将无济于事,因为每个中间路由器都独立做出路由决定。

据我所知,保存客户端的源地址并将数据包从前端主机(VPS-1- VPS-4)重定向到目标主机(VPS-5)的唯一方法是使用隧道。

简化的解决方案: * 规划额外的 ip 寻址以供隧道内使用。* 在每个前端主机 ( VPS-1- VPS-4) 上创建到VPS-5. 您可以根据需要进行任何类型的隧道传输。以最简单的方式,您可以使用静态 GRE 隧道,但它有一些限制,例如避免 NAT。* 在每台前端主机上,您只需要一条规则即可将流量转发到VPS-5. 示例VPS-

# vps-1 host
iptables -t nat -A PREROUTING \
         --dst <vps-1-pub-ip> -p udp --dport <srv-port> \
    -j DNAT --to-destination <vps-5-tun-ip>
Run Code Online (Sandbox Code Playgroud)
  • VPS-5你还应该配置额外的路由表和路由规则通过右前主回复:
# vps-5 host
ip route add 0/0 dev <vps-1-tun-iface> table 1
ip rule add fwmark 1 lookup 1 pref 10001
Run Code Online (Sandbox Code Playgroud)
  • 根据输入接口标记传入连接并将其保存到conntrack条目中:
iptables -t mangle -A PREROUTING \
         -m conntrack --ctstate NEW \
         -i <vps-1-tun-iface> \
    -j CONNMARK --set-mark 0x1
Run Code Online (Sandbox Code Playgroud)
  • 如果您的应用程序不侦听隧道 IP 地址,则应将来自前端主机的传入数据包重定向到侦听地址:
iptables -t nat -A PREROUTING \
         -i <vps-1-tun-iface> \
         -p udp --dport <srv-port> \
    -j DNAT --to-destination <srv-listen-ip>
Run Code Online (Sandbox Code Playgroud)
  • 在回复数据包上设置防火墙标记:
iptables -t mangle -A OUTPUT \
    -j CONNMARK --restore-mark
Run Code Online (Sandbox Code Playgroud)
  • 不要忘记在过滤器表中允许这些数据包:
iptables -t filter -A INPUT \
         -m conntrack --ctstate ESTABLISHED,RELATED
    -j ACCEPT
...
iptables -t filter -A INPUT \
         -p udp --dport <srv-port>
    -j ACCEPT
Run Code Online (Sandbox Code Playgroud)