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
私が知る限り、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
条件を設定して、特定の日付よりも古い場合にそれらを選択的に削除できます。
Ansible command
moduleは、シェルを介してコマンドを渡しません。これは、パイプなどのシェルオペレーターを使用できないことを意味します。そのため、出力にパイプシンボルが表示されます。 ansibleに関する限り、それはコマンドecho
を実行し、残りの行すべてをecho
への引数として使用しています。
シェルでコマンドラインを処理する必要がある場合は、Shell
ではなく se command
を使用します。
そして、ssh Hostキーを再生成するためのより良い方法があるはずですが、今は見つかりません...
このタスクには特別なモジュールを使用します。
- 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
申し訳ありませんが、タスクで「作成」を使用できませんでした。次のエラーが発生しました:
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 ""
@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
別のオプションは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 }}"
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