監査ログの概念¶
監査ログとは、Confluent Server Authorizer を使用して、認可アクティビティをキャプチャおよび保護し、Confluent Platform 上の Kafka クラスター内のトピックとして保持する手段です。具体的には、ACL および RBAC によって保護されているアクションをユーザーが実行しようとしたときに発生するアクセス許可チェックについて、実行時の決定が監査ログに記録されます。監査可能なイベントは発生順に記録されますが、監査ログメッセージがコンシューマーによってフェッチされる際には、順序が異なる可能性があります。
監査可能な各イベントには、誰が何をしようとしたか、いつ試行したか、システムが続行を許可したかどうかに関する情報が含まれています。
監査ログはデフォルトで有効になっており、包括的なアクセス許可を持つブローカー間プリンシパル(通常はユーザー kafka
)によって管理されます。
監査ログの最も重要な価値は、ローカルおよびリモートの Kafka クラスターに関するセキュリティリスクを評価するために使用できるデータを提供することです。監査データには、ローカルまたはリモートの Kafka クラスターとユーザーとのやり取りを追跡するために必要なすべての情報が含まれているため、以下のことが可能になります。
- プラットフォーム全体でのユーザーとアプリケーションによるアクセスを追跡する
- 異常な動作や例外を特定する
- セキュリティリスクをプロアクティブにモニタリングして解決する
Splunk Sink Connector、S3 Sink Connector、およびその他のシンクコネクターを使用すると、監査ログデータを分析用にターゲットプラットフォームに移動できます。
監査ログを構成して使用する前に、次のように Confluent Server Authorizer を構成する必要があります。
authorizer.class.name=io.confluent.kafka.security.authorizer.ConfluentServerAuthorizer
監査可能イベント¶
注釈
これらはイベント認可であるため、イベントが発生しようとしているタイミングでイベントが記録されます。また、タスクを最後まで実行するのではなく、実行できるかどうかを確認するためだけにユーザーがタスクを認可しようとすることがあります。このような場合でも、認可は監査ログに記録されます。
各タイプの監査ログイベントは、1 つのイベントカテゴリのみに属します。特定のイベントカテゴリに一致するように、監査ログルーティングルールを構成することもできます。デフォルトでは、MANAGEMENT イベントおよび AUTHORIZE イベントがキャプチャされます。
監査ログは、以下のイベントをキャプチャするように構成できます。
イベント名 | 説明 | カテゴリ | デフォルトでキャプチャ |
---|---|---|---|
mds.Authorize | MDS を使用して RBAC 認可がリクエストされています。 | AUTHORIZE | はい |
kafka.AlterConfigs | Kafka 構成が変更/更新されています。 | MANAGEMENT | はい |
kafka.AlterPartitionReassignments | トピックのパーティションの再割り当てが変更されています。 | MANAGEMENT | はい |
kafka.AlterReplicaLogDirs | パーティションのレプリカのログディレクトリが変更されています。 | MANAGEMENT | はい |
kafka.CreateAcls | Kafka ブローカーの ACL が作成されています。 | MANAGEMENT | はい |
kafka.CreateDelegationToken | 委任トークンが作成されています。 | MANAGEMENT | はい |
kafka.CreatePartitions | パーティションがトピックに追加されています。 | MANAGEMENT | はい |
kafka.CreateTopics | トピックが作成されています。 | MANAGEMENT | はい |
kafka.DeleteAcls | Kafka ブローカーの ACL が削除されています。 | MANAGEMENT | はい |
kafka.DeleteGroups | コンシューマーグループが削除されています。 | MANAGEMENT | はい |
kafka.DeleteRecords | レコードがトピックから削除されています。 | MANAGEMENT | はい |
kafka.DeleteTopics | トピックが削除されています。 | MANAGEMENT | はい |
kafka.ElectLeaders | レプリカがトピックのパーティションのリーダーとして選択されています。 | MANAGEMENT | はい |
kafka.ExpireDelegationToken | 委任トークンが期限切れとしてマークされています。 | MANAGEMENT | はい |
kafka.IncrementalAlterConfigs | Kafka ブローカーのダイナミック構成が変更されています。 | MANAGEMENT | はい |
kafka.OffsetDelete | コンシューマーグループ内のパーティションについてコミット済みのオフセットが削除されています。 | MANAGEMENT | はい |
kafka.RenewDelegationToken | 委任トークンが更新されています。 | MANAGEMENT | はい |
kafka.AddPartitionToTxn | パーティションがトランザクションに追加されています。 | PRODUCE | × |
kafka.EndTxn | トランザクションが完了します。 | PRODUCE | × |
kafka.InitProducerId | Kafka プロデューサーによって、トランザクションまたはべき等の書き込みが初期化されています。 | PRODUCE | × |
kafka.Produce | Kafka プロデューサーによって、レコードのバッチがトピックに書き込まれています。 | PRODUCE | × |
kafka.AddOffsetsToTxn | プロデューサーが、オフセットをコンシューマーグループコーディネーターに送信し、それらのオフセットを現在のトランザクションの一部としてマークする処理を行っています。 | CONSUME | × |
kafka.FetchConsumer | Kafka コンシューマーがレコードのバッチをトピックから読み取っています。 | CONSUME | × |
kafka.JoinGroup | Kafka コンシューマーがコンシューマーグループに参加します。 | CONSUME | × |
kafka.LeaveGroup | Kafka コンシューマーがグループを離脱します。 | CONSUME | × |
kafka.ListOffsets | トピックのパーティションのオフセットがリクエストされています。 | CONSUME | × |
kafka.OffsetCommit | コンシューマーが、処理されたパーティションのオフセットをコミットしています。 | CONSUME | × |
kafka.OffsetFetch | コンシューマーグループのコミット済みオフセットがリクエストされています。 | CONSUME | × |
kafka.SyncGroup | Kafka コンシューマーがグループのバランス調整に参加します。 | CONSUME | × |
kafka.TxnOffsetCommit | コンシューマーオフセットが、トランザクション内のコンシューマーグループに対してコミットされています。 | CONSUME | × |
kafka.ControlledShutdown | ブローカーがシャットダウンされます。 | INTERBROKER | × |
kafka.FetchFollower | パーティションのフォロワーレプリカを持つブローカーが、レプリケーション用のレコードをフェッチしています。 | INTERBROKER | × |
kafka.LeaderAndIsr | コントローラーが、リーダーと ISR(同期レプリカ)のステートをブローカーに送信しています。 | INTERBROKER | × |
kafka.StopReplica | トピックパーティションのレプリカについて、レプリケーションが停止されます。 | INTERBROKER | × |
kafka.UpdateMetadata | コントローラーが新しいメタデータをブローカーに送信しています。 | INTERBROKER | × |
kafka.WriteTxnMarkers | ブローカーが、トランザクションステートを更新するためにトランザクションマーカーを書き込んでいます。 | INTERBROKER | × |
kafka.DescribeAcls | Kafka ブローカーの ACL に関する情報がリクエストされています。 | DESCRIBE | × |
kafka.DescribeConfigs | ブローカーの構成に関する情報がリクエストされています。 | DESCRIBE | × |
kafka.DescribeDelegationToken | 委任トークンに関する情報がリクエストされています。 | DESCRIBE | × |
kafka.DescribeGroups | コンシューマーグループに関する情報がリクエストされています。 | DESCRIBE | × |
kafka.DescribeLogDirs | レプリカのログディレクトリに関する情報がリクエストされています。 | DESCRIBE | × |
kafka.FindCoordinator | Kafka コンシューマーが、グループコーディネーターに関する情報をリクエストしています。 | DESCRIBE | × |
kafka.ListGroups | コンシューマーグループに関する情報がリクエストされています。 | DESCRIBE | × |
kafka.ListPartitionReassignments | 現在のパーティションの再割り当てがリクエストされています。 | DESCRIBE | × |
kafka.Metadata | トピックのメタデータがリクエストされています。 | DESCRIBE | × |
kafka.OffsetForLeaderEpoch | リーダーエポックに対応する最後のオフセットがリクエストされています。 | DESCRIBE | × |
kafka.Heartbeat | コンシューマーが、まだアクティブであることをグループに知らせようとしています。 | HEARTBEAT | × |
監査ログのコンテンツ¶
次の例は、ユーザーが新しいトピックを作成するときにクラスターから返される監査ログメッセージの内容を示しています。
{
"id": "889bdcd9-a378-4bfe-8860-180ef8efd208",
"source": "crn:///kafka=8caBa-0_Tu-2k3rKSxY64Q",
"specversion": "1.0",
"type": "io.confluent.kafka.server/authorization",
"time": "2019-10-24T16:15:48.355Z",
"datacontenttype": "application/json",
"subject": "crn:///kafka=8caBa-0_Tu-2k3rKSxY64Q/topic=app3-topic",
"confluentRouting": {
"route": "confluent-audit-log-events"
},
"data": {
"serviceName": "crn:///kafka=8caBa-0_Tu-2k3rKSxY64Q",
"methodName": "kafka.CreateTopics",
"resourceName": "crn:///kafka=8caBa-0_Tu-2k3rKSxY64Q/topic=app3-topic",
"authenticationInfo": {
"principal": "User:admin"
},
"authorizationInfo": {
"granted": true,
"operation": "Create",
"resourceType": "Topic",
"resourceName": "app3-topic",
"patternType": "LITERAL",
"superUserAuthorization": true
},
"request": {
"correlation_id": "3",
"client_id": "adminclient-6"
},
"requestMetadata": {
"client_address": "/127.0.0.1"
}
}
}
監査ログの最初のセクションには、ログメッセージ自体に関する情報が表示されます。この部分はメッセージ配信時のエンベロープであると見なすことができます。これには、以下に示す監査ログ実装詳細が含まれています。
監査ログエントリ | 説明 |
---|---|
id | すべてのソースを対象にした一意性を保証する、ランダムに生成された UUID。 |
source | 認可の可否を決定した Kafka クラスターを識別します。常に CRN が含まれ、常に serviceName と同じです。 |
specversion | 使用中の CloudEvents のバージョン(CloudEvents は、イベントデータのフォーマットを定義する、ベンダーに依存しない仕様です)。 |
type | 発生したイベントのタイプ(認可リクエスト)。 |
time | イベントが発生した時刻。 |
datacontenttype | 監査データを提示する CloudEvent フォーマットを識別します(JSON)。 |
subject | アクセスが許可または拒否されたリソースを識別します。 |
confluentRouting | イベントの送信先のトピックを識別します。トピックのルーティングは構成可能です。詳細については「監査ログの構成」を参照してください。 |
監査ログの次のセクションには、ローカルおよびリモートの Kafka クラスターに関するセキュリティリスクを評価するために使用できるデータ(data
)が表示されます。
監査ログエントリ | 説明 |
---|---|
serviceName | 認可の可否を決定した Kafka クラスターを識別します。常に CRN が含まれ、常に source と同じです。 |
methodName | 発生したリクエストのタイプ。たとえば、上の methodName は、ユーザーが Kafka トピックを作成しようとしたことを示しています。このエントリには、上の表に示されているイベント名のうちの 1 つが含まれ、その前に mds (AUTHORIZE イベントの場合)または kafka (その他のイベントの場合)が表示されます。たとえば、mds.Authorize 、kafka.Metadata 、kafka.CreateTopics などです。 |
resourceName | リクエストのターゲットのリソース識別子(CRN)。たとえば、上記の resourceName は、一意に識別された Kafka クラスターでユーザーがトピックを作成しようとしたことを示しています。 |
authenticationInfo | リクエストを試行しているユーザー、サービスプリンシパルアカウント、またはプリンシパルを識別します。 |
authorizationInfo | リクエストを認可するために行われた決定に関する詳細が含まれています。上の例は、Kafka クラスターにトピックを作成するための認可リクエストが許可されたことを示しています。RBAC が使用されている場合は、リソースとロールが含まれます(存在する場合)。ACL が使用されている場合は、ACL 情報も含まれます。 |
requestMetadata | 認可リクエストがどのように送信されたかを識別し、リクエスターの IP アドレスがわかっていれば表示します。 |
監査ログのコンテンツを表示する方法の詳細については、「監査ログのオンザフライ表示」を参照してください。
監査ログのコンテンツ例¶
以下は、RBAC が有効になっている場合の監査ログメッセージの例です。
{
"id": "889bdcd9-a378-4bfe-8860-180ef8efd208",
"source": "crn:///kafka=8caBa-0_Tu-2k3rKSxY64Q",
"specversion": "1.0",
"type": "io.confluent.kafka.server/authorization",
"time": "2019-10-24T16:15:48.355Z",
"datacontenttype": "application/json",
"subject": "crn:///kafka=8caBa-0_Tu-2k3rKSxY64Q/topic=app3-topic",
"confluentRouting": {
"route": "confluent-audit-log-events"
},
"data": {
"serviceName": "crn:///kafka=8caBa-0_Tu-2k3rKSxY64Q",
"methodName": "kafka.CreateTopics",
"resourceName": "crn:///kafka=8caBa-0_Tu-2k3rKSxY64Q/topic=app3-topic",
"authenticationInfo": {
"principal": "User:resourceOwner1"
},
"authorizationInfo": {
"granted": true,
"operation": "Create",
"resourceType": "Topic",
"resourceName": "app3-topic",
"patternType": "LITERAL",
"rbacAuthorization": {
"role": "ResourceOwner",
"scope": {
"outerScope": [],
"clusters": {
"kafka-cluster": "j94C72q3Qpym0MJ9McEufQ"
}
}
}
}
}
}
以下は、ACL を使用している場合の監査ログメッセージの例です。
{
"id": "889bdcd9-a378-4bfe-8860-180ef8efd208",
"source": "crn:///kafka=8caBa-0_Tu-2k3rKSxY64Q",
"specversion": "1.0",
"type": "io.confluent.kafka.server/authorization",
"time": "2019-10-24T16:15:48.355Z",
"datacontenttype": "application/json",
"subject": "crn:///kafka=8caBa-0_Tu-2k3rKSxY64Q/topic=app3-topic",
"confluentRouting": {
"route": "confluent-audit-log-events"
},
"data": {
"serviceName": "crn:///kafka=8caBa-0_Tu-2k3rKSxY64Q",
"methodName": "kafka.CreateTopics",
"resourceName": "crn:///kafka=8caBa-0_Tu-2k3rKSxY64Q/topic=app3-topic",
"authenticationInfo": {
"principal": "User:alice"
},
"authorizationInfo": {
"granted": true,
"operation": "DescribeConfigs",
"resourceType": "Topic",
"resourceName": "app3-topic",
"patternType": "LITERAL",
"aclAuthorization" : {
"permissionType":"ALLOW",
"host":"*"
}
},
}
}
Confluent Resource Name(CRN)¶
CRN は、Confluent Platform 全体で参照されるリソースを一意に識別するための統一された方法であり、監査ログで使用されます。各 CRN は、関連する Confluent リソースクラスターを一意に識別する URI(Uniform Resource Identifier)であり、crn://
から始まります。
CRN のオーソリティ(ホスト名とも呼ばれます)をクラスターレベルで構成できます。Confluent Metadata Service (MDS) を使用している場合でも、デフォルトでこの設定は空です。オーソリティ名は、server.properties
の confluent.authorizer.authority.name=
オプションを使用してを指定しない限り、空のままになります。使用するクラスターまたはコンテキストが 1 つの場合は、このアプローチで十分です。
ただし、本稼働クラスターが複数あり、これらがすべて RBAC 用に単一の MDS を参照する一方で、独自の MDS を使用するクラスターのテストグループも存在するシナリオについて考えてみましょう。本稼働環境では同じ MDS を RBAC に使用しているため、使用するすべてのクラスターで、オーソリティを confluent.authorizer.authority.name=prod.mds.mycompany.com
として指定します。テスト環境では、オーソリティを confluent.authorizer.authority.name=test.mds.mycompany.com
として指定します。本稼働クラスターには "travel" という名前のトピックが含まれ、テストクラスターにも "travel" という名前のトピックがあります(それぞれのデータは異なります)。それぞれのクラスター用にオーソリティを構成したため、各 "travel" トピックがどのクラスターに存在するかをすばやく簡単に識別できます。本稼働環境のクラスターとテストクラスターの両方で同じ名前が使用されていても、異なるオーソリティによって 2 つを区別できます。
オーソリティは、インストールに関連付けられた DNS 名として設定することをお勧めします。これによって簡単に、CRN に意味を持たせることができます。このため、論理グループ(会社のステージング環境など)内のすべてのブローカーは、server.properties
内で同じ authority.name
(confluent.authorizer.authority.name=mds.mycompany.com
など)を指定する必要があります。単一の MDS によって管理されるクラスターなどの論理グループの場合、MDS に到達するために使用されるホスト名を指定する必要があります。意図的に区別しておく場合(別個の本稼働クラスター、別個のステージングクラスター、または別個のテストクラスターなど)を除いて、個々のクラスターに異なる authority.name
値を指定しないでください。
CRN のフォーマットはリソースによって異なります。
- Kafka クラスター:
<authority>/kafka=<kafka-cluster-id>
- トピック:
<authority>/kafka=<kafka-cluster-id>/topic=<topic-name>
- コンシューマーグループ:
<authority>/kafka=<kafka-cluster-id>/group=<consumer-group-name>
- ksqlDB クラスター:
<authority>/kafka=<kafka-cluster-id>/ksql=<ksql-cluster>
- Connect:
<authority>/kafka=<kafka-cluster-id>/connect=<connect-cluster>/connector=<connector-name>
監査ログを特定の Confluent リソースに関連付けるために使用される CRN の例を次に示します。
- Kafka クラスター:
crn://mds.mycompany.com/kafka=rKtuRNiDQb2k9NMml6rLfA
- トピック:
crn://mds.mycompany.com/kafka=rKtuRNiDQb2k9NMml6rLfA/topic=app1-topic
- コンシューマーグループ:
crn://mds.mycompany.com/kafka=rKtuRNiDQb2k9NMml6rLfA/group=app1-consumer-group
- KQSL クラスター:
crn://mds.mycompany.com/kafka=rKtuRNiDQb2k9NMml6rLfA/ksql=default_
- Connect:
crn://mds.mycompany.com/kafka=rKtuRNiDQb2k9NMml6rLfA/connect=ydfk/connector=sink-connector
監査ログのデフォルト構成¶
監査ログはデフォルトで有効になっており、包括的なアクセス許可を持つブローカー間プリンシパル(通常はユーザー kafka
)によって管理されます。
何も構成しなければ、監査ログはローカルクラスター内の単一のトピックに送信され、認可イベント "allowed" および "denied" がキャプチャされます。このトピックは confluent-audit-log-events
という名前になります。デフォルトの監査ログでは、認可イベントの MANAGEMENT および AUTHORIZE カテゴリ のみがキャプチャされます。
次の例は、デフォルトの監査ログ構成を示しています。
{
"destinations": {
"topics": {
"confluent-audit-log-events": {
"retention_ms": 7776000000
}
}
},
"default_topics": {
"allowed": "confluent-audit-log-events",
"denied": "confluent-audit-log-events"
}
}
監査ログを無効にする方法については、「監査ログの無効化」を参照してください。
監査ログの構成に関する考慮事項¶
ほとんどの組織には、厳格で具体的なセキュリティガバナンスの要件とポリシーが存在します。その場合は、監査ログをより詳細なレベルで構成できます。具体的には、以下のような構成が可能です。
- どの イベントカテゴリ をキャプチャするか(デフォルトで無効になっている生成、消費、ブローカー間などのカテゴリを含む)
- 重要度の異なるログをキャプチャするための複数のトピック
- どの クラスター に監査ログを配信するか
- セキュリティおよびパフォーマンス用に最適化された トピックデスティネーション のルート
- 組織のニーズに対応する 保持期間
- メッセージの量が多すぎてもパフォーマンスを低下させないための 除外プリンシパル
- 監査ログクラスターとやり取りするための Kafka ポート
生成および消費について監査ログを有効にするときは、ログに記録するイベントを厳選し、特に注意を要するトピックのみを対象としてログを構成します。
監査ログを保護するには、構成に関する以下の推奨事項も検討します。
- セキュリティを強化するには、監査ログを別のクラスターに送信します。監査ログクラスターのアクセス許可を制限して、監査ログの信頼性を確保します。
- アクセス許可が制限された監査ログプリンシパルを作成します(
confluent-audit
で識別されるユーザーなど)。デフォルトでは、包括的なアクセス許可を持つブローカープリンシパルが使用されます。
監査ログの送信先クラスター¶
監査ログメッセージの保持のみを目的として確保されているクラスターに監査ログメッセージを配信することを検討してください。これにより、組織の監査ログへのアクセスや改ざんを防止し、機密性の低いデータのログ量を抑えながら、機密性データの詳細な監査を選択的に実行できます。
監査ログを別のクラスターに配信する場合は、そのクラスターへの接続を構成する必要があります。
監査ログのデスティネーショントピック¶
監査ログ構成を計画するときは、トピック設定を慎重に検討します。監査ログメッセージは、サブジェクト、カテゴリ、認可の可否(許可されたか、拒否されたか)に基づいて、さまざまなトピックに柔軟にルーティングできます。特定サブジェクトのルート指定や、プレフィックス(機密性の高い認可イベントの場合は _secure-*
を使用するなど)とワイルドカードの使用により、より大きなリソースグループを扱うこともできます。
監査ログのレプリケーション係数と保持期間¶
監査ログのレプリケーション係数と保持期間を指定できます。監査ログ構成で指定した保持期間は、まだ存在していないトピックが監査ログ機能によって自動的に作成される場合にのみ適用されます。
手動でトピックを作成する際に指定した保持期間の値が、ルーター構成で指定されている保持期間と競合する場合は、手動で作成した設定が使用されます。監査ログメッセージのデフォルトの保持期間は 90 日(7776000000 ミリ秒)です。
Kafka ブローカーによって監査ログトピックが自動的に作成される場合、レプリケーション係数を指定するには、次のように confluent.security.event.logger.exporter.kafka.topic.replicas
オプションを使用します。
confluent.security.event.logger.exporter.kafka.topic.replicas=2
Kafka ブローカーでのレプリケーション係数の自動構成の詳細については、「レプリケーション係数の構成」を参照してください。
除外プリンシパル¶
除外プリンシパルを使用すると、監査ログメッセージの量を制御できます。生成と消費の監査ログがオンになっている場合は、プリンシパルによって実行される読み取りと書き込みによって追加の監査ログが生成されます。つまり、ログの読み取りおよび書き込みごとに、別の監査ログメッセージが作成されます。これを続けると、すぐに制御不能になり、クラスターのパフォーマンスにマイナスの影響が及ぶ可能性があります。
監査ログのボリュームが蓄積して管理できなくなる状態を回避するには、常に以下のような除外プリンシパルを構成に含める必要があります。
- 監査ログトピックへの書き込みの責任を負う、信頼できるプリンシパル。このプリンシパルによって実行されるタスクのみが監査ログに書き込まれるように指定します。このプリンシパルに追加のアクセス許可を付与しないでください。また、他のプリンシパルによる監査ログトピックへの書き込みを許可しないでください。
- 監査ログトピックからの読み取りの責任を負う、信頼できるプリンシパル。このプリンシパルによって実行されるタスクのみを監査ログで読み取るように指定します。このプリンシパルに追加のアクセス許可を付与しないでください。また、他のプリンシパルによる監査ログトピックからの読み取りを許可しないでください。
不要な監査ログの蓄積や、除外プリンシパルを構成する必要性を完全に回避するためのもう 1 つのアプローチとして、セキュリティで保護されアクセスが制限されているクラスターに監査ログを送信し、このクラスターで監査ログを有効にしないという方法もあります。