TPA, Ansible, and sudo

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

TPAにはルート権限が必要です。

  • パッケージをインストールします(オペレーティングシステムのネイティブパッケージマネージャーを使用した必須パッケージ、および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コードを実行します。 (Playbookは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がルートとして実行されると、とにかくできることに効果的な制限はありません。

ターゲットホストで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はシステムで実行されているすべてのプロセスを表示します)。必要に応じて、これらのいずれかまたはすべてを実行できますが、ロギングが増加するとオーバーヘッドが増加することは明らかです。

ローカル権限

installation instructions for TPA

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