On a Linux box with multiple IPs, I'm having a problem redirecting a privileged port to an unprivileged port on which a server is listening that's bound to a specific IP.
Add this rule to iptables to redirect incoming traffic from port 80 to 8080:
iptables --table nat --append PREROUTING --protocol tcp --dport 80 \
--jump REDIRECT --to-ports 8080
Then start a netcat to listen on all IPs, port 8080:
nc -l 0.0.0.0 8080
Then send a packet to port 80 from another machine:
echo foo | nc 10.0.0.39:80
echo foo | nc 10.0.0.39:8080
Both these packets are received. Now for the strange thing. When you make netcat listen on a specific IP, it doesn't see the redirected packet.
nc -l 10.0.0.39 8080
Now the packet sent to port 80 is not received; only the packet on port 8080. The difference is obviously how the server binds the listening port -- 0.0.0.0 works but a specific IP doesn't.
The problem is not in netcat, because nginx (where I do IP-based vhosting) has the same problem.
I tried to extend the iptables rule by specifying that the destination address is 10.0.0.39, but this still doesn't work.