Use iptables to DSCP tag traffic from a particular docker container
Linux - ContainersThis forum is for the discussion of all topics relating to Linux containers. Docker, LXC, LXD, runC, containerd, CoreOS, Kubernetes, Mesos, rkt, and all other Linux container platforms are welcome.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
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
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:
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.
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:
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.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.