この話はLinux全般で通用する話だと思いますが,試したのはUbuntu 24.04です。
はじめに#
Fortinet VPNはFortinetが提供するVPNで,SSL-VPNなどを提供しています。SSL-VPNはTLS/SSLを使ったVPN技術で,現実的な利点としてはTCPの443(HTTPSと同じ)を使うため各種フィルターを通過できる可能性が高く,ネットワーク関係のトラブルを回避しやすいことが挙げられます(こういった通信の制限は理念的には不適切ですが現実には良くあります。またネットワーク提供者の意図でなくとも技術的な未熟さが原因でHTTPSもどきの通信でないとうまくいかないというのもしばしばあります)。
Fortinet VPNはFortinetがクライアントを提供していますが,Linux版はあまりこなれていません。openfortivpnというソフトウェアがOSS(GPLv3)で提供されており,VPNクライアントとして利用可能です。
openfortivpnは最近SAMLログインという機能が実装され,標準的でない認証,例えばブラウザを経由した2FA認証など,を利用可能になりました。これの使い方を説明します。
SAMLによるVPNの仕組み#
ここでは vpn.example.com というサーバーの443番ポートを利用する場合を例として説明します。一般的なSAMLの話はせずにFortivpnでこうしているだろう,という仕組みについて説明します。外側からの観察で得られた予想なので詳細は間違っているかもしれません。あとrealmのような機能は今回は使わないものとします。
- openfortivpn (もしくは適当なVPNクライアント)を起動をすると,
localhost:8020でHTTPサーバーが待ち受ける - ブラウザで
https://vpn.example.com/remote/saml/start?redirect=1にアクセスする。このサーバーはVPNサーバーでもあるが,ポート443を待ち受けているのでHTTPSとしても反応できる - サーバーから組織のIdPへのリダイレクトが帰ってくる (リダイレクトの指示にVPNからだという情報を何らかの形で含む)
- IdPサーバーでブラウザ経由で認証する
- 認証成功後,
https://vpn.okayama-u.ac.jp/remote/saml/loginに認証情報がJavascriptのコード経由でpostされる - VPNサーバーはセッショントークンを作成し,
http://127.0.0.1:8020/?id=<session-token>へとリダイレクトする - このローカルホストのポートに待ち受けていたVPNクライアントがこのリダイレクトのリクエストを受け取り,セッショントークンを受け取る
- vpn.example.com の 443番ポート経由でこのセッショントークンを利用してVPNを張る。同じポートを利用するが,ここでは VPN のセッションを張るために利用される
実際の利用法#
以下のようなスクリプトを作って実行します。プログラムは $HOME/opt/bin/openfortivpn にインストールするものとします。
#!/bin/sh
OPENFORTIVPN=$HOME/opt/bin/openfortivpn
HOST=vpn.example.com
PORT=443
BROWSER=google-chrome
VPNOPTS="" # --trusted-cert などを指定する
$BROWSER https://$HOST:$PORT/remote/saml/start?redirect=1
sudo $OPENFORTIVPN $HOST:$PORT --saml-login $VPNOPTS
すると,ブラウザが開いて認証が実行されます。またsudoでopenfortivpnを動かすのでパスワードを入力する必要があります。
VPNの接続に成功するとターミナルには以下のように出力されます。
:
INFO: Interface ppp0 is UP.
INFO: Setting new routes...
INFO: Adding VPN nameservers...
INFO: Tunnel is up and running.
VPNを停止させたい場合はターミナルでCTRL-Cを入力してください。