Contesto
Ho usato l'ottimo contenitore Docker di Kyle Manna ( https://github.com/kylemanna/docker-openvpn ). Sto usando la cosiddetta documentazione "paranoica" per configurare il mio server OpenVPN, ma a mio avviso questo dovrebbe essere il modo standard e non il modo paranoico.
Configurazione
Per consentire la connessione bidirezionale tra i contenitori Docker selezionati e i client VPN, è necessario creare una rete Docker sulla quale si collegherà un contenitore a cui dovrebbe essere consentito l'accesso dai client VPN. Il server VPN sarà uno di quei container.
Il server VPN dovrebbe avere il client-to-client
, topology subnet
, dev tun0
(o altro dispositivo tun) e push "route <docker net IP> <docker net mask>"
configurato.
L'host del server VPN deve essere configurato per supportare l'inoltro di pacchetti IP da una sottorete a un'altra. Questo significa impostare sysctl ip_forward su 1 (dovrebbe essere il caso se si dispone dell'installazione Docker), consentendo ai pacchetti dal dispositivo tun di passare attraverso la catena FORWARD di iptables e impostare il routing corretto. Questo può essere riassunto con questi comandi:
$ sudo sysctl -w net.ipv4.ip_forward=1
$ sudo iptables -A FORWARD -i tun+ -j ACCEPT
$ sudo ip route add 192.168.255.0/24 via <IP address of OpenVPN server container>
Ad ogni modo, ecco le opzioni che ho usato per configurare il server:
$ docker run --rm --net=none -it -v $PWD/files/openvpn:/etc/openvpn kylemanna/openvpn:2.4 ovpn_genconfig -u udp://<FQDN> -N -d -c -p "route <docker net IP> <docker net range>" -e "topology subnet"
Ciò dovrebbe generare un file di configurazione del server simile a:
server 192.168.255.0 255.255.255.0
verb 3
key /etc/openvpn/pki/private/vpn.example.com.key
ca /etc/openvpn/pki/ca.crt
cert /etc/openvpn/pki/issued/vpn.example.com.crt
dh /etc/openvpn/pki/dh.pem
tls-auth /etc/openvpn/pki/ta.key
key-direction 0
keepalive 10 60
persist-key
persist-tun
proto udp
# Rely on Docker to do port mapping, internally always 1194
port 1194
dev tun0
status /tmp/openvpn-status.log
user nobody
group nogroup
client-to-client
### Push Configurations Below
push "dhcp-option DNS 8.8.8.8"
push "route 172.20.20.0 255.255.255.0"
### Extra Configurations Below
topology subnet
Esempio concreto
Prenderò ora un esempio concreto. In questo esempio, eseguirò il server OpenVPN sopra menzionato all'interno di Docker sull'host vpn.example.com. Questo contenitore è collegato alla rete Docker docker-net-vpn. Ecco i comandi (in questo esempio ho generato la configurazione del server direttamente sul server e ho saltato la generazione della CA, seguire invece la documentazione paranoica del progetto sopra citato):
$ docker network create --attachable=true --driver=bridge --subnet=172.20.20.0/24 --gateway=172.20.20.1 docker-net-vpn
$ docker run --rm --net=none -it -v $PWD/files/openvpn:/etc/openvpn kylemanna/openvpn:2.4 ovpn_genconfig -u udp://vpn.example.com -N -d -c -p "route 172.20.20.0 255.255.255.0" -e "topology subnet"
$ docker run --detach --name openvpn -v $PWD/files/openvpn:/etc/openvpn --net=docker-net-vpn --ip=172.20.20.2 -p 1194:1194/udp --cap-add=NET_ADMIN kylemanna/openvpn:2.4
$ sudo sysctl -w net.ipv4.ip_forward=1
$ sudo iptables -A FORWARD -i tun+ -j ACCEPT
$ sudo ip route add 192.168.255.0/24 via 172.20.20.2
Il primo comando crea una nuova rete Docker dedicata che definisce una nuova sottorete. Collegheremo il server OpenVPN a questa rete.
Il secondo crea la configurazione OpenVPN usando la stessa sottorete definita nel primo comando.
Il terzo crea il server OpenVPN. È collegato alla rete Docker appena creata e utilizza un IP fisso.
Il quarto e il quinto comando configurano l'inoltro IP.
L'ultimo comando aggiunge una nuova route verso la configurazione del client VPN tramite l'IP fisso del contenitore OpenVPN.
Nota
Non l'ho provato, ma dovrebbe essere possibile limitare la regola FORWARD per iptables. La creazione della rete Docker ha creato un nuovo dispositivo bridge. Questo bridge è denominato br-<ID>
con ID che sono i primi 12 caratteri dell'ID di rete Docker. Questo ID può essere ottenuto con docker network inspect -f '{{.Id}}' docker-net-vpn | cut -b-12
. Pertanto, il seguente comando è forse più restrittivo (quindi per quanto riguarda la sicurezza) ma dovrebbe comunque consentire il routing del nostro traffico:
$ NET_VPN_BRIDGE="br-$(docker network inspect -f '{{.Id}}' docker-net-vpn | cut -b-12)"
$ sudo iptables -A FORWARD -i tun+ -o ${NET_VPN_BRIDGE} -j ACCEPT
tap
, noiatun
, ci ho lavorato per più di 12 ore senza successo fino ad ora.