Ansibleプレイブックを実行していますが、1台のマシンで正常に動作します。
新しいマシンで初めて試すときに、次のエラーが表示されます。
17:04:34 PLAY [appservers] *************************************************************
17:04:34
17:04:34 GATHERING FACTS ***************************************************************
17:04:34 fatal: [server02.cit.product-ref.dev] => {'msg': "FAILED: (22, 'Invalid argument')", 'failed': True}
17:04:34 fatal: [server01.cit.product-ref.dev] => {'msg': "FAILED: (22, 'Invalid argument')", 'failed': True}
17:04:34
17:04:34 TASK: [common | remove old ansible-tmp-*] *************************************
17:04:34 FATAL: no hosts matched or all hosts have already failed -- aborting
17:04:34
17:04:34
17:04:34 PLAY RECAP ********************************************************************
17:04:34 to retry, use: --limit @/var/lib/jenkins/site.retry
17:04:34
17:04:34 server01.cit.product-ref.dev : ok=0 changed=0 unreachable=1 failed=0
17:04:34 server02.cit.product-ref.dev : ok=0 changed=0 unreachable=1 failed=0
17:04:34
17:04:34 Build step 'Execute Shell' marked build as failure
17:04:34 Finished: FAILURE
このエラーは、最初にソースマシン(ansible Playbookを実行している場所)に移動し、ターゲットマシンに(指定されたユーザーとして)手動でsshし、known_hostsファイルエントリに「yes」と入力すると解決できます。
今、同じansibleプレイブックを2回実行すると、エラーなしで動作します。
したがって、特定のユーザー(〜/ .sshフォルダー、ファイルknown_hosts)に対してssh known_hostsエントリーを初めて作成するときに、SSHが提供するプロンプトを抑制するにはどうすればよいですか?
〜/ .ssh/configファイルで次の設定エントリを使用すると、これができることがわかりました。
〜/ .ssh/config
# For vapp virtual machines
Host *
StrictHostKeyChecking no
UserKnownHostsFile=/dev/null
User kobaloki
LogLevel ERROR
すなわち、リモートマシンのユーザーの〜/ .ssh/configファイルに上記のコードを配置し、初めてAnsibleプレイブックを試すと、「yes」を入力するように求められず、プレイブックは正常に実行されます(ユーザーは、ソースマシンからターゲット/リモートマシンにknown_hostsファイルエントリを手動で作成します)。
私の質問:1.〜/ .ssh/configを使用する場合、どのセキュリティ問題に注意する必要がありますか?2.設定(configファイルにあるもの)をパラメーター/オプションとしてコマンドラインでansibleに渡すにはどうすればよいですか新しいマシンで最初に実行されます(プロンプトを表示せずに、ターゲットマシンのソースマシンのknown_hostsファイルエントリに依存しますか?
Ansible docsには これに関するセクション があります。引用:
Ansible 1.2.1以降では、デフォルトでホストキーチェックが有効になっています。
ホストが再インストールされ、「known_hosts」に別のキーがある場合、修正されるまでエラーメッセージが表示されます。ホストが最初に「known_hosts」にない場合、これにより、キーの確認が求められ、cronなどのAnsibleを使用している場合、インタラクティブなエクスペリエンスが得られます。これは必要ないかもしれません。
影響を理解し、この動作を無効にしたい場合は、/ etc/ansible/ansible.cfgまたは〜/ .ansible.cfgを編集することで無効にできます。
[defaults]
Host_key_checking = False
あるいは、これは環境変数によって設定できます:
$ export ANSIBLE_Host_KEY_CHECKING=False
また、paramikoモードでのホストキーチェックはかなり遅いため、この機能を使用する場合は「ssh」に切り替えることもお勧めします。
ローカルのknown_hosts
ファイルを更新するには、次のようにssh-keyscan
(ホスト名をIPアドレスに解決するDig
を使用)と無効モジュールknown_hosts
の組み合わせを使用しました。ファイル名ssh-known_hosts.yml
)
- name: Store known hosts of 'all' the hosts in the inventory file
hosts: localhost
connection: local
vars:
ssh_known_hosts_command: "ssh-keyscan -T 10"
ssh_known_hosts_file: "{{ lookup('env','HOME') + '/.ssh/known_hosts' }}"
ssh_known_hosts: "{{ groups['all'] }}"
tasks:
- name: For each Host, scan for its ssh public key
Shell: "ssh-keyscan {{ item }},`Dig +short {{ item }}`"
with_items: "{{ ssh_known_hosts }}"
register: ssh_known_Host_results
ignore_errors: yes
- name: Add/update the public key in the '{{ ssh_known_hosts_file }}'
known_hosts:
name: "{{ item.item }}"
key: "{{ item.stdout }}"
path: "{{ ssh_known_hosts_file }}"
with_items: "{{ ssh_known_Host_results.results }}"
そのようなymlを実行するには、次のようにします
ANSIBLE_Host_KEY_CHECKING=false ansible-playbook path/to/the/yml/above/ssh-known_hosts.yml
その結果、inventoryの各ホストについて、サポートされているすべてのアルゴリズムがhostname、ipaddressペアレコードの下のknown_hosts
ファイルに追加/更新されます。といった
atlanta1.my.com,10.0.5.2 ecdsa-sha2-nistp256 AAAAEjZHN ... NobYTIGgtbdv3K+w=
atlanta1.my.com,10.0.5.2 ssh-rsa AAAAB3NaC1y ... JTyWisGpFeRB+VTKQ7
atlanta1.my.com,10.0.5.2 ssh-ed25519 AAAAC3NaCZD ... UteryYr
denver8.my.com,10.2.13.3 ssh-rsa AAAAB3NFC2 ... 3tGDQDSfJD
...
(inventoryファイルは次のようになります:
[master]
atlanta1.my.com
atlanta2.my.com
[slave]
denver1.my.com
denver8.my.com
)
Xiongの答えとは対照的に、これはknown_hosts
ファイルのコンテンツを適切に処理します。
このプレイは、ターゲットホストが再イメージ化される仮想化環境を使用する場合に特に役立ちます(したがって、ssh pubキーが変更されます)。
ホストキーチェックを完全に無効にすることは、中間者攻撃につながるため、セキュリティの観点からは悪い考えです。
現在のネットワークが危険にさらされていないと想定できる場合(つまり、初めてマシンにsshしてキーが提示された場合、そのキーは実際にはマシンのものであり、攻撃者のものではありません)、使用できます- ssh-keyscan
および シェルモジュール は、既知のホストファイルに新しいサーバーのキーを追加します(編集: Stepanの答え これはより良い方法です):
- name: accept new ssh fingerprints
Shell: ssh-keyscan -H {{ item.public_ip }} >> ~/.ssh/known_hosts
with_items: ec2.instances
( ec2プロビジョニング の後に見られるように、ここで説明します。)
@Stepan Vavraの正解に従ってください。短いバージョンは次のとおりです。
- known_hosts:
name: "{{ item }}"
key: "{{ lookup('pipe', 'ssh-keyscan {{ item }},`Dig +short {{ item }}`') }}"
with_items:
- google.com
- github.com
Known_hostsファイルを準備するために次のようなことはしません:
ANSIBLE_Host_KEY_CHECKING=false ansible all -m ping
これにより、インベントリ内の各ホストに接続し、各プロンプトに対して「yes」を入力せずに各ホストのknown_hostsファイルを更新し、各ホストで「ping」モジュールを実行しますか?
クイックテスト(既知のホストファイルを削除してから上記を実行し、Ubuntu 16.04インスタンスで実行)により、既知のホストファイルに現在のフィンガープリントが読み込まれたようです。
@Stepan Vavraのソリューションは、エイリアスホストを使用していたため機能しませんでした(DNSを使用できない内部IPに接続していたため、インベントリ内の各ホストを参照し、ansible_Host変数を持つよりわかりやすい名前が必要でした)それぞれの実際のIPを指します)。上記の実行ははるかに簡単で、ansibleまたはsshでホストキーチェックを無効にすることなく、known_hostsファイルを準備しました。
サーバーOSレベルからこれを設定することもできます。プロンプトへのsshチェックを回避するために、ssh構成ファイルを構成する必要があります。
ファイルパスを編集します。
/etc/ssh/ssh_config
行のコメントを解除します。
StrictHostKeyChecking no
変更を保存して、それだけです
警告:Ansibleは、上記の設定の接続に対してSSHホストキー検証を実行しません