How make openvpn work with docker

2019-02-01 08:54发布

I have recently installed privacy vpn, and it turns out that enabled openvpn breaks docker.

When I try to run docker-compose up i get following error

ERROR: could not find an available, non-overlapping IPv4 address pool among the defaults to assign to the network

Disabling vpn fixes the problem (however I'd rather not disable it). Is there any way to make these two co-exist peacefully? I use debian jessie, and my openvpn has following version string

 OpenVPN 2.3.4 x86_64-pc-linux-gnu [SSL (OpenSSL)] [LZO] [EPOLL] [PKCS11] [MH] [IPv6] built on Jun 26 2017

A lot of people "solved" this problem by disabling the openvpn, so I'm asking specifically on how to make these two work at the same time.

References:

  1. https://stackoverflow.com/a/45377351/7918
  2. https://stackoverflow.com/a/42499393/7918

If this makes any difference my vpn provider is: https://www.ovpn.com/ and here is (somewhat redacted) config file:

client
dev tun

proto udp

remote host port
remote-random

mute-replay-warnings
replay-window 256

push "dhcp-option DNS 46.227.67.134"    
push "dhcp-option DNS 192.165.9.158"

remote-cert-tls server
cipher aes-256-cbc
pull

nobind
reneg-sec 432000
resolv-retry infinite

comp-lzo
verb 1

persist-key
persist-tun
auth-user-pass /etc/openvpn/credentials
ca ovpn-ca.crt
tls-auth ovpn-tls.key 1

5条回答
ら.Afraid
2楼-- · 2019-02-01 09:00

Based on answer from Anas El Barkani, here's a complete step-by-step example using PostgreSQL.

While VPN is not connected, create a permanent docker network:

docker network create my-network --subnet 172.24.24.0/24

In docker-compose file, specify network as external:

version: "2"
services: postgres: container_name: postgres image: postgres volumes: - ./volumes/postgres/data:/var/lib/postgresql/data environment: - POSTGRES_DB=dummy - POSTGRES_USER=user - POSTGRES_PASSWORD=123456 - POSTGRES_HOST=localhost networks: - default ports: - "127.0.0.1:5432:5432"
networks: default: external: name: my-network

That's all. Now you can enable your VPN, and start/stop container as usual:

docker-compose up -d
docker-compose down

No need to turn VPN on/off every time, or to add weird scripts as root.

查看更多
三岁会撩人
3楼-- · 2019-02-01 09:17

Some additional context here: the 0.0.0.0 and 128.0.0.0 routes are only created if the OpenVPN server (aka Access Server) is configured to push routes to send all the endpoint's Internet traffic via the VPN. By adding these broad routes, the user's Internet traffic can be routed while not interfering with routing on the local LAN, and ensuring that the endpoint remains able to route the OpenVPN traffic itself to the local router.

If sending all Internet traffic via the OpenVPN server isn't a requirement, you may be better off asking your VPN admin to create a profile that only routes traffic to required destinations (such as private IP address ranges) via the VPN instead of everything. That should avoid having to mess with the routes on the endpoint.

查看更多
家丑人穷心不美
4楼-- · 2019-02-01 09:19

You can also get docker-compose working if you define the subnet CIDR in your docker compose file:

networks:
  your-network:
   ipam:
      config:
      - subnet: 172.16.238.0/24
        gateway: 172.16.238.1

Another option: create first the network with the subnet CIDR and then specify in the docker compose file that you want to use this network:

network create your-network --subnet 172.24.24.0/24

In your docker compose file:

networks:
  your-network:
    external: true
查看更多
Ridiculous、
5楼-- · 2019-02-01 09:22

Solution (TL;DR;)

Create /etc/openvpn/fix-routes.sh script with following contents:

#!/bin/sh

echo "Adding default route to $route_vpn_gateway with /0 mask..."
ip route add default via $route_vpn_gateway

echo "Removing /1 routes..."
ip route del 0.0.0.0/1 via $route_vpn_gateway
ip route del 128.0.0.0/1 via $route_vpn_gateway

Add executable bit to the file: chmod o+x /etc/openvpn/fix-routes.sh. Change owner of this file to root: chown root:root /etc/openvpn/fix-routes.sh.

Add to your config following two lines:

 script-security 2
 route-up  /etc/openvpn/fix-routes.sh

Explanation

Openvpn adds routes that for following networks: 0.0.0.0/1 and 128.0.0.0/1 (these routes cover entire IP range), and docker can't find range of IP addresses to create it's own private network.

You need to add a default route (to route everything through openvpn) and disable these two specific routes. fix-routes script does that.

This script is called after openvpn adds its own routes. To execute scripts you'll need to set script-security to 2 which allows execution of bash scripts from openvpn context.

Thanks

I'd like to thank author of this comment on github, also thanks to ovpn support.

查看更多
闹够了就滚
6楼-- · 2019-02-01 09:23

Maybe one way to do it is to add all routes excluding 172.16.0.0/12 to route through VPN so we are sure everything going out is properly handled:

sudo ip route add 192.0.0.0/2 via $route_vpn_gateway
sudo ip route add 128.0.0.0/3 via $route_vpn_gateway
sudo ip route add 176.0.0.0/4 via $route_vpn_gateway
sudo ip route add 160.0.0.0/5 via $route_vpn_gateway
sudo ip route add 168.0.0.0/6 via $route_vpn_gateway
sudo ip route add 174.0.0.0/7 via $route_vpn_gateway
sudo ip route add 173.0.0.0/8 via $route_vpn_gateway
sudo ip route add 172.128.0.0/9 via $route_vpn_gateway
sudo ip route add 172.64.0.0/10 via $route_vpn_gateway
sudo ip route add 172.32.0.0/11 via $route_vpn_gateway
sudo ip route add 172.0.0.0/12 via $route_vpn_gateway

# And finally delete the default route which handle 172.16.0.0/12
sudo ip route del 128.0.0.0/1 via $route_vpn_gateway
查看更多
登录 后发表回答