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


108

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

これまでの研究:

  • StackOverflowの質問 1つの間違った答え(「を使用して-K」)と『私はパスワードなしsudoを必要と分かった』と言っ作者つの応答

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

  • このセキュリティStackExchangeの質問は、読み取りとしてNOPASSWD必要なものです

  • 記事「スケーラブルかつ理解プロビジョニング...」と言います。

    「sudoを実行するには、パスワードを入力する必要があります。これは、Ansibleを永久にブロックする確実な方法です。簡単な修正方法は、ターゲットホストでvisudoを実行し、Ansibleがログインに使用するユーザーがパスワードを入力する必要がないようにすることです」

  • 記事「基本的なAnsible Playbook」

    「Ansibleはルートとしてターゲットサーバーにログインし、sudoの必要性を回避したり、パスワードなしでansibleユーザーにsudoを許可したりすることができますが、いずれにしても、脾臓が食道を跳ね上げてウインドパイプをブロックする恐れがあります。しないで」

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

  • ansible issue#1227、「AnsibleはPlaybookのすべてのユーザーにsudoパスワードを要求する必要があります」。これは1年前にmpdehaanによって閉じられ、「これに対する需要はあまり見られません。ほとんどの場合、ユーザーアカウントまたはキーを使用します。」

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


2
SSHキーを使用しない理由はありますか?
Trondh

22
すでにSSHキーを使用しています。影響はありませんsudo(これにはまだパスワードが必要です)。
supervacuo

1
これはまさにあなたが探しているものではないかもしれませんが、Ubuntuボックスではまだキーを使用しています。つまり、ルートとして直接取得するために/ root / authorized_keysに公開キーを入れます。明らかな欠点は、sshを介したrootログインを許可していることです...また、sshを介したパスワードログインを禁止し、セキュリティを強化するためにfail2banを実行します。
セノスマイル

27
@senorsmileの応答に感謝します!質問を読んでいないことに対してあなたに反対票を投じることができるように、代わりに答えにしてください。
supervacuo

4
すなわちansible_ssh_password設定はSSHパスワードにのみ適用されます(手がかりは名前にあります...)。&私はすでにキーベースのSSHログインを使用しています。
supervacuo

回答:


53

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

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

だから、あなたが探している正確なソリューションを提供することはできませんが、あなたは尋ねました...

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

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

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

大企業でパスワードの再利用について話しましょう。システム管理者に各ノードで異なるパスワードを要求するのは妥当ですか?おそらくいくつかのノードについてですが、私の管理者/エンジニアは、1000ノードで異なるパスワードを使用する必要がある場合、反抗するでしょう。これを実装することもほぼ不可能であるため、各ユーザーは、スプレッドシートではなく、キーパスをどこかに独自のパスワードを保存する必要があります。また、パスワードをプレーンテキストで取り出すことができる場所にパスワードを配置するたびに、セキュリティが大幅に低下します。マシンでsudoにログインしたり、sudoを起動する必要があるたびにキーパスファイルを参照する必要があるよりも、本当に強力な1つまたは2つのパスワードを心から知っている方がはるかに好きです。

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

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

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

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

明らかに、あなたが引用した機能のリクエストが再開/完了した場合、あなたがしたいことは完全にサポートされます。それでも、セキュリティはリスク評価と妥協のプロセスです。ポストイットのメモに頼らずにパスワードを覚えることができるノードが数個しかない場合、個別のパスワードの方がわずかに安全です。しかし、私たちのほとんどにとって、それは実行可能な選択肢ではありません。


おかげで、@ Zeb-数十から数千のサーバーを持つユーザーは、NOPASSWDとにかく健全性の理由で使用すると想像していました(おそらく、より厳しいファイアウォールルールなどによってサポートされています)が、ユースケースと脅威に関する考えを読むのは良いことです型。
supervacuo

16
ただし、「事前承認済み」sudoコマンドに制限することについてのあなたの提案についてのコメントが1つあります(私が発見したとき、それNOPASSWDはかなり必要でした)。残念ながら、これも完全にサポートされていないようです-ansibleはeg chownmkdirバイナリを直接呼び出すことを約束しておらずsudo /bin/sh、ほとんどのモジュールが機能する必要があります。
supervacuo

エンジニアの1人がしばらく前に不満を言っていたのを思い出すようです。
ゼブ14年

36

Ansible 1.5以降では、host_varsおよび他の変数に暗号化されたボールトを使用できます。これにより、少なくともホストごと(またはグループごと)のansible_sudo_pass変数を安全に保存できます。残念ながら、--ask-vault-passansible呼び出しごとに1つのボールトパスワードのみを要求するので、一緒に使用するすべてのホストに対して1つのボールトパスワードに制限されます。

それにも関わらず、暗号化されたhost_varsにアクセスできない攻撃者は、攻撃するマシン(またはマシングループ)ごとに個別のsudoパスワードを必要とするため、一部の用途では、これは複数のホストで単一のsudoパスワードを使用するよりも改善される場合があります。


3
このansible_sudo_passオプションも新しいようです—そして私が求めていたものを実行するようです。単一のボールトパスワードは、私の目的にも理想的です。ありがとう!
supervacuo

この方法を使用してすべて 暗号化を回避する方法はありhost_varsますか?(潜在的な制限はアレックスデュプイによって指摘されました)
supervacuo

1
@supervacuo -すべてのホストVARSを暗号化することを避けるために、ちょうどmain.yml(暗号化されていない)とsecret.yml(暗号化)を含むホストvarディレクトリを使用する-の最後の部分を参照このdocセクション同じ技術-それは「ローリー」グループを語りますホスト変数およびグループ変数で機能します。私はこれを頻繁に使用しますが、唯一のバリエーションは、シークレットが一部のプレイブックにのみ必要な場合、それを別のツリーに完全に保存し、ホストまたは変数名を含むパスを介して含めると便利です。
-RichVel

1
Vaultで「ansible_ssh_pass」値を暗号化した場合、「ansible_sudo_pass」値も複製する必要がありますか?2番目のsudo_pass値が最初の 'ssh_pass'値を参照する方法はありますか?
emeraldjava

ボールトパスワードの使用に関する
適切な説明は、

22

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

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

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

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

  • これansible_sudo_pass:により、暗号化セキュリティのイプシロン増加のために、ファイルにパスワードのみが保存されます(既知のプレーンテキストはありません)。さらに重要なことは、他のすべてのホスト固有の変数を暗号化していないことを意味するため、ボールトパスワードなしで読み取ることができます。

  • パスワードを別のディレクトリに置くと、ファイルをソース管理から遠ざけたり、git-cryptなどのツールを使用して暗号化された形式で保存したりすることが容易になります(vault機能のない以前のAnsibleで使用できます)。私はgit-cryptを使用し、暗号化されたファイルシステムで暗号化されていない形式でリポジトリをチェックアウトするだけなので、vaultに煩わされず、vaultパスワードを入力する必要はありません。(もちろん、両方を使用する方が安全です。)

ansible_ssh_passでルックアップ関数を使用することもできます。これは、ansible_sudo_passを持たない以前のバージョンのAnsibleでも可能です


2
私はついに(!ありがとう)これを試しに周りましたが、それはなしで動作する方法を見ることができませんgit-crypt。私が見る限り。Ansible lookup暗号化されたボールトでの使用をまだサポートしていないようです。passwordモジュールのドキュメントは暗号化されたストレージのためのいくつかのように、まだ文書化されていないサポートがあると言うが、私は詳細を見つけるためには至っていません。手がかりはありますか?
supervacuo

19

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

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

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

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


3

それにもかかわらず、これは非常に古いスレッドです。

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

これは非常にきれいに見えます、ありがとう—パスワードを2か所に保存する必要がないというアイデアが好きです。現時点では私は(GNOMEキーリングは非常に移植思われないので)おそらく私が作ることができKeepassXを使用してこだわってpython-keepass仕事を?
supervacuo

私の知る限り、python-keyringはこれを抽象化したものであるため、同僚は他のOSを使用できます。または、keepassx dbをUSBスティックに保存し、異なるOSのワークステーションから管理する必要がありますか?
ミルコフリーデンハーゲン

理解した; 私は、GNOME以外のシステムでパスワードにアクセスするには、すでにKeepassXを使用する必要があることを意味していたので、それらを保存するとgnome-keyring重複レコードを保持することになります。それでも道よりよい使用するよりもNOPASSWD、しかし...
supervacuoを

0

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

例えば

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

その後、芝居では、次を使用してsudoパスワードを検索できます。

lookup('env', 'pass1') 
lookup('env', 'pass2') 
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.