title: Docker ignores iptable rules when using "-p <port>:<port>"
body: <p>Just realized a few days ago that Docker seems to bypass my iptable rules. I am not incredible experienced with Docker nor iptables. Tried a lot of different things the last days. Also saw that there was big change in recent docker versions with a special DOCKER-chain that should allow me to do that. However not sure what I am doing wrong but it never does what I expect it to do.</p>
  
  <p>So what I want is quite simple. I want that it behaves like expected. That if I have an ACCEPT-Rule to go through and if not it gets blocked.</p>
  
  <p>My iptable looked originally like that (so before my many unsuccessful attempts):</p>
  
  <pre><code>*filter
  :INPUT ACCEPT [0:0]
  :FORWARD ACCEPT [0:0]
  :OUTPUT ACCEPT [779:162776]
  -A INPUT -i lo -j ACCEPT
  -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
  -A INPUT -p tcp -m tcp --dport 22 -j ACCEPT
  -A INPUT -p tcp -m tcp --dport 80 -j ACCEPT
  -A INPUT -s 1.2.3.4 -p tcp -m tcp --dport 123 -j ACCEPT
  -A INPUT -j DROP
  COMMIT
  </code></pre>
  
  <p>Hoped that it does exactly what I want. Just allow access to ports 22 and 80 and also allow port 123 from the ip 1.2.3.4. However If I create a container with "-p 123:123" everybody can access it. Can anybody help me and tell me how I have to change the above file?</p>
  
  <p>Thanks!</p>
  
  <p>Docker-Version: 1.6.2</p>
  
  <h2>Edit:</h2>
  
  <p>Left initially my different tries out to not overcomplicate the question. However adding at least one of them could maybe be helpful. </p>
  
  <pre><code>*nat
  :PREROUTING ACCEPT [319:17164]
  :INPUT ACCEPT [8:436]
  :OUTPUT ACCEPT [0:0]
  :POSTROUTING ACCEPT [16:960]
  :DOCKER - [0:0]
  COMMIT
  
  
  *filter
  :INPUT ACCEPT [0:0]
  :FORWARD ACCEPT [0:0]
  :OUTPUT ACCEPT [779:162776]
  :DOCKER - [0:0]
  -A INPUT -i lo -j ACCEPT
  -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
  -A INPUT -p tcp -m tcp --dport 22 -j ACCEPT
  -A INPUT -p tcp -m tcp --dport 80 -j ACCEPT
  -A DOCKER -s 1.2.3.4 -p tcp -m tcp --dport 123 -j ACCEPT
  -A DOCKER -j DROP
  -A INPUT -j DROP
  COMMIT
  </code></pre>
  
  <p>The above kind of works. However get then a lot of other problems. For example do I get problems with container linking, DNS does not work anymore, and so on. So then end up adding a lot of additional rules to fix that issues but I get never to a state where it runs properly. So I guess there most be better and easier solution out there.</p>
  
  <h2>Solution:</h2>
  
  <p>Ended up doing more or less exactly what larsks said. Just did not add it to the FORWARD chain, I added it to the DOCKER chain instead. The problem with the FORWARD chain is that Docker adds its stuff in there when it restarts in first position. Which results in having my rules getting pushed down and not having any effect. However for the DOCKER chain it seems Docker appends only additional rules so mine stay in effect. So when I save my rules and then restart the server everything still works fine.</p>
  
  <p>So now it looks more or less like that:</p>
  
  <pre><code>*filter
  :INPUT ACCEPT [0:0]
  :FORWARD ACCEPT [0:0]
  :OUTPUT ACCEPT [779:162776]
  :DOCKER - [0:0]
  # That I can access from IP 1.2.3.4
  -A DOCKER -s 1.2.3.4/32 -p tcp -m tcp --dport 123 -j ACCEPT
  # That I can access from other Docker containers
  -A DOCKER -o docker0 -p tcp -m tcp --dport 123 -j ACCEPT
  # Does not allow it for anything else
  -A DOCKER -p tcp --dport 123 -j DROP
  
  -A INPUT -i lo -j ACCEPT
  -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
  -A INPUT -p tcp -m tcp --dport 22 -j ACCEPT
  -A INPUT -p tcp -m tcp --dport 80 -j ACCEPT
  -A INPUT -j DROP
  COMMIT
  </code></pre>