Background / Why would I want to do this?
A client, where their new web server is running their custom application in docker, wants the server to be restricted to VPN access only. They neither want to host the application internally and provide us developers with access to their network, nor do they want an internet based solution with other security options. They have been very specific with their request even down to the encryption methods.
What do I need to do / What have I tried
Unfortunately, docker likes to play with iptables making ports publicly accessible, which we can’t have. I need to disable docker’s ability to mess with iptables and then manually configure either ufw or iptables directly to correctly process the packets between interfaces.
I have Googled this a lot and have tried many different examples that seem close, but few are exactly the same task and my lack of experience with unix firewalls has meant a lot of wasted time where one thing works and another breaks or I simply find myself back to square one, with the dockerised website working with or without the VPN connection.
I’m pretty familial with docker and docker-compose. In this scenario, I’m using jwilder/nginx-proxy, mariadb and a custom debian-stretch container for a ruby application. All this works OK.
I’ve configured OpenVPN on the server suing this guide and have successfully connected via the OpenVPN windows client, so that works. I can currently use this VPN connection and see my IP address change when visiting other sites further confirming that this looks good.
Version numbers and such:-
- Debian GNU/Linux 9 \n \l
Docker version 18.09.0, build 4d60db4
docker-compose version 1.23.2, build 1110ad01
OpenVPN 2.4.0 x86_64-pc-linux-gnu
Current interfaces: -
-
Docker bridge?
br-7392762a0f11: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.18.0.1 netmask 255.255.0.0 broadcast 172.18.255.255 -
Main docker interface
docker0: flags=4099<UP,BROADCAST,MULTICAST> mtu 1500
inet 172.17.0.1 netmask 255.255.0.0 broadcast 172.17.255.255 -
External WAN
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet [external server ip] netmask 255.255.255.0 broadcast 134.213.56.255 -
Rackspace local
eth1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 10.181.160.253 netmask 255.255.224.0 broadcast 10.181.191.255 -
Loopback
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0 -
OpenVPN
tun0: flags=4305<UP,POINTOPOINT,RUNNING,NOARP,MULTICAST> mtu 1500
inet 10.8.0.1 netmask 255.255.255.255 destination 10.8.0.2
I’ve followed this guide to disable dockers iptable manipulation which allows me to continue to use my dockerised application, but this is about as far as I can get without screwing things up.
I wonder if one of you smart chaps with decent networking knowledge might be kind enough to provide me with some definitive instructions preferably using ufw, to get the routing configured correctly so that only when an active VPN connection is up, can anything on the server be accessed, whilst not killing off DNS lookups and other external requests that could be made from within the application container e.g. SMPT connections. Of course I need to be able to get a VPN connection up and running to start with. OpenVPN is using the default UDP port of 1194
Any help would be very much appreciated and I’m sure this would be of use to others also.
Many thanks!