web-dev-qa-db-ja.com

Ansible経由でホストSSHキーを生成する方法は?

Ansible(およびssh-keygen)を介して少数のリモートサーバー上でsshホストキーを再生成しようとしていますが、ファイルが表示されないようです。プレイブックは正常に実行されますが、リモート上のファイルは変更されません。

これらのリモートはUbuntu 14.04を実行していて、適切なバージョンのecho -eを使用できないため(これは、ansibleによると)、python-pexpectハッカーに頼る必要があります。

何が欠けていますか?私のプレイブックと出力は以下の通りです:

プレイブック

---
- hosts: all
  become: true
  gather_facts: false

  tasks:
    - name: Generate /etc/ssh/ RSA Host key
      command : echo -e 'y\n'|ssh-keygen -q -t rsa -f /etc/ssh/ssh_Host_rsa_key -C "" -N ""
      register: output
    - debug: var=output.stdout_lines

    - name: Generate /etc/ssh/ DSA Host key
      command : echo -e 'y\n'|ssh-keygen -q -t dsa -f /etc/ssh/ssh_Host_dsa_key -C "" -N ""
      register: output
    - debug: var=output.stdout_lines

    - name: Generate /etc/ssh/ ECDSA Host key
      command : echo -e 'y\n'|ssh-keygen -q -t ecdsa -f /etc/ssh/ssh_Host_ecdsa_key -C "" -N ""
      register: output
    - debug: var=output.stdout_lines

出力

$ ansible-playbook ./playbooks/ssh-hostkeys.yml -l myhost.mydom.com, 
Sudo password: 

PLAY [all] **********************************************************************************************

TASK [Generate /etc/ssh/ RSA Host key] ******************************************************************
changed: [myhost.mydom.com]

TASK [debug] ********************************************************************************************
ok: [myhost.mydom.com] => {
    "output.stdout_lines": [
        "y", 
        "|ssh-keygen -q -t rsa -f /etc/ssh/ssh_Host_rsa_key -C  -N "
    ]
}

TASK [Generate /etc/ssh/ DSA Host key] ******************************************************************
changed: [myhost.mydom.com]

TASK [debug] ********************************************************************************************
ok: [myhost.mydom.com] => {
    "output.stdout_lines": [
        "y", 
        "|ssh-keygen -q -t dsa -f /etc/ssh/ssh_Host_dsa_key -C  -N "
    ]
}

TASK [Generate /etc/ssh/ ECDSA Host key] ****************************************************************
changed: [myhost.mydom.com]

TASK [debug] ********************************************************************************************
ok: [myhost.mydom.com] => {
    "output.stdout_lines": [
        "y", 
        "|ssh-keygen -q -t ecdsa -f /etc/ssh/ssh_Host_ecdsa_key -C  -N "
    ]
}

PLAY RECAP **********************************************************************************************
myhost.mydom.com : ok=6    changed=3    unreachable=0    failed=0  
11
Server Fault

私が知る限り、ssh-keygenに「y」をパイプする必要がある唯一の理由は、コマンドが既存のファイルを置き換える場合です。私の意見では、これは構成管理ツールから何かを行うための良い方法ではありません。

タスクをべき等になるように調整する必要があります。具体的には、creates: filenameをコマンドに追加すると、新しいキーは、プレイブックを実行するたびに置き換えられるのではなく、存在しない場合にのみ作成されます。

---
- hosts: all
  become: true
  gather_facts: false

  tasks:
  - name: Generate /etc/ssh/ RSA Host key
    command : ssh-keygen -q -t rsa -f /etc/ssh/ssh_Host_rsa_key -C "" -N ""
    args:
      creates: /etc/ssh/ssh_Host_rsa_key

  - name: Generate /etc/ssh/ DSA Host key
    command : ssh-keygen -q -t dsa -f /etc/ssh/ssh_Host_dsa_key -C "" -N ""
    args:
      creates: /etc/ssh/ssh_Host_dsa_key

  - name: Generate /etc/ssh/ ECDSA Host key
    command : ssh-keygen -q -t ecdsa -f /etc/ssh/ssh_Host_ecdsa_key -C "" -N ""
    args:
      creates: /etc/ssh/ssh_Host_ecdsa_key

なんらかの理由でそれらのキーを交換したい場合(たとえば、キーが古すぎる場合など)、別のタスクを追加してそれらを削除することができます。これは簡単な削除です

- file:
    state: absent:
    path: "{{item}}"
  loop:
  - /etc/ssh/ssh_Host_rsa_key
  - /etc/ssh/ssh_Host_dsa_key
  - /etc/ssh/ssh_Host_ecdsa_key

特定の時間より前に生成されたファイルを削除する場合は、statモジュールを使用してこのファイルの詳細を取得し、when条件を設定して、特定の日付よりも古い場合にそれらを選択的に削除できます。

14
Zoredache

Ansible command moduleは、シェルを介してコマンドを渡しません。これは、パイプなどのシェルオペレーターを使用できないことを意味します。そのため、出力にパイプシンボルが表示されます。 ansibleに関する限り、それはコマンドechoを実行し、残りの行すべてをechoへの引数として使用しています。

シェルでコマンドラインを処理する必要がある場合は、Shellではなく se command を使用します。

そして、ssh Hostキーを再生成するためのより良い方法があるはずですが、今は見つかりません...

6
Michael Hampton

このタスクには特別なモジュールを使用します。

- name: Generate an OpenSSH keypair with the default values (4096 bits, rsa)
  openssh_keypair:
    path: /home/youruser/.ssh/id_rsa
    owner: youruser
    group: youruser

- name: Fix owner of the generated pub key
  file:
    path: /home/youruser/.ssh/id_rsa.pub
    owner: youruser
    group: youruser
2
Jorj

申し訳ありませんが、タスクで「作成」を使用できませんでした。次のエラーが発生しました:

ERROR! 'creates' is not a valid attribute for a Task

結果として、私は次のタスクを使用します。

- name: remove existing ssh_Host keys
  file: path={{ item }} state=absent
  with_items:
    - "/etc/ssh/ssh_Host_rsa_key"
    - "/etc/ssh/ssh_Host_dsa_key"
    - "/etc/ssh/ssh_Host_ecdsa_key"

- name: Generate /etc/ssh/ RSA Host key
  command : ssh-keygen -q -t rsa -f /etc/ssh/ssh_Host_rsa_key -C "" -N ""

- name: Generate /etc/ssh/ DSA Host key
  command : ssh-keygen -q -t dsa -f /etc/ssh/ssh_Host_dsa_key -C "" -N ""

- name: Generate /etc/ssh/ ECDSA Host key
  command : ssh-keygen -q -t ecdsa -f /etc/ssh/ssh_Host_ecdsa_key -C "" -N ""
1
MaxiReglisse

@Zoredacheは正解ですが、Ansibleの最近のバージョンでは失敗します(@MaxiReglisseで示されます)。代わりに次のコードを使用してください。

---
- hosts: all
  become: true
  gather_facts: false

  tasks:
  - name: Generate /etc/ssh/ RSA Host key
    command : ssh-keygen -q -t rsa -f /etc/ssh/ssh_Host_rsa_key -C "" -N ""
    args:
      creates: /etc/ssh/ssh_Host_rsa_key
1
David Weber

別のオプションはserモジュールを使用することです。これの良い面は、べき等のタスクを取得することです。ローカルホストでSSH鍵を生成する方法の例を次に示します。

- name: Generate ssh keys
  local_action:
    module: "user"
    name: "{{ lookup('env','USER') }}"
    generate_ssh_key: true
    ssh_key_type: "{{ item.0 }}"
    ssh_key_bits: "{{ item.1 }}"
    ssh_key_file: "{{ playbook_dir }}/{{ item.0 }}_{{ item.1 }}_key"
  with_together:
  - [ 'rsa', 'dsa' ]
  - [ 2048, 1024 ]
  loop_control:
    label: "{{ item.0 }}_{{ item.1 }}_key"

- name: Copy generated ssh keys to remote machine
  copy:
    src: "{{ playbook_dir }}/{{ item.0 }}_{{ item.1 }}_key"
    dest: "/etc/ssh/ssh_Host_{{ item.0 }}_key{{ item.1 }}"
  with_nested:
  - [ 'rsa', 'dsa' ]
  - [ '', '.pub' ]
  notify:
  - Restart sshd
  loop_control:
    label: "/etc/ssh/ssh_Host_{{ item.0 }}_key{{ item.1 }}"
1
HeroFromEarth

Openssh_keypairおよびauthorized_keyモジュールを使用して、キーをansible Hostに保存せずに同時に作成およびデプロイします。

- openssh_keypair:
    group: root
    owner: root
    path: /some/path/in/your/server
    register: ssh_key

- name: Store public key into Origin
  delegate_to: central_server_name
  authorized_key:
     key: "{{ssh_key.public_key}}"
     comment: "{{ansible_hostname}}"
     user: any_user_on_central
0
MUY Belgium