I would like to remap outbound traffic from within a docker container to a different port. Eg: I would like to curl from within the container and have the request actually be made to curl (this is similar to what kube-proxy does for kubernetes).

I understand that within a docker container I can run:

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

And then requests will behave as desired. However, I'd like to only edit the iptables rules on the host to get the same functionality.

I have a docker network with id 8e8799c36e69, if I run iptables-save | grep 8e8799c36e69 on the host I get the following rules:

-A POSTROUTING -s ! -o br-8e8799c36e69 -j MASQUERADE
-A DOCKER -i br-8e8799c36e69 -j RETURN
-A FORWARD -o br-8e8799c36e69 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -o br-8e8799c36e69 -j DOCKER
-A FORWARD -i br-8e8799c36e69 ! -o br-8e8799c36e69 -j ACCEPT
-A FORWARD -i br-8e8799c36e69 -o br-8e8799c36e69 -j ACCEPT
-A DOCKER-ISOLATION-STAGE-1 -i br-8e8799c36e69 ! -o br-8e8799c36e69 -j DOCKER-ISOLATION-STAGE-2
-A DOCKER-ISOLATION-STAGE-2 -o br-8e8799c36e69 -j DROP

Is it possible to hook into these rules so that I can set up my port rewrite just within that network? (is this event the correct approach?).

Maybe just something like this?

iptables -t nat -I OUTPUT -o br-8e8799c36ec9  --src 0/0 --dst -p tcp --dport 8080 -j REDIRECT --to-ports 8181

Or maybe I don't need the docker bridge network and I can somehow filter on traffic coming from within the container?


When I start a docker container it creates these rules:

-A POSTROUTING -s -d -p tcp -m tcp --dport 8080 -j MASQUERADE
-A DOCKER ! -i docker0 -p tcp -m tcp --dport 8080 -j DNAT --to-destination
-A DOCKER -d ! -i docker0 -o docker0 -p tcp -m tcp --dport 8080 -j ACCEPT

The container has ip addr on my machine. So I've added this rule:

sudo iptables -t nat -A OUTPUT -s -p tcp -d --dport 8080 -j DNAT --to-destination

To try and get a test request to to request, but it doesn't seem to work.

edit 2:

If I'm trying to rewrite a port for a service that is listening locally I got it working with this:

sudo iptables -t nat -A OUTPUT -p tcp -d $LOCAL_IP --dport $REQUESTED_PORT -j DNAT --to-destination :$DESTINATIO_PORT
sudo iptables -t nat -I PREROUTING -s $CONTAINER_IP -d $LOCAL_IP -p tcp --dport $REQUESTED_PORT -j REDIRECT --to-ports $DESTINATION_PORT

that seems to just work with local ips

edit 3: kube-proxy source has some more information about their approach and various gotcha's:



  • Docker adds a ton of of iptables rules (a lot more than you've seen). Inserting your own rules there without breaking anything will be quite difficult. Trying to figure out what docker is doing and how your own rules can fit in there will probably be quite time consuming.
    – dirkt
    Mar 14, 2020 at 20:28
  • For sure. I'm exploring building something like kube-proxy for hashicorp's nomad. The service will have to manage many iptables rules alonside docker just like kube-proxy does.
    – maxm
    Mar 14, 2020 at 20:29

1 Answer 1


Ok, figured it out.

If I would like to redirect traffic from to for a container with an ip address then you can add the following rule:

sudo iptables -t nat -A PREROUTING --protocol tcp --destination \
    --dport 80 --source \
    --jump DNAT --to-destination

This also seems to work with public external ip addrs.

REDIRECT doesn't seem to work because [source]:

It redirects the packet to the machine itself by changing the destination IP to the primary address of the incoming interface (locally-generated packets are mapped to the address).

Still not entirely sure what was going on, but I think that's why REDIRECT was working with some things served locally (especially anything listening on, but not external ips.

You must log in to answer this question.

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