LoginSignup
4
4

More than 5 years have passed since last update.

AnsibleのCopyモジュールでsudoers.d配下にファイル追加をしたらroot権限がお亡くなりになった

Last updated at Posted at 2017-05-15

こんなエラーが吐かれたあと、sudo権限がお亡くなりになった。

TASK [users : copy sudoers] *****************************************************************************************************************************************************************changed: [ipaddress] => (item={u'dest': u'.', u'src': u'roles/users/files/usersfile'})
fatal: [ipaddress]: FAILED! => {"failed": true, "msg": "Failed to get information on remote file (/etc/sudoers.d/.): Shared connection to ipaddress closed.\r\n"}
        to retry, use: --limit @xxx.retry

ansibleの公式を見るとわかるが、sodoers関連の管理はlineinfileモジュールを使うのが定石のよう。

# Validate the sudoers file before saving
- lineinfile:
    path: /etc/sudoers
    state: present
    regexp: '^%ADMIN ALL='
    line: '%ADMIN ALL=(ALL) NOPASSWD: ALL'
    validate: 'visudo -cf %s'

http://docs.ansible.com/ansible/lineinfile_module.html

で、原因は?

諸説あり。今後、正確に特定したい。
今回確認したところをメモ。

追記 2017/5/16

改行コードが原因だった。
MacとWindowsとでは改行コードが異なる。
windowsの改行コードはCRLFだ。

備忘録:改行コード「LF」と「CR」と「CRLF」の違い

解決策

  • Windowsで使用していたAtomの設定を変える

「OSデフォルトの文字コードを使用する」設定になっていた。
なので、Atomユーザは以下の記事を参考にして改行コード設定をLFに変換しておく。

Atomエディタ上からファイルを新規作成する際のデフォルトの改行コードを設定する(Windows環境)

  • .gitconfigで改行コードの設定をする

MacからPushしたコードの改行コードはLFなのに、windowsでPullしたコードはCRLFになってしまったりするので、設定を追記しておく。

windows環境の git で改行コードの自動変換に注意

  • 試しに新規作成したファイルの改行コードを確認

以下のコマンドで改行コードを確認できる。
$がついていれば改行コードLF。

$ cat -e <filename>

また、Atomユーザは右下のステータスで簡単に改行コードを確認・変更ができる。

sudoers.d配下のファイルアクセス権が変わった?

検証環境のサーバで試しにアクセス権を640に変更して、そのユーザがsudoになることができないか試したが、sudoが使用できたので違うっぽい。

ソースコードをvisudo -cfしたらsyntax errorだった

いやもうこれだろって感じ。ただ、ファイルの内容は既存のファイルからコピーしたものだった。

bash on Windowsから実行したことによる文字コード

上記のsyntax errorが出ていた理由はこれではないか。
サーバに設定されていた文字コードはASCII (LF)
失敗した際の文字コードはASCII (CRLF)だった。
実行環境(Windows、Mac、Linuxなど)によって差分がある説。

対応策

  • Copyモジュールでsudoers.d/にファイルを置くのではなく/etc/sudoersに直接記述させる
  • syntaxチェックをするコマンドを叩かせる
  • 万が一root権限が死んでもvisudo出来る方法を確立させる

Copyモジュールでsudoers.d/にファイルを置くのではなく/etc/sudoersに直接記述させる

冒頭の通り、lineinfileモジュールとregexpを使って記述するように変える。

syntaxチェックをするコマンドを叩かせる

まるまる引用で申し訳ないが、commandモジュールを使って万が一に備える方法って感じ。
Ansible的にはcommand、Shellモジュールを使うのは冪等性が保てないので、やるとしても最終手段という認識。
そして今回はその最終手段を使うべきとき。

tasks:

        - name: Copy sudoers file for safety
          command: cp -f /etc/sudoers /etc/sudoers.tmp

        - name: Create sudoers file backup
          command: cp -f /etc/sudoers /etc/sudoers.bak

        - name: Create admins group
          group: name=admins system=yes state=present

        - name: make sure we can sudo as admin group
          lineinfile: dest=/etc/sudoers.tmp state=present regexp='^%admin' line='%admin ALL=(ALL) ALL'

        - name: also make sure ssh-agent works via sudo
          lineinfile: dest=/etc/sudoers.tmp state=present regexp='^Defaults env_keep\+\=SSH_AUTH_SOCK' line='Defaults env_keep+=SSH_AUTH_SOCK'

        - name: Final sudoers file check
          shell: visudo -q -c -f /etc/sudoers.tmp && cp -f /etc/sudoers.tmp /etc/sudoers

sudoers safety and sanity checking in playbook

万が一root権限が死んでもvisudo出来る方法を確立させる

root権限がない時点でお手上げ。と思いきや、探せばあるもので。
pkexec visudoコマンドでなんとスーパーユーザでvisudoを実行できるらしい。
ただ、このpkexecは予めインストールしてないと打てない・・・。今回の件のように、お亡くなりになってからでは遅いので注意。
今回はスナップショットで復元することになった・・・。これがあればサーバを止めなくてもよかったなあ。

/etc/sudoersがsyntax errorでsudo使えなくなった時の対処法

おわりに

sudo関連は怖い。と、同時に、万が一に備えてrootになる方法を把握しておかなければならないなと思った。
「amazonLinuxはデフォルトでrootユーザになれないので、cfgをいじる必要がある」とかも知らなかった。

4
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
4