sshを使ってVPNっぽいことをするsshuttleというアプリケーションがある。 便利なので業務でも使っているのだけど、毎回ヒストリーから実行するのがめんどくさいのでsystemdで管理することにした。
事前準備
sshuttleは一般ユーザで実行した場合、内部でsudoを実行する。
systemdから実行した場合、sudoのパスワード入力待ちになってしまうためこれを回避しなくてはらない。
幸い最近のsshuttleでは --sudoers
オプションが追加されていて、これを実行することでsshuttleに必要なsudoersファイルを設定してくれるのでとても便利だ。
❯ sshuttle --sudoers Success, sudoers file update. ❯ sudo cat /etc/sudoers.d/sshuttle_auto Cmnd_Alias SSHUTTLE273 = /usr/bin/env PYTHONPATH=/usr/lib/python3/dist-packages /usr/bin/python3 /usr/bin/sshuttle * user ALL=NOPASSWD: SSHUTTLE273
次にssuttleの設定ファイルを用意する。
shuttleはオプションで挙動を変えることができるが、設定ファイルを使ってそれらオプションを設定することもできる。
オプションを追加したくなった場合に、いちいちUnitファイルを変更するのはめんどくさいので設定ファイルに分けるという方法にした。
設定ファイルのパスはXDGを尊重して ~/.config/sshuttle.conf
にした*1。
❯ cat ~/.config/sshuttle.conf 192.168.127.0/24 --remote your-bastion-server
Unitファイルの配置
/etc/systemd/system
に配置することもできるのだが、これだとsystemワイドの設定になる。
私の用途だとそれでは広すぎるのでユーザスコープに限定することにした。
~/.config/systemd/user/
に配置するとそのユーザのみになるので、この配下に以下のようなUnitファイルを配置した。
❯ cat ~/.config/systemd/user/sshuttle.service [Unit] Description=sshuttle [Service] Type=forking ExecStartPre=test -f %h/.config/sshuttle.conf ExecStart=/usr/bin/sshuttle @%h/.config/sshuttle.conf --daemon --pidfile /run/user/%U/sshuttle.pid PIDFile=/run/user/%U/sshuttle.pid [Install] WantedBy=default.target
ファイルを配置したらdaemon-reloadする。
このときに明示的に --user
をつける必要がある。
❯ systemctl --user daemon-reload
起動
以下のコマンドで起動できる
❯ systemctl --user start sshuttle.service
enableもできるが、常に起動されると私の場合都合が悪いので都度起動にしている。
NetworkManagerで同じことがしたいと思った
systemdだとやっぱり少し重いなぁっと思い、NetworkManager経由でsshuttleを起動したいと思っていた。
イメージ的には nmcli c u sshuttle
とするか、GNOMEの通知領域からONにするイメージ(下図)。
なので、NetworkManagerのプラグインの書き方について色々調べていたのだが全くそれっぽいドキュメントが見つからなかった…。 諦めていたのだけど、ある時以下のようなリポジトリを見つけた。
これはどうもsshトンネルを使ったNetworkManager用のVPNトンネルプラグインのようだ。 sshトンネルはポートフォワードと違いL2まで流せるのだけど、root権限が必要なので私の要件にはマッチしなかった…
このコードを解析してsshuttle版のNetworkManagerプラグインを作るというのも面白そうだが、systemdで使えるようにしてしまって今はあまりモチベーションがわかないのでいつかまた・・・。
*1:置き場はどこでもよい