How to enable transparent HTTP/S redirection through proxy using iptables?

My current setup consists of the following elements:

  • A router flashed with OpenWRT with two interfaces: eth0 is the access to the gateway and eth1 manages the local network (192.128.2.0/24)
  • A box (that cannot be used in bridge mode), set up to allow the router in its DMZ (192.168.1.0/24)
  • A privoxy server up and running on the router, listening on port 4000 (interface eth1)

When I setup the clients on eth1 to use 192.168.2.1:4000 as an HTTP and HTTPS proxy, all goes well. However, my attempts at using iptables to automate this redirection process have all failed so far. Here is the last attempt I made:

iptables -t mangle -A PREROUTING -i eth1 -p tcp -m multiport --dport 80,443 -j TPROXY --on-ip 0.0.0.0 --on-port 4000 --tproxy-mark 1/1
iptables -t mangle -A PREROUTING -i eth0 -s 192.168.1.0/24 -j ACCEPT
iptables -t mangle -A PREROUTING -i eth0 -d 192.168.1.0/24 -j ACCEPT
iptables -t mangle -A PREROUTING -i eth0 -m multiport --sport 80,443 -j MARK --set-mark 1/1

My understanding is the following:

  1. The first rule marks HTTP/S (dport=80 or 443) packets coming from the local clients and redirect them to the proxy server
  2. The second and third rules allow for local traffic between the two local networks
  3. The last rule marks the remaining incoming traffic with the mark 1/1

Then, I used ip to define a route for policy routing based on the mark I set up with iptables:

ip rule add fwmark 1/1 table 1
ip route add local 0.0.0.0/0 dev lo table 1

And of course it doesn't work and I don't even know why... Maybe my proxy server doesn't support the TPROXY feature and I should go with only MARK rules... But even then I'm a little lost here.


First of all, have a look here: Concepts of Interception Caching to have some idea on the advantages, disadvantages or possible issues of using transparent proxy.

Secondly, HTTPS or ssl traffic won't work with a normal transparent proxy. You need to have a special configuration called ssl-bump, which has its own issues to consider in regards of privacy.

Third,

  • if you have your squid setup correctly for transparent/intercept mode (running on port 3128) and
  • assuming eth0 as external and eth1 as internal (lan, 192.168.1.0/24) interface, here are two sample iptables rules for redirecting http traffic:

    iptables -t nat -A PREROUTING -i eth1 -p tcp --dport 80 -j DNAT --to 192.168.1.1:3128

    iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j REDIRECT --to-port 3128

This is without using Tproxy.