web-dev-qa-db-ja.com

ホストごとのパスワードでansibleを安全に実装するにはどうすればよいですか?

既存のサーバーのグループを管理するために ansible を使用したいと思います。 ansible_hostsファイルを作成し、単一のホストのみを対象とするコマンドで(-Kオプションを使用して)正常にテストしました

ansible -i ansible_hosts Host1 --Sudo -K # + commands ...

私の問題は、各ホストのユーザーパスワードが異なることですが、Ansibleでこれを処理する方法を見つけることができません。

-Kを使用すると、単一のSudoパスワードを事前に入力するように求められるだけで、それ以降のすべてのホストに対してプロンプトを表示せずに試行されるようです。

Host1 | ...
Host2 | FAILED => Incorrect Sudo password
Host3 | FAILED => Incorrect Sudo password
Host4 | FAILED => Incorrect Sudo password
Host5 | FAILED => Incorrect Sudo password

これまでの研究:

  • a StackOverflow質問 不正解1つ( "use -K")と作成者による "パスワードなしのSudoが必要であることがわかりました"という1つの応答

  • Ansible docs 、「パスワードなしのSudoを使用すると、自動化が容易になりますが、必須ではありません。」 (強調鉱山)

  • このセキュリティStackExchangeの質問 は、NOPASSWDが必要であることを読み取りと見なします

  • 記事 "スケーラブルで理解可能なプロビジョニング..." とは、

    "Sudoを実行するには、パスワードの入力が必要になる場合があります。これは、Ansibleを永久にブロックする確実な方法です。ターゲットホストでvisudoを実行し、ユーザーAnsibleがログインに使用することを確認してください。パスワードを入力する必要はありません」

  • 記事 "Basic Ansible Playbooks"

    "Ansibleはターゲットサーバーにrootとしてログインし、Sudoの必要性を回避するか、AnsibleユーザーにパスワードなしでSudoを許可することができますが、そうすると、脾臓がガレットを跳び上がらせる恐れがあります私の気管をふさぐので、私はしません」

    私の考えは正確ですが、単一のサーバーを超えて拡張する方法は?

  • ansible issue#1227 、「Ansibleはプレイブックのすべてのユーザーに対してSudoパスワードを要求するべきである」、これはmpdehaanによって「これに対する多くの需要は見られなかったと思います。ほとんどの人は、ほとんどの場合、1つのユーザーアカウントからのみ、またはキーを使用してsudoingしています。」

では、このような状況でAnsibleをどのように使用していますか? /etc/sudoersNOPASSWDを設定し、ホスト間でパスワードを再利用するか、ルートSSHログインを有効にすると、セキュリティが大幅に低下するように見えます。

110
supervacuo

あなたは確かにあなたの研究をしました...

Ansibleでの私のすべての経験から、あなたが達成しようとしていることはサポートされていません。あなたが言ったように、ansibleはパスワードなしのSudoを必要としないと述べています、そしてあなたは正しいです、それはそうではありません。しかし、もちろん複数の設定を実行せずに、ansible内で複数のSudoパスワードを使用する方法はまだ見ていません。

だから、私はあなたが探している正確な解決策を提供することはできませんが、あなたは尋ねました...

「このような状況でAnsibleをどのように使用しているのですか?/ etc/sudoersでNOPASSWDを設定する、ホスト間でパスワードを再利用する、またはルートSSHログインを有効にすることはすべて、セキュリティが大幅に低下するように見えます。」

私はあなたにそれについて一つの見解を与えることができます。私のユースケースは、グローバルSaaS会社をサポートする複数のデータセンターの1kノードであり、この会社では、ビジネスの性質上、非常に厳格なセキュリティ管理を設計/実装する必要があります。セキュリティは常にバランスの取れた行為です、ユーザビリティが高まり、セキュリティが低下します。このプロセスは、10台のサーバーまたは1,000台または100,000台を実行している場合も変わりません。

パスワードまたはsshキーを介してrootログインを使用しないことが絶対に正しいです。実際、サーバーにネットワークケーブルが接続されている場合は、ルートログインを完全に無効にする必要があります。

大企業で、パスワードの再利用について話しましょう。システム管理者に各ノードで異なるパスワードを要求するのは理にかなっていますか?おそらく2、3のノードですが、私の管理者/エンジニアは、1000のノードで異なるパスワードを使用する必要がある場合、反乱を起こします。それを実現することもほぼ不可能ですが、各ユーザーは独自のパスワードを、スプレッドシートではなくキーパスに格納する必要があります。また、パスワードをプレーンテキストで引き出せる場所に置くたびに、セキュリティが大幅に低下します。マシン上でSudoにログインしたり、Sudoを起動したりするたびにキーパスファイルを調べる必要がなく、基本的には1つまたは2つの本当に強力なパスワードを知っているほうがいいです。

したがって、パスワードの再利用と標準化は、安全な環境でも完全に受け入れ可能で標準的なものです。それ以外の場合は、ldap、keystone、およびその他のディレクトリサービスが存在する必要はありません。

自動化されたユーザーに移行すると、sshキーはうまく機能しますが、それでもSudoを通過する必要があります。選択肢は、自動化されたユーザー用の標準化されたパスワード(多くの場合は許容されます)、または指摘したようにNOPASSWDを有効にするためのものです。ほとんどの自動化されたユーザーは、いくつかのコマンドを実行するだけなので、NOPASSWDを有効にすることは非常に可能であり、確かに望ましいですが、事前に承認されたコマンドに対してのみです。パスワードなしのコマンドリストを簡単に更新できるように、構成管理(この場合は可)を使用してsudoersファイルを管理することをお勧めします。

さて、リスクをさらに分離するためにスケーリングを開始した後に実行できるいくつかのステップがあります。 1000ほどのノードがありますが、すべてが「本番」サーバーではなく、一部はテスト環境などです。すべての管理者が本番サーバーにアクセスできるわけではなく、他の場所と同じように同じSSOユーザー/パス|キーを使用できます。ただし、自動化されたユーザーは少し安全です。たとえば、非運用管理者がアクセスできる自動化ツールには、運用環境では使用できないユーザーと資格情報があります。すべてのノードでansibleを起動する場合は、2つのバッチで実行する必要があります。1つは非実稼働用、もう1つは実稼働用です。

ただし、puppetも使用します。これは、強制的な構成管理ツールであるため、すべての環境に対するほとんどの変更が、pushpetを通じてプッシュされるためです。

明らかに、あなたが引用したその機能要求が再開されたり完了したりした場合、あなたがしようとしていることは完全にサポートされます。それでも、セキュリティはリスク評価と妥協のプロセスです。付箋に頼らずにパスワードを覚えることができるノードが数個しかない場合は、個別のパスワードの方が少し安全です。しかし、私たちのほとんどにとって、それは実行可能なオプションではありません。

55
Zeb

Ansible 1.5以降では、Host_varおよびその他の変数に 暗号化されたボールト を使用できます。これにより、少なくともホスト(またはグループ)ごとのansible_Sudo_pass変数を安全に。残念ながら、--ask-vault-passは、ansible呼び出しごとに単一のボールトパスワードの入力を要求するだけなので、一緒に使用するすべてのホストの単一のボールトパスワードに制限されます。

それでも、一部の用途では、暗号化されたHost_varsにアクセスできない攻撃者が攻撃するすべてのマシン(またはマシングループ)に個別のSudoパスワードを必要とするため、これは複数のホストに単一のSudoパスワードを設定するよりも改善される可能性があります。

37
Daniel Neades

Ansible 1.5では、lookup('password', …)を使用してansible_Sudo_pass変数を設定できます。

ansible_Sudo_pass: "{{ lookup('password', 'passwords/' + inventory_hostname) }}"

これは、いくつかの理由でHost_vars/のファイルを使用するよりも便利だと思います。

  • 私は実際にwith_password: "passwords/{{ inventory_hostname}} encrypt=sha256_crypt"を使用してdeployリモートユーザーのパスワードをプロビジョニングします(これはSudoに必要です)ので、すでに存在していますファイル内(ただし、これらの平文検索を行うと、ハッシュ値が生成されるときにファイルに保存されているソルト値が失われます)。

  • これにより、暗号化セキュリティがいくらか向上するため、ファイルにパスワードだけが保持されます(ansible_Sudo_pass:既知のプレーンテキストなし)。さらに重要なことは、他のすべてのホスト固有の変数を暗号化していないため、ボールトのパスワードなしでそれらを読み取ることができるということです。

  • パスワードを別のディレクトリに配置すると、ファイルをソース管理の外に置いたり、 git-crypt のようなツールを使用して暗号化した形式で保存したりすることが簡単になります(これを以前のAnsibleで使用できます)ボールト機能が不足しています)。私はgit-cryptを使用しており、暗号化されたファイルシステムでは復号化された形式でリポジトリをチェックアウトするだけなので、ボールトを気にする必要がなく、ボールトのパスワードを入力する必要はありません。 (もちろん、両方を使用する方が安全です。)

lookup関数をansible_ssh_passとともに使用することもできます。これはansible_Sudo_passを持たない以前のバージョンのAnsibleでも可能です。

23
Alex Dupuy

pass の使用は、sudoパスワードを使用してansibleを提供する簡単な方法です。 passは、ファイルごとに1つのパスワードを格納します。これにより、gitまたはその他の方法でパスワードを簡単に共有できます。また、(GnuPGを使用して)安全であり、gpg-agentを使用している場合は、使用するたびにパスワードを入力せずにansibleを使用できます。

サーバーfooservers/fooとして保存されているパスワードをansibleに提供するには、次のようなインベントリファイルで使用します。

[servers]
foo ansible_Sudo=True \
    ansible_Sudo_pass="{{ lookup('pipe', 'pass servers/foo') }}"

以前にgpg-agentのキーのロックを解除した場合、これはパスワードを入力する必要なしにansibleで実行されます。


更新:現在、Ansibleには passwordstoreプラグイン を通じてこの機能が組み込まれています。上記と同等のものは次のとおりです。

[servers]
foo ansible_Sudo=True \
    ansible_Sudo_pass="{{ lookup('passwordstore', 'servers/foo') }}"

パスワードがまだない場合は作成することも可能で、非常に便利です。

21
fqxp

これはかなり古いスレッドですが、それでも:

  • 私たちは社内で2つの異なる認証システムを使用しており、マシンの管理は私のチームのローカルワークステーションから行われます。
  • vars_plugin for Ansible(いくつかの認証システムを区別するかなり完全な実装が https://Gist.github.com/mfriedenhagen/e488235d732b7becda81 にあります):
  • 認証システムの名前はグループ固有です。
  • 使用されるログイン/ Sudoユーザーは、グループおよび管理者固有です。
  • したがって、管理者の環境からユーザーをプルし、python-keyringライブラリを介して、対応するパスワードをパスワードセーフから取得します(Mac OS Xのキーチェーンを使用しますが、kwallet Gnomeおよび_win_cryptoのドキュメントもサポートされています)。
  • Mac OS Xのキーチェーンでパスワードにアクセス許可を設定して、コマンドラインプログラムのセキュリティがホストが使用するすべての認証システムのパスワードへのアクセスを要求していることを通知するため、「ansible -s all -m ping」を実行します。 2つのプロンプト(認証システムごとに1つ)が表示されます。ここでスペースバーを押すと、ansibleがパスワードを取得します。
3

ここで遅くなる人:c.f. https://stackoverflow.com/a/37002802

Per Host, in your inventory hosts file (inventory/<inventoryname>/hosts)
[server]
10.0.0.0 ansible_Sudo_pass=foobar

Per group, in your inventory groups file (inventory/<inventoryname>/groups)
[server:vars]
ansible_Sudo_pass=foobar

Per group, in group vars (group_vars/<groupname>/ansible.yml) and encrypted (ansible-vault create group_vars/<groupname>/ansible.yml)
ansible_Sudo_pass: "foobar"
0
gen.st4ck

これを行う1つの可能な方法は、環境変数を使用することです。

例えば.

pass1=foo pass2=bar ansible-playbook -i production servers.xml

次に、演劇で、次を使用してSudoパスワードを検索できます。

lookup('env', 'pass1') 
lookup('env', 'pass2') 
0
Paul Calabro

これは完全に可能です。パスワードなどの変数を使用するようにインベントリを定義できます。

在庫:

[023_mqtt]
023-softbank-mqtt01 ansible_Host=IP.IP.IP.IP ansible_ssh_private_key_file=/path/to/my_key ansible_ssh_user=my_user ansible_become=yes ansible_become_method=Sudo ansible_become_pass='{{ my_user_pass }}'

ジャンプサーバーを使用している場合(必要な場合)、在庫があるgroup_vars/023_mqtt.yamlファイルが必要です。

ansible_ssh_common_args: '-o ProxyCommand="ssh -i /path/to/your/jump_key -W %h:%p -q [email protected]"'

最後に、ボールトを定義してパスワードを保存します。インベントリファイルと同じフォルダ内に作成することをお勧めします。

ansible-vault create passwds.yaml
[enter a vault pass]

パスワードを追加します。

my_user : 'my_user's Sudo password'

これを実行するには、追加の変数としてボールトを渡します。

 ansible -a "docker ps" -i /path/to/hosts hosts_group --ask-vault-pass --extra-vars '@passwd.yaml'

これを複数のホストに対して定義しました。各ホストには、独自のSSHキー、SSHパスフレーズ、SSH Sudoパスワードがあり、正常に機能します。完全な記事については、私のgitをチェックしてください:

https://github.com/flow0787/ansible/blob/master/README.md

0
Florin