はじめに
私はUbuntuの知識が皆無で、QiitaやAIなどから情報を収集し、サーバーを構築(?)しています。
その一環で /etc/sudoers
を編集することがあり、件のコマンドを実行しました。それが失敗だったようです。
そのような失敗はなかなか起きないでしょうが、似たような状況が発生した時のために、また反省という意味も込めて、書き起こしておきます。
本記事は、chmod 666 /etc/sudoers
の実行を推奨するものではありません。
このコマンドを実行するとかなりめんどくさいことになるので、やめましょう。
- (特にUnix系・Ubuntuに精通している方は)本記事を読む上で、「なんでそんなことをするんだ?」「それはやっちゃダメだろう!」となる場面が多々あると思われますが、ご容赦ください。
- 本記事の中で、明らかに違う単語などを使っている箇所があるかもしれません。
もし間違っている場合は、コメント等で教えていただけると嬉しいです。
Ubuntu Serverにおけるリカバリーモードを用いたrootユーザーのパスワードの変更方法については、次の章を参考してください。なお、すでにrootユーザーのパスワードが設定され、有効化されている場合は、本記事に記載された方法は適用外となります。
- 第3章-1
- 第3章-2
- 第4章-1
- 第4章-2
- 第4章-4
- 第5章-4
Ubuntu Serverで /etc/sudoers
が world writable
であるために sudo
が使用できない状態から修復する方法については、次の章を参考してください。なお、本記事に記載された方法は、rootユーザーのパスワードが必要です。
- 第5章-2
- 第5章-3
実行環境
サーバー
- OS
NAME="Ubuntu"
VERSION_ID="24.04"
VERSION="24.04.2 LTS (Noble Numbat)"
- sudoバージョン
Sudo version 1.9.15p5
Sudoers policy plugin version 1.9.15p5
Sudoers file grammar version 50
Sudoers I/O plugin version 1.9.15p5
Sudoers audit plugin version 1.9.15p5
説明の前に
この記事では、(パスワードの部分を除き)どうしても chmod 666 /etc/sudoers
や /etc/sudoers
という言葉を繰り返し使用します。
そのため、このコマンドの意味やファイルの内容をまとめます。
1. /etc/sudoers
ってどんなファイル?
/etc/sudoers
ファイルは、sudoコマンドの動作を制御する重要な設定ファイルです。
...しかし、実は筆者、このファイルのことをよく知りません。(まずい)
中途半端な知識で語ってはいけない系のファイルなので、ここでは詳しくは記入しません。
そのため、他の方が解説している記事を見ていただければと思います。
2. chmod 666 /etc/sudoers
ってどんなコマンド?
chmod 666 /etc/sudoers
は、簡単に言うと「すべてのユーザーが /etc/sudoers
を読み書きできるようにする (実行の権限は与えない)」コマンドです。
例の如く筆者は chmod
の使い方もよく知りません。(非常にまずい)
chmodはいろんな方が解説してくださっているぽいですので、そちらをご覧ください。
問題の状況・解決
第1章: 開けなかった sudoers
、使えなくなった sudo
筆者は /etc/sudoers
を編集したかったので、次の手順で編集しようとしました。
1. 最初に、サーバーにSSHと何か(よくわかっていない)で接続しよう。
クライアントからSSHと何か(NFS? SMB? SFTP?)で接続しました。
2. とりあえず、Visual Studio Codeで開いてみよう。
Visual Studio Codeで /etc/sudoers
を開きました。 開こうとしました。
しかし、権限エラーに遭遇します。
Unable to read file '/Volumes/[Server]/etc/sudoers' (NoPermissions (FileSystemError): An unknown error occurred. Please consult the log for more details.)
3. etcはお嫌いかい? ホームディレクトリにコピーしてみよう。
ファイルをホームディレクトリに移してみて、もう一度やってみることにしました。
$ sudo cp /etc/sudoers ./
希望を持って開いてみましたが... やっぱりエラーでした。
4. 権限いじって直接編集すりゃいいよね。← あかん
「権限いじって直接編集すればいいのでは?」と思いつき、件のコマンドを実行するのではなく、AIに下のコードを書かせてました。
#!/bin/bash
# スクリプトをrootとして実行していることを確認
if [ "$(id -u)" -ne 0 ]; then
echo "このスクリプトはroot権限で実行する必要があります。"
echo "sudo $0 を実行してください。"
exit 1
fi
# ファイルの指定方法
if [ -z "$1" ]; then
read -p "権限を変更するファイルのパスを入力してください: " TARGET_FILE
else
TARGET_FILE=$1
fi
# ファイルが存在するか確認
if [ ! -f "$TARGET_FILE" ]; then
echo "指定されたファイルが存在しません: $TARGET_FILE"
exit 1
fi
# 元の権限を保存
ORIGINAL_PERMS=$(stat -c "%a" "$TARGET_FILE")
echo "元の$TARGET_FILEの権限: $ORIGINAL_PERMS"
# 権限を変更 (すべての人が読み書きできるように)
echo "$TARGET_FILEの権限を666に変更します..."
chmod 666 "$TARGET_FILE"
echo "現在の$TARGET_FILEの権限: $(stat -c "%a" "$TARGET_FILE)"
# 一時停止(ここで必要な作業を行うことができます)
echo ""
echo "警告: $TARGET_FILEファイルの権限が変更されました。"
echo "セキュリティリスクがあるため、必要な作業が完了したらすぐに元に戻してください。"
echo ""
read -p "元の権限に戻す準備ができたらEnterキーを押してください..."
# 元の権限に戻す
echo "$TARGET_FILEの権限を元の状態 ($ORIGINAL_PERMS) に戻します..."
chmod $ORIGINAL_PERMS "$TARGET_FILE"
echo "現在の$TARGET_FILEの権限: $(stat -c "%a" "$TARGET_FILE")"
echo "完了しました。"
このプログラムは実行するとそのファイルの安全性が著しく下がります。
実行しないことをおすすめします。
システムファイル、特に権限関係のファイルには使用しないでください。
下手するとシステムが動かなくなります。
プログラムをホームディレクトリに保存すれば、あとは実行するだけです。
$ sudo bash ./Unlocker.sh
権限を変更するファイルのパスを入力してください: /etc/sudoers
元の/etc/sudoersの権限: 440 /etc/sudoersの権限を666に変更します...
Unlocker.sh: line 44: unexpected EOF while looking for matching `)'
...もちろんエラーが出ますが。
この時点で、 chmod 666 /etc/sudoers
は実行されていたようです。
5. デバッグしよう! ← 問題はそこじゃない... ことはないがそうじゃない。
「なんでだろう」と思いつつAIにデバッグさせていました。
#!/bin/bash
set -x
# ~~以下同じ~~
「これで行けるかなー」と実行してみましたが...
$ sudo bash ./Unlocker.sh
sudo: /etc/sudoers is world writable
sudo: error initializing audit plugin sudoers_audit
さっきとはまた違うエラーが出たわけです。
ここで私は sudo: /etc/sudoers is world writable
に注目しました。
/etc/sudoers
が world writable
? 妙ですね。書き込める( writable
)って書いてあるのです。
「これ、変更できてるじゃん」と。この時点で気づきました。
第2章: su
を使う...? パスワードわ゙がん゙な゙い゙(泣)
無事に(無事じゃない)/etc/sudoers
が編集できたことで、私はホクホク顔で戻ってきました。
「あとは戻すだけだ」と。そう信じて疑いませんでした。
1. sudo
、死す!
「アプリケーションは途中で落ちてしまったが、chmod 440 /etc/sudoers
をすればいいだろう」と思っていましたが...
$ chmod 440 /etc/sudoers
chmod: changing permissions of '/etc/sudoers': Operation not permitted
...まあ、これは当たり前です。権限がなければ実行できるわけができません。
当然、sudo
を使用すれば実行できるはずだと思いました。
$ sudo chmod 440 /etc/sudoers
sudo: /etc/sudoers is world writable
sudo: error initializing audit plugin sudoers_audit
...あるぇ? sudo
くん? し、死んでる…
2. sudo
が使えないなら su
を使えばいいじゃない。rootユーザーのパスワード? 知らない子ですねぇ。
誰かは言いました。「sudo
が使えないなら su
を使えばいいじゃない。」と。
しかし、私は su
に期待していませんでした。
$ su
Password:
su: Authentication failure
貴様ァ... まさかよォ... 今ログインしているユーザーのパスワードじゃダメなのかァ...?
第3章: 起動しないGRUBと裏切りのシングルユーザーモード
もはや普通の起動方法では/etc/sudoers
の権限を設定できないと考えた私は、「シングルユーザーモード」を使用することにしました。
1. 再起動・ESC/Shift... 君は誰やねん?
GRUBを起動することになったのですが...
起動時にShiftを押しても反応なし、ESCを押すとノートパソコン本来の起動メニューが起動するというふうに、GRUBが起動できません。
2. 電源ブッチで起動するGRUB
色々調べると、Windows Recovery Environmentと同じように、「起動中に電源を落とす」とGRUBが起動するという情報を得ました。
やってみたところ、起動したので、 e
キーを押して起動構成の編集画面に入りました。
3. 違う見解と起動しないシングルユーザーモード
しかしここからが問題で、この起動構成の編集内容が、AIモデルやWebサイトによって全く違います。
ChatGPTは次のように言いました:
# linux で始まる行の末尾に以下を追加する:
init=/bin/bash
Grokは次のように言いました:
ro(read-only)をrw single #に変更して、root権限でシステムを起動。
と、全く異なるやり方を示します。とりあえず私はChatGPTに従い、起動してみました...
が、目立った変化は見られず。
他にやったら起動できるのかもしれませんが、私にはもう一つの心当たりがありました。
第4章: 約束のリカバリーモード
もう一つの心当たり - rootユーザーのパスワード変更について書いてあったWebページに、「リカバリーモード」についてとその入り方の記述がありました。
シングルユーザーモードに見切りをつけた私は、流れるようにリカバリーモードに浮気 ダイバートしました。
1. すんなり入るGRUB
またGRUBに入ります。2回目以降は簡単に入れるようになりました。
2. どこぞのシングルユーザーモードとは違う、入りやすいリカバリーモード
矢印キーと Enter
キーを使用して Advanced options for Ubuntu
を選択し Ubuntu, with Linux 6.8.0-54-generic (recovery mode)
を選択するとリカバリーモードに入れます。
なんと簡単なことでしょう。
3. rootでログイン、しかし一部しか使えない?
リカバリーモードというピンク色の画面に入ると、色々選べるメニューがありました。
先ほどのパスワードの変更について書いてあったページもターミナルを使っていたことを考え、そのページの通り root
を選び Press Enter for maintenance
と言われたので Enter
キーを押しました。
するとターミナルにアクセスできました。
そこで、試しに dir
をしてみると snap
しか表示されませんでした。
「これじゃあ修復できないじゃないか。」と思いました。問題のファイルは /etc/
の中にある sudoers
なのだから。
... 正攻法で行くことにします。
4. いけ、 passwd
!
現在の状況を整理しましょう。
-
sudo
が使用できない →/etc/sudoers
が権限設定が666(rw-rw-rw-)になっているから -
su
が使用できない → rootユーザーのパスワードを忘れたから -
chmod 440 /etc/sudoers
が使用できない →sudo
やsu
が使えないから
これを置き換えると
-
su
が使用できなかったのはrootユーザーのパスワードを忘れたからです - rootユーザーのパスワードがわかれば
su
を実行できます -
su
を実行できればsudo
を用いずとも直接rootユーザーとして/etc/sudoers
の権限設定を修正することができます
ということになります。
リカバリーモードではrootユーザーのパスワードをリセットすることができます。
$ passwd root
New password:
Retype new password:
passwd: password updated successfully
やったぜ。
第5章: 終わり(終わらない[終わり])
su
が使用可能になった今、もはや後は流れ作業となりました。
1. ひとりで通常起動できるかな?
早速電源ボタンを2回ポチり、起動。
2. su
、君に決めた!
さっそくrootユーザーでログインしようとしましたが、なぜかログインできず。
一度自身のアカウントにログインし、ユーザー変更 ( su
) でログインしました。
3. 奥義! chmod
!
管理者権限で実行できる状態になった私は、目的の chmod 440 /etc/sudoers
を実行しました。
$ chmod 440 /etc/sudoers
何も出ません。成功です。やったぜ。
$ sudo ls /root
snap
4. ジ。~AIの助言について~
さて、解決したように思われたこの問題ですが、AIから一つ助言がありました。
「chmod 440 /etc/sudoers
を実行した後は、次のコマンドを実行して無効化してください。」と。
$ passwd -l root
passwd: password changed.
これで、修復は完了です。
5. 考察(常識)
上で、rootユーザーのパスワードは無効化されました。
しかし、なぜ、AIは無効化するよう助言したのでしょうか。
それを考えると、次のようなことが考察されます。
「rootユーザーのパスワード、元々無効化されているのではないか。」
実際、それは事実のようです。
Q. Ubuntu Serverでは、初期状態でrootユーザーのパスワードは無効化されている?
A. はい、Ubuntu Serverでは初期状態でrootユーザーのパスワードは無効化されています。...
(初めてこれを知った...)
結論
私は、chmod 666 /etc/sudoers
を実行し、それにより発生したエラーを修復したことから、以下のことを学びました。
-
chmod 666 /etc/sudoers
は実行しない。 (/etc/sudoers
の権限を変更しない) -
/etc/sudoers
を編集したい時は、visudo
を使用する - rootユーザーのパスワードは、初期状態で無効化されている
普通は行われないようなコマンドなので、このような状況になる方は限りなくゼロに近いでしょうが、もし、似たような状況に陥ってしまった方は本記事で修復できればと思います。
最後までご覧いただき、ありがとうございました。
おまけ: 再現方法
問題の再現方法です。もっとも、再現する人もいないでしょうが...
再現してみたい方は、仮想環境を使用してください。
実機では行わないでください。
- 次のプログラムをホームディレクトリかどこかに保存する
#!/bin/bash
# スクリプトをrootとして実行していることを確認
if [ "$(id -u)" -ne 0 ]; then
echo "このスクリプトはroot権限で実行する必要があります。"
echo "sudo $0 を実行してください。"
exit 1
fi
# ファイルの指定方法
if [ -z "$1" ]; then
read -p "権限を変更するファイルのパスを入力してください: " TARGET_FILE
else
TARGET_FILE=$1
fi
# ファイルが存在するか確認
if [ ! -f "$TARGET_FILE" ]; then
echo "指定されたファイルが存在しません: $TARGET_FILE"
exit 1
fi
# 元の権限を保存
ORIGINAL_PERMS=$(stat -c "%a" "$TARGET_FILE")
echo "元の$TARGET_FILEの権限: $ORIGINAL_PERMS"
# 権限を変更 (すべての人が読み書きできるように)
echo "$TARGET_FILEの権限を666に変更します..."
chmod 666 "$TARGET_FILE"
echo "現在の$TARGET_FILEの権限: $(stat -c "%a" "$TARGET_FILE)"
# 一時停止(ここで必要な作業を行うことができます)
echo ""
echo "警告: $TARGET_FILEファイルの権限が変更されました。"
echo "セキュリティリスクがあるため、必要な作業が完了したらすぐに元に戻してください。"
echo ""
read -p "元の権限に戻す準備ができたらEnterキーを押してください..."
# 元の権限に戻す
echo "$TARGET_FILEの権限を元の状態 ($ORIGINAL_PERMS) に戻します..."
chmod $ORIGINAL_PERMS "$TARGET_FILE"
echo "現在の$TARGET_FILEの権限: $(stat -c "%a" "$TARGET_FILE")"
echo "完了しました。"
このプログラムは実行するとそのファイルの安全性が著しく下がります。
実行しないことをおすすめします。
システムファイル、特に権限関係のファイルには使用しないでください。
下手するとシステムが動かなくなります。
- 実行する
sudo bash ./Unlocker.sh
権限を変更するファイルのパスを入力してください: /etc/sudoers
元の/etc/sudoersの権限: 440 /etc/sudoersの権限を666に変更します...
Unlocker.sh: line 44: unexpected EOF while looking for matching `)'
- もう一度実行する
sudo bash ./Unlocker.sh
sudo: /etc/sudoers is world writable
sudo: error initializing audit plugin sudoers_audit
やったね!