従来、一般的なアプリケーションは次のコンポーネントで構成されています。
この単純なケースでは、基本的な設定で十分です。
- アプリケーションは、ユーザーに対して単純なローカル認証メカニズムを使用します
- アプリケーションは単純な接続プールを使用します
- データベースアクセス用に定義された単一のユーザーがあります
ただし、組織が進化し、大きくなるにつれて、より多くのコンポーネントが追加されます。
- データベースにアクセスするより多くのテナントアプリまたはアプリのインスタンス
- データベースにアクセスするその他のサービスとシステム
- すべての(またはほとんどの)サービスの中央認証/承認(AA)
- 将来のスケーリングを容易にするためのコンポーネントの分離
上記のスキームでは、すべての懸念事項が個々のコンポーネントに分けられ、各コンポーネントは特殊な目的を果たします。ただし、接続プールは、上記で見た以前のより単純なセットアップのように、単一の専用データベースユーザーを使用します。
新しいコンポーネントに加えて、新しい要件もあります:
- データベースレベルでユーザーが実行できることをよりきめ細かく制御する
- 監査
- より便利なシステムロギング
より多くのアプリケーションコードまたはより多くのレイヤーをアプリケーションに追加することで、3つすべてをいつでも実装できますが、これは面倒で保守が困難です。
さらに、PostgreSQLは、前述の領域(セキュリティ、行レベルのセキュリティ、監査など)で非常に豊富なソリューションのセットを提供するため、これらすべてのサービスをデータベース層に移動することは完全に理にかなっています。これらのサービスをデータベースから直接取得するには、データベース内の1人のユーザーを忘れて、代わりに実際の個々のユーザーを使用する必要があります。
これにより、次のようなスキームになります。
私たちのユースケースでは、私たちが使用する上記のスキームで構成される典型的なエンタープライズセットアップについて説明します。
- Wildflyアプリサーバー(バージョン10の例を示しています)
- LDAP認証/承認サービス
- pgbouncer接続プール
- PostgreSQL 10
jboss / wildflyがLDAP認証と承認を長年サポートしているため、PostgreSQLはLDAPを長年サポートしているため、これは典型的な設定のようです。
ただし、pgbouncerは2017年後半のバージョン1.8以降にのみLDAP(およびこれはPAM経由)のサポートを開始しました。つまり、それまでの誰かは、そのようなエンタープライズセットアップで最もホットなPostgreSQL接続プールを使用できませんでした(これは、私たちが選択したどの角度から見ても有望ではありませんでした)見てください)!
このブログでは、各レイヤーで必要なセットアップについて説明します。
Wildfly10の設定
データソースの構成は次のようになります。最も重要なものを示しています:
<xa-datasource jndi-name="java:/pgsql" pool-name="pgsqlDS" enabled="true" mcp="org.jboss.jca.core.connectionmanager.pool.mcp.LeakDumperManagedConnectionPool">
<xa-datasource-property name="DatabaseName">
yourdbname
</xa-datasource-property>
<xa-datasource-property name="PortNumber">
6432
</xa-datasource-property>
<xa-datasource-property name="ServerName">
your.pgbouncer.server
</xa-datasource-property>
<xa-datasource-property name="PrepareThreshold">
0
</xa-datasource-property>
<xa-datasource-class>org.postgresql.xa.PGXADataSource</xa-datasource-class>
<driver>postgresql-9.4.1212.jar</driver>
<new-connection-sql>
SET application_name to 'myapp';
</new-connection-sql>
<xa-pool>
<max-pool-size>400</max-pool-size>
<allow-multiple-users>true</allow-multiple-users>
</xa-pool>
<security>
<security-domain>postgresqluser</security-domain>
</security>
</xa-datasource>
重要なパラメータと値を太字で示しています。 pgbouncerサーバーの設定に従って、IPアドレス(またはホスト名)、データベース名、およびポートを定義することを忘れないでください。
また、通常のユーザー名/パスワードの代わりに、セキュリティドメインを定義する必要があります。これは、上記のようにデータソースセクションで指定する必要があります。その定義は次のようになります:
<security-domain name="postgresqluser">
<authentication>
<login-module code="org.picketbox.datasource.security.CallerIdentityLoginModule" flag="required">
<module-option name="managedConnectionFactoryName" value="name=pgsql,jboss.jca:service=XATxCM"/>
</login-module>
</authentication>
</security-domain>
このようにして、wildflyはセキュリティコンテキストをpgbouncerに委任します。
注: このブログでは、基本事項について説明します。つまり、TLSについては使用も言及もしませんが、インストールで使用することを強くお勧めします。
Wildflyユーザーは、次のようにLDAPサーバーに対して認証する必要があります。
<login-module code="<your login module class>" flag="sufficient">
<module-option name="java.naming.provider.url" value="ldap://your.ldap.server/"/>
<module-option name="java.naming.security.authentication" value="simple"/>
<module-option name="java.naming.factory.initial" value="com.sun.jndi.ldap.LdapCtxFactory"/>
<module-option name="principalDNPrefix" value="uid="/>
<module-option name="uidAttributeID" value="memberOf"/>
<module-option name="roleNameAttributeID" value="cn"/>
<module-option name="roleAttributeID" value="memberOf"/>
<module-option name="principalDNSuffix"
value=",cn=users,cn=accounts,dc=yourorgname,dc=com"/>
<module-option name="userSrchBase" value="dc=yourorgname,dc=com"/>
<module-option name="rolesCtxDN"
value="cn=groups,cn=accounts,dc=yourorgname,dc=com"/>
<module-option name="matchOnUserDN" value="true"/>
<module-option name="unauthendicatedIdentity" value="foousr"/>
<module-option name="com.sun.jndi.ldap.connect.timeout" value="5000"/>
</login-module>
上記の設定ファイルはwildfly10.0に適用されます。いずれの場合も、ご使用の環境の公式ドキュメントを参照することをお勧めします。
PostgreSQLの構成
PostgreSQLに認証を指示するため(注: LDAPサーバーに対して、postgresql.confとpg_hba.confに適切な変更を加える必要があります。関心のあるエントリは次のとおりです。
postgresql.conf内:
listen_addresses = '*'
およびpg_hba.conf:
#TYPE DATABASE USER CIDR-ADDRESS METHOD
host all all ip.ofYourPgbouncer.server/32 ldap ldapserver=your.ldap.server ldapprefix="uid=" ldapsuffix=",cn=users,cn=accounts,dc=yourorgname,dc=com"
ここで定義したLDAP設定が、アプリサーバー構成で定義したものと完全に一致していることを確認してください。 LDAPサーバーに接続するようにPostgreSQLに指示できる操作モードは2つあります。
- シンプルバインド
- 検索してバインド
単純なバインドモードでは、LDAPサーバーへの接続が1つだけ必要なため、高速ですが、2番目のモードよりも何らかの方法で厳密なLDAPディクショナリ構成が必要です。検索およびバインドモードにより、柔軟性が向上します。ただし、平均的なLDAPディレクトリの場合、最初のモード(単純なバインド)は問題なく機能します。 PostgreSQLLDAP認証に関する特定のポイントに下線を引く必要があります。
- これは認証のみと関係があります (パスワードの確認)。
- ロールメンバーシップは、通常どおりPostgreSQLで引き続き実行されます。
- ユーザーは通常どおり(CREATE user / roleを介して)PostgreSQLで作成する必要があります。
LDAPユーザーとPostgreSQLユーザー間の同期を支援するソリューションがいくつかあります(例:ldap2pg)。または、ユーザーを追加または削除するためにLDAPとPostgreSQLの両方を処理する独自のラッパーを作成することもできます。
今日のホワイトペーパーをダウンロードするClusterControlを使用したPostgreSQLの管理と自動化PostgreSQLの導入、監視、管理、スケーリングを行うために知っておくべきことについて学ぶホワイトペーパーをダウンロードするPgBouncerの構成
ネイティブLDAPサポートがまだpgbouncerにないため、これはセットアップの最も難しい部分です。唯一のオプションはPAMを介して認証することです。つまり、これはLDAPの正しいローカルUNIX /LinuxPAMセットアップに依存します。
したがって、手順は2つのステップに分かれています。
最初のステップは、pgbouncerがPAMと連携するように構成およびテストすることであり、2番目のステップは、LDAPと連携するようにPAMを構成することです。
pgbouncer
pgbouncerはPAMサポートを使用してコンパイルする必要があります。そのためには、次のことを行う必要があります。
- libpam0g-devをインストールします
- ./ configure --with-pam
- pgbouncerを再コンパイルしてインストールします
pgbouncer.ini(またはpgbouncer構成ファイルの名前)は、pam用に構成する必要があります。また、上記のセクションで説明したパラメータに従って、データベースとアプリケーションの正しいパラメータが含まれている必要があります。定義または変更する必要があるもの:
yourdbname = host=your.pgsql.server dbname=yourdbname pool_size=5
listen_addr = *
auth_type = pam
# set pool_mode for max performance
pool_mode = transaction
# required for JDBC
ignore_startup_parameters = extra_float_digits
もちろん、pgbouncerのドキュメントを読み、必要に応じてpgbouncerを調整する必要があります。上記の設定をテストするには、新しいローカルUNIXユーザーを作成し、pgbouncerへの認証を試みるだけです。
# adduser testuser
<answer to all question, including password>
ローカルpasswdファイルから読み取るときにpgbouncerがPAMと連携するには、pgbouncer実行可能ファイルがrootとsetuidによって所有されている必要があります。
# chown root:staff ~pgbouncer/pgbouncer-1.9.0/pgbouncer
# chmod +s ~pgbouncer/pgbouncer-1.9.0/pgbouncer
# ls -l ~pgbouncer/pgbouncer-1.9.0/pgbouncer
-rwsrwsr-x 1 root staff 1672184 Dec 21 16:28 /home/pgbouncer/pgbouncer-1.9.0/pgbouncer
注:ルートの所有権とsetuidの必要性(これは私がテストしたすべてのdebian / ubuntuシステムに当てはまります)は、公式のpgbouncerドキュメントでもネット上のどこでも文書化されていません。
次に、(pgsqlスーパーユーザーとして)postgresqlホスト(またはpsql -h your.pgsql.server)にログインし、新しいユーザーを作成します。
CREATE USER testuser PASSWORD 'same as the UNIX passwd you gave above';
次に、pgbouncerホストから:
psql -h localhost -p 6432 yourdbname -U testuser
データベースサーバーに直接接続しているかのように、プロンプトが表示され、テーブルが表示されるはずです。このユーザーをシステムから削除し、すべてのテストが終了したらデータベースから削除することを忘れないでください。
PAM
PAMがLDAPサーバーとインターフェイスするためには、追加のパッケージlibpam-ldapが必要です。インストール後のスクリプトは、LDAPサーバーの正しいパラメーターで応答する必要があるテキストモードダイアログを実行します。このパッケージは、/ etc / pam.dファイルに必要な更新を行い、/ etc/pam_ldap.confという名前のファイルも作成します。将来何かが変更された場合は、いつでも戻ってこのファイルを編集できます。このファイルの最も重要な行は次のとおりです。
base cn=users,cn=accounts,dc=yourorgname,dc=com
uri ldap://your.ldap.server/
ldap_version 3
pam_password crypt
LDAPサーバーと検索ベースの名前/アドレスは、上記で説明したPostgreSQLpg_hba.confおよびWildflystandalone.xmlconfファイルで指定されているものと完全に同じである必要があります。 pam_login_attributeのデフォルトはuidです。 /etc/pam.d/common-*ファイルを調べて、libpam-ldapのインストール後に何が変更されたかを確認することをお勧めします。ドキュメントに従って、/ etc / pam.d / pgbouncerという名前の新しいファイルを作成し、そこですべてのPAMオプションを定義できますが、デフォルトのcommon-*ファイルで十分です。 /etc/pam.d/common-authを見てみましょう:
auth [success=2 default=ignore] pam_unix.so nullok_secure
auth [success=1 default=ignore] pam_ldap.so use_first_pass
auth requisite pam_deny.so
auth required pam_permit.so
Unix passwdが最初にチェックされ、これが失敗した場合はLDAPがチェックされるため、ローカルlinux / unix / etc/passwdとLDAPの両方に定義されているユーザーのローカルパスワードを消去する必要があることに注意してください。 。次に、最終テストを行います。 LDAPサーバーで定義され、PostgreSQLでも作成されているユーザーを選択し、DBから(pgsql -h your.pgsql.serverを介して)、次にpgbouncerから(psql -h your.pgbouncer.serverを介して)認証を試みます。 、そして最後にあなたのアプリを介して。アプリ、接続プール、PostgreSQL用の単一のセキュリティシステムを実現しました!