I have some difficulties figuring out how to correctly restrict outside access to docker containers.
So far I was using multiple user-defined bridges and exposed HTTP/HTTPS ports.
For example I had:
docker-net-1:
0.0.0.0:9080->80/tcp, 0.0.0.0:9443->443/tcp
docker-net-2:
0.0.0.0:8380->80/tcp
I then used a reverse proxy on my docker host to provide outside access via port 443 to the different services using name based virtual hosts and making sure everything goes via https.
To prevent direct access to the exposed ports I used the DOCKER-USER
chain in iptables.
-A DOCKER-USER -i eth0 -m conntrack --ctstate ESTABLISHED,RELATED -j RETURN
-A DOCKER-USER -i eth0 -j DROP
Now I need to host 2 more applications. They are in separate networks but both expose port 22.
0.0.0.0:9022->22/tcp
0.0.0.0:9122->22/tcp
The tricky part for me now is that I need different firewall rules for those ports.
What I tried so far:
Proxy
As it is SSH I do not see how it can be easily done
Opening port in DOCKER-USER - 1st attempt
As per default external access is disabled in my
DOCKER-USER
I added the follwing:-A DOCKER-USER -p tcp -m tcp --dport 9022 -j RETURN -A DOCKER-USER -p tcp -m tcp --dport 9122 -j RETURN -A DOCKER-USER -i eth0 -m conntrack --ctstate ESTABLISHED,RELATED -j RETURN -A DOCKER-USER -i eth0 -j DROP
Those first 2 rules however never got any hit.
Opening port in DOCKER-USER - 2nd attempt
When looking at the iptables chains again it became clear that at this point the port is not 9022 but 22.
-A DOCKER-USER -p tcp -m tcp --dport 22 -j RETURN
which works as expected.
Opening port in DOCKER-USER - 3rd attempt
I thought about using the additional network interfaces or ip subnets created by docker to distinguish between the two different applications, but the names of the network interfaces seem like randomly created and the IP addresses are probably also not a good way of solving the problem as those addresses change like the network names when recreated.
What now?
What is the best solution here? Ideally I do not want something that breaks when services are restarted, like manipulating existing DOCKER chains or using IPs that change.