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コードを実行します。
Playbookは\ ``raw``
シェルコマンドを実行できますが、TPAはそのようなタスクをPythonインタープリターをブートストラップするためにのみ使用します。

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

Ansibleがsudoを使用する方法の1つの重要な結果は、 `privilege escalation must be general <https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_privilege_escalation.html#privilege-escalation-must-be-general>`_ 
です。一部の管理者が慣れているように、\ ``sudoers.conf``
ではsudo呼び出しを特定のコマンドに制限することはできません。ほとんどのタスクは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パスワードを入力するように求めます。次に、リモートサーバーでlogin/sudoパスワードプロンプトをネゴシエートし、指定したパスワードを送信します。これにより、Playbookの実行時間が著しく長くなります。

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

sudoオプション
--------------

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

必要に応じて、次のいずれかを設定して、Ansibleが使用するsudoオプション\ ``-H -S -n``
を変更できます。

-  ``ansible.cfg`` の\ ``[privilege_escalation]``
   セクションの\ ``become_flags``

-  環境内の\ ``ANSIBLE_BECOME_FLAGS``

-  インベントリの\ ``ansible_become_flags``

3つの方法はすべて同等ですが、特定の必要がある場合にのみsudoオプションを変更します。デフォルトが選択されたのには十分な理由があります。たとえば、パスワードなしのsudoが誤って構成されている場合、\ ``-S -n``
を削除するとタスクがタイムアウトします。

ロギング
--------

Playbookの実行の場合、sudoログは、 ``sudo -i``
が使用される場合にbashの呼び出しのみを表示するのと同様に、ほとんどのPythonの呼び出しを示します。

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

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

ローカル権限
------------

 :ref:`installation instructions for TPA <TPA installation>` 

sudoは、「何らかの形でrootとしてこれらのコマンドを実行します。」の短縮形としてのみ言及しています。
TPAがインストールされ、\ ``tpaexec setup``
を実行すると、TPAはローカルマシンで昇格した特権を必要としません。ただし、Dockerを使用する場合、Dockerデーモンに接続する権限を持つUnixグループに属するユーザーとしてtpaexecを実行する必要があります。
