ぶていのログでぶログ

思い出したが吉日

sshuttleをsystemdで管理する

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にするイメージ(下図)。

f:id:buty4649:20211207131817p:plain

なので、NetworkManagerのプラグインの書き方について色々調べていたのだが全くそれっぽいドキュメントが見つからなかった…。 諦めていたのだけど、ある時以下のようなリポジトリを見つけた。

github.com

これはどうもsshトンネルを使ったNetworkManager用のVPNトンネルプラグインのようだ。 sshトンネルはポートフォワードと違いL2まで流せるのだけど、root権限が必要なので私の要件にはマッチしなかった…

このコードを解析してsshuttle版のNetworkManagerプラグインを作るというのも面白そうだが、systemdで使えるようにしてしまって今はあまりモチベーションがわかないのでいつかまた・・・。

*1:置き場はどこでもよい