netfilter.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Morteza Behboodian <xeptore@gmail.com>
To: netfilter@vger.kernel.org
Subject: Question: How to pass Docker container traffic through iptables tproxy?
Date: Mon, 26 Feb 2024 13:20:16 +0330	[thread overview]
Message-ID: <845cf958-5334-44e1-b3da-cd8972b2835b@gmail.com> (raw)

I have a TPROXY-supported proxy server running on my machine (listening 
on 127.0.0.1:8080). I configured iptables to redirect traffic to this 
proxy server using `TPROXY` target as below:

```sh
ip route add local default dev lo table 100
ip rule add fwmark 1 table 100

iptables -t mangle -N PROXY
# Ignore private IPs
iptables -t mangle -A PROXY -d 10.0.0.0/8 -j RETURN
iptables -t mangle -A PROXY -d 100.64.0.0/10 -j RETURN
iptables -t mangle -A PROXY -d 127.0.0.0/8 -j RETURN
iptables -t mangle -A PROXY -d 169.254.0.0/16 -j RETURN
iptables -t mangle -A PROXY -d 172.16.0.0/12 -j RETURN
iptables -t mangle -A PROXY -d 192.0.0.0/24 -j RETURN
iptables -t mangle -A PROXY -d 224.0.0.0/4 -j RETURN
iptables -t mangle -A PROXY -d 240.0.0.0/4 -j RETURN
iptables -t mangle -A PROXY -d 255.255.255.255/32 -j RETURN
iptables -t mangle -A PROXY -d 192.168.0.0/16 -j RETURN

iptables -t mangle -A PROXY -p tcp -j TPROXY --on-port 8080 --on-ip 
127.0.0.1 --tproxy-mark 1
iptables -t mangle -A PROXY -p udp -j TPROXY --on-port 8080 --on-ip 
127.0.0.1 --tproxy-mark 1
iptables -t mangle -A PREROUTING -j PROXY


iptables -t mangle -N PROXY_SELF
# Ignore private IPs
iptables -t mangle -A PROXY_SELF -d 10.0.0.0/8 -j RETURN
iptables -t mangle -A PROXY_SELF -d 100.64.0.0/10 -j RETURN
iptables -t mangle -A PROXY_SELF -d 127.0.0.0/8 -j RETURN
iptables -t mangle -A PROXY_SELF -d 169.254.0.0/16 -j RETURN
iptables -t mangle -A PROXY_SELF -d 172.16.0.0/12 -j RETURN
iptables -t mangle -A PROXY_SELF -d 192.0.0.0/24 -j RETURN
iptables -t mangle -A PROXY_SELF -d 224.0.0.0/4 -j RETURN
iptables -t mangle -A PROXY_SELF -d 240.0.0.0/4 -j RETURN
iptables -t mangle -A PROXY_SELF -d 255.255.255.255/32 -j RETURN
iptables -t mangle -A PROXY_SELF -d 192.168.0.0/16 -j RETURN

iptables -t mangle -A PROXY_SELF -m mark --mark 2 -j RETURN
iptables -t mangle -A PROXY_SELF -p tcp -j MARK --set-mark 1
iptables -t mangle -A PROXY_SELF -p udp -j MARK --set-mark 1
iptables -t mangle -A OUTPUT -j PROXY_SELF
```

It works as expected for locally-generated network. However, there's a 
problem with Docker container networks. As I didn't change any of its 
default network/iptables configuration, it uses internet-connected 
network device (`eth0`) as gateway to pass outgoing networks from. When 
I enable iptables tproxy to redirect traffic to the proxy server, all 
traffic originated from my machine is properly passed through the proxy 
server, but the traffic originated from inside Docker container does not 
reach the proxy server, and fails to access the internet. How can I 
resolve it?


I also used `LOG` iptables target for every chain in every table to see 
how packets traverse through, and to debug (or guess) what the issue is. 
 From what I understood, for locally-generated packets as they pass 
through `mangle` table `OUTPUT` chain, they are marked with fwmark 1, 
then routed to `lo` device (instead of the default internet-connected 
device `eth0`) because of the `ip route`, and `ip rule` commands, and 
they will then received on `lo` device, which get redirected to the 
proxy server by `tproxy` target defined in `mangle` table's `PREROUTING` 
chain, and the rest of the proxying process. On the other hand, for 
packets sent from Docker container, they are first received on `docker0` 
(default Docker bridge network device), and once they are redirected by 
`tproxy` target, the packet _hangs_ in `nat` table `INPUT` chain, which 
AFAIK is just before they are handed over to the proxy server process. 
As I don't see any log message from proxy server, I guess these packets 
are being dropped (?) somehow. I tested the followings as well:

- Running the proxy server bounded to `0.0.0.0`
- Enabling `net.ipv4.ip_forward` kernel option
- Letting `docker0` packets to pass through the `mangle` table 
`PREROUTING` chain first by just marking them with fwmark 1 (without 
jumping to `tproxy`), and let `ip route` to re-route them back to `lo` 
(similar to what happens for locally-generated packets), and then apply 
tproxy redirection for the associated packet that is received later on 
on the `lo` device. This works as expected for the _forwared_ packet, 
but the corresponding packet that is received on `lo` device hangs right 
after the `mangle` table's `PREROUTING` chain and does no proceed.

But with no results...

Any help is appreciated.

As I'm new to iptables advanced networking on Linux (started completely 
since 3 days ago), please also let me know if there is any more 
information that needs to be provided.

Cheers

                 reply	other threads:[~2024-02-26  9:50 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=845cf958-5334-44e1-b3da-cd8972b2835b@gmail.com \
    --to=xeptore@gmail.com \
    --cc=netfilter@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).