2

I have two Systems A and B. A is a TCP Client and sends a message to TCP Server on B.

------------------                --------------------------

  System A                        System B
  192.168.0.5 wlan0               192.168.0.3 wlan0
  127.0.0.1   lo                  127.0.0.1 lo
  TCP Client    <------------>    TCP Server on 127.0.0.1
------------------                ----------------------------

The TCP Client sends message to 192.168.0.3.

This should be redirected to the local interface of B as the TCP Server is running on 127.0.0.1 at Port 8000 of System B.

Therefore, I wrote the following ip table rules, however my Server at B doesn't receive any messages. Oh btw these two systems are Ubuntu linux systems.

Here is what I did on System B:

#Enable IP Forwarding for NAT
echo "1" > /proc/sys/net/ipv4/ip_forward

#Flush all iptable chains and start afresh
sudo iptables -F

#Forward incoming packets on 192.168.0.3 at wlan0 interface to 127.0.0.1
sudo iptables -t nat -A PREROUTING -p tcp -i wlan0 -d 192.168.0.3 --dport 8000 -j DNAT --to 127.0.0.1:8000

#Explicitly allow incoming connections on port 8000 
sudo iptables -A INPUT -i wlan0 -p tcp --dport 8000 -m state --state NEW,ESTABLISHED -j ACCEPT

#Explicitly allow outgoing messages from port 8000
sudo iptables -A OUTPUT -o wlan0 -p tcp --sport 8000 -m state --state ESTABLISHED -j ACCEPT

Then I start the Server on B and send a message from TCP Client on A. I can see the packets on wireshark from 192.168.0.5 on wlan0 but they never get forwarded :(

Please help.

UPDATE:

After inputs from experts here, I have made a more realistic "NAT" scenario for applying the forwarding rules but I have still issues: I have explained this in my newer post: Iptables: Forwarding packets doesn't work

user907810
  • 141
  • 1
  • 2
  • 5
  • There is a simple bug in your code. I believe it should be echo "1" > /proc/sys/net/ipv4/ip_forward Additionally I'm not sure why you'd like to use NAT anyway. It doesn't make sense. NAT is something where you hide a network behind the NATting host and act in place of the origin host. – Jens Bradler Apr 26 '12 at 08:56
  • Oops that was really a typo error! Let me edit it! – user907810 Apr 26 '12 at 13:17

4 Answers4

3

Here is a total non-answer answer.
as Jens Bradler said in his comment, the simplest thing to do here is to bind the service to the public IP address on port 8000, rather than NAT the connection. You can secure access to the single Server A by iptables rules like so;

 -A INPUT -s 192.168.0.5/32 -p tcp -m tcp --dport 8000 -j ACCEPT
 -A INPUT -p tcp -m tcp --dport 8000 -j REJECT
Tom
  • 10,886
  • 5
  • 39
  • 62
2

Tom H's non-answer answer is better, but if you don't like it, here is a direct answer:

Sorry, my iptables skills are best when I can tinker, test, check, logs, repeat... and I don't have your system to play with, but here is my advice anyway. You probably will need to debug using the logs.

Change the direction of your redirect, as stated by Jens Bradler:

echo "1" > /proc/sys/net/ipv4/ip_forward

Prove it is right

cat /proc/sys/net/ipv4/ip_forward

Output from cat:

1

Add a rule to ACCEPT using the FORWARD table also.

sudo iptables -A FORWARD -i wlan0 -p tcp --dport 8000 -j ACCEPT

Remove the "-m state" stuff from the incoming rule (optional... unnecessary I think):

sudo iptables -A INPUT -i wlan0 -p tcp --dport 8000 -j ACCEPT

Probably anywhere that you added "ESTABLISHED", you should also have "RELATED" (Not sure but I think a return packet that starts a connection is related, but not established).

sudo iptables -A OUTPUT -o wlan0 -p tcp --sport 8000 -m state --state RELATED,ESTABLISHED -j ACCEPT

The FORWARD rule to go with the above accept, reverse of the other FORWARD.

sudo iptables -A FORWARD -o wlan0 -p tcp -s 127.0.0.1 --sport 8000 -m state --state RELATED,ESTABLISHED -j ACCEPT

Instead of using Wireshark, use -j LOG.

First check to see that there aren't already LOG rules (the default ones are better than the following... but you used flush; mine will spam your server hard):

sudo iptables --list --line-numbers -v
sudo iptables -t nat --list --line-numbers -v

If not, then add them:

sudo iptables -A INPUT -j LOG
sudo iptables -A OUTPUT -j LOG
sudo iptables -A FORWARD -j LOG
sudo iptables -t nat -A PREROUTING -j LOG

Watch the logs

tail -F /var/log/firewall

# or if that file doesn't exist:
tail -F /var/log/messages
Karl Wilbur
  • 140
  • 5
Peter
  • 2,546
  • 1
  • 18
  • 25
  • BTW I've done similar to the above a bunch, but I have never used "-j DNAT" – Peter Apr 26 '12 at 13:11
  • Thanks Peter. I am going to try this now and let you know :) – user907810 Apr 26 '12 at 13:21
  • Oh I guess even the first FORWARD rule should omit -m state, am I right? – user907810 Apr 26 '12 at 13:28
  • Hi Peter, I tried exactly what you said, however when the client on System A sends a packet to Server on B, the log message only shows the SYN requeston System B at 192.168.0.5 but that is all. The server doesnt receive the message as it doesnt get forwarded I guess :( – user907810 Apr 26 '12 at 13:50
  • Yes, the "-m state"| on its own is just a mistake. (I'll remove it now) – Peter Apr 27 '12 at 13:54
  • The log should include any "DROP" and "REJECT" results (anything that makes it to the LOG line because there was no ACCEPT line)... so if it only has the SYN then maybe that is what is rejected. Does it say that it is rejected? For example of a drop log (having to do with rpc I think), see next comment. – Peter Apr 27 '12 at 13:59
  • Apr 26 12:45:53 linux-esae kernel: [697677.775154] IN=eth0 OUT=eth2 SRC=10.5.0.55 DST=10.6.0.66 LEN=84 TOS=0x00 PREC=0x00 TTL=63 ID=32045 DF PROTO=UDP SPT=51528 DPT=111 LEN=64 – Peter Apr 27 '12 at 13:59
  • Oh actually you should add --log-prefix "drop: " or your line won't say that it was dropped. – Peter Apr 27 '12 at 14:03
  • Hi Peter, var/log/messages show that the SYN packets on INPUT are being dropped. What is the problem?? – user907810 May 02 '12 at 09:55
  • Hi Peter, I changed the setup a bit to have a more real scenario of forwarding with NAT. But I have the same problem as here. Please check my new post: http://serverfault.com/questions/385251/iptables-forwarding-packets-doesnt-work – user907810 May 02 '12 at 12:31
1

System B:

sysctl -w net.ipv4.conf.wlan0.route_localnet=1
iptables -t nat -A PREROUTING -i wlan0 -p tcp --dport 8080 -j DNAT --to 127.0.0.1
nezabudka
  • 111
  • 4
1

You can't ever perform -j DNAT --to 127.0.0.1.

127.0.0.1 is a super-duper-special address; it would only accept connections from 127.0.0.1.

@Tom H's answer is the way you should set up your server.

pepoluan
  • 4,918
  • 3
  • 43
  • 71
  • Shouldn't a NAT (the t being for "translation") translate the source address to the 127.0.0.1 so the listening process will think it is accepting something from there? – Peter May 02 '12 at 19:56