-- Views
June 29, 26
スライド概要
長年SELinuxをオフで運用していたサーバにおいて、
/etc/selinux/config
の
SELINUX=disabled
を
SELINUX=enforcing
に変えて再起動したらサーバが動かなくなった失敗から学ぶSELinuxを無効から有効にするための理解
フリーランスのITエンジニアです 普段はLinuxをメインに使用しています
SELinuxを有効にして、セキュリティを強化するはずがOSが死んだ件 Whilver IT 白銀 太可志 Whilver ITが提供なく孤独にお送りしています!!
おしながき はじめに そもそものきっかけ サーバ環境 作業内容 復旧開始 復旧作業 SELinuxの有効に際して どうすればよかったか まとめ Whilver ITが提供なく孤独にお送りしています!!
・はじめに 本内容ではSELinux自体の話はしません 仕組みまできちんと理解しようとするのはかなり膨大になるので、 ChatGPTで作成したメモ or PDFあるいは別途AI等で確認ください ・そもそものきっかけ かなり前から運用していたサーバがあり、当時はサーバ構築時にSELinuxを無効にしていました そんな状況のサーバからいくばくか経ったある日(2026-03-27)に突如気付いたのです そういえば、当時SELinux無効にしていたような… /etc/selinux/config を確認すると、SELINUX=disabledになっていました SELinuxを有効にして運用しているサーバもあるし、このサーバもSELinuxを有効にして運用してもよ くね と思ったのです Whilver ITが提供なく孤独にお送りしています!!
・サーバ環境 さくらのVPS Fedora 43 ISOアップロードで、インストール(インストール時点では、その時点で最新のバージョン) インストール後は、dnf upgradeやdnf system-upgradeで最新にしていました ・作業内容 無効にしたときは、インストール直後に/etc/selinux/configファイルの SELINUX=enforcing ↓ SELINUX=disabled としたので、この逆である SELINUX=disabled ↓ SELINUX=enforcing にして、再起動しました Whilver ITが提供なく孤独にお送りしています!!
再起動すると、サーバが応答しなくなりました サーバ自体は起動するが、SELinuxが大量のエラーを出してsystemdがフリーズ Whilver ITが提供なく孤独にお送りしています!!
・復旧開始 さくらのVPSで運用しているサーバなので電源操作で強制シャットダウンしたのち、 OSを起動させて、コンソールが立ち上げられる状態になる間にGRUBが終わってしまう… なのでコンソールで見る頃にはフリーズ状態(前ページ) 詰んでしまった…(と思ってたんですが…) 自分で管理している個人サーバなので、いっそ再インストールしようかとも思ったんですが… Whilver ITが提供なく孤独にお送りしています!!
・復旧作業 さくらのVPSのコントロールパネルのOS再インストールメニューから Fedora 43のISOをアップロードしてISOから起動し、VNCコンソールを立ち上げる GRUBでTroubleShooting、Rescue a Fedora systemを選択 以下の画像はVirtualBoxのものですが、実際にはさくらのVPSのVNCコンソール Whilver ITが提供なく孤独にお送りしています!!
Rescueモードで起動したら、 Please make a selection from the above: と表示されるので「1」を入力してEnterを押下 Whilver ITが提供なく孤独にお送りしています!!
Rescue Shellの表示後、 Please press ENTER to get a shell: と表示されるので、Enterを押下し、指示通りに chroot /mnt/sysroot と入力 ここまでできたら、/etc/selinux/configを編集して SELINUX=enforcing ↓ SELINUX=disabled に戻して再起動し、OSが起動できることを確認 Whilver ITが提供なく孤独にお送りしています!!
・SELinuxの有効に際して Red HatのSELinuxのトピックス https://www.redhat.com/ja/topics/linux/what-is-selinux にある通り、いきなりenforcingにはしてはいけない SELINUX=enforcing とするだけで有効にできるものと思っていた(これがそもそもの元凶) SELINUX=disabledにして再起動という手順で無効にしていると、気付きにくいかも(私だけ!?w) 余談ですが無効にする場合、Red Hat 9からはSELINUX=disabledではなくgrubbyを使えとのこと https://access.redhat.com/solutions/3176 https://docs.redhat.com/ja/documentation/red_hat_enterprise_linux/9/html/using_selinux/changingselinux-states-and-modes_using-selinux いきなりSELINUX=enforcingにすると、未ラベルだったり、ラベルが正しくないなどの問題を引き起こす SELinuxを無効にしている際に作成されたファイルシステムのオブジェクトにラベルが追加されない lsの「-Z」オプション等でラベルを確認できるが、確認したところでどうにかなるものではない Whilver ITが提供なく孤独にお送りしています!!
・どうすればよかったか 一旦、SELINUX=permissiveにして再起動 Permissiveにすることで、SELinuxのエラーがあっても拒否しない 次に、 sudo ausearch -m AVC,USER_AVC -ts boot | tail -n 50 でメッセージを確認しておく その後、 sudo fixfiles -F onboot を実行して再起動 再起動時にラベルの再設定が行われる(時間がかかることもあるため気長に待つ) ラベル再設定後にもう一度、 sudo ausearch -m AVC,USER_AVC -ts boot | tail -n 50 を実行し再起動前の出力と比較して、メッセージが増えていないようなら、 sudo journalctl -b -p warning..alert | grep -i selinux を実行して、selinux絡みのエラーが出ていないことを確認 私の環境ではausearchのメッセージは増えておらず、journalctlでselinuxのエラーは出ていなかった Whilver ITが提供なく孤独にお送りしています!!
問題がなかったので、/etc/selinux/configファイルの、SELINUX部分を SELINUX=enforcing に変更して再起動したところ、問題なく起動しました Whilver ITが提供なく孤独にお送りしています!!
・まとめ 長年RHEL系でSELinuxを無効の状態で運用していたサーバでSELinuxを有効にする場合は要注意 SELinuxを無効→有効の流れはそういえばやったことなかった(完全に勉強不足でした) SELINUXの無効→有効の流れは、 SELINUX=disabled → SELINUX=permissive にしたあと、 fixfiles -F onboot で問題ないことを確認して、SELINUX=enforcingへ Whilver ITが提供なく孤独にお送りしています!!
SELinux の内部動作 — どのタイミングで、誰が、何を見て、どこで拒否するのか — 発表用メモ / 想定質問対策 要点: SELinux は「怪しい挙動を後から検出する」仕組みではなく、カーネルの重要操作の直前でア クセス要求を捕まえ、主体・対象・操作に分解して、ポリシー照合の結果をその場で allow / deny している。 1. まず一言でいうと • ユーザー空間のプロセスが open / read / write / connect / execve などのシステムコールを呼ぶ。 • カーネルはその処理の途中にある LSM (Linux Security Modules) フックで SELinux を呼ぶ。 • SELinux は「主体ラベル」「対象ラベル」「オブジェクトクラス」「要求権限」を取り出して判定 する。 • 結果が許可なら処理続行。拒否なら EACCES / EPERM などで失敗し、AVC 監査ログが残る。 2. 内部の登場人物 要素 LSM フック SELinux フック 役割 発表での言い方 カーネルの重要操作地点に差し 「SELinux が割り込むポイン 込まれた入口 ト」 LSM から呼ばれる SELinux 本体 「実際に判定材料を集める箇 側の処理 所」 SID コンテキスト文字列の内部表現 AVC 判定結果のキャッシュ Security Server AVC に無いときに最終判定を計 「ラベルを高速に扱うための ID」 「毎回ポリシー全文を読まない ための高速化」 「ロード済みポリシーから答え
算 を出す中核」 3. 実際の処理フロー ユーザー空間のプロセス ↓ syscall(open/read/write/connect/execve ...) ↓ カーネル通常処理 + DAC 確認 ↓ LSM hook ↓ SELinux hook ↓ 主体 SID / 対象 SID / class / permission を作る ↓ AVC 参照 ├─ ヒット → allow / deny └─ ミス ↓ → Security Server がポリシー計算 → AVC に格納 enforcing なら deny で遮断 permissive なら通すが監査 ↓ audit log 出力(必要に応じて) 4. 「ポリシーに引っかかる」の正体 • 基本は「allow ルールに一致する許可がない」こと。 • 判定の材料は、主体 type・対象 type・object class・permission の組み合わせ。 • たとえば file に対する read は通るが、write / create / append は別権限なので別判定。 • そのため「読めるのに書けない」「起動できるのに外部接続だけ落ちる」が普通に起こる。 allow httpd_t httpd_sys_content_t:file { read open getattr }; 5. 具体例 例 1: httpd がホームディレクトリを読めない • 主体: httpd_t
• 対象: user_home_t • class: file • 要求: open, read, getattr ポイント: Unix パーミッションが 644 でも、httpd_t → user_home_t:file read を許可するルールが 無ければ deny。 例 2: 読めるが書けない • 主体: httpd_t • 対象: httpd_sys_content_t • class: file / dir • 要求: write, add_name, create, append ポイント: httpd_sys_content_t は主に配信用。書き込みが必要なら httpd_sys_rw_content_t など 書き込み前提の type が必要。 例 3: 外部通信だけ落ちる • 主体: httpd_t • 対象: ソケット / ポート関連 • class: tcp_socket など • 要求: name_connect ポイント: ファイルアクセスではなく socket 系フックで判定される。boolean は内部的にはポリシー 条件分岐の ON/OFF。 6. execve() が特別なのはなぜか execve() では「実行できるか」だけでなく、新しいプロセスにどのドメインを与えるか まで判定され る。
• 実行ファイルラベルが httpd_exec_t なら、type_transition により起動後のプロセスが httpd_t へ 遷移する。 • ラベルが狂っていて bin_t などになっていると、期待したドメイン遷移が起きず、起動後の権限ま で変わる。 7. なぜラベル不整合で OS が死ぬのか • SELinux はアプリ層の追加チェックではなく、カーネルの要所で毎回呼ばれる。 • systemd, login, udev, sshd, dbus などの重要コンポーネントも同じ仕組みで判定される。 • そのため /etc, /var, 実行ファイル, ソケット, 状態ディレクトリのラベルが壊れると、ブート途中か ら連鎖的に失敗しうる。 8. AVC ログの読み方 avc: denied { read } for pid=1234 comm="httpd" name="index.html" scontext=system_u:system_r:httpd_t:s0 tcontext=unconfined_u:object_r:user_home_t:s0 tclass=file • scontext = 主体 • tcontext = 対象 • { read } = 欲しかった権限 • tclass=file = オブジェクトクラス 発表では「AVC ログは SELinux の思考過程の抜粋」と言うと伝わりやすい。 9. 想定質問への短い返し 質問 どこで弾いてるの? 返し カーネルの LSM フック地点。open, exec, connect などの重要操作の直前。 主体ラベル、対象ラベル、object class、要求 何を見てるの? permission。内部では主に SID 化された値で扱 う。
毎回ポリシー全文を読むの? root でも止まるの? Permission denied の正体は? まず AVC を見る。無ければ Security Server が ロード済みポリシーから計算する。 DAC とは別レイヤなので、SELinux が deny なら root でも止まる。 アプリ視点ではただの失敗だが、実際は allow に 一致せず enforcing で deny された結果。 10. 締めに使いやすい一文 SELinux は「怪しい挙動をあとから検出する」仕組みではなく、カーネルが操作を実行する瞬間に割 り込んで、その場で拒否できる 仕組み。だから強いし、ラベルを壊すとブートまで死ぬ。 作成: ChatGPT