19

Suppose I have a network with a server routing all connections from inside the network to the Internet. How can I set up iptables so that instead of routing incoming connections to the Internet, it instead routes them to localhost port 8080. All help is appreciated.

4
  • The problem is that with simple redirection (destination IP address NAT) you will lose the original destination IP address. Do you want to setup a transparent HTTP proxy or should it process other protocols than HTTP too? Oct 18, 2013 at 13:14
  • It doesn't matter if its transparent or not
    – DankMemes
    Oct 18, 2013 at 14:49
  • Redirecting all the traffic to a proxy is a base for transparent proxy :) Oct 18, 2013 at 15:54
  • Here's another answer that really helped me out: unix.stackexchange.com/questions/111433/…
    – Wren T.
    May 16, 2014 at 4:38

3 Answers 3

11
sysctl net.ipv4.ip_forward=1 
iptables -t nat -A PREROUTING -p tcp --dport 80 -j DNAT --to-destination 127.0.0.1:8080
10
  • 1
    don't use bold ....
    – user218473
    Oct 18, 2013 at 13:11
  • Thanks! I haven't tried this yet but I suspect what I've been missing is the ip forwarding command. And next time, please use code blocks, not bold.
    – DankMemes
    Oct 18, 2013 at 13:16
  • @AlexAntonov please use code blocks. Select your text in edit mode and click the brackets icon.
    – DankMemes
    Oct 18, 2013 at 13:18
  • @ZoveGames, sorry, fixed it. Oct 18, 2013 at 13:29
  • 5
    I experimented with this. The ip_forward sysctl is not necessary. However the route_localnet option here is. I see now this is exactly what Juan Cespedes' answer states. Feb 8, 2015 at 2:23
46

that can be done with iptables, but only with kernel >= 3.6.

You will have to do:

sysctl -w net.ipv4.conf.all.route_localnet=1
iptables -t nat -I PREROUTING -p tcp --dport 80 -j DNAT --to 127.0.0.1:8080

ip_forward is not necessary, because the packet is not forwarded, but if you don't include the sysctl for route_localnet (which works only in kernels >= 3.6), the packet will be dropped by the kernel because it considers it a "martian", coming from the outside and having a destination address of 127.0.0.1

5
  • Yup, that works Feb 15, 2016 at 14:09
  • Did not know about route_localnet. So old school and couldn't figure out why ip_forward wasnt working (suspected it wasn't needed but tried anyway).
    – dmourati
    Nov 1, 2016 at 3:38
  • 2
    Make sure you save net.ipv4.conf.all.route_localnet=1 in /etc/sysctl.conf otherwise it won't be persistent and after reboot the variable will go back to 0, causing the packet dropped. Then it would be very hard to figure why now everything is not working... it happened to me. ;)
    – viz
    Mar 12, 2018 at 18:23
  • 2
    Sorry to necro an old question but is there an ipv6 equivalent of net.ipv4.conf.all.route_localnet for use with ip6tables?
    – Kebian
    Jul 10, 2019 at 2:56
  • 1
    amazing. ive spent 4 hours until find it
    – Alex
    Jul 24, 2023 at 19:46
0

Reading the debian documentation (maybe works for other distros) I used this to redirect podman/docker ports to localhost:

8080 -> 80

8083 -> 443

#!/bin/bash

# reset iptables rules
iptables -F
iptables -X
iptables -t nat -F
iptables -t nat -X
iptables -t mangle -F
iptables -t mangle -X
iptables -P INPUT ACCEPT
iptables -P FORWARD ACCEPT
iptables -P OUTPUT ACCEPT

# redirect ports
iptables -t nat -I OUTPUT --src 0/0 --dst 127.0.0.1 -p tcp --dport 80  -j REDIRECT --to-ports 8080
iptables -t nat -I OUTPUT --src 0/0 --dst 127.0.0.1 -p tcp --dport 443 -j REDIRECT --to-ports 8083

check it:

curl -k https://localhost
curl https://localhost

https://wiki.debian.org/Firewalls-local-port-redirection

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .