当記事は、法政大学理工学部 Advent Calendar 2024の記事です。
あらかじめ断っておきますと、言葉遣いがカスです。
法政のVPNとおさらばしよう
ある日、私がコネバイト先の人とWEB面談みたいなのをしていたら、やたらZOOMがカクついていました。なんでかなと思っていたら、なんと法政VPNが繋ぎっぱなしになっていました。どおりで重いわけですよ。研究中はVPNをつなぎますが、こうも重いとちょっとした待ち時間にオンラインゲームもできなくて非常に不便です。
以上のことから、VPNが必要な通信以外はVPNを通さずに行う方法が求められています。知らんけど。
本記事では、WSLのUbuntuをプロキシサーバとして経由するSSH接続を検討する。
関連研究
この問題に対し、過去の偉大な先輩方がやり方を残してくれていました[1]。
これによると、ラズベリーパイをVPNに接続しプロキシサーバとして用いています。どうやらPC側からSSH接続するときにそのプロキシサーバを経由するようにすると、PC側をVPNに接続しなくて済むようです。
しかしこの手法には1つの欠点があります。それが何かというと、ラズパイが意外と高いということです。いや、安いやつは3000円くらいで買えるけど、mini HDMIとかいう謎のケーブルじゃないとディスプレイに繋げないし、充電もtype-bのマイクロUSBだから最近使う機器が少ないせいで持ってません。そう考えると結局金がかかるのです。まあこんなことに金使いたくないってのが大きいけど。
しかしそこら辺を考えてるとき、ふとあることに気づきました。そういえばWindows上で動くLinux OSがあったなと。
提案手法
本記事では、WSLのUbuntuを経由したSSH接続を提案する。といってもWSLってWindows上で動くんだから、どっちかをVPNにつないだらどっちもVPNにつながっちゃうんじゃないの?と思う人もいるでしょう。しかし問題ありません。どうやらWSL1ではそんな感じだったけど、WSL2ではWindowsとは独立した接続が行えるようです。やったぜ。
提案手法をざっくりまとめると、
Windowsを起動する
→WSL2のUbuntuが立ち上がる
→Ubuntu上でVPNに接続
→Ubuntu上でプロキシサーバが立ち上がる
→Windows側からSSH接続するときにはプロキシサーバを経由する。
といった感じです。
なので大学に持っていくPCで同じことやったら変なことになりそうだよねってことで、今回は家で使う用のWindowsを想定しています。Macは知らん。
実装
まずWindows側の設定をいじる。
Windowsの設定→システムから、下のほうにあるオプション機能を選択します。そしたら一番下のWindowsのその他の機能を選択、「Linux用 Windowsサブシステム」と「Virtual Machine Platform」にチェックを入れます(たしか)。あとこれをやったら再起動が必要だったような気がする。
お次はMicrosoft StoreからUbuntuをインストールします。いろいろあるけどよくわからんので普通のUbuntuとだけ書いてあるのにした。
とりあえずUbuntuを起動する前に、普通のコマンドプロンプトとかPower Shellで、
wsl -l -v
を打ってWSLのバージョンを確認します。Ubuntuが2になってれば良い。
なってない場合は、
wsl --set-version Ubuntu 2
とかでいけるんだと思う。たぶん。自分の環境では最初から2だったので。
Ubuntuで作業
まずは、
sudo apt update
でパッケージリストをアップデートして、
sudo apt install openfortivpn
でOpenFortiVPN
をインストール。先輩方の手法ではOpenConnect
を使っていたけど、法政のVPNクライアントが変更になったのでこれで動くのか不安なのでFortiClient VPNのLinux版みたいなのを使います。インストールが終わったら、
openfortivpn --version
でバージョンを確認。
そしたらconfigをいじりましょう。/etc/openfortivpn/
にあるconfigファイルをいい感じにする。sudo
を使わないとPermission Deniedって言われるので注意。
このファイルの中身のコメントアウトを外して、
host = sslvpn.hosei.ac.jp
port = 443
username = (学生証番号)
password = (パスワード)
にします(VPNに接続するときに使うやつ。パスワード直書きするの怖いけどいい方法あるのかな?)。
UbuntuをVPNに接続してみよう
さっそく、
sudo openfortivpn
でVPNに接続してみよう...と思ったらなんかエラーが出た。エラーの内容的にはこいつ信頼していいの?ってことらしい。エラーを見ると--trusted-cert ~~
みたいなのをくっつけてやり直せって言ってるようです(この~~って部分が人によって変わるのかわからんので今回は貼らない。自分のを見てコピペする)。
なので、
sudo openfortivpn --trusted-cert ~~
にして実行してみる。
つながった...が、ログが表示されてコマンドが打てないぞ?こういう時はCtrl+zでプロセスをいったん中断、bg
を入力してプロセスをバックグラウンドに移す。
コマンドのあとに'&'を入れると最初からバックグラウンドでやってくれるらしいが、sudoのパスワード求められたりすると変になる。
UbuntuをSSHに繋げる
これで本当につながったんだろうか?確かめるためにSSH接続してみましょう。
いつも通り、
ssh-keygen -t ed25519
で鍵を生成、.pubのほうをルートの人に渡してサーバーに登録してもらう。いつものやつでconfigを作ったら(OSはLinuxを選択).sshのところに配置する。
さっそくssh plant-ai01
とかでSSH接続してみましょう。
ところで、wslをVPNにつないでsshしようとすると名前解決でバグるらしい。でも自分の環境では起きてないので何とも言えない。起きた人がいたらwsl-vpnkit
を調べてなんかうまいことやってください。
接続を便利に
plantにつながった!!
とは思いつつも毎回これやるのは大変なのでいろいろ便利な設定をする。
まず簡単なところとして、/etc/openfortivpn/config
にtrusted-cert = ~~
を追記する。
これで、
sudo openfortivpn
だけでVPNに繋がるようになる。
VPNを自動化
次にUbuntuを開くたびに勝手にVPNにつながるようにしましょう。
今回はsystemdというものを使い、Ubuntuの起動時に自動でVPNに接続するサービスを作成する。
まずは/etc/wsl.conf
を開き、systemd=true
にする。そしたら/etc/systemd/system/
にopenfortivpn.service
を作成する。中身は、
[Unit]
Description=OpenFortiVPN Service
After=network.target
[Service]
ExecStart=/usr/bin/openfortivpn -c /etc/openfortivpn/config
Restart=always
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=openfortivpn
[Install]
WantedBy=multi-user.target
って感じ。
ファイルが作成出来たら、
sudo systemctl enable openfortivpn
でサービスを有効化、
sudo systemctl start openfortivpn
でサービスを開始する。
Ubuntuを再起動してVPNにつながってるか確認してみましょう。再起動はコマンドプロンプトから、
wsl --shutdown
を入力して再度起動すれば良い。
これでUbuntuを起動したらVPNにつながるようになりました。VScodeとか使わないならここからやれば済む。
プロキシサーバをたてる
でもやっぱりVScodeが使えたら便利なので、Ubuntuでプロキシサーバを立て、そこを経由してSSH接続する。といっても、
ssh -fNTD 127.0.0.1:(好きなポート番号) tebasaki
をUbuntuで入力するだけでできる。
あとはWindows側からここを経由してSSHするように設定を変更する。Windowsの/.sshにおいてあるconfigの、
Host tebasaki
Hostname iyatomi-gw.k.hosei.ac.jp
User iyatomi
IdentityFile ~/.ssh/id_ed25519
みたいになってるところを、
Host tebasaki
Hostname iyatomi-gw.k.hosei.ac.jp
User iyatomi
IdentityFile ~/.ssh/id_ed25519
ProxyCommand ncat --proxy-type socks5 --proxy 127.0.0.1:(さっき決めたポート番号) %h %p
にする(念のため変更前のconfigは別のところにとっておく)。
これで設定は終了(のはず)。Windows側からssh plant-ai01
とかでつながるか確認してみましょう。
これを大学に持っていくPCでやると、大学行ったときに繋がらなくなる。
自動でプロキシサーバを立てよう
sshがつながったらあとはもう一息。systemdを用いてUbuntu起動時に自動でプロキシサーバが立つようにします。
まずはプロキシサーバを起動するためのbashを作成する。
名前は適当にproxy_server.sh
とかにして、内容は以下のような感じ。
#!/bin/bash
VPN_TARGET="iyatomi-gw.k.hosei.ac.jp"
RETRIES=10
SLEEP_INTERVAL=3
echo "Checking VPN connection..."
for ((i=1; i<=RETRIES; i++)); do
if ping -c 1 "$VPN_TARGET" &> /dev/null; then
echo "VPN is connected. Starting the server..."
ssh -fNTD 127.0.0.1:(好きなポート番号) tebasaki &
exit 0
else
echo "VPN not connected yet. Retrying... ($i/$RETRIES)"
sleep "$SLEEP_INTERVAL"
fi
done
echo "VPN connection failed. Exiting."
exit 1
そしたら、
chmod +x proxy_server.sh
で実行権限を与えておく。
お次は/etc/systemd/system/
に移動しまして、proxy_server.serviceを作りましょう。中身は以下の通り。
[Unit]
Description=Start Proxy server after VPN is connected
After=openfortivpn.service
Requires=openfortivpn.service
[Service]
Type=oneshot
ExecStart=/home/(ユーザー名)/proxy_server.sh
RemainAfterExit=true
Restart=no
[Install]
WantedBy=multi-user.target
ファイルができたら、systemdはrootディレクトリにある.sshしか見てくれないので、rootディレクトリに.sshの中身を移します。
sudo cp /home/(user名)/.ssh/* /root/.ssh/
って感じ。
そしたら、
sudo systemctl daemon-reload
sudo systemctl enable proxy_server.service
sudo systemctl start proxy_server.service
でサービスを有効化する。
あとはコマンドプロンプトから、
wsl --shutdown
を入力してwslを再起動。これで自動的にプロキシサーバが立ち上がっているはずなので、コマンドプロンプトからSSH接続してみましょう。たぶんつながるはず。
タスクスケジューラを設定する
最後にWindows起動時にUbuntuが自動で立ち上がるようにして終了です。
タスクスケジューラを開いたら右側のタスクの作成を押す。
名前を適当にわかりやすいのに決めたら、ユーザーがログオンしているかどうかにかかわらず実行するを選択し、最上位の特権で実行するにチェックをつける。
トリガーのタブに移動し、トリガーを新規作成、スタートアップ時に設定する。
操作を新規作成し、プログラムの開始を選択、プログラム/スクリプトのところにwsl -d Ubuntu
を入力する。
Windowsを再起動してコマンドプロンプトからssh接続できることを確認したら、VScodeとかでも接続出来てるか確認しましょう。たぶんつながるんじゃなかろうか。
まとめ
UbuntuでVPNに接続、プロキシサーバを立てることで、WindowsをVPNに接続せずにSSH接続を行うことができました(少なくとも自分は)。
systemdとタスクスケジューラを用いて、自動でプロキシサーバを立てることができた(みんなもできてるといいんだが)。
しかしこれがどんだけPCに負荷をかけるかもわからんのだよな。タスクスケジューラは使わずにSSHしたいときだけUbuntuを起動するのがいいかもしれない。
とはいえ、何もしなくてSSHできるのはとても便利。研究しながらゲームもできるぞ。やったぜ。
終わり。
参考文献
[1]"たのしいSSH", https://clutter.ikuta.me/%E3%81%9F%E3%81%AE%E3%81%97%E3%81%84ssh/,
あとなんかよくわからんブログとかChatGPTとか。