iptables.problems Obsid@sentry.net (7/23/00) This text is for documenting the problems I encountered while working with the Netfilter package and provide some solutions that I found. Please send any further questions or comments to obsid@sentry.net. ############################################################################## # (1) ## Situation: 3 computers; A, B, and C A == 192.168.1.1 B(eth0) == 192.168.1.3 B(eth1) == 123.123.123.123 (external) C == 192.168.1.2 - B is a dual homed firewall, and is redirecting(DNAT) web traffic to computer C which is running a web server. - A is a node on the network, and wants to talk to computer C which is on the same network segment. - B is doing SNAT(Masquerading) for the internal network. The external IP address for the firewall(B) resolves to some domain name, ie. sentry.net. Anyone outside, when accessing sentry.net via port 80 will get sent to port 80 on C. No problems. ## Problem: Unfortunately, however, when computer 'A' types in http://www.sentry.net/ the connection is refused. Computer 'A' can, of course, type in http://192.168.1.2/ and access the website without problems, but this is inconvenient. ## What's up? Nutshell answer - - 'A' types in http://www.sentry.net, this resolves to 123.123.123.123 - If the firewall has no rules to masquerade internal traffic, the connection is immediately shut down. Let's say we try to fix the problem by redirecting internal traffic destined to 123.123.123.123, on port 80, to our internal webserver. - 'A' types in http://www.sentry.net, this resolves to 123.123.123.123 - Connection is redirected to computer C by computer B; C receives SYN from B. - Computer C sees the query and sees that the source ip, 192.168.1.1 is on it's own network so therefore sends the SYN/ACK reply to computer A directly. - The problem is basically this. Since 'C' received the query from 'B', the sequence numbers are different than the sequence numbers that computer 'A' originally sent to computer 'B'. Therefore the SYN/ACK reply from computer 'C' to computer 'A' will be different than what computer 'A' expects. When computer 'A' receives the response from 'C' it immediately sends a reset to resynch the connection. This goes on and on, and a connection is never established. More Explanations: http://www.linuxdoc.org/HOWTO/IP-Masquerade-HOWTO-6.html#ss6.8 (ipchains) http://www.false.net/ipfilter/1999_08/0187.html (ipfilter) ## Solutions: 1) Set up a DMZ, put the webserver on a separate network segment. 2) Set up an internal DNS system to make your domain resolve to the IP addy of the internal machine. This is extremely annoying and inconvenient. 3) The URL: http://www.false.net/ipfilter/1999_08/0187.html provides a possible solution when using ipfilter. My own testing of this solution yielded mixed results, but it's possible that it may work well under proper circumstances. 4) My simple solution using IPtables: - Set up DNAT to redirect packets from the internal network headed for certain ports and to the external IP address, the IP address that www.sentry.net(using the above situation) resolves to. In this case, the redirection would be to 192.168.1.2. - Masquerade(SNAT) these same connections to the IP address of the external interface. So, we're essentially changing both the source and destination of these connections. My rules look similar to this: ## DNAT ## /usr/local/bin/iptables -t nat -A PREROUTING -i eth0 -p tcp -s 192.168.1.0/24 -d 123.123.123.123 --dport 80 -j DNAT --to 192.168.1.2:80 ## SNAT ## /usr/local/bin/iptables -t nat -A POSTROUTING -o eth0 -p tcp -s 192.168.1.0/24 -d 192.168.1.2 --dport 80 -j SNAT --to 192.168.1.3 In this case eth0 is my internal interface. The first rule changes the destination of the packet, essentially redirecting the packet. The second rule changes the source and effectively "masquerades" those connections. As far as computer C(192.168.1.2) is concerned, it's talking to B(internal, 192.168.1.3). # Overhead: Minimal, we're masquerading internal traffic only under very specific circumstances. # Errata: There are a couple quirks. - You need to make sure your not redirecting the very service you rely on to log on to your firewall, for instance telnet, ssh. If these are being "redirected" to another machine(ie. computer C), then how can we log in to the firewall remotely? Solutions: (A) Don't log on to the firewall remotely. (B) Set the telnet/SSH to listen on a non-redirected port on the firewall. (C) Create an alias for your internal ip address. In other words, bind an extra IP address to the internal interface. - ifconfig eth2:1 192.168.1.69, as an example. Then, to get to your firewall, just type 192.168.1.69. Even set up an internal DNS scheme for the network(like I did) so that firewall.arg resolves to 192.168.1.69. - If your internal interface does already have an alias set up, for whatever reason, then you need to do SNAT with the source of the primary IP addy. For instance, use the IP address associated with eth2, not eth2:1 to do Source NAT. Otherwise you may have some problems. I'm not sure if this is always the case, try it and see what happens. - And, finally, the only wierdness I haven't figured out. FTPing to the firewall, to the alias IP address discussed above(eth2:1), requires me to use passive mode. FTPing from the firewall, however, does not. The problem is probably something obvious, but I dunno, nor do I care that much. ############################################################################## # (2) ## Problem: Telnet, FTP hangs. ## What's Up? The tcpd(tcp wrappers) on the remote machine wants an ident response. This can also happen with some mail servers. ## Solutions: (A) Recompile tcpd on the remote machine and disable the ident stuff. (B) Run identd, or get a "safe" identd that won't surrender any useful information: - www.SecurityFocus.com - packetstorm.securify.com (C) REJECT instead of DROP queries to port 113 at the firewall. Most mail servers, etc., will just stop requesting ident responses after a few seconds if it receives an error. ## Errata: - REJECT doesn't work. - This was(in my case) a bug in the linux-2.4.0-test1 and perhaps test2 kernel. (A) Upgrade ##############################################################################