iptables bad tcp cksum for DNAT OUTPUT
Hi:
I've searched for this topic and found some similar stuff but not exactly, so here goes (sorry if I could not find it). I am trying to use DNAT for some seemingly unorthodox usage. I am *not* trying to setup a firewall. I am not a network admin. I am trying to setup a scenario for internal development. I am completely internal to my local network and I have 3 standard end-hosts to play with, which we can call;
client
server
3rd_host
I have a standard TCP client / server scenario in which I would like to create some asymmetric routes.. i.e traffic from client to server is on one network interface and traffic from server back to client on on another network interface. The client is multi-homed with the following:
eth0: 100.21.13.05/21 <--- I want server packets to arrive here
tun0: 192.168.13.05/21 <--- I want client packets to be sent here
Client connection requests are sent to server port@host equal to 5001@100.21.13.13
iptables is configured like this:
sudo /sbin/iptables -t nat -A OUTPUT -p tcp -d 100.21.13.13 --dport 5001 -j DNAT --to-destination 192.168.13.13
** As an aside. The above works fine if server is reachable on tun0 and I want all incoming and outgoing packets to use tun0 interface... ***
Packets sent out tun0 now has Source IP = 192.168.13.05 and Dest IP = 192.168.13.13. Very Nice.. Now lets suppose that tun0 interface is really destined to 3rd_host in which 3rd_host is ip_forwarding. So 3rd_host is also muti-homed:
tun0: 192.168.13.89/21 <--- client packets arrive here
eth0: 100.21.13.89/21 <--- client packets are sent here (after DNAT)
On 3rd_host I have the following commands:
sudo /sbin/iptables -i tun0 -A PREROUTING -t nat -j DNAT --to-destination 100.21.13.13
sudo /sbin/iptables -d 100.21.13.13 -p tcp -A POSTROUTING -t nat -j SNAT --to-source 100.21.13.05
So now in a sense, 3rd_host has effectively undone the NAT translation that client performed.. tcpdump on eth0 shows Source IP = 100.21.13.05 and Dest IP = 100.21.13.13. The server in single homed:
eth0: 100.21.13.13/21
And Source and Dest IP are the expected 100.21.13.05 and 100.21.13.13 respectively..
Now for the problem: The TCP 3-way handshake is completed successfully (SYN from client, SYN-ACK from server, ACK from client all ok), however the first user level packet from client (first packet after client ACK) has a "bad tcp cksum". There is more.. I watch the tcpdump on the client eth0 and tun0 interfaces.. Only the very first SYN packet from the client is sent to the tun0 and everything else sent by the client appears on the eth0 interface. This is very unexpected by me. This is the root of my question and problem.. Why is SYN packet the only packet to be sent on tun0? I read that iptables nat table only "evaluates" the first packet in a "stream" and then all packets in teh same "stream" follow it's lead. And, why is a bad tcp cksum error created on first real user data packet. I suppose the latter question has something to do with the former.
I think this might have to do with the definition of a stream possibly.. What is a stream? This must be the Kernel's notion of a tcp connection defined by port@host pairs. Looking at open file descriptors on client I can see that my socket is still defined as the original 100.21.x.x address pairs, so I don't know why subsequent packets are not matching the DNAT rule..
Any help, please..
Thanks in Advance
|