

# Babelfish で Active Directory セキュリティグループを使用して Kerberos 認証を設定する
<a name="babelfish-kerberos-securityad"></a>

Babelfish バージョン 4.2.0 以降では、Active Directory セキュリティグループを使用して Babelfish の kerberos 認証を設定できます。Active Directory を使用して kerberos 認証の設定を完了するための前提条件は次のとおりです。
+  「[Babelfish を使用した Kerberos 認証](babelfish-active-directory.md)」に記載されているすべてのステップに従う必要があります。
+ DB インスタンスが Active Directory に関連付けられていることを確認します。これを確認するために、コンソールで、または [https://docs.aws.amazon.com/cli/latest/reference/rds/describe-db-instances.html](https://docs.aws.amazon.com/cli/latest/reference/rds/describe-db-instances.html) AWS CLI コマンドを実行して、ドメインメンバーシップのステータスを表示できます。

  DB インスタンスのステータスは kerberos 対応である必要があります。ドメインメンバーシップの理解についての詳細は、「[ドメインのメンバーシップを理解する](postgresql-kerberos-managing.md#postgresql-kerberos-managing.understanding)」を参照してください。
+ NetBIOS ドメイン名と DNS ドメイン名の間のマッピングを確認するには、次のクエリを使用します。

  ```
  SELECT netbios_domain_name, fq_domain_name FROM babelfish_domain_mapping;
  ```
+ 先に進む前に、個々のログインを使用した Kerberos 認証が期待どおりに機能することを確認します。Active Directory ユーザーとして Kerberos 認証を使用する接続は成功する必要があります。問題が発生した場合は、「[頻繁に発生するエラー](babelfish-active-directory.md#babelfish-active-directory-errors)」を参照してください。

## pg\$1ad\$1mapping 拡張機能のセットアップ
<a name="babelfish-kerberos-securityad-setpgextn"></a>

 「[pg\$1ad\$1mapping 拡張機能のセットアップ](AD.Security.Groups.md#AD.Security.Groups.Setup)」に記載されているすべてのステップに従う必要があります。拡張機能がインストールされていることを確認するには、TDS エンドポイントから次のクエリを実行します。

```
1> SELECT extname, extversion FROM pg_extension where extname like 'pg_ad_mapping';
2> GO
extname       extversion
------------- ----------
pg_ad_mapping 0.1

(1 rows affected)
```

## グループログインの管理
<a name="babelfish-kerberos-securityad-managing"></a>

 「[ログインの管理](babelfish-active-directory.md#babelfish-active-directory-login-managing)」に記載されている手順に従って、グループログインを作成します。メンテナンスを容易にするために、ログイン名は Active Directory (AD) セキュリティグループ名と同じにすることをお勧めしますが、必須ではありません。例えば、次のようになります。

```
CREATE LOGIN [corp\accounts-group] FROM WINDOWS [WITH DEFAULT_DATABASE=database]
```

# T-SQL グループログインと AD セキュリティグループのマッピング
<a name="babelfish-kerberos-securityad-maptsql"></a>

 データベースサーバーへのアクセスを必要とする AD セキュリティグループごとに、T-SQL Windows グループログインを明示的にプロビジョニングする必要があります。少なくとも 1 つのプロビジョニングされた AD セキュリティグループに属する AD ユーザーは、データベースサーバーにアクセスできます。

**注記**  
この T-SQL ログインは、パスワードベースの認証を使用して認証できなくなります。

 例えば、accounts-group は AD のセキュリティグループであり、このセキュリティグループを Babelfish でプロビジョニングする場合は、[corp\$1accounts-group] の形式を使用する必要があります。
+ AD セキュリティグループ: accounts-group
+ TSQL ログイン: [corp\$1accounts-group]
+ 特定の TSQL ログインの同等の PG ロール: accounts-group@CORP.EXAMPLE.COM

 管理者は、次の psql コマンドを使用して、PostgreSQL エンドポイントから AD セキュリティグループと T-SQL ログイン間のマッピングを作成できるようになりました。関数の使用についての詳細は、「[`pg_ad_mapping` 拡張機能の関数の使用](AD.Security.Groups.md#AD.Security.Groups.functions)」を参照してください。

**注記**  
T-SQL ログインは、マッピングを追加するときに login\$1name@FQDN 形式で指定する必要があります。TDS エンドポイント経由で接続する場合、重みは無視されます。重み付けの使用の詳細については、「[PostgreSQL ポートの PostgreSQL エンドポイント経由で Babelfish に接続する](babelfish-kerberos-securityad-connect-pgendpoint.md)」を参照してください。

```
postgres=>select pgadmap_set_mapping('accounts-group', 'accounts-group@CORP.EXAMPLE.COM', <SID>, <Weight>);
```

AD セキュリティグループの SID の取得については、「[PowerShell での Active Directory グループ SID の取得](AD.Security.Groups.md#AD.Security.Groups.retrieving)」を参照してください。

次の表は、AD セキュリティグループから T-SQL ログインへのマッピングの例を示しています。


| AD セキュリティグループ | TSQL ログイン | 特定の TSQL ログインと同等の PG ロール | Weight | 
| --- | --- | --- | --- | 
| accounts-group | [corp\$1accounts-group] | accounts-group@CORP.EXAMPLE.COM | 7 | 
| sales-group | [corp\$1sales-group] | sales-group@CORP.EXAMPLE.COM | 10 | 
| dev-group | [corp\$1dev-group] | dev-group@CORP.EXAMPLE.COM | 7 | 

```
postgres=> select admap.ad_sid, admap.ad_grp, lgn.orig_loginname, lgn.rolname, admap.weight from pgadmap_read_mapping() as admap, sys.babelfish_authid_login_ext as lgn where admap.pg_role = lgn.rolname;
    ad_sid    |     ad_grp     |    orig_loginname   |             rolname             | weight
--------------+----------------+---------------------+---------------------------------+--------
 S-1-5-67-890 | accounts-group | corp\accounts-group  | accounts-group@CORP.EXAMPLE.COM |     7
 S-1-2-34-560 | sales-group    | corp\sales-group     | sales-group@CORP.EXAMPLE.COM    |     10
 S-1-8-43-612 | dev-group      | corp\dev-group       | dev-group@CORP.EXAMPLE.COM      |     7
 (7 rows)
```

# TDS エンドポイント経由で Babelfish に接続する
<a name="babelfish-kerberos-securityad-connect"></a>

 次の例では、user1 は accounts-group および sales-group のメンバーであり、user2 は accounts-group および dev-group のメンバーです。


| ユーザー名 | AD セキュリティグループのメンバーシップ | 
| --- | --- | 
| user1 | accounts-group、sales-group | 
| user2 | accounts-group、dev-group | 

 sqlcmd ユーティリティを使用して Babelfish データベースサーバーに接続します。次の例に従って、Kerberos を使用してユーザー (この例では user1) が認証されたかどうかを確認できます。

```
1> select principal, gss_authenticated from pg_stat_gssapi where pid = pg_backend_pid();
2>  GO
principal               gss_authenticated
----------------------  -----------------
user1@CORP.EXAMPLE.COM  1 

((1 rows affected))
1> select suser_name();
2>  GO
suser_name
----------
corp\user1 

(1 rows affected)
```

 この例では、user1 は accounts-group と sales-group の権限を継承します。`sys.login_token` システムビューを使用してグループメンバーシップを確認できます。

```
1> SELECT name, type FROM sys.login_token;
2>  GO
name                type
------------------- ----
corp\accounts-group WINDOWS GROUP
corp\sales-group    WINDOWS GROUP

(2 rows affected)
```

## 監査とログ記録
<a name="babelfish-kerberos-securityad-audit"></a>

 AD セキュリティプリンシパル ID を決定するには、次のコマンドを使用します。

```
1> select suser_name();
2> GO
suser_name
----------
corp\user1

(1 rows affected)
```

現在、AD ユーザー ID はログに表示されません。`log_connections` パラメータを有効にすると、DB セッションの確立をログに記録できます。詳細については、「[log\$1connections](https://docs.aws.amazon.com/prescriptive-guidance/latest/tuning-postgresql-parameters/log-connections.html)」を参照してください。出力には、次の例に示すように、プリンシパルとして AD ユーザー ID が含まれます。この出力に関連付けられたバックエンド PID は、属性アクションを実際の AD ユーザーに戻すのに役立ちます。

```
bbf_group_ad_login@babelfish_db:[615]:LOG: connection authorized: user=bbf_group_ad_login database=babelfish_db application_name=sqlcmd GSS (authenticated=yes, encrypted=yes, principal=user1@CORP.EXAMPLE.COM)
```

# AD セキュリティグループメンバーシップの権限の使用
<a name="babelfish-kerberos-securityad-privileges"></a>

## サーバーレベルの権限の継承
<a name="babelfish-kerberos-securityad-inheritpriv-server"></a>

 特定の AD セキュリティグループのメンバーである AD ユーザーは、マッピングされた Windows グループログインに付与されたサーバーレベルの権限を継承します。例えば、Babelfish の `sysadmin` サーバーロールにメンバーシップが付与されている `accounts-group` AD セキュリティグループを考えてみましょう。次のコマンドを使用して、サーバーレベルの権限を継承できます。

```
1> ALTER SERVER ROLE sysadmin ADD MEMBER [corp\accounts-group];
```

 したがって、`accounts-group` AD セキュリティグループのメンバーである Active Directory ユーザーは、`sysadmin` ロールに関連付けられたサーバーレベルの権限を継承します。つまり、`accounts-group` のメンバーである `corp\user1` のようなユーザーは、Babelfish 内でサーバーレベルのオペレーションを実行できるようになります。

**注記**  
 サーバーレベルの DDL を実行するには、個々の AD ユーザーの Windows ログインが存在している必要があります。詳細については、「[制限](babelfish-kerberos-securityad-limitations.md)」を参照してください。

## データベースレベルの権限の継承
<a name="babelfish-kerberos-securityad-inheritpriv-database"></a>

 データベースレベルの権限を付与するには、データベースユーザーを作成し、Windows グループログインとマッピングする必要があります。特定の AD セキュリティグループのメンバーである AD ユーザーは、そのデータベースユーザーに付与されたデータベースレベルの権限を継承します。次の例では、Windows グループ [corp\$1accounts-group] のデータベースレベルの権限がどのように割り当てられているかを確認できます。

```
1> CREATE DATABASE db1; 
2> GO
1> USE db1;
2> GO
Changed database context to 'db1'.
1> CREATE TABLE dbo.t1(a int);
2> GO
```

 Windows グループログイン [corp\$1accounts-group] 用のデータベースユーザー [corp\$1sales-group] を作成します。このステップを実行するには、sysadmin のメンバーであるログインを使用して TDS エンドポイント経由で接続します。

```
1> CREATE USER [corp\accounts-group] FOR LOGIN [corp\accounts-group];
2> GO
```

 次に、AD ユーザー user1 として接続し、テーブル t1 へのアクセスを確認します。データベースレベルの権限をまだ付与していないため、アクセス許可の拒否エラーが発生します。

```
1> SELECT * FROM dbo.t1;
2> GO
Msg 33557097, Level 16, State 1, Server db-inst, Line 1
permission denied for table t1
```

データベースユーザー [corp\$1accounts-group] にテーブル t1 の SELECT を付与します。このステップを実行するには、sysadmin のメンバーであるログインを使用して TDS エンドポイント経由で接続します。

```
1> GRANT SELECT ON dbo.t1 TO [corp\accounts-group];
2> GO
```

 AD ユーザー user1 として接続し、アクセスを検証します。

```
1> SELECT * FROM dbo.t1;
2> GO
a
-----------

(0 rows affected)
```

# デフォルトまたは明示的なスキーマに基づく DDL ステートメントの動作の処理
<a name="babelfish-kerberos-securityad-ddl"></a>

 AD 認証セッションを使用する場合、現在のセッションのデフォルトスキーマは次の条件によって決まります。
+ 個々のデータベースユーザーが存在する場合、ユーザーのデフォルトスキーマは現在のセッションのデフォルトスキーマと見なされます。
+ グループデータベースユーザーのデフォルトスキーマが存在する場合、グループデータベースユーザーのデフォルトスキーマは、最小のプリンシパル ID を持つ現在のセッションのデフォルトスキーマと見なされます。

## CREATE DDL ステートメントの動作について
<a name="babelfish-kerberos-securityad-ddlcreate"></a>

 CREATE DDL ステートメントに明示的なスキーマが指定されていない場合、オブジェクトの作成は現在のセッションのデフォルトスキーマで行われます。スキーマがデフォルトか明示的かを判断できない場合、DDL ステートメントは次のエラーをスローします。

```
"Babelfish Unsupported Command : Schema required for CREATE DDLs when connecting with Active Directory Group authentication. Assign default schema to group user or specify schema in command."
```

**Example : Windows グループユーザー用のデフォルトスキーマが存在しない**  
Windows グループユーザー [corp\$1accounts-group] には NULL のデフォルトスキーマがあり、AD ユーザー user1 はスキーマを明示的に指定せずに DDL を実行しようとしています。個々の Windows ログインとユーザーは user1 には存在しないため、Windows グループユーザー [corp\$1accounts-group] のデータベースレベルの権限のみを取得します。  

```
1> create TABLE t2(a int);
2> GO

Msg 33557097, Level 16, State 1, Server db-inst, Line 1
Babelfish Unsupported Command : Schema required for CREATE DDLs when connecting with Active Directory Group authentication. Assign default schema to group user or specify schema in command.
```
AD ユーザー user1 の個々の Windows ログインとユーザーは存在しません

**Example : Windows グループユーザーにデフォルトのスキーマが存在する**  
sysadmin を使用して、デフォルトスキーマで [corp\$1accounts-group] ログインのための Windows グループユーザーを作成します。  

```
1> CREATE USER [corp\accounts-group] FOR LOGIN [corp\accounts-group] WITH DEFAULT_SCHEMA = sch_acc;
2> GO
1> CREATE SCHEMA sch_acc AUTHORIZATION [gad\accounts-group];
2> GO
1> SELECT name, principal_id, default_schema_name FROM sys.database_principals WHERE name = 'corp\accounts-group';
2> GO
                
name               principal_id default_schema_name
------------------ ------------ -------------------
corp\accounts-group 24162        sch_acc

(1 rows affected)
```
 AD ユーザー user1 を使用してスキーマを明示的に指定せずにオブジェクトを作成してみてください。テーブル t2 は、[corp\$1accounts-group] Windows グループユーザーのデフォルトスキーマで作成されます。このオブジェクトの所有者はスキーマ sch\$1acc の所有者と同じになります。  

```
1> CREATE TABLE t_group(a int);
2> GO
1> SELECT name, schema_name(schema_id) FROM sys.objects WHERE name like 't_group';
2> GO

name    schema_name
------- -----------
t_group sch_acc

(1 rows affected)
```
AD ユーザー user1 の個々の Windows ログインとユーザーは存在しません

**Example : 個々のデータベースユーザーが AD ユーザーにも存在する**  
 個々のデータベースユーザーが AD ユーザーにも存在する場合、オブジェクトは常に個々のデータベースユーザーに関連付けられたスキーマに作成されます。データベースユーザーにスキーマが存在しない場合、dbo スキーマが使用されます。AD ユーザー user1 の個々の Windows ログインおよびデータベースユーザーを作成します。sysadmin ログインを使用して TDS エンドポイント経由で接続する   

```
1> CREATE LOGIN [corp\user1] FROM WINDOWS;
2> GO
1> CREATE USER [corp\user1] FOR LOGIN [corp\user1] WITH DEFAULT_SCHEMA = sch1;
2> GO
1> CREATE SCHEMA sch1 AUTHORIZATION [corp\user1];
2> GO
1> SELECT name, default_schema_name FROM sys.database_principals WHERE name = 'corp\user1';
2> GO

name      default_schema_name
--------- -------------------
corp\user1 sch1

(1 rows affected)
```
 AD ユーザー user1 を使用して接続し、スキーマを明示的に指定せずにオブジェクトを作成してみてください。テーブル t2 はスキーマ sch1 で作成されます。また、このオブジェクトの所有者はスキーマ sch1 の所有者と同じであることに注意してください。  

```
1> CREATE TABLE t2(a int);
2> GO
1> SELECT name, schema_name(schema_id) FROM sys.objects WHERE name like 't2';
2> GO
            
name schema_name
---- -----------
t2   sch1

(1 rows affected)
```

# 制限
<a name="babelfish-kerberos-securityad-limitations"></a>
+ ダンプ/復元ユーティリティは、pg\$1ad\$1mapping 拡張マッピングのダンプをサポートしていません。復元後にこれらのマッピングを再作成する必要があります。
+ ブルー/グリーンデプロイは、`pg_ad_mapping` を使用する Babelfish および Aurora PostgreSQL インスタンスではサポートされていません。
+ 暗黙的なスキーマの作成はサポートされていません。暗黙的なスキーマの作成を必要とする DDL ステートメントはサポートされていません。
+ サーバーレベルの DDLs ALTER AUTHORIZATION ON DATABASE、CREATE DATABASE、CREATE LOGIN、ALTER LOGIN、ALTER SERVER ROLE、ALTER DATABASE は、個々の Windows ログインが存在しない場合、グループ AD 認証セッションではサポートされず、グループの Windows ログインのみが存在します。この制限を回避するには、パスワード認証セッションでこれらのオペレーションを実行するか、個々の Windows ログインを作成することをお勧めします。
+ 暗黙的なユーザー作成はサポートされていません。理想的な T-SQL 動作 (Babelfish ではまだサポートされていません): DDL や、GRANT/REVOKE などのアクセスコントロールステートメントなど、コマンドで AD ユーザー名が指定されているものの、データベースに存在しない場合、AD ユーザーとして指定されたデータベースユーザーは暗黙的に作成されます。
+ PSQL エンドポイントで作成され、グループ AD 認証セッションの TDS エンドポイントから実行される PL/pgSQL プロシージャまたは関数の DDL の場合:
  + ALTER/DROP ステートメントがサポートされます。
  + CREATE TABLE、CREATE VIEW、CREATE INDEX、CREATE FUNCTION/PROC、CREATE TYPE、CREATE SEQUENCE、CREATE TRIGGER、SELECT INTO、CREATE FULLTEXT INDEX、CREATE UNIQUE INDEX は、スキーマが明示的に指定されておらず、現在のセッションのデフォルトスキーマが null の場合にエラーをスローします。
  + CREATE DATABASE、CREATE EXTENSION、および (T-SQL ではなく) PG 固有のオブジェクト CREATE サブスクリプション、CREATE テーブルスペース、CREATE ポリシー、CREATE 変換用の他のすべての CREATE ステートメントはサポートされていません。
+ PostgreSQL エンドポイントからの DDL は、グループ AD 認証セッションではサポートされていません。回避策として、パスワードベースの認証メカニズムを使用し、マスターユーザーまたは他のユーザーを使用することでいつでも接続できます。
+ SUSER\$1SID()、IS\$1SRVROLEMEMBER()、IS\$1MEMBER()、sys.dm\$1exec\$1sessions などのシステムオブジェクトには、次の制限があります。
  + AD ユーザーまたは AD セキュリティグループが指定されている場合、SUSER\$1SID() は SID を返しません。
  + 現在の AD ユーザーが Windows グループログインのサーバーロールメンバーシップからサーバーロールメンバーシップを継承している場合、IS\$1SRVROLEMEMBER() はロールメンバーシップを考慮しません。
  + IS\$1MEMBER() は、Windows グループ関連のクエリに対して false を返します。
  + sys.dm\$1exec\$1sessions には、login\$1name 列、nt\$1user\$1name 列の想定値が表示されません。

# PostgreSQL ポートの PostgreSQL エンドポイント経由で Babelfish に接続する
<a name="babelfish-kerberos-securityad-connect-pgendpoint"></a>

TDS ポートで作成されたグループログインを利用して、PostgreSQL ポート経由で接続することもできます。PostgreSQL ポート経由で接続するには、PostgreSQL クライアントアプリケーションから `<ad_username@FQDN>` 形式で AD ユーザー名を指定する必要があります。`<DNS domain name\ad_username>` 形式は使用できません。

PostgreSQL は、デフォルトでユーザー名の大文字と小文字を区別して比較します。Aurora PostgreSQL で大文字と小文字を区別せずに Kerberos ユーザー名を解釈するには、カスタム Babelfish クラスターパラメータグループで krb\$1caseins\$1users パラメータを true に設定する必要があります。このパラメータはデフォルトで false に設定されています。詳細については、「[Aurora PostgreSQL DB クラスターの大文字と小文字を区別しないユーザー名を設定する](postgresql-kerberos-setting-up.md#postgresql-kerberos-setting-up.create-logins.set-case-insentive)」を参照してください。

## AD ユーザーが複数のグループに属する場合の T-SQL エンドポイントと PostgreSQL エンドポイントの動作の違い
<a name="babelfish-kerberos-securityad-diff-tsql-pg"></a>

AD ユーザー user1 は、[corp\$1accounts-group] と [corp\$1sales-group] の 2 つの AD セキュリティグループの一部であり、DB 管理者がユーザーマッピングを次のように設定しているとします。

```
postgres=> select * from pgadmap_read_mapping();
            
ad_sid       | pg_role                         | weight | ad_grp 
-------------+---------------------------------+--------+---------------
S-1-5-67-980 | accounts-group@CORP.EXAMPLE.COM | 7      | accounts-group
S-1-2-34-560 | sales-group@CORP.EXAMPLE.COM    | 10     | sales-group
(2 rows)
```

ユーザーが T-SQL エンドポイントから接続している場合、認可中に、関連付けられたすべての T-SQL ログインから権限を継承します。この例では、user1 は T-SQL グループのログインから権限の統合を継承し、重みは無視されます。これは標準の T-SQL 動作と一致しています。

ただし、同じユーザーが PostgreSQL エンドポイントから接続する場合、関連付けられた T-SQL ログインのうち、重みが最も高いものからのみ権限を継承できます。2 つの T-SQL グループログインに同じ重みが割り当てられた場合、AD ユーザーは、最後に追加されたマッピングに対応する T-SQL ログインの権限を継承します。あいまいさを避けるために、個々の DB ロールの相対的なアクセス許可/権限を反映する重みを指定することをお勧めします。次の例では、user1 は PSQL エンドポイントを介して接続され、セールスグループ権限のみを継承しています。

```
babelfish_db=> select session_user, current_user;

   session_user               |   current_user
------------------------------+---------------------------
 sales-group@CORP.EXAMPLE.COM | sales-group@CORP.EXAMPLE.COM
(1 row)


babelfish_db=> select principal, gss_authenticated from pg_stat_gssapi where pid = pg_backend_pid();

     principal          | gss_authenticated
------------------------+-------------------
 user1@CORP.EXAMPLE.COM | t
(1 row)
```