1

I have a server with two network adaptors: eth0 and eth1. This server is running two distinct https webservers: One is listening on eth0 (172.29.49.112:8443) The other is listening on eth1 (172.29.49.113:4443)

I have NAT rules for iptables that successfully redirect the standard https port (443) for both of these applications, but the iptables rules will only work for ONE of the rules at a time (which one it activates seems to be random across reboots).

Here are the rules loaded at boot time from rc.local (yes, I know that running my firewall rules from rc.local is not recommended):

#!/bin/sh -e

# setup port forwarding for gerrit and jenkins instances
su root -c "/sbin/iptables -t nat -A PREROUTING -i eth1 -d 172.29.49.113 -p tcp --dport 443 -j REDIRECT --to-port 4443"
su root -c "/sbin/iptables -t nat -A PREROUTING -i eth0 -d 172.29.49.112 -p tcp --dport 443 -j REDIRECT --to-port 8443"

# start gerrit (jenkins should auto-start as a service)
su gerrit2 -c "/home/gerrit2/gerrit/bin/gerrit.sh start"

exit 0

And here is the output of "iptables -t nat -L -n -v":

Chain PREROUTING (policy ACCEPT 14458 packets, 1446K bytes)
 pkts bytes target     prot opt in     out     source               destination         
    6   360 REDIRECT   tcp  --  eth0   *       0.0.0.0/0            172.29.49.112        tcp dpt:443 redir ports 8443
    0     0 REDIRECT   tcp  --  eth1   *       0.0.0.0/0            172.29.49.113        tcp dpt:443 redir ports 4443

Chain INPUT (policy ACCEPT 7436 packets, 874K bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain OUTPUT (policy ACCEPT 94 packets, 7050 bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain POSTROUTING (policy ACCEPT 94 packets, 7050 bytes)
 pkts bytes target     prot opt in     out     source               destination         

As you can see there are no other rules being loaded.

When I only run one of the two rules everything works correctly (for that rule), but then even if I clear the rules with "iptables -t nat -F" I can't enable the other rule (unless I reboot - that seems to clear things properly).

Why am I trying to do this? I want my users to be able to access jenkins.servername.localnet and gerrit.servername.localnet rather than jenkins.servername.localnet:4443 etc. (Obviously jenkins.servername.localnet resolves to 172.29.49.113 and .112 for gerrit).

At one point I thought that it may be the jenkins/gerrit webservers listening on all IPs causing the problem. But both of them are set to listen only on a single IP (jenkins - 172.29.49.113, gerrit - 172.29.49.112).

It's probably not required, but just incase it helps - here is the output of ifconfig:

eth0      Link encap:Ethernet  HWaddr 00:0c:29:99:52:e8  
          inet addr:172.29.49.112  Bcast:172.29.63.255  Mask:255.255.240.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:78588 errors:0 dropped:0 overruns:0 frame:0
          TX packets:27399 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:16180230 (15.4 MiB)  TX bytes:6329245 (6.0 MiB)

eth1      Link encap:Ethernet  HWaddr 00:0c:29:99:52:f2  
          inet addr:172.29.49.113  Bcast:172.29.63.255  Mask:255.255.240.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:45058 errors:0 dropped:0 overruns:0 frame:0
          TX packets:9 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:3496805 (3.3 MiB)  TX bytes:378 (378.0 B)

lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          UP LOOPBACK RUNNING  MTU:16436  Metric:1
          RX packets:1090 errors:0 dropped:0 overruns:0 frame:0
          TX packets:1090 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:268078 (261.7 KiB)  TX bytes:268078 (261.7 KiB)

This has been incredibly frustrating since it ALMOST works.

I'm running Debian Wheezy, Gerrit 2.10 and Jenkins 1.604.

Things I've already looked at: CAP_NET_BIND_SERVICE is not an easy solution because gerrit is initialized through a script. authbind is a tool that will probably do what I want, but I'd prefer avoiding yet another layer.

3
  • 1
    Why are you using the REDIRECT rule? I think you should use DNAT. Apr 2, 2015 at 10:53
  • It's a bit bizarre to have two distinct NICs that have IP addresses in the same subnet, it doesn't really help with anything. Why not just have eth0 with 172.29.49.112/24 and then add 172.29.49.113/32 as an extra address to eth0? i think your problem may be due to traffic not arriving at the network card you expect it to (i.e. the -i ethX part of the iptables command).
    – wurtel
    Apr 2, 2015 at 12:35
  • you can use a wildcard for -i param eg -i eth+ will match (in regex terms) eth.
    – gwillie
    Apr 7, 2015 at 6:37

1 Answer 1

1

Tero Kilkanen pointed me in the right direction on this, although it took a while for me to work out the syntax. It looks like iptables was confused regarding which IP the newly redirected data should go to.

DNAT specifies the target port AND the target IP, so it works correctly now. The final commands I used were as follows:

su root -c "/sbin/iptables -t nat -A PREROUTING -p tcp -m tcp -d 172.29.49.113 --dport 443 -j DNAT --to 172.29.49.113:4443"
su root -c "/sbin/iptables -t nat -A PREROUTING -p tcp -m tcp -d 172.29.49.112 --dport 443 -j DNAT --to 172.29.49.112:8443"

Note for wurtel and user1036745: Setting the input nic with a wildcard did not make a difference. (especially since by default iptables sets a wildcard entry for the input nic anyway, so no need to specify "eth+") But thanks for taking the time to reply anyway.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .