ansible でノーパスログイン(公開鍵認証)設定する

公開鍵認証をするために、対象のサーバの指定ユーザの authorized_keys を設定するモジュール「authorized_key」があるのでそれを使用する。

前提

  • authorized_key モジュール実行時はパスワード認証でログインする
  • root ユーザでログインする
  • root ユーザの RSA鍵ファイルを作成(ssh-keygen)してあること
  • /dev/cdrom に CentOS メディアが接続されていること

手順

プレイブック作成

setup.root.authorized_keys.yml を作成する。

---

# 対象サーバの root ユーザの authorized_keys に /root/.ssh/id_rsa.pub の公開鍵を追加する。

- hosts: '{{ hosts }}'
  tasks:
    - name: setup authorized_keys
      authorized_key: user=root
                      key="{{ lookup('file', '/root/.ssh/id_rsa.pub') }}"
実行

garnet-vm11 に対して実行する。-k オプションをつけてパスワードを入力する。

# ansible-playbook setup.root.authorized_keys.yml -k --extra-vars="hosts=garnet-vm11"
SSH password: (password)

PLAY [garnet-vm11] ************************************************************ 

GATHERING FACTS *************************************************************** 
ok: [garnet-vm11]

TASK: [setup authorized_keys] ************************************************* 
failed: [garnet-vm11] => {"failed": true}
msg: Aborting, target uses selinux but python bindings (libselinux-python) aren't installed!

FATAL: all hosts have already failed -- aborting

PLAY RECAP ******************************************************************** 
           to retry, use: --limit @/root/setup.root.authorized_keys.retry

garnet-vm11                : ok=1    changed=0    unreachable=0    failed=1   

失敗。どうやら SELinux が有効な環境では libselinux-python パッケージが対象サーバ側に入っている必要があるようだ。

libselinux-python パッケージインストール

パッケージインストールには yum モジュールを使ってみる。yum がちゃんと動かないとお話しにならないのだが、ネット接続しないしばりで、あえて CentOS 6.4 のメディアからインストールする。

プレイブック install.libselinux-python.yml を作成する。

  • mount モジュールは fstab をいじるためのもののようなので使わず。
---

# /dev/cdrom にセットされている CentOS のメディアを使用して libselinux-python パッケージをインストールする。
#  ・/media/CentOS にマウントする。同ディレクトリを作成・削除する。
#  ・外部通信ができないとエラーになるためリポジトリ base,extras,updates は disablerepo 扱いにする。

- hosts: '{{ hosts }}'
  tasks:
    - name: mkdir /media/CentOS
      shell: "test -d /media/CentOS || mkdir -p -m 755 /media/CentOS"

    - name: mount CentOS media
      shell: "mountpoint /media/CentOS &>/null || mount /dev/cdrom /media/CentOS"

    - name: install libselinux-python
      yum: disablerepo=base,extras,updates enablerepo=c6-media name=libselinux-python state=present

    - name: umount CentOS media
      shell: "! mountpoint /media/CentOS || umount /media/CentOS"

    - name: rmdir /media/CentOS
      shell: "! test -d /media/CentOS || rmdir /media/CentOS"

実行!

# ansible-playbook install.libselinux-python.yml -k --extra-vars="hosts=garnet-vm11"
SSH password: 

PLAY [garnet-vm11] ************************************************************ 

GATHERING FACTS *************************************************************** 
ok: [garnet-vm11]

TASK: [mkdir /media/CentOS] *************************************************** 
changed: [garnet-vm11]

TASK: [mount CentOS media] **************************************************** 
changed: [garnet-vm11]

TASK: [install libselinux-python] ********************************************* 
changed: [garnet-vm11]

TASK: [umount CentOS media] *************************************************** 
changed: [garnet-vm11]

TASK: [rmdir /media/CentOS] *************************************************** 
changed: [garnet-vm11]

PLAY RECAP ******************************************************************** 
garnet-vm11                : ok=6    changed=5    unreachable=0    failed=0   
再実行

libselinux-python パッケージを入れた後に再実行して無事成功した。

# ansible-playbook setup.root.authorized_keys.yml -k --extra-vars="hosts=garnet-vm11"
SSH password: (password)

PLAY [garnet-vm11] ************************************************************ 

GATHERING FACTS *************************************************************** 
ok: [garnet-vm11]

TASK: [setup authorized_keys] ************************************************* 
changed: [garnet-vm11]

PLAY RECAP ******************************************************************** 
garnet-vm11                : ok=2    changed=1    unreachable=0    failed=0 

パスワードなしでログインできることを確認する。
前の接続から60秒以内だと接続が再利用されるので、/root/.ansible/cp の下のファイルがなくなってから実施する。

# ls -l /root/.ansible/cp
total 0

# ansible garnet-vm11 -m command -a uptime
garnet-vm11 | success | rc=0 >>
 03:22:55 up  5:31,  2 users,  load average: 0.00, 0.00, 0.00