web-dev-qa-db-ja.com

Ansibleを使用したsudoers.dファイルの確認

環境全体でsudoersファイルを管理するために使用するAnsibleプレイブックがあります。/etc/sudoersに最小限のsudoersファイルを保持したいので、追加したいものはすべて/etc/sudoers.dの下の個別のファイルに入れられます。

私のAnsibleプレイブックには、これらのファイルをプッシュするための次のタスクが含まれています。

- name: copy sudoers files
  copy:
    src: "{{ item }}"
    dest: "/etc/sudoers.d/{{ item }}"
    backup: yes
    owner: root
    group: root
    mode: 0440
    validate: /usr/sbin/visudo -cf %s
  with_items:
    - admins
    - Apache
    - monitor

タスクには、ファイルをコミットする前にファイルが有効であることを確認するための検証句が含まれており、これは通常はうまく機能しています。しかし、今日、アップデートがSudoを壊す問題に遭遇しました。ファイルは検証ステップに合格しましたが、メインの/ etc/sudoersファイルのUser_Aliasと同じ名前のUser_Aliasを含んでいました。その後Sudoを実行しようとすると、解析エラーが発生しました。

私の質問はこれです-このようなエラーをキャッチできるAnsibleからのsudoersファイルへの更新をテストするにはどうすればよいですか?ファイルが配置されたら、visudo -cを実行してエラーをキャッチできますが、検証手順が機能しないため、これを挿入します。 Ansibleには%sプレースホルダーが必要です。そうでない場合でも、visudo -cがキャッチしないように、ファイルを所定の場所にコピーする前に検証が行われます。

5
virtex

私はそれを働かせました。これが私がしたことです。最初に、一連のAnsibleタスクを追加して、/ etc/sudoers.stage.dにステージングディレクトリを作成し、/ etc/sudoers.dの内容をそこにコピーします。次に、このステージング領域にファイルをアップロードし、それらのいずれかが変更されている場合は、カスタムスクリプトを実行してアクティブ化します。

プレイブックのロジックは次のようになります

- name: delete staging area
  file:
    path: "/etc/sudoers.stage.d"
    state: absent
  changed_when: false

- name: copy /etc/sudoers.d to staging area
  Shell: "cp -rp /etc/sudoers.d /etc/sudoers.stage.d"
  changed_when: false

- name: stage sudoers files
  copy:
    src: "{{item}}"
    dest: "/etc/sudoers.stage.d/{{item}}"
    backup: yes
    owner: root
    group: root
    mode: 0440
    validate: /usr/sbin/visudo -cf %s
  with_items:
    - admins
    - Apache
    - monitor
  register: sudoers_d

- block:
  - name: Push out activate script
    copy:
      src: activate_sudoers.sh
      dest: /usr/local/bin/activate_sudoers.sh
      owner: root
      group: root
      mode: 0700

  - name: activate change
    Shell: /bin/sh /usr/local/bin/activate_sudoers.sh /etc/sudoers.stage.d

  when: sudoers_d.changed

そして、activate_sudoers.shスクリプトは次のようになります。

#!/bin/sh

function usage {
    echo "Usage: $0 <stage directory>" >&2
    exit 1
}

function abort {
    echo "*** Error detected" >&2
    [ "$#" -gt 0 ] && echo "***" $@ >&2
    exit 1
}

PATH=/usr/bin:/bin:/usr/sbin:/sbin
export PATH

test $# -eq 1 || usage
test -d "$1" || abort "Stage directory $1: missing or not a directory"
test -d /etc/sudoers.old.d && rm -rf /etc/sudoers.old.d
test -d /etc/sudoers.old.d && abort "Failed to remove /etc/sudoers.old.d"

mv /etc/sudoers.d /etc/sudoers.old.d \
  && mv "$1" /etc/sudoers.d \
  && visudo -c

if [ $? -eq 0 ]; then
    # Success - clean up
    rm -rf /etc/sudoers.old.d
    exit 0
else
    # Failure - roll back
    rm -rf /etc/sudoers.d
    mv /etc/sudoers.old.d /etc/sudoers.d
    abort "sudoers update failed"
fi

思っていたよりも少し長くて複雑ですが、仕事は完了です。うまくいけば、これは同じ問題に遭遇している他の誰にとっても役立つでしょう。

2
virtex

これを試しましたか:

- copy:
    src: '{{ item }}'
    dest: '/etc/sudoers.d/{{ item }}'
    owner: root
    group: root
    mode: 0440
    validate: 'bash -c "cat /etc/sudoers %s | visudo -cf-"'

わたしにはできる。

2
SAM