Slide 1

Slide 1 text

cronの構造問題と、 なぜsystemd.timerに移行すべきか OSC2026 Nagoya © 2026 ryosuke 1

Slide 2

Slide 2 text

本セミナーは写真撮影・SNS投稿OK © 2026 ryosuke 2

Slide 3

Slide 3 text

自己紹介 職歴 元航空自衛官(IT実務未経験) サーバー運用経歴 年齢 出来事 18歳~ Windowsサーバー運用開始 22歳~ Linuxを触り始める 24歳~ Arch Linux デスクトップ導入 / Raspberry Piでファイルサーバー構築 29歳~ 現在のDebian構成へ移行(現在に至る) 0.導入 © 2026 ryosuke 3

Slide 4

Slide 4 text

Debianサーバー構成 ハード: Express5800/S70(通称:鼻毛鯖、2011年頃製) HDD増設用 鉄板マウント + SATA拡張カード コンテナ管理: Podman Quadlet DockerではなくPodmanでsystemdと統合 障害通知: ntfy(Pushover代替の通知サービス、自作unit) unitが失敗すると通知を発火 定期実行: cronは使わず全てsystemd.timer user unitとして運用 → 本題へ続く 0.導入 © 2026 ryosuke 4

Slide 5

Slide 5 text

本日の流れ 1.最小権限の原則とユーザーユニット 2.cronの構造問題とsystemd.timerへの移行 3.Dockerの構造問題とPodman Quadletへの移行 4.終章 0.導入 © 2026 ryosuke 5

Slide 6

Slide 6 text

1.最小権限の原則とユーザーユニット なぜrootで動かしてはいけないのか、原義から考える 1.最小権限の原則とユーザーユニット © 2026 ryosuke 6

Slide 7

Slide 7 text

最小権限の原則(一般的な認識) セキュリティ対策として広く知られる 攻撃者への被害範囲を最小化する Zero Trust・IAMの文脈で語られる 「rootで動かすな」の根拠 主要ベンダーの解説も全てセキュリティ文脈 1.最小権限の原則とユーザーユニット © 2026 ryosuke 7

Slide 8

Slide 8 text

最小権限の原則(原義) 設計原則 f) より原文冒頭から引用 f) Least privilege: Every program and every user of the system should operate using the least set of privileges necessary to complete the job. Primarily, this principle limits the damage that can result from an accident or error. — Saltzer & Schroeder, 1975 1.最小権限の原則とユーザーユニット © 2026 ryosuke 8

Slide 9

Slide 9 text

最小権限の原則(原義) 論文の位置づけ Saltzer & Schroeder (1975) はセキュリティ論文 設計原則(Design Principles) として分類されている 設計原則とは (意訳)「セキュリティ上の欠陥のない実装を導くための経験から得られた原則」 1.最小権限の原則とユーザーユニット © 2026 ryosuke 9

Slide 10

Slide 10 text

最小権限の原則(原義) つまり セキュリティ論文の著者自身が設計原則として分類 「第一に、この原則は事故やエラーから生じる被害を制限する」と明言 まずはエラーを防ぐ、次にセキュリティを守る 1.最小権限の原則とユーザーユニット © 2026 ryosuke 10

Slide 11

Slide 11 text

system unitとuser unitの違い システムユニットとユーザーユニット system unit:root権限で動く /etc/systemd/system/* ミスをするとあらゆるシステムからユーザー領域まで波及する user unit:ログインユーザーの権限で動く ~/.config/systemd/user/* ミスをしても実行したユーザー領域に限定される 1.最小権限の原則とユーザーユニット © 2026 ryosuke 11

Slide 12

Slide 12 text

user unitの使い方 user unitの恒久化 $ sudo loginctl enable-linger username linger は居残りという意味 ログアウトするとunitが停止してしまうのを恒久的に防ぐ user unitの操作 $ systemctl --user enable --now hogehoge.service $ systemctl --user list-timers sudoを使わないので誤操作リスクが非常に低下する 1.最小権限の原則とユーザーユニット © 2026 ryosuke 12

Slide 13

Slide 13 text

2.cronの構造問題とsystemd.timerへの移行 cronの何が問題か 2.cronの構造問題とsystemd.timerへの移行 © 2026 ryosuke 13

Slide 14

Slide 14 text

cronとは? AT&Tベル研究所が1975年頃に開発 先程の論文(1975年9月)と同じ1975年に制作 日本では広く使われている 2.cronの構造問題とsystemd.timerへの移行 © 2026 ryosuke 14

Slide 15

Slide 15 text

具体的想定シナリオ サーバーを保守する3年目の先輩と1年目の新人がcron周辺のタスク障害対応 先輩が crond を一旦止める指示を出すが disable を一度実行してから stop を実行 その後 start を実行して無事にcronは動き出す サーバー再起動時にcronがエラーを吐かずに起動しなくなる 2.cronの構造問題とsystemd.timerへの移行 © 2026 ryosuke 15

Slide 16

Slide 16 text

cronは全てのタスクをsystem unitで管理する 2.cronの構造問題とsystemd.timerへの移行 © 2026 ryosuke 16

Slide 17

Slide 17 text

cronは全てのタスクをsystem unitで管理する crond というsystem unitが全てのタスクを集中管理 ユーザー権限のタスクであろうとsystem unitで動いている ユーザー権限はuser unitとして運用するのが最小権限に沿った設計 集中管理をするということは、 crond に関わる誤操作で全てのタスクが死ぬ これは最小権限の理念である被害範囲の局所化の考え方に反する 2.cronの構造問題とsystemd.timerへの移行 © 2026 ryosuke 17

Slide 18

Slide 18 text

systemd.timerではどうなるのか 2.cronの構造問題とsystemd.timerへの移行 © 2026 ryosuke 18

Slide 19

Slide 19 text

systemd.timerではどうなるのか crond というsystem unitが存在しない user unitでユーザー領域のみで完結 user unitで運用していれば、他のユーザーにまで事故の拡大を起こすのが構造上 難しくなる 仮に1人分を全て止める場合でも systemctl --user stop *.timer という操作が 必要になる 2.cronの構造問題とsystemd.timerへの移行 © 2026 ryosuke 19

Slide 20

Slide 20 text

systemd.timerにもデメリットがある 記述量が多くなる傾向がある 学習曲線が高く敷居が高そう 1つのタイマーを動かそうとすると .service と .timer 2つのファイルが必要になる しかし「2つの分離」は最小権限の原則に沿った意図的な設計 2.cronの構造問題とsystemd.timerへの移行 © 2026 ryosuke 20

Slide 21

Slide 21 text

それでもsystemd.timerにはこんなメリットが 1. テンプレートユニットで複数のタイマーをまとめて管理できる 2. 時間の管理と実行の管理が別れているのでデバックが容易 3. 知識さえあればデフォルト値を書かないという選択肢がある 4. systemdはLinuxの主要ディストリビューションに標準採用、10年後も使える知識 2.cronの構造問題とsystemd.timerへの移行 © 2026 ryosuke 21

Slide 22

Slide 22 text

最小構成の例 # hello.timer [Timer] OnCalendar=daily # hello.service [Service] ExecStart=/usr/bin/echo "Hello World!" 2.cronの構造問題とsystemd.timerへの移行 © 2026 ryosuke 22

Slide 23

Slide 23 text

私の自宅サーバーでの使い方 [Unit] OnFailure=notify@%n 各キーワードの意味 記述 意味 OnFailure= 失敗時に起動するユニットを指定 %n そのユニットファイル自身の名前に展開される [email protected] @ を含む テンプレートユニット( %i でインスタンス名を受け取れる) %i インスタンス名 テンプレートユニットの @ から . の間の部分 2.cronの構造問題とsystemd.timerへの移行 © 2026 ryosuke 23

Slide 24

Slide 24 text

私の自宅サーバーでの使い方 動作イメージ [email protected] というテンプレートユニットファイルを事前に作っておく。 backup.service が失敗 → [email protected] が呼び出され [email protected] が起動 通知したい各ユニットに OnFailure=notify@%n を書くだけ どのユニットが失敗したかを通知に乗せられる イベント駆動型なので常駐せずにリソースも食わない 2.cronの構造問題とsystemd.timerへの移行 © 2026 ryosuke 24

Slide 25

Slide 25 text

私の自宅サーバーでのファイル構成 少ないファイルで多くのユニットを管理する テンプレート タスク数 [email protected] / [email protected] 3個 [email protected] / scheduled- [email protected] 8個 [email protected] 上記 + その他個別タイマーやコン テナ = 28個 1つの通知テンプレートユニットファイルが39個のunitの失敗を報告 2.cronの構造問題とsystemd.timerへの移行 © 2026 ryosuke 25

Slide 26

Slide 26 text

cronには失敗をトリガーとした通知の仕組みがない タスクが失敗しても… cronはエラーを検知して通知する手段がメールしかない 気づかないままバックアップが数週間止まっていた、という事故が起きうる systemd.timerなら OnFailure= で解決できる 失敗時に任意のunitを起動できる → 通知サービスと組み合わせるだけ cronのようにメール送信のためのMTAを立てる必要はない 通知の中身(WebhookやAPI呼び出し)を自分で自由に定義できる ただし全Unitに個別に書くと管理コストになる 新しいUnitを追加のたびに書き忘れるリスクがある 2.cronの構造問題とsystemd.timerへの移行 © 2026 ryosuke 26

Slide 27

Slide 27 text

Unitの命名規則 systemdのunit名において - は階層の区切り文字として機能する sysmtedでは - はディレクトリ表現の / と同じような意味を持つ 例: scheduled-backup-daily.service scheduled → backup → daily という階層を表す scheduled/backup/daily のように変換して読める 2.cronの構造問題とsystemd.timerへの移行 © 2026 ryosuke 27

Slide 28

Slide 28 text

ドロップイン 既存のUnitファイルを直接編集せずに設定を上書きする仕組み unit名.d/ ディレクトリに .conf ファイルを置くと自動で読み込まれる ~/.config/systemd/user/ ├── scheduled-backup-daily.service ← 元のUnit └── scheduled-backup-daily.service.d/ └── override.conf ← これがドロップイン(上書き) override.conf に書いた設定が元のUnitにマージされる 2.cronの構造問題とsystemd.timerへの移行 © 2026 ryosuke 28

Slide 29

Slide 29 text

プレフィックスに - 付けて途中で切り上げるドロッ プイン Unit名の途中までをディレクトリ名にして末尾を - にすると そのプレフィックスで始まる全Unitにドロップインが適用される ~/.config/systemd/user/ ├── scheduled-backup-daily.service ├── scheduled-backup-weekly.service ├── scheduled-backup-monthly.service └── scheduled-backup-.service.d/ ← ← ← ここ! └── override.conf ← 上記3つ全てに適用される scheduled-backup-daily も scheduled-backup-weekly も scheduled-backup- というプレフィックスを共有しているため全て対象 2.cronの構造問題とsystemd.timerへの移行 © 2026 ryosuke 29

Slide 30

Slide 30 text

3.Dockerの構造問題とPodman Quadletへの移行 Dockerの何が問題か 3.Dockerの構造問題とPodman Quadletへの移行 © 2026 ryosuke 30

Slide 31

Slide 31 text

Dockerとは? Solomon Hykes らが2013年に公開 コンテナ技術を一般に広めた立役者 日本でも広く使われている 3.Dockerの構造問題とPodman Quadletへの移行 © 2026 ryosuke 31

Slide 32

Slide 32 text

Dockerはcronとまったくおなじ問題を抱えている dockerd というsystem Unitが全てのコンテナを集中管理 ユーザーが起動したコンテナであろうとsystem unitで動いている これはcronで crond がユーザーのタスクを管理するのと同じ構造 dockerd は常にrootで常駐するデーモン docker.sock はroot所有 → 一般ユーザーが使うにはdockerグループへの追 加が必要 dockerグループへの追加は実質的なrootの付与と等価 つまり最小権限の原則(被害局所化)の精神に二重に反している 3.Dockerの構造問題とPodman Quadletへの移行 © 2026 ryosuke 32

Slide 33

Slide 33 text

Podman Quadletではどうなるのか dockerd に相当する常駐デーモンが存在しない コンテナはsystemdが直接管理するuser unitとして動く ユーザーは自分のコンテナだけを管理する 誤操作しても自分のuser unit内に被害が留まる 他ユーザーや他コンテナへの波及が構造上難しくなる 3.Dockerの構造問題とPodman Quadletへの移行 © 2026 ryosuke 33

Slide 34

Slide 34 text

Quadletとは Podmanに同梱されているsystemdジェネレーター systemd unitとほぼ同じ記法 .container ファイルを置くだけでsystemd unitを自動生成する 宣言的に書けてGit管理しやすい # ユーザーか書くユニットファイル ~/.config/containers/systemd/ └── myapp.container # 自動生成される実体のユニットファイル /run/user/{UID}/systemd/generator/ └── myapp.service 3.Dockerの構造問題とPodman Quadletへの移行 © 2026 ryosuke 34

Slide 35

Slide 35 text

第2章の通知の仕組みがそのまま使える Quadletの機能としてsystemdのようなドロップイン機能が実装 プレフィックスドロップインがsystemdと同様に適用 コンテナを追加してもsystemdと同様に通知設定の記述が不要 OnFailure=notify@%n の仕組みがそのまま流用できる ~/.config/containers/systemd/ ├── media-.container.d/ │ └── override.conf ├── media-komga.container └── media-navidrome.container 3.Dockerの構造問題とPodman Quadletへの移行 © 2026 ryosuke 35

Slide 36

Slide 36 text

コンテナをテンプレートユニット化 systemdと同じ記法でテンプレートユニットを作れる # コンテナファイル ~/.config/containers/systemd/[email protected] # タイマーファイル ~/.config/systemd/user/[email protected] 起動と実行の分離がなされているのでこのような統合ができる timerの enable と start を実行すればコンテナが定期実行されるようになる 3.Dockerの構造問題とPodman Quadletへの移行 © 2026 ryosuke 36

Slide 37

Slide 37 text

4. 終章 4.終章 © 2026 ryosuke 37

Slide 38

Slide 38 text

まとめ:rootを極力触らずに運用できる 役割 移行前 移行後 定期実行 cron(system unit) systemd.timer(user unit) コンテナ Docker(root常駐デーモン) Podman Quadlet(user unit) 障害通知 なし / 個別実装 OnFailure=notify@%n 過去の失敗から経験的に誤操作を防ごうとした それが最小権限の原則の原義になっていた root権限を殆ど扱わずにユニットを運用できる 4.終章 © 2026 ryosuke 38

Slide 39

Slide 39 text

振り返り:3つの話の共通点 第1章:設計原則としての最小権限 → user unitという選択 第2章:cronの集中管理 → systemd.timerで分散・局所化 第3章:Dockerの集中管理 → Podman Quadletで分散・局所化 「rootで動かすな」の根拠は セキュリティではなく設計原則だった 4.終章 © 2026 ryosuke 39

Slide 40

Slide 40 text

ご清聴ありがとうございました 執筆記事 (zenn - ryosuke) 参考文献 Saltzer & Schroeder (1975) "The Protection of Information in Computer Systems" systemd.unit man page: man systemd.unit systemd.timer man page: man systemd.timer quadlet man page: man podman-systemd.unit 4.終章 © 2026 ryosuke 40