Take the 2-minute tour ×
Server Fault is a question and answer site for system and network administrators. It's 100% free, no registration required.

Unfortunately we have a client who has hardcoded a device to point at a specific IP and port. We'd like to redirect traffic from their IP to our load balancer which will send the HTTP POSTs to a pool of servers able to handle that request. I would like existing traffic from all other IPs to be unaffected.

I believe iptables is the best way to accomplish this and I think this command should work:

/sbin/iptables -t nat -A PREROUTING -s $CUSTIP -j DNAT -p tcp --dport 8080 -d $CURR_SERVER_IP --to-destination $NEW_SERVER_IP:8080

Unfortunately it isn't working as expected. I'm not sure if I need to add another rule, potentially in the POSTROUTING chain?

Below I've substituted the variables above with real IPs and tried to replicate the layout in my test environment in incremental steps.
$CURR_SERVER_IP = 192.168.2.11
$NEW_SERVER_IP = 192.168.2.12
$CUST_IP = 192.168.0.50

  • Port forward on the same IP

    /sbin/iptables -t nat -A PREROUTING -p tcp -d 192.168.2.11 --dport 16000 -j DNAT --to-destination 192.168.2.11:8080

Works exactly as expected.

  • IP and port forward to a different machine

    /sbin/iptables -t nat -A PREROUTING -p tcp -d 192.168.2.11 --dport 16000 -j DNAT --to-destination 192.168.2.12:8080

Connections seem to timeout.

  • Restrict IP and port forward to only be applied to requests from a specific IP

    /sbin/iptables -t nat -A PREROUTING -p tcp -s 192.168.0.50 -d 192.168.2.11 --dport 16000 -j DNAT --to-destination 192.168.2.12:8080

I've added the ACCEPT rule as @Massimo suggested but still not seeing any success.

I started fresh and have run the following commands:

# /sbin/iptables -t nat -A PREROUTING -p tcp -d 192.168.2.11 --dport 16000 -j DNAT --to-destination 192.168.2.12:8080   
# iptables -A FORWARD -j ACCEPT

And the rules now look like:

# iptables -L  -v --line-numbers  (see FORWARD rule 7)

Chain INPUT (policy ACCEPT 1115M packets, 889G bytes)  
num   pkts bytes target     prot opt in     out     source               destination           
1        0     0 ACCEPT     udp  --  virbr0 any     anywhere             anywhere            udp dpt:domain   
2        0     0 ACCEPT     tcp  --  virbr0 any     anywhere             anywhere            tcp dpt:domain   
3        0     0 ACCEPT     udp  --  virbr0 any     anywhere             anywhere            udp dpt:bootps   
4        0     0 ACCEPT     tcp  --  virbr0 any     anywhere             anywhere            tcp dpt:bootps   

Chain FORWARD (policy ACCEPT 112 packets, 5936 bytes)  
num   pkts bytes target     prot opt in     out     source               destination           
1        0     0 ACCEPT     all  --  any    virbr0  anywhere             192.168.122.0/24    state RELATED,ESTABLISHED 
2        0     0 ACCEPT     all  --  virbr0 any     192.168.122.0/24     anywhere              
3        0     0 ACCEPT     all  --  virbr0 virbr0  anywhere             anywhere              
4        0     0 REJECT     all  --  any    virbr0  anywhere             anywhere            reject-with icmp-port-unreachable 
5        0     0 REJECT     all  --  virbr0 any     anywhere             anywhere            reject-with icmp-port-unreachable 
6        0     0 ACCEPT     all  --  any    any     anywhere             anywhere            state RELATED,ESTABLISHED 
7        6   336 ACCEPT     all  --  any    any     anywhere             anywhere            

Chain OUTPUT (policy ACCEPT 813M packets, 428G bytes)
num   pkts bytes target     prot opt in     out     source               destination         

and

# iptables -L -t nat -v --line-numbers
Chain PREROUTING (policy ACCEPT 3108K packets, 242M bytes)
num   pkts bytes target     prot opt in     out     source               destination         
1        0     0 DNAT       tcp  --  any    any     anywhere             192.168.2.11 tcp dpt:16000 to:192.168.2.12:8080 

Chain POSTROUTING (policy ACCEPT 13M packets, 790M bytes)
num   pkts bytes target     prot opt in     out     source               destination         
1     8644 1979K MASQUERADE  all  --  any    any     192.168.122.0/24     anywhere            

Chain OUTPUT (policy ACCEPT 13M packets, 792M bytes)
num   pkts bytes target     prot opt in     out     source               destination         

Does anyone see obvious issues that would cause a browser to time out when I go to http://192.168.2.11:16000?

thanks,

share|improve this question
2  
Just a comment; an easier way of showing us your iptables rules is to run iptables-save; the output of this is typically more useful (since it shows the actual commands used to create the rule). This is for future reference and not a request to change your current question. –  larsks Feb 12 '11 at 2:12

4 Answers 4

up vote 1 down vote accepted

Your NAT rule seems ok, but have you also added an ACCEPT rule for this traffic?

Otherwise, NAT will kick in finely, but then the resulting packet will silently be dropped...


Update:

You need this rule in the FORWARD chain (which is where packets going thorugh the firewall but not directly related to it are processed).

FORWARD rules are applied after PREROUTING rules (like NAT), so when this rule is applied the packets will appear like they're coming from the original IP but directed to the modified new destination IP. The rule should thus be somewhat like this:

/sbin/iptables -A FORWARD -s $CUSTIP -d $NEW_SERVER_IP -j ACCEPT
share|improve this answer
    
I have not added any ACCEPT rules. I'm new to iptables so I'll do some more research but are you suggesting I need this rule on $CURR_SERVER_IP to accept from $CUST_IP or on $NEW_SERVER_IP? –  cclark Jun 10 '10 at 17:35
    
@cclark: see edit above. –  Massimo Jun 10 '10 at 18:00
    
Thanks. Still no dice. I've updated and included the rules list above in hopes that a little more information might shed some light on the issue. –  cclark Jun 12 '10 at 0:25

I had posted a similar question and found the answer for it my self. Here is the link : -

How to use iptables to forward requests to a jBoss server running on a different machine?

share|improve this answer

I presume you're using the linux box as a router and that this linux box can see the new IP.

I believe that the NAT table only kicks in when /proc/sys/net/ipv4/ip_forward is set to 1. To make this persistent, put the following line in /etc/sysctl.conf:

net.ipv4.ip_forward = 1
share|improve this answer

(One of the most serious problems here is people don't know how to ask question. It makes Serverfault.com look like Guesswhatfault.com.)

In your question nothing's said bout topology, alas. We don't know whether could your server reach back your client — they're in different subnets, actually. Would you client think the server's reachable is another question. You can try using MASQUERADE/SNAT to change client's IP or think a little bit how to explain what your question really is.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.