SSH
Ansible
known_hosts
host_key_checking

AnsibleのSSH接続エラーの回避設定

More than 1 year has passed since last update.


AnsibleのSSH接続エラーの回避設定


概要

Managed NodeにSSHで一度も接続をしたことが無い時や、fingerprintが変わった時、OpenSSHのチェック機能により警告が表示され、ansibleの実行ができないことがあります。これを回避するための設定を記載します。


動作環境

CentOS 6

Ansible 2.1


警告メッセージが表示される状況

以下のような状況で警告メッセージが表示されます。



  • Managed NodeにSSHで接続したことがなく、~/.ssh/known_hostsにfingerprintが無いとき。


    • sshでの接続時、以下のようなメッセージが表示されます。

    The authenticity of host 'XXX.XXX.XXX.XXX (XXX.XXX.XXX.XXX)' 
    
    can't be established.
    RSA key fingerprint is XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX.
    Are you sure you want to continue connecting (yes/no)?


    • ansibleやansible-playbookを実行時、以下のようなメッセージが表示されます。

    Using a SSH password instead of a key is not possible 
    
    because Host Key checking is enabled and sshpass does not support this.
    Please add this host's fingerprint to your known_hosts file to manage this host.



  • Managed Nodeのサーバ更改後、初めてSSHで接続した時。

    (=IPアドレスの変更はないが物理やOSが変更された)

    (=fingerprintが変わり~/.ssh/known_hostsと値が一致しなくなった)


    • sshでの接続時、以下のようなメッセージが表示されます。

    @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
    
    @ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @
    @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@


    • ansibleやansible-playbookを実行時、以下のようなメッセージが表示されます。

    SSH encountered an unknown error during the connection. 
    
    We recommend you re-run the command using -vvvv,
    which will enable SSH debugging output to help diagnose the issue



回避方法



  • ansible.cfgのssh_argsの設定

    /etc/ansible/ansible.cfgの[ssh_connection]のブロックに以下の設定を記載する。

    [ssh_connection]
    
    ssh_args = -o ControlMaster=auto -o ControlPersist=60s -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null



  • 設定の意味


    • デフォルト設定

      ControlMaster,ControlPersistはデフォルトの設定のままなので割愛。

    • StrictHostKeyChecking=no

      ホストのデータベースファイル(デフォルトでは~/.ssh/known_hosts)に存在しないときに確認なしに接続する。

      fingerprintは確認なしにホストのデータベースファイルに記録されていく。


    • UserKnownHostsFile=/dev/null

      ホストのデータベースファイル。(デフォルトでは~/.ssh/known_hosts)

      データベースファイルを常に空(/dev/null)にすることで、Managed Nodeのサーバ更改時など、fingerprintが変わった時に、データベースファイルを整合性が取れずエラーとなってしまうのを回避する。




  • 問題点


    • インベントリファイルに記載されているサーバは、すべて信頼できることが前提となる。




他の回避方法


  1. 手動でSSHで接続

    全ての対象サーバ・ユーザに対してSSHで接続を行う。


    • 問題点

      対象が多いと手間である。

      fingerprintが変わった時に対処(~/.ssh/known_hostsの修正)が必要になる。





  2. ansibleを実行するユーザのSSH設定

    ansibleを実行するControl MachineのユーザのSSH設定で、fingerprintのチェックを行わないようにする。


    • 設定(例)

    $ vi ~/.ssh/config
    
    Host 192.168.0.*
    StrictHostKeyChecking no
    UserKnownHostsFile=/dev/null


    • 問題点

      Hostで記載した対象・範囲がすべて信頼できることが前提となる。

      ansibleの実行時以外の通常のSSH接続時もこの設定が効いてくる。




  3. ansible.cfgのhost_key_checkingの設定

    ansible.cfgに、host_key_checkingというStrictHostKeyCheckingに相当する設定項目がある。

    Anible公式のドキュメント(Docs>>Getting Started>>Host Key Checking)にはこれが掲載されている。


    • 設定(例) [defaults]のブロックにhost_key_checking = Falseを設定

    $ vi /etc/ansible/ansible.cfg
    
    [defaults]
    host_key_checking = False


    • 問題点

      ~/.ssh/known_hostsに登録されている値のチェックは有効なので、fingerprintが変わった時にエラーになるので、その対処(~/.ssh/known_hostsの修正)が必要になる。




おわりに

セキュリティ的には回避するのではなく、事前にSSHで接続してknown_hostsを作っていおいた方がよい。

ただ、fingerprintが変わるタイミングは、サーバ更改やハード交換といったときになるので、そこでknown_hostsの更新が必要と気づく人がどれだけいるだろか。かなりの割合でエラーになって調べて気づくのではないだろうか。

最終的には、セキュリティ・運用等の要件によって設定方法を選択する必要がある。

以上