TPA, Ansible, and sudo

TPAはsudoでAnsibleを使用して、ターゲットインスタンスで昇格した権限でタスクを実行します。このページでは、Ansibleがsudoを使用する方法(TPA固有ではありません)と、TPAで管理されるシステムへの結果について説明します。

TPAにはroot権限が必要です。

  • パッケージをインストールする(オペレーティングシステムのネイティブパッケージマネージャーを使用して必須パッケージ、およびpipを使用してオプションパッケージ)

  • サービスを停止、リロード、および再起動します(Postgres、repmgr、efm、etcd、haproxy、pgbouncerなど)

  • 他のさまざまなタスクを実行するため(例、クラスターファクトの収集、スイッチオーバーの実行、クラスターノードのセットアップ)

TPAもsudoを使用できる必要があります。 ansible_user: root を設定することにより、 rootとして直接sshインすることができますが、 sudoを使用して他のユーザー(postgresなど)としてタスクを実行します。

Ansible sudo呼び出し

Ansibleがsudoを使用してタスクを実行すると、ターゲットインスタンスで次のようなプロセスが表示されます。

/bin/bash -c sudo -H -S -n  -u root /bin/bash -c \
  ""echo BECOME-SUCCESS-kfoodiiprztsyerriqbjuqhhbemejgpc ; \
  /usr/bin/python2"" && sleep 0

sudo yum install -y xyzpkg のようなものを期待していた人は、これに驚くことがよくあります。概して、Ansibleのほとんどのタスクは、認識可能なシェルコマンドを実行するのではなく、Pythonインタープリターを呼び出してPythonコードを実行します。 (プレイブックはraw シェルコマンドを実行できますが、TPAはそのようなタスクを使用して、Pythonインタープリターをブートストラップします。)

Ansibleモジュールには、さまざまな複雑さのPythonコードが含まれており、Ansible Playbookは、YAML形式で記述された単なるシェルスクリプトではありません。任意のAnsible Playbookを実行するのと同じことを行うシェルコマンドを「抽出」する方法はありません。

Ansibleがsudoを使用する方法には、1つの重要な結果があります。privilege escalation must be generalです。つまり、一部の管理者が慣れているように、sudo呼び出しをsudoers.confの特定のコマンドに制限することはできません。ほとんどのタスクはPythonを呼び出すだけです。すべてのコマンドのランダムな文字列がなければ、pythonへのsudoアクセスを制限できた可能性がありますが、Pythonがrootとして実行されると、とにかくできることに効果的な制限はありません。

ターゲットホストでPythonモジュールを実行することは、Ansibleの仕組みです。これは、決してTPAに固有のものではなく、これらの考慮事項は、他のAnsibleプレイブックにも等しく適用されます。

推奨事項

  • SSH公開キーベースの認証を使用して、ターゲットインスタンスにアクセスします。

  • SSHユーザーがパスワードなしでsudoコマンドを実行できるようにします。

  • コマンドではなく、時間でアクセスを制限します。

TPAは、メンテナンスウィンドウなど、クラスターを最初にセットアップする場合、またはtpaexec deploy を再度実行して構成を変更する場合にのみアクセスを必要とします。それまでは、アクセスを完全に無効にできます(sshとsudoの両方に対する1行の変更)。

デプロイ中に、Ansibleが行うことはすべて、プレイブックが何をしているのか、そして提供するパラメーターに基づいて一般的に予測可能であり、各アクションは、ターゲットインスタンスのシステムログと、 tpaexec自分自身が実行されているマシン上のAnsibleログに表示されます。

Ansibleの焦点は、実行できるアクションにきめの細かい制限を課すことではなく、実行時に何をするかを可視化することです。

SSHおよびsudoパスワード

パスワードなしのSSHキー認証とパスワードなしのsudoアクセスを設定することを 強く お勧めしますが、パスワードを使用することもできます。

tpaexecを実行する前に環境でANSIBLE_ASK_PASS=yes とANSIBLE_BECOME_ASK_PASS=yes を設定した場合、Ansibleはリモートサーバーのログインパスワードとsudoパスワードの入力を求めます。次に、リモートサーバーでログイン/ sudoパスワードプロンプトをネゴシエートし、指定したパスワードを送信します(これにより、プレイブックの実行に著しく時間がかかります)。

パスワードの組み合わせを使用してアクセスを制限するよりも、必要ないときに特定のアカウントを介したアクセスを完全に無効にする方がより効果的なセキュリティ制御であると考えているため、この操作モードはお勧めしません。 sshに公開鍵認証を使用すると、サーバーにアクセスできる人を効果的に制御できます。共有パスワードまたは複数の共有パスワードを保護するよりも、承認されたユーザーごとに単一の秘密鍵を保護する方が簡単です。また、 ssh / sudoレベルでアクセスを必要なときに制限すると、メンテナンスウィンドウ中にパスワードによってセキュリティが追加されることはありません。

sudoオプション

sudoでAnsibleを使用するには、 sudoers.confでrequiretty を設定しないでください。

必要に応じて、ansible.cfgの[privilege_escalation] セクションでbecome_flags 、環境のANSIBLE_BECOME_FLAGS 、またはインベントリーのansible_become_flags を設定することにより、Ansibleが使用するsudoオプション(-H -S -n )を変更できます。 3つの方法はすべて同等ですが、特定の必要がある場合にのみsudoオプションを変更してください。デフォルトが選択されたのには正当な理由があります。たとえば、パスワードのないsudoが正しく構成されていない場合、 -S -n を削除するとタスクがタイムアウトします。

ロギング

プレイブックの実行の場合、 sudoログには、ほとんどがPythonの呼び出しが表示されます(誰かがsudo -i を使用したときにbashの呼び出しのみが表示されるのと同じように)。

詳細については、syslogには、ターゲットインスタンスでの各モジュール呼び出しに対する正確な引数が表示されます。そのモジュールが呼び出された理由のより高いレベルのビューについては、コントローラーのansible.logに、そのタスクが何をしようとしていたかと結果が表示されます。

さらに詳細な情報、または監査データの独立したソースが必要な場合は、サーバーでauditdを実行し、SELinuxログファイルを使用できます。 bpftrace/bccから、より詳細なsyscallレベルの情報を取得できます(たとえば、opensnoopはシステムで開かれているすべてのファイルを表示し、execsnoopはシステムで実行されるすべてのプロセスを表示します)。必要に応じて、これらのことのいずれかまたはすべてを行うことができますが、ロギングが増加するとオーバーヘッドが増加するという明らかな警告があります。

ローカル権限

sudoについては、「これらのコマンドをルートとして実行する」の省略形としてのみ言及してください。 TPAをインストールし、 tpaexec setup を実行すると、TPA自分自身にローカルマシンでの昇格した特権は必要ありません。 (ただし、Dockerを使用する場合は、Dockerデーモンへの接続が許可されたグループに属するユーザーとしてtpaexecを実行する必要があります。)