Port forwarding from something not your firewall

I have a number of web servers which want to express their port 443 to the world. These machines also have IPv6, and that’s what I hope many clients will use. Since HTTPS servers can not do virtual hosting, and port 443 on CREDIL’s firewall is already taken, what can I do?

We have other public IPs, with other (virtual) machines that have internal and external connections. I could use their port 443s.

I previously did this for port-119 (NNTP). I had set things up like:

iptables -A PREROUTING -d ${myexternalip}/32 -p tcp -m tcp --dport 119 -j DNAT --to-destination ${serverinternalip}:119 iptables -A POSTROUTING -d ${serverinternalip}/32 -p tcp -m tcp --dport 119 -j MASQUERADE

The first statement is relatively ordinary. Change the destination address. The second statement is annoying. It is critical on machines when the default route does not point at it. Basically, it changes the source IP that connects to the ${myinternalip} to be the internal address of the firewall.

This actually necessary even on the default route: without this, internal connections to port 119 do not work – this is because the internal machine sees a connection originating from the internal client IP, to the internal IP. The problem is that the internal client actually has a connection from it’s IP, to the external IP of the firewall.

The above method works fine, except…. the internal machine sees the connection as being from the internal IP of the firewall. That really sucks from a point of view of logging!

How to solve it? The problem is that packets with an origin of port 443 needs to go to the other machine… this is what I did:

On the gateway machine:

iptables -A PREROUTING -d ${myexternalip}/32 -p tcp -m tcp --dport 443 -j DNAT --to-destination ${serverinternalip}:443

On the target machine:

iptables -A OUTPUT -t mangle '!' -d ${myinternalnetwork}/24 -j MARK --set-mark 443 ip rule add fwmark 443 table 443 ip route add 0.0.0.0/0 via ${myinternaliP} table 443

It’s very important that you set the mark using the mangle chain. It will not work on the NAT or the regular OUTPUT chain!

The result is now that packets with origin port 443, go via this alternate firewall, and the web server itself will see the correct originating IP.