If you run OpenVPN as an unprivileged user
and/or in a chroot environment, it can't dynamically modify routes. This
becomes a problem if you run multiple OpenVPN daemons, no matter whether they
run on the same box or on different servers. When a client disconnects from
one instance and later connects to another instance, you have to update your
internal routing information for that client. To solve this, I've been using
the BIRD Internet Routing Daemon.
The relevant part of my /usr/local/etc/openvpn.conf looks like this:
mode server chroot /usr/local/etc/openvpn/chroot client-connect /bin/cc.sh client-disconnect /bin/cc.sh script-security 2 user openvpn group openvpnNote that the location of the client-connect and client-disconnect script /bin/cc.sh is relative to the chroot directory /usr/local/etc/openvpn/chroot, which contains three subdirectories:
drwxr-xr-x 2 root wheel bin drwxr-xr-x 2 root wheel ccd drwxrwxr-x 2 root openvpn tmp
-r-xr-xr-x 1 root wheel cc.sh -r-xr-xr-x 2 root wheel nc -r-xr-xr-x 2 root wheel shI copied sh from /rescue/sh, while nc was hardlinked to sh. All binaries in /rescue are statically linked, so they'll work even in a chroot environment.
router id 10.23.42.1; log syslog all; filter rfc1918 { if net ~ 192.168.0.0/16 then accept; else reject; } protocol kernel { persist; scan time 0; import all; export all; } protocol device { scan time 0; import all; export all; } protocol direct { } protocol static { include "/usr/local/etc/openvpn/chroot/tmp/*.conf"; import filter rfc1918; export none; }Usually, BIRD creates its control socket in /var/run. In order to have it somewhere else, you have to tweak /etc/rc.conf:
bird_config="/usr/local/etc/bird.conf -s /usr/local/etc/openvpn/chroot/tmp/bird.ctl"Of course you can download my cc.sh script and put it to /usr/local/openvpn/chroot/bin.