[Fedora] カフェのフリー WiFi から SoftEther VPN サーバーに接続する為の Bash スクリプト
前書き
最近、カフェに出かけるときに持っていくパソコンは chromebook から Fedora に変わりました。chromebook を床に落としてしまって破損し、うまく開閉できなくなったのでしかたなく Fedora を持っていくようになりました。
Fedora に限らず Linux パソコンを外出先から SoftEther VPN サーバー (VPN サーバー) に接続するのは結構面倒だったりします。
chromebook の場合は L2TP/IPsec に接続するための機能が OS に備わっているので、操作的にはワンタッチで VPN サーバーに接続できます。
Linux の場合は VPN 接続したあと、手動でルーティングテーブルの修正が必要だったりします。これは相当面倒くさいです。
ひょっとしたら Linux にも OS に組み込まれている機能でワンタッチでルーティングテーブルの修正まで行ってくれるものもあるのかもしれませんが、今のところそういう機能については知りません。
そこで Fedora を外出時に持ち出すことが増えてきたので、VPN サーバーの接続とその後のルーティングテーブルの設定を自動化する Bash スクリプトを作ったのでそれについて書いておきます。
前提条件
- VPN サーバーがセットアップ済みであること
- SoftEther VPN クライアント (VPN クライアント) がパソコン (今回は Fedora) にセットアップ済みであること
- Fedora が起動したときに VPN クライアントのプロセスが自動起動する設定になっていること
- VPN サーバーに接続するときのプロトコルが SoftEther VPN プロトコル (Ethernet over HTTPS = SSLVPN みたいなもの) であること
- VPN クライアントの仮想 LAN カードに設定する IP アドレスは、VPN サーバー側の DHCP サーバーから通知アドレスを使用すること
- Fedora が使用する DNS サーバーはカフェの WiFi のルーター (カフェの DHCP サーバー) から通知されるものとすること
- カフェの WiFi ルーター (カフェの DHCP サーバー) から通知されるデフォルトゲートウェイは Metric 設定がされていること
Bash スクリプト
作った Bash スクリプトは以下の通りです。各自の環境にあわせて変更する必要のある箇所を 赤字 にしています。
#!/usr/bin/bash echo 'デフォルトゲートウェイの IP アドレスを取得します...' ip_route_output=$(ip route 2>/dev/null) default_gateway_info=$(echo "$ip_route_output" | grep 'default via' 2>/dev/null) default_gateway_ip=$(echo "$default_gateway_info" | awk '{print $3}' 2>/dev/null) echo 'VPN サーバーのホスト名の名前解決を実行して VPN サーバーの IP アドレスを取得します...' vpnserver_ip=$(getent hosts yourvpnserver.softether.net | awk '{ print $1 }' 2>/dev/null) echo 'VPN サーバーに接続します...' sudo /usr/local/vpnclient/vpncmd /client localhost /cmd accountconnect vpn_to_home > /dev/null 2>&1 echo 'VPN サーバーに対するスタティックルートを設定します...' sudo ip route add ${vpnserver_ip} via ${default_gateway_ip} > /dev/null 2>&1 echo 'VPN クライアントの仮想 NIC の IP 設定を DHCP サーバーに要求します...' sudo dhclient vpn_vnic > /dev/null 2>&1
1 – 6 行目まででやっていること
VPN サーバーに接続したあと、Fedora のルーティング設定を変更する必要があります。そのための準備として、現在 (= スクリプト実施前) のデフォルトゲートウェイの IP アドレスを取得し、
default_gateway_ip
という変数に格納しています。
8 -9 行目でやっていること
VPN サーバーのホスト名 (FQDN) のグローバル IP アドレスを名前解決して取得し、
vpnserver_ip
という変数に格納しています。以下のコマンドの yourvpnserver.softether.net をご自身の VPN サーバーの FQDN に置き換えてください。
vpnserver_ip=$(getent hosts yourvpnserver.softether.net | awk '{ print $1 }' 2>/dev/null)
11 – 12 行目でやっていること
VPN サーバーに接続しています。
この時 SoftEther VPN のコマンドである vpncmd を実行しています。
以下コマンドの vpn_to_home は VPN 接続名ですので、ここをご自身の設定に合わせてください。
sudo /usr/local/vpnclient/vpncmd /client localhost /cmd accountconnect vpn_to_home > /dev/null 2>&1
VPN 接続名は、VPN クライアントをセットアップするときに accountcreate コマンドで指定したものです。以下のコマンドリファレンスで “接続設定の名前” と説明されている箇所です。
[コマンドリファレンス] 6.5.21 “AccountCreate”: 新しい接続設定の作成
14 – 15 行目でやっていること
VPN サーバーのグローバル IP アドレスに対するスタティックルートを通過しています。
17 – 18 行目でやっていること
VPN クライアントの仮想 LAN カードの IP 設定を、VPN サーバー側にある DHCP サーバーに要求しています。
これにより、VPN サーバー側にある DHCP サーバーから、仮想 LAN カード用の IP アドレスとデフォルトゲートウェイが渡されます。
スクリプトを実行する
スクリプト実行前の状況確認
- ip a コマンドで、Fedora に設定されているインターフェイスと IP アドレスの情報を確認
- ip route コマンドで、ルーティングテーブルを確認
- nmcli dev show | grep DNS で Fedora が使用している DNS サーバーを確認
$ ip a 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever inet6 ::1/128 scope host valid_lft forever preferred_lft forever 2: enp0s31f6: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc fq_codel state DOWN group default qlen 1000 link/ether a8:13:74:95:10:77 brd ff:ff:ff:ff:ff:ff 3: wlp2s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000 link/ether f4:96:34:33:38:62 brd ff:ff:ff:ff:ff:ff inet 10.222.103.90/17 brd 10.222.127.255 scope global dynamic noprefixroute wlp2s0 valid_lft 293sec preferred_lft 293sec inet6 fe80::17e6:18b2:4cb6:f7bc/64 scope link noprefixroute valid_lft forever preferred_lft forever 4: vpn_vnic: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UNKNOWN group default qlen 1000 link/ether 5e:09:e2:80:f7:64 brd ff:ff:ff:ff:ff:ff inet6 fe80::5c09:e2ff:fe80:f764/64 scope link valid_lft forever preferred_lft forever $ ip route default via 10.222.0.1 dev wlp2s0 proto dhcp src 10.222.103.90 metric 600 10.222.0.0/17 dev wlp2s0 proto kernel scope link src 10.222.103.90 metric 600 $ nmcli dev show | grep DNS IP4.DNS[1]: 101.110.ii.jjj IP4.DNS[2]: 101.110.xx.yyy $ curl ifconfig.me; echo 60.93.ii.jjj $
チェックすべきポイントは、
- wlp2s0 というインターフェイスが WiFi 接続で使用されているインターフェイスです。このインターフェイスがカフェの WiFi に接続されています。wlp2s0 は DHCP サーバーで IP 設定しますので、カフェの DHCP サーバーにより 10.222.103.90 という IP アドレスがリースされていることがわかります。
- vpn_vnic というインターフェイスは VPN 接続で使用するインターフェイスです。この時点では、まだ VPN サーバーに接続しないこともあり IP アドレスが設定されていません。
- ip route コマンドでルートテーブルを確認しています。default via 10.222.0.1 がデフォルトゲートウェイの設定を表しています。10.222.0.1 がデフォルトゲートウェイの IP アドレスで、これもカフェの DHCP サーバーから通知されています。
- default via 10.222.0.1 の最後に metric 600 と表示されています。これはこのデフォルトゲートウェイに優先度として 600 が設定されているという意味です。
- nmcli dev show | grep DNS で Fedora が使用している DNS サーバーを表示させています。これは、カフェの DHCP サーバーから通知された DNS サーバーです。
- curl ifconfig.me; echo では、インターネットに接続するときの送信元となるグローバル IP アドレスを確認しています。この時に表示されるアドレスはカフェのインターネット回線が使用しているグローバル IP アドレスとなり、このアドレスを使ってインターネット側と通信しています。
いざ、スクリプトを実行!
実行すると以下の用に表示されるでしょう。
$ ./connect_vpn.bash
デフォルトゲートウェイの IP アドレスを取得します...
VPN サーバーのホスト名の名前解決を実行して VPN サーバーの IP アドレスを取得します...
VPN サーバーに接続します...
[sudo] hoge のパスワード:
VPN サーバーに対するスタティックルートを設定します...
VPN クライアントの仮想 NIC の IP 設定を DHCP サーバーに要求します...
$
スクリプト実行後の状況確認
どのように変化したか確認します。
$ ip a 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever inet6 ::1/128 scope host valid_lft forever preferred_lft forever 2: enp0s31f6: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc fq_codel state DOWN group default qlen 1000 link/ether a8:13:74:95:10:77 brd ff:ff:ff:ff:ff:ff 3: wlp2s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000 link/ether f4:96:34:33:38:62 brd ff:ff:ff:ff:ff:ff inet 10.222.103.90/17 brd 10.222.127.255 scope global dynamic noprefixroute wlp2s0 valid_lft 270sec preferred_lft 270sec inet6 fe80::17e6:18b2:4cb6:f7bc/64 scope link noprefixroute valid_lft forever preferred_lft forever 4: vpn_vnic: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UNKNOWN group default qlen 1000 link/ether 5e:09:e2:80:f7:64 brd ff:ff:ff:ff:ff:ff inet 10.1.0.3/24 brd 10.1.0.255 scope global dynamic vpn_vnic valid_lft 259256sec preferred_lft 259256sec inet6 fe80::5c09:e2ff:fe80:f764/64 scope link valid_lft forever preferred_lft forever $ ip route default via 10.1.0.1 dev vpn_vnic default via 10.222.0.1 dev wlp2s0 proto dhcp src 10.222.103.90 metric 600 10.1.0.0/24 dev vpn_vnic proto kernel scope link src 10.1.0.3 10.222.0.0/17 dev wlp2s0 proto kernel scope link src 10.222.103.90 metric 600 49.242.xxx.yyy via 10.222.0.1 dev wlp2s0 $ nmcli dev show | grep DNS IP4.DNS[1]: 101.110.25.155 IP4.DNS[2]: 101.110.10.155 $ curl ifconfig.me; echo 217.178.xx.yyy $
- WiFi 用インターフェイス wlp2s0 の状態はそのまま変化なしです。
- VPN 用インターフェイス vpn_vnic に 10.1.0.3 という IP アドレスが設定されました。これは、VPN 接続した後に VPN サーバー側の DHCP サーバーからリースされたアドレスです。カフェの DHCP サーバーからリースされたアドレスではありません。
- ip route コマンドを見ると default via 10.1.0.1 dev vpn_vnic というデフォルトゲートウェイ (10.1.0.1) の設定が追加されています。デフォルトゲートウェイが 2 つ設定されると動作がおかしくなることがありますが、追加されたデフォルトゲートウェイには metric の設定がありません。これは metric デフォルト値である 0 が使用されていると考えられます。
- もともとのデフォルトゲートウェイには metric 600 が設定されています。metric の値は、小さいほど優先される動作となります。こんとあめデフォルトゲートウェイが 2 つ設定されテイルが、使用されているのは 10.1.0.1 の方になるので動作がおかしくなることはありません。
- 49.242.xxx.yyy 宛のルート情報が追加されています。これは、VPN サーバーのグローバル IP アドレス宛のスタティックルートです。via 10.222.0.1 dev wlp2s0 から、WiFi 用インターフェイスを使って 10.222.0.1 (カフェの Wi-Fi ルーターの IP ) にルーティングすることが定義されています。
- Fedora が使用する DNS サーバーはそのまま変化なしです。
- curl ifconfig.me; echo では、インターネットに接続するときの送信元となるグローバル IP アドレスを確認しています。この時に表示されるアドレスは VPN サーバー側のインターネット回線が使用しているグローバル IP アドレスとなり、このアドレスを使ってインターネット側と通信しています。言い換えると、カフェから VPN 接続を通って VPN サーバーに接続 (これをトンネル接続などと呼ばれることがあります) し、そこから VPN サーバー側のグローバル IP アドレスを使ってインターネットと通信するイメージになります。
まとめ
Bash スクリプトを実行した後、支障なくインターネットを使うことができればスクリプトがうまく機能したと判断できるでしょう。
スクリプトは Fedora で動作確認していますが、他のディストリビューションでも動作するのではないかと思います。