JuniperのNetwork Connect利用時に外部にアクセスする
はじめに
私の大学では学内に専用のネットワークがあり、学生が学外から安全な経路でアクセスできるようにするために、Juniper Networks社の製品を導入してVPN接続サービスを提供しています。VPNに接続する際はWeb上のログイン画面でユーザーIDとパスワードを入力、接続モードを全ての通信でVPNを経由するNetworkConnect、ログイン後のWebシステム上でのみ学内にアクセスできるWebモード(リバースプロキシ)から選択してログインする必要があります。
しかし、この2つのモードにはそれぞれ問題があり、NetworkConnectでは外部のサイトにアクセスできず、Webモードではリバースプロキシを通すため、アドレスバーのURLを書き換える必要があり、任意のアドレスに簡単に飛べません(例えばブックマークから特定の科目のページにアクセスできません)。
そこで、OpenConnectというVPN クライアントとSplit Tunnelingという技術で学内はVPNを経由、それ意外はVPNを経由しないようにし、より簡単に接続するためにOpenConnectをラップしたスクリプトを作成しました。
なお、自作したスクリプトは現時点ではMacのみをサポートしています。
使ったもの
OpenConnect
OpenConnectは初め、CiscoのAnyConnect SSL VPNをサポートするために作成されたもので、その後、Pulse Connect Secureとして知られるJuniper SSL VPNをサポートしました。ということが下記のページに書かれています。
Split Tunneling
VPN接続
VPN接続 + Split Tunneling
鍵のマークがVPN ゲート、ビルのマークが学内、Webの画面が外部のページです。 Split Tunnelingを利用するとIPを指定することで、指定したIPとそれ以外でVPN ゲートを通すか通さないかを分けることが出来ます。
これを実現するために、OpenConnectではvpncというスクリプト(以下、vpnc-script)を利用しています。 また、vpncではrouteコマンドでルーティングテーブルを書き換えることによって特定のIPのみをVPNゲートを通すようにしているようです。
実際にルーティングテーブルがどのように変わるかを確認したい場合は、
$ netstat -rn > a $ netstat -rn > b $ diff a b
とすると良いと思います。
手順
セットアップ
TUN/TAP
仮想ネットワークデバイスです。
$ brew cask install tuntap
OpenConnect
VPN クライアントです。
$ brew install openconnect
HomebrewでOpenConnectを入れるとvpnc-scriptも/usr/local/etc/vpnc-script
にインストールされます。
Juniper Network Connect Client
OpenConnectの簡素なラッパーです。
$ brew install tuntap $ brew install openconnect $ git clone https://github.com/lightnet328/jncc ~/.jncc $ cp ~/.jncc/jncc.config.example ~/.jncc/jncc.config $ vim ~/.jncc/jncc.config $ echo 'export PATH="$PATH:$HOME/jncc"' >> ~/.zshrc $ exec $SHELL -l
bashを使ってる方は~/.zshrc
を~/.bashrc
と読み替えて実行してください。
接続
OpenConnect
利用するVPNサーバーがJuniper VPNで、認証方式がIDとパスワードの場合、以下のコマンドでネットワーク接続することができます。
$ sudo openconnect --user myid0123 vpn.tekitou.ac.jp --juniper
ただ、これでは前述した通り、全ての通信がVPNを経由してしまいます。 VPNを経由したいIPアドレスがわかっている場合は、以下のようなスクリプトを用意し、openconnectコマンドにそのパスを渡してあげることでVPNを通るかどうか振り分けることができます。
export CISCO_SPLIT_INC=2 export CISCO_SPLIT_INC_1_ADDR=xxx.xxx.xxx.xxx export CISCO_SPLIT_INC_1_MASK=255.255.255.255 export CISCO_SPLIT_INC_1_MASKLEN=32 export CISCO_SPLIT_INC_2_ADDR=xxx.xxx.xxx.xxx export CISCO_SPLIT_INC_2_MASK=255.255.255.255 export CISCO_SPLIT_INC_2_MASKLEN=32 exec /usr/local/etc/vpnc-script
$ sudo openconnect --user myid0123 vpn.tekitou.ac.jp --juniper --script=(SCRIPT PATH)
マニュアルはman openconnect
かOpenConnect VPN client.でどうぞ。
Jniper Network Connect Client
VPNを経由したいIPアドレスが予めわかっている場合は前述の手段で困りませんが、多くの場合はわからないと思います。そこで、設定ファイルにVPNを経由したいドメインを書いておくことで自動でIPアドレスを求めるクライアントを作りました。
安直なネーミングですが、Juniper Network Connect ClientとしてGitHubに公開しています。
仕組みとしては単純で、まずOpenConnectでVPN接続し、その状態でnslookupして設定しておいたドメイン名をIPアドレスに変換し、そのIPアドレスのみをVPNに通すようにしています。
他の部分も結構簡素なので何かあればIssueを建てるなりPull Requestを送るなりしてください。
設定ファイルはjncc.config
で中身は以下のようになっています(コメントは除きました)。
ID=myid0123 SERVER=vpn.tekitou.ac.jp SPLIT_HOSTS[0]=portal.tekitou.ac.jp SPLIT_HOSTS[1]=xxx.tekitou.ac.jp SPLIT_HOSTS[2]=oxo.tekitou.ac.jp VPNC_SCRIPT_FILE=/usr/local/etc/vpnc-script
接続する時は、
$ sudo jncc connect
切断する時は、
$ sudo jncc disconnect
を実行するだけです。
簡単ですね。
おわりに
ネットワークには詳しくないのですが、なんとかVPN接続の手間を減らすことが出来ました。もし、間違っている点があれば、コメントやTwitterのリプライにてお知らせいただければ幸いです。
気がつけば2016年ももうすぐ終わりですね。良いお年を。