LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Containers (https://www.linuxquestions.org/questions/linux-containers-122/)
-   -   Use iptables to DSCP tag traffic from a particular docker container (https://www.linuxquestions.org/questions/linux-containers-122/use-iptables-to-dscp-tag-traffic-from-a-particular-docker-container-4175659375/)

bluenote73 08-18-2019 09:51 PM

Use iptables to DSCP tag traffic from a particular docker container
 
Without docker, this command would allow me to tag traffic from a particular application that I wanted to (via openwrt split tunnel plugin) route out my VPN: sudo iptables -t mangle -A OUTPUT -p tcp -m owner --uid-owner vpnuser -j DSCP --set-dscp 0x10

I can test this with something like: sudo -u vpnuser -- curl ipinfo.io

So - I have made my docker container run as the user in question.

But docker creates a big mess in iptables, and I'm afraid I don't know iptables well enough to understand what's going on, so I don't know where to put my tagging. The existing command I use works for regular applications still, but not for the docker container running under the user I specified because I guess the docker packets are being redirected?.

Here is what it looks like:
Quote:

# Generated by xtables-save v1.8.2 on Fri Aug 16 14:42:03 2019
*filter
:INPUT ACCEPT [0:0]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [0:0]
:DOCKER - [0:0]
:DOCKER-ISOLATION-STAGE-1 - [0:0]
:DOCKER-ISOLATION-STAGE-2 - [0:0]
:DOCKER-USER - [0:0]
-A FORWARD -j DOCKER-USER
-A FORWARD -j DOCKER-ISOLATION-STAGE-1
-A FORWARD -o docker0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -o docker0 -j DOCKER
-A FORWARD -i docker0 ! -o docker0 -j ACCEPT
-A FORWARD -i docker0 -o docker0 -j ACCEPT
-A DOCKER -d 172.17.0.3/32 ! -i docker0 -o docker0 -p tcp -m tcp --dport 6789 -j ACCEPT
-A DOCKER -d 172.17.0.4/32 ! -i docker0 -o docker0 -p tcp -m tcp --dport 51413 -j ACCEPT
-A DOCKER -d 172.17.0.4/32 ! -i docker0 -o docker0 -p udp -m udp --dport 51413 -j ACCEPT
-A DOCKER -d 172.17.0.4/32 ! -i docker0 -o docker0 -p tcp -m tcp --dport 9091 -j ACCEPT
-A DOCKER-ISOLATION-STAGE-1 -i docker0 ! -o docker0 -j DOCKER-ISOLATION-STAGE-2
-A DOCKER-ISOLATION-STAGE-1 -j RETURN
-A DOCKER-ISOLATION-STAGE-2 -o docker0 -j DROP
-A DOCKER-ISOLATION-STAGE-2 -j RETURN
-A DOCKER-USER -j RETURN
COMMIT
# Completed on Fri Aug 16 14:42:03 2019
# Generated by xtables-save v1.8.2 on Fri Aug 16 14:42:03 2019
*nat
:PREROUTING ACCEPT [0:0]
:INPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:DOCKER - [0:0]
-A PREROUTING -m addrtype --dst-type LOCAL -j DOCKER
-A POSTROUTING -s 172.17.0.0/16 ! -o docker0 -j MASQUERADE
-A POSTROUTING -s 172.17.0.3/32 -d 172.17.0.3/32 -p tcp -m tcp --dport 6789 -j MASQUERADE
-A POSTROUTING -s 172.17.0.4/32 -d 172.17.0.4/32 -p tcp -m tcp --dport 51413 -j MASQUERADE
-A POSTROUTING -s 172.17.0.4/32 -d 172.17.0.4/32 -p udp -m udp --dport 51413 -j MASQUERADE
-A POSTROUTING -s 172.17.0.4/32 -d 172.17.0.4/32 -p tcp -m tcp --dport 9091 -j MASQUERADE
-A OUTPUT ! -d 127.0.0.0/8 -m addrtype --dst-type LOCAL -j DOCKER
-A DOCKER -i docker0 -j RETURN
-A DOCKER ! -i docker0 -p tcp -m tcp --dport 6789 -j DNAT --to-destination 172.17.0.3:6789
-A DOCKER ! -i docker0 -p tcp -m tcp --dport 51413 -j DNAT --to-destination 172.17.0.4:51413
-A DOCKER ! -i docker0 -p udp -m udp --dport 51413 -j DNAT --to-destination 172.17.0.4:51413
-A DOCKER ! -i docker0 -p tcp -m tcp --dport 9091 -j DNAT --to-destination 172.17.0.4:9091
COMMIT
# Completed on Fri Aug 16 14:42:03 2019

phil.d.g 08-21-2019 12:02 AM

Hmmm.

As far as the kernel is concerned the packets from your docker containers aren't created locally, and there is no socket associated with them and thus no owner information. I think. Docker containers use virtual machine technology and have a virtual ethernet device dedicated to them. As far as the host kernel is concerned, there is no difference between traffic from a docker image and that from another physical machine.

The man page says the owner module can only be used in the OUTPUT and POSTROUTING chains, so you could try:

Code:

$ sudo iptables -t mangle -A POSTROUTING -p tcp -m owner --uid-owner vpnuser -j DSCP --set-dscp 0x10
But, I still think it won't work, because the kernel doesn't know the owner for those packets.

I think the easiest way of tagging your traffic is going to be via the source IP or MAC addresses. And, make sure that your docker container has a fixed one of whichever you choose.

EDIT: Correcting a mistake. Or, at the least, striking something that might cause an off topic discussion.

bluenote73 08-21-2019 12:20 PM

Quote:

Originally Posted by phil.d.g (Post 6027598)
Hmmm.

As far as the kernel is concerned the packets from your docker containers aren't created locally, and there is no socket associated with them and thus no owner information. I think. Docker containers use virtual machine technology and have a virtual ethernet device dedicated to them. As far as the host kernel is concerned, there is no difference between traffic from a docker image and that from another physical machine.

The man page says the owner module can only be used in the OUTPUT and POSTROUTING chains, so you could try:

Code:

$ sudo iptables -t mangle -A POSTROUTING -p tcp -m owner --uid-owner vpnuser -j DSCP --set-dscp 0x10
But, I still think it won't work, because the kernel doesn't know the owner for those packets.

I think the easiest way of tagging your traffic is going to be via the source IP or MAC addresses. And, make sure that your docker container has a fixed one of whichever you choose.

EDIT: Correcting a mistake. Or, at the least, striking something that might cause an off topic discussion.

Thank you so much for this, this makes a tonne of sense. I did try the command mentioned and you're right, it didn't work. However, you make a great suggestion. Since docker has a simpler built-in way of identifying the traffic, why not use that. I couldn't see the forest for the trees :) I have made my container keep the dynamic MAC it had as static. But I'm still stymied on where to apply my matching rule? It seems like DSCP tagging can only be applied in certain places too.

Thanks for your help!

bluenote73 08-21-2019 12:38 PM

A little more meditation and trial and error and this worked for me, please comment if you think there's a problem here:

Quote:

sudo iptables -t mangle -A PREROUTING -m mac --mac-source XX:XX:XX:XX:XX:XX -j DSCP --set-dscp 0x10
Thank you for your help!

phil.d.g 08-21-2019 05:53 PM

Quote:

Originally Posted by bluenote73 (Post 6027837)
It seems like DSCP tagging can only be applied in certain places too.

Sorry, I should've double checked that too.

In terms of what you've ended up with: it looks fine to me.

bluenote73 08-21-2019 06:43 PM

Quote:

Originally Posted by phil.d.g (Post 6027971)
Sorry, I should've double checked that too.

In terms of what you've ended up with: it looks fine to me.

Thank you so much, this seems to work and I have it persistent now.


All times are GMT -5. The time now is 07:33 PM.