-1

I am attempting to take a TCP service running on port 1234, and make it appear as if it's running on port 81. I thought the following might do it:

iptables -A PREROUTING -t nat -p tcp --dport 81 -j REDIRECT --to-port 1234

However, if I fire up nc -l 1234 in one terminal, then nc 127.0.0.1 81 in another, I don't get a connection. The second nc just exits immediately. tcpdump tells me:

$ sudo tcpdump -i lo -v
tcpdump: listening on lo, link-type EN10MB (Ethernet), capture size 65535 bytes
07:54:21.628583 IP (tos 0x0, ttl 64, id 60458, offset 0, flags [DF], proto TCP (6), length 60)
    localhost.45729 > localhost.81: Flags [S], cksum 0xfe30 (incorrect -> 0x06a3), seq 4232210875, win 43690, options [mss 65495,sackOK,TS val 755089 ecr 0,nop,wscale 6], length 0
07:54:21.628595 IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto TCP (6), length 40)
    localhost.81 > localhost.45729: Flags [R.], cksum 0x98dc (correct), seq 0, ack 4232210876, win 0, length 0

Looks as if the connection is attempted, then immediately reset. I see there's an incorrect checksum -- is that a problem, and if so, how do I fix it?

The other nc is listening on port 1234, as verified by netstat and attempting to connect to port 1234 directly, successfully.

Oddly, nothing seems to be matching PREROUTING the nat table at all:

$ sudo iptables -t nat -L -n -v
Chain PREROUTING (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 REDIRECT   tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:81 redir ports 1234

Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain OUTPUT (policy ACCEPT 2 packets, 120 bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain POSTROUTING (policy ACCEPT 2 packets, 120 bytes)
 pkts bytes target     prot opt in     out     source               destination         

Note the 0 counters, despite my multiple attempts to make the connection with nc above. Now, it's my understanding that all traffic should be going through the PREROUTING chain, so I should see something. What gives?

Phil Frost
  • 637
  • 5
  • 18

1 Answers1

1

NAT redirection doesn't work on traffic both from and to localhost. Try from another system on the LAN.

Edit: Try looking at this question, which deals with getting unprivileged daemons to listen on privileged ports. The first answer is of no help, but the next one down should be.

As for whether telling you that it doesn't work is not helpful, you are completely free to think that. Note, however, that I've saved you wasting time debugging your NAT rules, by letting you know that you don't have an implementation problem; instead, the issue is that you can't do what you want in the way you want to do it. Probably only Rusty Russell can tell you why it doesn't work.

MadHatter
  • 78,442
  • 20
  • 178
  • 229
  • That's rather difficult, since the service in question will in fact need to be accessed over localhost. Any alternate solution? – Phil Frost Apr 14 '14 at 15:14
  • Yes; bind to port 81 instead. – MadHatter Apr 14 '14 at 15:16
  • Perhaps you could elaborate on *why* it doesn't work, with links to documentation, etc. Just telling me it doesn't work isn't really helpful -- I already know that. – Phil Frost Apr 14 '14 at 15:19
  • Binding to port 81 brings a different problem: this service does not run as root, nor does it include any facility for doing so. – Phil Frost Apr 14 '14 at 15:22
  • Setup a simple tcp proxy on port 81? – Zoredache Apr 14 '14 at 15:24
  • Thanks for finding the duplicate. It was much more helpful than this answer. – Phil Frost Apr 14 '14 at 15:46
  • Phil: you're welcome. Perhaps you can learn from this to ask the question you want answered, not make an assumption about method and then ask for implementation assistance. http://meta.stackexchange.com/questions/66377/what-is-the-xy-problem is worth reading, and sheds light on this issue. – MadHatter Apr 14 '14 at 17:35
  • No, this is the question I want answered. This is not an XY problem. I don't want to know how to use xinted, or set up a proxy, or bind to a low port. I don't want to be told the thing I know doesn't work doesn't work, unless you can provide some documentation explaining it. Fortunately, the duplicate you linked not only provides a more specific explanation of what doesn't work (localhost doesn't go through *PREROUTING*) but also provides a solution (use the OUTPUT chain). – Phil Frost Apr 14 '14 at 17:46