docker firewall blocking at the source port

Today I installed my brand new docker host system, started some images and as usual trying to setup iptables to restrict the ports to specific source servers and ports.

Hours later I learned that this was kinda not so easy.

  • You cannot use the INPUT chain as Docker works with the standard bridge in the FORWARD chain.
  • The DOCKER-USER chain (which is a part of the FORWARD chain) see packets after they have been redirected to the destination port, so if we have multiple containers running at port 8000 internally it get’s very complex to find the correct container, not to mention new containers starting up.

One example:

I have a docker image that runs a web-server listening inside the container on port 8000 which is mapped to the host port 80 as in this config:

ports:
– “80:8000”

This means my host is listening on port 80 and that get’s redirected to the Docker container on port 8000.

Now the DOCKER-USER chain sees only port 8000 where I could drop some other source IP.

But I want to selectively open ports and let not configured ones dropped by default, even if somebody spin’s up new containers.

The docker-documentation and some other sources disable the iptables feature of docker and manually configure the firewall, which is okay but not that what I wanted as the sources allow general inter-container communication or have a VERY complex rulesystem that I don’t want to explain the my Administrator colleagues of that system.

 

The solution to this is hidden within the iptables flow diagram:

The PREROUTING chain of the nat table is the first one that get touched and where the source port of 80 is redirected to the container on the destination port 8000.

So we tag the SYN packets we want to drop in the PREROUTING chain of the mangle table with the MARK target and later at the DOCKER-USER chain of the filter table we will drop them accordingly.

My final ruleset looks like that:

 

#!/bin/bash

#Flush and setup:
/sbin/iptables -F DOCKER-USER
/sbin/iptables -t mangle -F PREROUTING

##############
# Docker conf
###############
#packets in NAT table are only traversed with the first packet!
#MARK1: allowed packet
#MARK2: drop this in FORWARDING (DOCKER-USER)Chain
#Mark everything with 0x2, so block everything
/sbin/iptables -t mangle -A PREROUTING -i ens3 -m state –state NEW -j MARK –set-mark 2
###
# Mark the packets we want to allow with 0x1 (which are previously also mark’ed with 0x2)
###
/sbin/iptables -t mangle -A PREROUTING -i ens3 -m tcp -p tcp –dport 80 -s xxx.xxx.xxx.xxx -j MARK –set-mark 1
/sbin/iptables -t mangle -A PREROUTING -i ens3 -m tcp -p tcp –dport 443 -j MARK –set-mark 1

###
# Drop the packets marked with 0x2
###

/sbin/iptables -A DOCKER-USER -m mark –mark 2 -j DROP
/sbin/iptables -A DOCKER-USER -j RETURN

This ruleset will allow port 80 from a specific IP address and port 443 from every source IP. Everything else exposed by docker containers is not reachable for anybody – or at least they cannot open a TCP connection to it because the initial SYN packets are dropped away.

And the best is I can start as much containers as I want on port 8000 and don’t have to fiddle around with the internal docker ports.

Hope that helps somebody ;)

Advertisements

SSL Funambol on Android without adding Certificates

Recently I wrote a blog entry about how to add a root certificate to your rooted android keystore for using SSL funambol.
This works perfectly as long as you have root access to the device.

Sometimes you come into the situation where you cannot root the device, eg. in a corporate environment or if you just don’t want to crack a new device just to make the funambol client working, like me for now.

I’ve got a new Motorola Xoom and needed funambol to sync my contacts and calendar entries.

After asking Mr. Google there are only 2 ways till Android 4.x is ready:

  • Using http without ssl
  • Using ssl and recode the funambol client to accept all cert’s

I decided to use the 2nd solution – this also refreshes my java a little bit :-)

Of course i want to share everything with you – if you’re too lazy to read all the stuff you can point your Android client here to install my compiled Funambol 10.0.8 client without the certificate check:

For Android < 4.0 this binary works:

Direct download with android: funambol-android-10.0.8_Tasks-devBioS.apk

Mirror 1: funambol-android-10.0.8_Tasks-devBioS.apk

Since ICS (>= 4.0) people having problems syncing Calender. This is because they made changes in the Calender API wich renders the Calendar Sync unusable, you can use this binary (which only works on ICS and greater):
Direct download with android: funambol-android-10.1.3_Tasks-devBioS.apk

UPDATE 2012-04-03: I activated the task sync feature also and re-uploaded the binary.
If anyone is intrested in the source on how to activate it, drop me a line and i will update the post.

Continue reading “SSL Funambol on Android without adding Certificates”