はじめに
実務にて、macOS + VirtualBox の CentOS を起動するとログイン画面が表示されず YouTube のグルグルのような感じで永遠に読み込み中の状態になってしまった、それを解決した情報になります。
下記画像は読み込み中画面にて →
、又は esc
キー押下後のブートシーケンスです。
発生していたエラーは下記の 6 点です。
- [FAILED] Failed to start Login Service.
- [FAILED] Failed to start Authorization Manager.
- [DEPEND] Dependency failed for Dynamic System Tuning Daemon.
- [FAILED] Failed to start Accounts Service.
- [FAILED] Failed to start Modem Manager.
- [FAILED] Failed to start RealtimeKit Scheduling Policy Service.
ssh
コマンドによるログインは失敗する、且つ CentOS のカーネルバージョンを切り換えて起動しても現象は発生する状態です。
環境
- Host OS : macOS Big Sur 11.5.2
- VirtualBox : 6.1.28
- Guest OS : CentOS 7.6.1810
解説
結論から言うと、SELinux(Security-Enhanced Linux)を無効にすることで解決しました。
初めに、GRUB(Grand Unified Bootloader)メニューにて e
キーを押下して設定ファイル(/boot/grub2/grub.cfg)を開きます。
GRUB とは ブートローダー のことです。ブートローダーとは BIOS(Basic Input/Output System)が 補助記憶装置 から呼び出す OS(Operating System)を動かすプログラムのことです。
…厳密に説明すると長くなっちゃうので省略しますね、下記画像が GRUB メニューです。
e
キーを押下すると下記のような画面が表示されます。
↓
キーを入力して下方にカーソルを移動させると行頭で linux16 /vmlinuz-...
と書かれた行があるので、行末に rw init=/bin/sh
と書き加え control
+ x
キーを押下して シングルユーザーモード を起動します。
=
は隣にある ^
キーを押下すると入力できます。
rw init=/bin/sh
下記のような Bourne Shell を実行できる画面が表示されます。
vi
コマンドで SELinux の設定ファイルを編集します。
vi /etc/selinux/config
i
キーで入力モードに切り替えて、赤枠の SELINUX
の設定値を disabled
に書き換えます。スペルミスや大文字入力、SELINUXTYPE
の行と間違えないようにしましょう、設定を間違えると カーネルパニック が発生する可能性があります。
次は esc
キーでコマンドモードに切り換え :wq
コマンドを実行して上書き保存して vi を終了します。
私の場合は SELINUX
が disables
に設定されていたのでエラーが発生していました。d
をつけろよデコ助野郎!
最後に exce
コマンドで /sbin/init
をオーバーレイします。
exec /sbin/init
これでログイン画面が表示されると思います、ssh
コマンドでログインもできるようになりました。
それでも解決しない場合は、下記の対処法で解決できるかもしれません。
- 仮想マシンの設定画面からストレージタブを選択して、ストレージデバイスを確認すると CentOS の iso をマウントしたままになっていたので割り当てを除去する。
- 仮想マシンの設定画面からディスプレイタブを選択して、グラフィックスコントローラーで VMAVGA を選択する。
また、SELinux の設定ファイルに書き間違いがあった場合は下記の状態でフリーズすることがあります。
因みに、今回のような現象が発生する場合は監査ログ(/var/log/audit/audit.log)を調査すると原因を特定することができます。
ausearch -m avc
コマンドを実行すると監査ログの AVC 拒否メッセージを確認することができます。AVC(Access Vector Cache)とは SELinux のアクセスに対する判断のキャッシュのことです。
ausearch -m avc
例えば、下記のようなメッセージが記録されています。
type=AVC msg=audit(1635956322.813:137):
avc: denied { read } for pid=1399
comm="lpqd"
name="cups.sock"
dev="tmpfs"
ino=16199
scontext=system_u:system_r:smbd_t:s0
tcontext=system_u:object_r:cupsd_var_run_t:s0
tclass=sock_file permissive=1
各フィールドの値を簡単に説明します。
type=AVC
: レコードの種類です。msg=audit(1635956322.813:137)
: UNIX時間 です。avc: denied
: AVC 拒否しています。{ read }
: パーミッションはread
(読み取り)です。for pid=1399
: プロセス ID です。comm="lpqd"
: 使用コマンドです。name="cups.sock"
: システムコールに引数としてcups.sock
を渡しています。dev="tmpfs"
: デバイスです。ino=16199
: inode 番号です。scontext=system_u:system_r:smbd_t:s0
: アクセス元のプロセスのコンテキストです。ユーザー(system_u)、ロール(system_r)、タイプ(smbd_t)に区切られています。tcontext=system_u:object_r:cupsd_var_run_t:s0
: アクセス先のオブジェクトのコンテキストです。tclass=sock_file
: アクセス先のオブジェクトのクラスはsock_file
です。
要約すると lpqd
による cups.sock
への読み取りアクセスを拒否しているということです。
root
ユーザーでログインして find
コマンドで inode 番号を指定して検索すると関連するファイルを見つけることができるかもしれません。
例えば、下記のコマンドは ino=16199
を検索します。
find / -inum 16199
また、audit2allow
コマンドを利用して監査ログから拒否理由、解決方法などを出力することもできます。例えば、下記のコマンドは lpqd
の AVC 拒否メッセージの解決方法を表示します。
ausearch -m avc | audit2allow -M lpqd
SELinux=permissive
(SELinux ポリシーを強制しないが監査ログに記録してアクセスを許可するモード)に切り換えると現象が発生する場合は、SELinux ポリシーを削除している可能性があります。
シングルユーザーモードから rpm -qa | grep selinux
コマンドを実行することで selinux-policy
の存在を確認することができます。
selinux-policy
が存在しない場合は、誰かが SELinux ポリシーを削除しちゃったかもしれないですね。
具体的な解決例については、本題よりも文章が多くなってしまうので別の記事で纏められればと思います。
以上です。
おわりに
SELinux は不正侵入による情報漏洩の被害を抑える素敵なセキュリティ標準機能ですが、一般ユーザーの利便性に欠ける部分があってとりあえず無効化、又は Permissive モードに設定されていることがあります。
確かに有効化するのが理想的だけど、SELinux が絶対に必要でない、且つ過剰セキュリティが慣れていない開発者の時間をたくさん奪うのであれば無効化で良いと思います。