LinuxのOpenVPNクライアントでスプリットトンネリング

OpenVPNのLinuxクライアントを使ってスプリットトンネルのVPN接続をしようとした所、route-nopullが効かなかったので、別の対処を行った。redirect-gateway def1を削除。

現象

CentOSにOpenVPNのクライアントをインストールし、スプリットトンネルとするためにVPN接続プロファイルにroute-nopullを指定した。

しかしながら、それでも接続後のルーティングテーブルに0.0.0.0/1128.0.0.0/1を追加され、すべての通信がVPN経由となってしまった。

対処法

設定ファイル中のredirect-gateway def1route-nopullに優先されてしまうため、redirect-gateway def1を削除してroute-nopullrouteを指定する。

# redirect-gateway def1
route-nopull
route 192.168.10.0 255.255.255.0

対処法 (あまり洗練されていない方法)

以下の対処法でも動作はするが、上記の方法が簡潔

route-nopullの代わりにroute-noexecを指定することで解決した。

ただしそのままではVPN接続の認証/切断後にルーティングテーブルが変更されないので、必要なものは自分で追加/削除する必要があり、そのためにroute-uproute-pre-downも指定する。

また、route-uproute-pre-downに指定したスクリプトを実行するには、script-security 2の記載も必要。

以下はsystemdを使うUbuntuおよびCentOSで動作確認した。

例えば設定ファイル(/etc/openvpn/client/vpnconnection1.conf)に以下の記述を追加する。

script-security 2
pull
route-noexec
route-up "/etc/openvpn/client/vpnconnection1_route-up.sh"
route-pre-down "/etc/openvpn/client/vpnconnection1_route-pre-down.sh"

vpnconnection1_route-up.shは以下のように記述し、chmod +xで実行権限を付与。

この場合は192.168.10.0/24のみVPN経由とする設定。

${route_vpn_gateway}はOpenVPNから渡される環境変数であり、その他はReference manual for OpenVPN 2.4 | OpenVPNを参照のこと。

またipコマンドはフルパスで記述しておいたほうが良い(UbuntuとCentOSで異なるので注意)。

#!/bin/bash

/usr/sbin/ip route add 192.168.10.0/24 via ${route_vpn_gateway}

同様にvpnconnection1_route-pre-down.shも以下のように記述し、chmod +xしておく。

#!/bin/bash

/usr/sbin/ip route del 192.168.10.0/24 via ${route_vpn_gateway}

サービスとしての起動方法は通常通り。

sudo systemctl start openvpn-client@vpnconnection1

ちなみに、systemdのUnitファイルの方でExecStartPostを指定しておいて、そこでルーティングテーブルを削除しても良さそうに見えるが、再接続された場合に再度ルーティングテーブルが追加されてしまうのでNG。

参考