Port forwarding sounds easier than it can be when things need to work robustlyA customer wanted to have an internal service accessible for their roadwarriors. The service was a web application on port 8080, what was preventing access was an iptables firewall running SuSE linux.
The first thing i noticed was you can use the standard setup tool YaST to open up particular ports, but you can not click to tell SuSE what to do on that port (port forwarding a.k.a. DNAT). A little delving into the depths of the config files yielded a variable FW_FORWARD_MASQ. This is most probably known to everyone who uses linux as router, since you need this to open up your firewall for eMule :-)
This did not solve our problem though; the web service was perfectly reachable from the firewall box, i could get the webpage i wanted via telnet to port 8080 on the application server. What did not work was the access via packet forwarding from the outside. tcpdump showed normal behavior for the internal connection, SYN packets from the outside never yielded any answer whatsoever from the internal network. Some playing with the iptables entries included difficulties with adding DNAT entries to the OUTPUT chain of the nat table, which cost quite some time but yielded no results.
Brooding about the tcpdump output led to a suspicion: The other box was connected directly via a switch, and no drop messages from iptables indicated that anything was sent. So I had a look at the routing table of the application server (a windows box, hence no real option for diagnostics). The standard gateway was different from the firewall computer, it was a hardware router instead. This led to the idea that the router say SYN-ACK without SYN and thus simply discarded the packets.
The next futile attempts led to the insight that netcat is a bit underdocumented and ssh tunnelling does not really solve this setup and reusing a squid installation was not feasible. So googling resulted in some hints that xinetd might be apt for the task of redirection. A RedHat FAQ, of all things, explained how to set this up:
# default: on
# description: forward connections to our service
flags = REUSE
socket_type = stream
wait = no
user = root
redirect = xxx.xxx.xxx.xxx 8080
log_on_failure += USERID
One thing that is further needed is an entry for „internal-service-name“ in /etc/services (perhaps it’s also working with port numbers, I don’t really care, this way everyone knows what’s happening). Restart xinetd and ta-da, it works. Took too long, bereft me of some years of my life since the customer kept calling to get a status, but it’s a good feeling now that it works.
Alas, the customer claims it still does not work. Tcpdump shows that no data is sent to the application server when the connection comes from somewhere else than my place. Adrenaline. Concentration. Insight. Tcpd regulates who may connect to the services on that firewall, so i need another entry in /etc/hosts.allow to enable everyone to connect to that particular port:
internal-service-name : ALL : ALLOW
Done. Finally. Next time don’t let the customer evade before he tried himself.