■ はじめに
Ansible には Cisco IOS へ show コマンドを実行できる ios_command モジュールが用意されています。
このモジュールは設計上、コマンド実行結果にパスワードで指定した文字列が含まれる場合、パスワードに関係ない箇所でも******** でマスクするという動作をします。(例外あり、後述。)
この記事では動作の確認と対応案をご紹介します。
- 動作確認バージョン
- Ansible 2.5.0
- Ansible 2.4.3
■ 現象
詳細は以下の issue に記載されています。(設計上の動作のため closed )
例えば、cisco99 というパスワードを指定していいて、かつ、パスワードに関係ない箇所にも cisco99 という文字列が含まれているコンフィグ想定して、どのような時にどのようにマスクされるかを見ていきます。
- 想定事前コンフィグ抜粋
interface Loopback0 description hogehogecisco99hogehoge
以下のように、 ios_config モジュール内の provider の password オプションでパスワードを指定すると、コマンド実行結果にそのパスワードと文字列が ******** でマスクされます。
Playbook
- hosts: ios gather_facts: no connection: local tasks: - name: show ios_command: commands: - show run provider: username: cisco password: cisco99 # パスワード register: result - name: debug debug: msg: "{{ result.stdout_lines[0] }}"
出力結果例(抜粋)
パスワードと同じ文字列である cisco99 がマスクされます。
interface Loopback0 description hogehoge********hogehoge
このように、パスワードが平文でコンフィグに書かれている場合にマスクすることを意図した設計のようですが、パスワードが同じ文字列が、description などパスワードと関係ない箇所に現れる場合でもマスクします。
■ 対応案
パスワードと同じ文字列をコンフィグに含めない
パスワード認証を利用する場合は、まずはこれが原則かと思います。
鍵を利用する
冒頭で紹介した issue のコメントでも提案されている方法です。鍵利用した認証に変更することで、そもそもPlaybookや変数でパスワードをしなくなるので上記のような現象は起こらなくなります。
ansible_ssh_pass 変数を利用する
ios_config モジュール内の provider の password オプションでパスワードを指定するのではなく、どこかしらで ansible_ssh_pass で変数で指定するとマスクされません。
Playbook
- hosts: ios gather_facts: no connection: local # 今回は見通しが良いようにPlaybook内に変数定義 vars: ansible_user: cisco ansible_ssh_pass: cisco99 # パスワード tasks: - name: show ios_command: commands: - show run register: result - name: debug debug: msg: "{{ result.stdout_lines[0] }}"
出力結果例(抜粋)
パスワードと同じ文字列である cisco99 がマスクされず、そのまま出力されます。
interface Loopback0 description hogehogecisco99hogehoge
Ansible 2.5 の場合
Ansible 2.5 では network_cli という新しいコネクションタイプの利用が推奨されています。netowrk_cli では、そもそもモジュール内の privider オプションで指定した認証情報は利用せず、ansible_user や ansible_ssh_pass などの変数を利用します。
Playbook
- hosts: ios gather_facts: no connection: network_cli # 今回は見通しが良いようにPlaybook内に変数定義 vars: ansible_user: cisco ansible_ssh_pass: cisco99 # パスワード ansible_network_os: ios # network_cli 固有の変数 tasks: - name: show ios_command: commands: - show run register: result - name: debug debug: msg: "{{ result.stdout_lines[0] }}"
出力結果例(抜粋)
パスワードと同じ文字列である cisco99 がマスクされず、そのまま出力されます。
interface Loopback0 description hogehogecisco99hogehoge
■ まとめ
セキュリティを考慮した設計上の動作ではありますが、状況によっては副作用的な動きとなります。上記であげた対応案が参考になれば幸いです。
なお、本件は 2018/03/24 に参加させていただいた Ansible Workshop #3 2018 Spring で小耳に挟んだ話でした。気になったでので確認してみました。