概要
下記のように sudo コマンドが使えなくなり、root権限が得られなくなった場合の復旧方法を記す.
ただし、Ubuntu Desktop をインストールした環境限定である.
より厳密には pkexec と pkttyagent の両コマンドが使える環境限定である.
関連 Qiita 記事
・sudoコマンドがいきなり使えなくなった!
・Chefでsudoersをいじったらsudoできなくなったの巻
・AnsibleのCopyモジュールでsudoers.d配下にファイル追加をしたらroot権限がお亡くなりになった
詳細
ここでは /etc/sudoers.d/jenkins
を編集ミスしたことによって、sudo が一切使えなくなった場合と仮定する.
つまり、次の状況からの復旧方法である.
・/etc/sudoers.d/jenkins
を削除したいが、sudo ができなくなり困り果てる
$ sudo rm -f /etc/sudoers.d/jenkins
>>> /etc/sudoers.d/jenkins: 構文エラー near line 2 <<<
>>> sudo: @ olU 内 2 行付近で構文解析エラーが発生しました
>>> sudo: 有効な sudoers のソースが見つかりません。終了します
>>> sudo: ポリシープラグインを初期化できません
検証環境
Ubuntu 16.04
恐らく Ubuntu 18.04 や 20.04 でも問題無い.
手順
1. 端末(コンソール)を2個起動させる
該当PC にログインした状態の端末 (gnome-terminal や TeraTerm などのコンソール) を 2個起動させる.
起動させた2個の端末を便宜上「端末A」「端末B」とする.
2. 「端末A」のプロセス番号を確認する
「端末A」で次のように実行するとプロセス番号が判明する.
ここでは「12345」であった. この番号を控えておく.
$ echo $$
12345
2. 「端末B」から pkttyagent を使って「端末A」に接続する
端末A のプロセス番号「12345」を指定して pkttyagent
というコマンドを実行する
なお、この時点で pkttyagent が存在しないようであれば、残念ながら本ページの手順では復旧できない💀...スマヌ
$ pkttyagent -proccess 12345
3. 「端末A」で「pkexec rm -f /etc/sudoers.d/jenkins」を実行する
$ pkexec rm -f /etc/sudoers.d/jenkins
すると「端末B」に次のような表示がされるので、「jenkins」アカウントのパスワードを入力する
==== AUTHENTICATING FOR org.freedesktop.policykit.exec ===
`/bin/rm'を管理者として実行するためには認証が必要です
Authenticating as: foo,,, (foo)
Password:
その結果、「端末A」での「pkexec rm -f /etc/sudoers.d/jenkins」に成功する.
4. 文法ミスが無い「/etc/sudoers.d/jenkins」を作成する
「端末A」で以下を実行すれば復旧完了となる.
$ cat <<EOL | sudo tee /etc/sudoers.d/jenkins
Defaults:jenkins !requiretty
jenkins ALL=(ALL:ALL) ALL
EOL
以上.
面倒でも /etc/sudoers や /etc/sudoers.d/* を編集する場合は visudo を使うべし. (自戒)
あとがき
事前に policykit-1 をインストールしておく
最悪の場合に pkexec や pkttyagent が使えるように、次を実行して先の 2つのコマンドを導入しておきましょう. (未検証ですが)
$ sudo apt-get install -y policykit-1
参考記事