I have a linux machine, and there is a proxy server runs on this same machine listening I want to use iptables to achieve:

  1. For all outgoing HTTP(S) requests via port 1080, direct connect without any processing
  2. For all HTTP(S) requests from other ports, proxy through
  3. Incoming requests are not touched and received normally

You may wonder why I proxy the outgoing requests to itself, it's because the proxy server also does obfuscation and some other fancy stuff.

I've read many answers, but most of them are only interested in requests via/to some specific ports (e.g. 80), whereas I want all but one ports.

I know I can use commands like

iptables -t nat -A OUTPUT -p tcp -j DNAT --to-destination

But I guess this may simply result in a self-routing loop.

In this blog, the author provides a solution

If you want to run the client on the same machine as the server (you’re in a coffee shop on your laptop; have a pastry for me), we can’t use the PREROUTING table, because it only applies to packets coming from outside. What we can do is modify the destination port on packets OUTPUT by our client process. The catch is that it will also affect packets output by mitmproxy, and we’ll get into a routing loop.

There are probably several ways to solve this, but the one that worked for me was running mitmproxy as root, and making the iptables rule not apply to root-owned processes.

sudo iptables -t nat -A OUTPUT -p tcp -m owner ! --uid-owner root --dport 443 -j REDIRECT --to-port 8080

  • -m owner: Load the owner module.
  • ! –uid-owner root: Rule does not apply to root-owned processes

But there is only one user root on my machine and I have no intention to create another one for this.

BTW, I'm not sure if I need to set /proc/sys/net/ipv4/ip_forward to 1 in this case.

You can assume the OS is a newly installed Ubuntu 20.04.

EDIT: Clarify the "traffic" refers to HTTP requests.

  • Are you talking about web traffic, or can your proxy do an unlimited number of different types of application processing? Or do you really mean to say that you want all your outbound traffic to go through a SOCKS proxy? If so, then iptables is not the right tool for the job Commented Nov 11, 2020 at 14:21
  • Yes, web traffic. I indeed want all outbound traffic to go through that proxy, so they can get processed (obfuscation, etc.). I tried some programs like proxychains, but I have more than one applications to handle. Setting environment variables is a solution, but not all applications respect that. Commented Nov 11, 2020 at 14:54
  • Please edit your question to make it clear you are only referring to web traffic. You might want to clarify that this is (or isn't) http and/or https Commented Nov 11, 2020 at 14:59
  • Edited, hope now it's clearer. Commented Nov 11, 2020 at 15:09

1 Answer 1

# Enable routing
sudo echo 1 > /proc/sys/net/ipv4/ip_forward
# Enable forwarding to loopback interface
sudo sysctl -w net.ipv4.conf.eth0.route_localnet=1
# Forward all TCP  except TCP/1080
iptables -t nat -A OUTPUT -p tcp ! --dport 1080 -j DNAT --to-destination
# Enable NAT (aka Masqurade)
sudo iptables -t nat -A POSTROUTING -j MASQUERADE
  • In the third command, I suppose it's --dport. I tried those commands on the machine, and use curl to test, but unfortunately, no matter what URL I use, curl only complains "Connection refused". The log file of the local proxy server also indicates no connection was received. Commented Nov 12, 2020 at 16:25
  • Lets say user connects using destination port 8000/TCP, connection will be obviously refused because there is nothing listening on TCP 8000 Commented Nov 12, 2020 at 17:15
  • Sorry I can't quite understand what should be listening on port 8000 (as in your example). Like if I use curl, my understanding is an arbitrary port is used to send the original request, then iptables will force it to go through the local proxy server listening on port 1080, next the proxy server (re-)sends the processed request using another port, either to the original target or the next node in the proxy chain. Commented Nov 12, 2020 at 20:54
  • Users coming throuhg any port, except TCP/1080 must be redirected to the proxy? If thats the case, your firewall DNAT rule must include a port range of 1024-65535 Commented Nov 13, 2020 at 11:02
  • Not exactly. That machine is not a server, it's just a regular desktop PC I use every day. And there is a VPN-like application running on it. I just want to ensure all requests are processed before they are actually sent out. So there is nothing about inbound connections. Commented Nov 13, 2020 at 14:08

You must log in to answer this question.

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