OpenConnect
OpenConnect は、client-to-site VPNs 向けのフリーかつオープンソースのソフトウェアです。いわゆる SSL VPN サーバー/ゲートウェイ/コンセントレーターに接続することができ、具体的には以下に対応しています:
- Cisco AnyConnect anyconnect
- Palo Alto Networks (PAN) GlobalProtect gp
- Junos / Ivanti Pulse Secure pulse、詳細は Pulse Connect Secure を参照
- Juniper Network Connect nc
- Fortinet fortinet
- F5 f5
- Array Networks array
インストール
GNOME や KDE のようなデスクトップ環境を使用している場合は、おそらく NetworkManager を利用しているため、その統合のために networkmanager-openconnect パッケージをインストールしてください。このパッケージは依存関係として openconnect パッケージもインストールします。統合が不要な場合は、openconnect パッケージのみをインストールしてください。
一部の VPN はスプリットルーティングとして構成されており、その結果スプリット DNS も使用されます。これに対応するため、また一般的にも、systemd-resolved と resolv.conf の stub モードを使用することが推奨されます。これを確認するには resolvectl を実行し、Global セクション内に "resolv.conf mode: stub" という行があるか確認してください。出力全体を理解することは非常に有用であるため、学習しておくとよいでしょう。VPN に接続している場合、出力は概ね以下のようになります:
$ resolvectl
Global
Protocols: -LLMNR -mDNS -DNSOverTLS DNSSEC=no/unsupported
resolv.conf mode: stub
Link 2 (enp1s0)
Current Scopes: DNS
Protocols: +DefaultRoute +LLMNR -mDNS -DNSOverTLS DNSSEC=no/unsupported
Current DNS Server: 192.168.0.1
DNS Servers: 192.168.0.1
DNS Domain: ~home.box
Link 3 (tun0)
Current Scopes: DNS
Protocols: -DefaultRoute +LLMNR -mDNS -DNSOverTLS DNSSEC=no/unsupported
Current DNS Server: 10.10.10.10
DNS Servers: 10.10.10.10
DNS Domain: ~example.org ~int.example.net
使用方法
OpenConnect を単体で使用する場合
OpenConnect には多くのオプションがあります。詳細は openconnect(8) を参照してください。最も単純なケースでは、Cisco AnyConnect VPN を使用している場合、アドレスを指定し、プロンプトに従ってユーザー名とパスワードを入力するだけです:
$ sudo openconnect vpnserviceaddr
Cisco AnyConnect 以外の VPN タイプを使用する場合は、"--protocol" オプションを追加し、nc、gp、pulse、f5、fortinet、または array のいずれかを指定します:
$ sudo openconnect --protocol=vpntype vpnserviceaddr
ユーザー名を指定することも可能です:
$ sudo openconnect --protocol=vpntype -u user vpnserviceaddr
一部の VPN は、フルトンネルやスプリットトンネル接続など、異なるアクセス構成に応じた認証グループを提供しています。利用可能な auth-group を表示し、サービスの詳細情報を取得するには、以下を実行します:
$ sudo openconnect --protocol=vpntype --authenticate vpnserviceaddr
接続時にコンピューターに関する情報の収集を必要とする VPN もあります。その場合は "--csd-wrapper" オプションが役立つことがあります。利用・調整可能なスクリプトは "/usr/lib/openconnect/" にあります:
$ sudo openconnect --protocol=vpntype --csd-wrapper=script vpnserviceaddr
一部の VPN は、Google、Microsoft AzureActiveDirectory、Okta などのアイデンティティプロバイダー (IdP) に認証を委譲します。このシナリオは一般にシングルサインオン (SSO) と呼ばれ、通常は SAML 2.0 または OIDC 標準が使用されます。動作の流れは次の通りです: ブラウザまたは webview で VPN の SSO アドレスを開くと、IdP にリダイレクトされ、最終的に VPN ページに戻り cookie を取得します。この cookie は "-C,--cookie" または "--cookie-on-stdin" オプションを使って openconnect に渡す必要があります。ブラウザから cookie を取得するには、開発者ツールを使用してください。
$ sudo openconnect --protocol=vpntype --cookie-on-stdin vpnserviceaddr
Fortinet の SSO VPN の場合、ブラウザの開発者ツールを使う代わりに openfortivpn-webview-qtAUR を使用して cookie を取得できます:
$ sudo openconnect --protocol=fortinet -C "$(openfortivpn-webview vpnserviceaddr)" vpnserviceaddr
OpenConnect は IP ルーティングや DNS ルーティングを設定するために、いくつかの環境変数をスクリプトに渡します。デフォルトでは "/etc/vpnc/vpnc-script" が使用されます。このスクリプトは必要に応じていくつかの環境変数に対応しており、例えば VPN によって配布されたものに加えて DNS ドメインを追加するには "CISCO_SPLIT_DNS" を使用できます:
$ sudo CISCO_SPLIT_DNS=~internal.example.com,~10.in-addr.arpa openconnect --protocol=vpntype vpnserviceaddr
デフォルトのスクリプトの代わりに独自のスクリプトを使用することも可能で、その場合は "-s,--script" オプションを使います:
$ sudo openconnect --protocol=vpntype -s script vpnserviceaddr
また、ocproxy-gitAUR のようなプロキシと組み合わせて、SSH のようなポートフォワーディングを行うこともできます。例えば rdesktop を使用して localhost:13389 に接続すると、VPN 経由で rds.int.example.net:3389 の RDS サービスに転送されます:
$ openconnect --protocol=vpntype --script-tun -s "ocproxy -L 13389:rds.int.example.net:3389" vpnserviceaddr $ rdesktop localhost:13389
NetworkManager を使用する場合
NetworkManager はコマンドラインインターフェース nmcli、ターミナルユーザーインターフェース nmtui、および D-Bus API に対応した各種デスクトップ環境から操作できます。NetworkManager において VPN は "vpn" タイプの接続の一種です。OpenConnect を使った "MyOrgVPN" という接続を CLI で作成するには、以下を実行します:
$ nmcli connection add \ connection.id MyOrgVPN \ connection.type vpn \ vpn.service-type openconnect \ vpn.data cookie-flags=2,gateway=vpnserviceaddr,protocol=vpntype vpn.secrets gateway=vpnserviceaddr,gwcert=
nmcli connection up MyOrgVPN(--ask なし)や GNOME の右上メニュー、または GNOME 設定(コントロールセンター)から接続を有効化すると、通常はユーザー名やパスワード、場合によっては 2FA / MFA を入力するウィンドウが表示されます。VPN タイプが anyconnect または gp の場合、SSO シナリオも動作することが多いです。他のデスクトップ環境では、NetworkManager 接続を操作するために network-manager-applet、nm-connection-editor などのパッケージが必要になる場合があります。
一方で nmcli --ask connection up MyOrgVPN や nmtui、nmtui connect MyOrgVPN を使用した場合、期待される挙動とは異なり、ユーザー名などではなく "Cookie (vpn.secrets.cookie)" の入力を求められます。これを提供するには、以下のような Bash スクリプトを利用できます:
~/vpn-up.bash
#!/usr/bin/bash connection_name=$(nmcli -t -g type,name connection \ | grep -Po '^vpn:\K.*' \ | sed 's/\\:/:/g' | fzf ) eval "$(nmcli -t -g vpn.data connection show "$connection_name" \ | grep -Po '(^|[ ,])(protocol|gateway)\ =\ [^,]*' \ | sed 's/ //g')" eval "$(openconnect --authenticate --protocol="$protocol" "$gateway")" nmcli connection up "$connection_name" \ passwd-file <(echo "vpn.secrets.cookie:$COOKIE")
接続を無効化するには、nmcli connection down MyOrgVPN、nmtui、または GNOME の右上メニューや GNOME 設定を使用します。
WebAuth および Anyconnect を使用したシングルサインオン(SSO)
networkmanager-openconnect は Cisco AnyConnect の WebAuth によるシングルサインオン (SSO) をサポートしています。WebAuth を使用するには:
- networkmanager-openconnect のオプション依存関係(例: webkit2gtk-*)をインストールする
- この接続の VPN タブの "User Agent" フィールドに "AnyConnect Linux_64 4.10.07061" のような値を設定する
接続を有効化すると、WebAuth 用のブラウザウィンドウが表示されます。認証が成功すると、networkmanager-openconnect は openconnect を起動し、接続に必要な "webvpn" cookie を渡します。
netctl を使用する場合
シンプルな tuntap netctl.profile(5) を使うことで通常の netctl のワークフローに OpenConnect を統合することができます。例:
/etc/netctl/vpn
Description='VPN'
Interface=vpn
Connection=tuntap
Mode=tun
#User=root
#Group=root
BindsToInterfaces=(enp0s25 wlp2s0)
IP=no
PIDFILE=/run/openconnect_${Interface}.pid
SERVER=vpn.example.net
AUTHGROUP="<AUTHGROUP>"
LOCAL_USERNAME=<USERNAME>
REMOTE_USERNAME=<VPN_USERNAME>
# Assuming the use of pass(1):
PASSWORD="`su ${LOCAL_USERNAME} -c "pass ${REMOTE_USERNAME}" | head -n 1`"
ExecUpPost="echo '${PASSWORD}' | /usr/bin/openconnect --background --pid-file=${PIDFILE} --interface=${Interface} --authgroup=\"${AUTHGROUP}\" --user=${REMOTE_USERNAME} --passwd-on-stdin ${SERVER}"
ExecDownPre="kill -INT $(cat ${PIDFILE}) ; ip link delete ${Interface}"
以下のように実行することができます:
$ netctl start vpn $ netctl restart vpn $ netctl stop vpn
これは LOCAL_USERNAME が gpg-agent を実行しており、PGP キーのパスフレーズがキャッシュされていることを前提としています。
pass の対話的入力を使用したい場合は、PASSWORD_CMD に以下を設定します:
DISPLAY=":0"
PASSWORD_CMD="su ${LOCAL_USERNAME} -c \"DISPLAY=${DISPLAY} pass ${REMOTE_USERNAME} | head -n 1\""
DISPLAY 変数は環境に応じて調整してください。