webdevqa.jp.net

ansible sshプロンプトknown_hostsの問題

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ファイルエントリに依存しますか?

33
Arun Sangal

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」に切り替えることもお勧めします。

38
Ben Whaley

ローカルの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キーが変更されます)。

29
Stepan Vavra

ホストキーチェックを完全に無効にすることは、中間者攻撃につながるため、セキュリティの観点からは悪い考えです。

現在のネットワークが危険にさらされていないと想定できる場合(つまり、初めてマシンにsshしてキーが提示された場合、そのキーは実際にはマシンのものであり、攻撃者のものではありません)、使用できます- ssh-keyscan および シェルモジュール は、既知のホストファイルに新しいサーバーのキーを追加します(編集: Stepanの答え これはより良い方法です):

- name: accept new ssh fingerprints
  Shell: ssh-keyscan -H {{ item.public_ip }} >> ~/.ssh/known_hosts
  with_items: ec2.instances

ec2プロビジョニング の後に見られるように、ここで説明します。)

16
Xiong Chiamiov

@Stepan Vavraの正解に従ってください。短いバージョンは次のとおりです。

- known_hosts:
    name: "{{ item }}"
    key: "{{ lookup('pipe', 'ssh-keyscan {{ item }},`Dig +short {{ item }}`') }}"
  with_items:
   - google.com
   - github.com
7
user1634074

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ファイルを準備しました。

5
Nick Istre

サーバーOSレベルからこれを設定することもできます。プロンプトへのsshチェックを回避するために、ssh構成ファイルを構成する必要があります。

ファイルパスを編集します。

/etc/ssh/ssh_config

行のコメントを解除します。

StrictHostKeyChecking no

変更を保存して、それだけです

警告:Ansibleは、上記の設定の接続に対してSSHホストキー検証を実行しません

1
dsaydon