NAT Multiples servers

Posted on

NAT Multiples servers – A server stack is the collection of software that forms the operational infrastructure on a given machine. In a computing context, a stack is an ordered pile. A server stack is one type of solution stack — an ordered selection of software that makes it possible to complete a particular task. Like in this post about NAT Multiples servers was one problem in server stack that need for a solution. Below are some tips in manage your linux server when you find problem about linux, networking, iptables, routing, reverse-proxy.

I need an expert to configure the NAT redirection (iptables) to maintain the source address of the client. Currently my servers work but all clients appear with the private IPs of my vLAN.

Example of the operation of my server redirection:

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)

But when redirecting the traffic changes the IP of the client to the private IP of the public server where the client accesses.

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

This is the problem that all clients are assigned the private IP when the redirection is done and I need to maintain the real IP of the client.

If I remove the rule “iptables -t nat -A POSTROUTING -j MASQUERADE”

Then the IPs of the clients are maintained but the server responds the packets with the private IP to the IPs of the clients.

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

I want keep real IP of clients but the (VPS 5) no routing back out the packets to internet.

I know two ways to solve your issue:

Simple way

You can use the additional port ranges in the DNAT rule on the VPS hosts without SNAT rule. And based on these port numbers the VPS-5 routes back the replies through right host.

Short example:

  • Plan the additional port numbers on the VPS-5 to which the other hosts will forward packets from clients. Let’s guess the VPS-1 forward packets to VPS-5 tcp/10001, the VPS2 – to VPS-5 tcp/10002 and so on.

  • On every VPS host you need only the one rule to forward traffic to the special port of the VPS-5. So, on VPS-1 the rule will looks like:

# 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
  • On the VPS-5 you need more complex configuration. The trick in that, what port number to which the VPS5 receives the forwarded request, also points to the VPS host, through which the replies should be routed.

  • On the VPS-5 you need the separate routing table and the routing rule per every other VPS host. Example for VPS-1 and 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
  • Mark the incoming connections from the VPS hosts and save it into the conntrack entry:
# vps-5 host
iptables -t mangle -A PREROUTING 
         -m conntrack --ctstate NEW 
         -p udp --dport 10001 
    -j CONNMARK --set-mark 0x1
  • Redirect the request to the service port:
# vps-5 host
iptables -t nat -A PREROUTING 
         --dst <vps-5-ip> -p udp --dport 10001:10004 
    -j REDIRECT --to-ports 85
  • Set the firewall mark on reply packets to route back them to right the VPS host:
# vps-5 host
iptables -t mangle -A OUTPUT 
         -m conntrack --ctstate DNAT --ctdir REPLY 
    -j CONNMARK --restore-mark

This way is applicable only if the hosts is connected to each other directly. Otherwise you should use the next way.

Tunnel mode

In some cases the servers aren’t connected directed to each other, but through some routers. In these cases the way, described above, won’t help, because every intermediate router make decision about routing independently.

Only way, what I know, to save the source address of client and redirect the packets from a front host (VPS-1VPS-4) to the target host (VPS-5), is usage of tunneling.

Simplified solution:
* Plan the additional ip addressing for usage inside the tunnels.
* On every front host (VPS-1VPS-4) you create the tunnel to VPS-5. You can you any type of tunneling what you want. In simplest way you can use the static GRE tunnels, but it have some limitations like avoiding NAT.
* On every front host you need only one rule to forward traffic to the VPS-5. Example for 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>
  • On the VPS-5 you should also configure additional routing tables and routing rules to reply through the right front host:
# vps-5 host
ip route add 0/0 dev <vps-1-tun-iface> table 1
ip rule add fwmark 1 lookup 1 pref 10001
  • Mark the incoming connections based on input interface and save it into the conntrack entry:
iptables -t mangle -A PREROUTING 
         -m conntrack --ctstate NEW 
         -i <vps-1-tun-iface> 
    -j CONNMARK --set-mark 0x1
  • If your app doesn’t listen the tunnel ip addresses, you should redirect the incoming packets from the front hosts to listened address:
iptables -t nat -A PREROUTING 
         -i <vps-1-tun-iface> 
         -p udp --dport <srv-port> 
    -j DNAT --to-destination <srv-listen-ip>
  • Set the firewall mark on reply packets:
iptables -t mangle -A OUTPUT 
    -j CONNMARK --restore-mark
  • Don’t forget allow these packets in the filter table:
iptables -t filter -A INPUT 
         -m conntrack --ctstate ESTABLISHED,RELATED
    -j ACCEPT
...
iptables -t filter -A INPUT 
         -p udp --dport <srv-port>
    -j ACCEPT

Leave a Reply

Your email address will not be published. Required fields are marked *