🐧

systemd-unitを/etc/systemd/system/ に全て置いていませんか?

に公開

はじめに

私はIT実務未経験です。但し、9年間程自宅でLinuxサーバーを保守運用してきた実績があります。その経験に基づいて分かりやすく簡単なsystemd user unitを使うべき理由を書かせていただきます。

気づき

1年程前、特に理由もなくターミナルを弄っているときに"man systemd.unit"のコマンドを実行しドキュメントの冒頭を眺めていました。そしたらなんと/etc/systemd/system/* 以外にもunitをたくさん置ける場所があるということに気が付きました。特に目を引いたのが "~/.config/systemd/user/*" というディレクトリの場所です。なぜなら"~"は一般ユーザーのホームディレクトリを指し示す場所だからです。

色々調べるとこのディレクトリは一般ユーザー権限でunitを実行するためのディレクトリであり、基本はここで管理することが推奨されていることに気が付きました。

正直にいうと今まで"/etc/systemd/system/*" で全てのunitを管理していた私は衝撃を受けました。言われてみれば確かにそうで、たとえばcronという自動実行デーモンを編集するときは

$ crontab -e

と書きますが、Linux触りたてだとなんでもsudoで実行してしまう癖があり(私もかつてそうでした)、その結果

$ sudo crontab -e

というシステム権限で実行してしまうため、これは本来行ってはいけない行為です。何故ならこれはシステム権限で全てスクリプトを実行してしまい、スクリプトに問題があれば最悪システムのコードまで書き換えたり削除してしまうリスクがあるためです。

arch wikiでは

実はこの情報自体は日本語情報としてすでに存在しており、arch wikiにユーザー権限での使い方を明記されています。詳しい使い方はこの記事を参照していただければと思います。

https://wiki.archlinux.jp/index.php/Systemd/ユーザー

しかしながら現状日本語圏では"/etc/systemd/system/*"に配置することが一般化しており、さらにunitファイル内でUser=とGroup=を指定し降格処理を施しています。つまり、最小権限の原則は実務でも知られているにもかかわらず「そもそもunit自体に最初からroot権限を与えない手段」という発想が抜け落ちている可能性があります。User=とGroup=で降格処理をするのは、最初からroot権限を与えなければ不要な作業です。

ではどうすればいいのか?

答えは単純で、「ウェルノウンポートで動いているunit」か、「root権限が必要なシステム操作を行うunit」であればそのまま"/etc/systemd/system/*"で大丈夫です。

ウェルノウンポートで管理されているunitに関しては"/etc/systemd/system/*"で管理する必要がどうしてもあります。ウェルノウンポートとはhttpやsshやftpやsmtpなどの主要な0-1023番までのポート番号を指す用語です。Linuxカーネルの仕様上、これらのポートへのバインドにはroot権限が必要とされています。逆を言えば、ウェルノウンポートを使うunitやroot権限が必要なシステム操作を行うunit以外は、全て一般ユーザー権限で事足ります。大多数のunitは一般ユーザー権限で事足りるはずです。

また重要な点として、ユーザーunitを自動起動するためには特定のユーザーに対してroot権限で一度このコマンドを実行する必要が出てきます。

# loginctl enable-linger username

これの何が素晴らしいのか?

ユーザー権限で実行されれば当然unit編集や"systemctl" "journalctl" 等のunit操作全てでsudoという昇格が不要になります。つまりsudo権限のない一般のユーザーですら許可された範囲内であればsystemd-unitを作成し高度な処理が行えるということです。

$ systemctl --user start hogehoge.service
$ systemctl --user daemon-reload
$ systemctl --user list-timers

sudoをそもそも使わないため、User=やGroup=表記をしていない場合も一般ユーザー内での被害に留まり、大きな被害が出にくいという特性があります。

結びに

実際にこれらを実行する際としてはファイルを移動させファイルの所有者権限を変更し、しかもsudoではなく"--user"オプションが必要になって始めは不慣れな操作ではあります。しかし、一度これを導入してしまえば人間による誤操作のリスクが格段に減り、セキュリティ上もそもそもunitにroot権限を最初から与えないという発想になっています。

これによってサーバー操作中の事故やunitを介した乗っ取り等の被害を最小化することができるので安心してベッドで眠る事が出来ると私は考えております。

Discussion