API サーバーの監査ログを有効化、クエリ、アラート設定し、コンプライアンスとセキュリティのニーズを満たします。
クラスター監査は API サーバーのリクエストとレスポンスを記録し、操作履歴の追跡や異常の調査を可能にします。
Container Service for Kubernetes (ACK) マネージドクラスター、ACK 専用クラスター、ACK Serverless クラスターに適用されます。
登録済みクラスターについては、「クラスター監査の使用」をご参照ください。
課金
監査ログデータには機能ごとの課金が適用されます。詳細については、「請求書の表示」および「機能ごとの課金」をご参照ください。
クラスター監査を有効にすると、Simple Log Service (SLS) のコストが発生します。ログの量を監視し、コンプライアンス要件に合った保持期間を設定してください。デフォルトの保持期間は、ACK マネージドクラスターで 30 日、ACK 専用クラスターで 365 日です。
前提条件
お使いの Alibaba Cloud アカウントで、以下の SLS クォータが十分であることを確認してください。
-
SLS プロジェクトクォータ
-
SLS プロジェクトごとの Logstore クォータ
-
SLS プロジェクトごとのダッシュボードクォータ
クォータの詳細と引き上げ申請については、「リソースクォータの調整」をご参照ください。
クラスター監査の有効化
デフォルトでは、クラスター作成時に [Log Service の有効化] が選択されています。無効にした場合は、以下の手順で再度有効にしてください。
-
ACK コンソールにログインします。左側メニューで、[クラスター] をクリックします。
-
[クラスター] ページで、対象のクラスター名をクリックします。左側メニューで、[セキュリティ] > [クラスター監査] を選択します。
-
SLS プロジェクトを選択し、クラスター監査を有効にします。
ACK は、プロジェクトに audit-${clustereid} という Logstore を自動的に作成します。
デフォルトのインデックスは変更しないでください。変更すると、監査レポートが正しく生成されなくなります。
監査ログレポートの表示
ACK は、4つの組み込み監査ログレポートを提供します。[クラスター監査] ページで、名前空間または RAM ユーザーでフィルタリングできます。
任意のチャートの
アイコンをクリックすると、全画面表示したり、そのクエリステートメントをプレビューしたりできます。
概要
すべてのクラスターイベントと優先度の高いイベントの詳細を表示します。これには、RAM ユーザーの操作、インターネットアクセス、コマンド実行、リソース削除、Secret へのアクセス、CVE 脆弱性が含まれます。
操作の概要
以下のリソースに対する作成、更新、削除、読み取り操作の統計を提供します。
-
コンピューティングリソース:Deployment、StatefulSet、CronJob、DaemonSet、Job、Pod
-
ネットワークリソース:Service、Ingress
-
ストレージリソース:ConfigMap、Secret、PersistentVolumeClaim (PVC)
-
アクセス制御リソース:Role、ClusterRole、RoleBinding、ClusterRoleBinding
操作の詳細
特定のリソースタイプの操作を表示します。クエリするリソースタイプを選択してください。レポートには、総数、名前空間の分布、成功率、および時系列の傾向が表示されます。
CRD リソースまたはリストされていないリソースをクエリするには、複数形のリソース名を入力します。 たとえば、AliyunLogConfigをクエリする場合は、AliyunLogConfigsと入力します。
CVE 脆弱性
Kubernetes の CVE 脆弱性を表示します。RAM ユーザー ID でフィルタリングできます。修正方法については、「\[CVE セキュリティ\] CVE 脆弱性の修正」をご参照ください。
詳細なログデータのクエリ
カスタムクエリやより詳細な分析を行うには、SLS コンソールで生の監査ログデータにアクセスします。
デフォルトの保持期間は、ACK マネージドクラスターで 30 日、ACK 専用クラスターで 365 日です。保持期間を変更するには、「Logstore の管理」をご参照ください。
-
ACK コンソールにログインします。左側メニューで、[クラスター] をクリックします。
-
[クラスター] ページで、対象のクラスター名をクリックします。左側メニューで、[クラスター情報] をクリックします。
-
[クラスターリソース] タブで、[Log Service プロジェクト] の横にあるプロジェクト ID をクリックします。Logstores リストで、[audit-${clustereid}] という名前の Logstore をクリックします。
-
クエリステートメントなどを入力し、[検索と分析] をクリックします。
一般的なクエリパターン:
-
RAM ユーザー別:RAM ユーザー ID を入力します。
-
リソース別:リソース名 (Deployment、Service、ConfigMap など) を入力します。
-
システムコンポーネントの除外:システムコンポーネントのノイズを除外します。
NOT user.username: node NOT user.username: serviceaccount NOT user.username: apiserver NOT user.username: kube-scheduler NOT user.username: kube-controller-manager
構文の詳細については、「クエリメソッド」をご参照ください。
アラート設定
SLS のアラートルールを設定することで、特定の操作が発生した際にリアルタイムで通知を受け取ることができます。通知方法として、DingTalk チャットボット、カスタム Webhook、Alibaba Cloud メッセージセンターなどが利用できます。
詳細については、「SLS でのアラートルールの設定」をご参照ください。
アラート例 1:コンテナで実行されたコマンド
ユーザーがコンテナ内でコマンドを実行した際にアラートを送信します。各アラートには、コンテナ、コマンド、ユーザー、イベント ID、時刻、ソース IP アドレスが含まれます。
クエリステートメントの例:
verb : create and objectRef.subresource:exec and stage: ResponseStarted | SELECT auditID as "Event ID", date_format(from_unixtime(__time__), '%Y-%m-%d %T' ) as "Time", regexp_extract("requestURI", '([^\?]*)/exec\?.*', 1)as "Resource", regexp_extract("requestURI", '\?(.*)', 1)as "Command" ,"responseStatus.code" as "Status code",
CASE
WHEN "user.username" != 'kubernetes-admin' then "user.username"
WHEN "user.username" = 'kubernetes-admin' and regexp_like("annotations.authorization.k8s.io/reason", 'RoleBinding') then regexp_extract("annotations.authorization.k8s.io/reason", ' to User "(\w+)"', 1)
ELSE 'kubernetes-admin' END
as "User account",
CASE WHEN json_array_length(sourceIPs) = 1 then json_format(json_array_get(sourceIPs, 0)) ELSE sourceIPs END
as "Source IP address" order by "Time" desc limit 10000
条件式: "Event ID" =~ ".*"
アラート例 2:API サーバーからのインターネットアクセス失敗
クラスターからのアウトバウンドインターネットリクエストを監視します。リクエスト数が 10 に達し、失敗率が 50% を超えた場合にトリガーされます。
クエリステートメントの例:
* | select ip as "Source IP address", total as "Number of times of Internet access", round(rate * 100, 2) as "Failure rate in percentage", failCount as "Number of times of illegal access", CASE when security_check_ip(ip) = 1 then 'yes' else 'no' end as "Whether the IP address is risky", ip_to_country(ip) as "Country", ip_to_province(ip) as "Province", ip_to_city(ip) as "City", ip_to_provider(ip) as "ISP" from (select CASE WHEN json_array_length(sourceIPs) = 1 then json_format(json_array_get(sourceIPs, 0)) ELSE sourceIPs END
as ip, count(1) as total,
sum(CASE WHEN "responseStatus.code" < 400 then 0
ELSE 1 END) * 1.0 / count(1) as rate,
count_if("responseStatus.code" = 403) as failCount
from log group by ip limit 10000) where ip_to_domain(ip) != 'intranet' and ip not LIKE '%,%' and not try(is_subnet_of('7.0.0.0/8', ip)) ORDER by "Number of times of Internet access" desc limit 10000
条件式: Source IP address =~ ".*"
クラスター監査設定の管理
SLS プロジェクトの変更
監査ログを別の SLS プロジェクトに移行するには:
-
ACK コンソールにログインします。左側メニューで、[クラスター] をクリックします。
-
[クラスター] ページで、対象のクラスター名をクリックします。左側メニューで、[セキュリティ] > [クラスター監査] を選択します。
-
[Log Service プロジェクトの変更] をクリックし、プロンプトに従います。
クラスター監査の無効化
-
ACK コンソールにログインします。左側メニューで、[クラスター] をクリックします。
-
[クラスター] ページで、対象のクラスター名をクリックします。左側メニューで、[セキュリティ] > [クラスター監査] を選択します。
-
[クラスター監査の無効化] をクリックします。
サードパーティのログサービスの使用 (ACK 専用クラスターのみ)
監査ログストレージには SLS が推奨されます。サードパーティのログサービスを使用する場合は、クラスターの作成時に SLS をスキップして、そのサードパーティサービスを統合します。RAW 監査ログは、マスターノード上の /var/log/kubernetes/kubernetes.audit に JSON 形式で保存されています。
監査ポリシーと監査バックエンドの設定 (ACK 専用クラスター)
ACK 専用クラスターでは、デフォルトで [Log Service の有効化] が選択されています。監査イベントは監査ポリシーに従い収集され、バックエンドのログファイルシステムに書き込まれます。
監査ポリシー
監査ポリシーは、どのイベントをどの詳細レベルで収集するかを定義します。監査レベルは 4 種類あります。
| 監査レベル | 収集される内容 |
|---|---|
| None | 何も収集しません。一致するイベントはスキップされます。 |
| Metadata | リクエストメタデータ (ユーザー情報、タイムスタンプなど) のみ。リクエストまたはレスポンスのボディは含まれません。 |
| Request | リクエストメタデータとボディ。レスポンスボディは含まれません。非リソースリクエストは対象外です。 |
| RequestResponse | リクエストメタデータ、ボディ、レスポンスボディ。非リソースリクエストは対象外です。 |
監査ポリシーは、--audit-policy-file フラグによって、マスターノードの /etc/kubernetes/audit-policy.yml から読み込まれます。デフォルトの ACK ポリシー:
apiVersion: audit.k8s.io/v1 # 必須。クラスターの Kubernetes バージョンが 1.24 以降の場合は audit.k8s.io/v1 に設定し、1.24 より前の場合は audit.k8s.io/v1beta1 に設定します。
kind: Policy
# RequestReceived ステージで監査イベントを生成する必要はありません。
omitStages:
- "RequestReceived"
rules:
# 以下の種類のリクエストは頻繁に発生し、リスクが低いため、ルールを None に設定してこれらのリクエストをスキップすることを推奨します。
- level: None
users: ["system:kube-proxy"]
verbs: ["watch"]
resources:
- group: "" # コア
resources: ["endpoints", "services"]
- level: None
users: ["system:unsecured"]
namespaces: ["kube-system"]
verbs: ["get"]
resources:
- group: "" # コア
resources: ["configmaps"]
- level: None
users: ["kubelet"] # レガシー kubelet ID
verbs: ["get"]
resources:
- group: "" # コア
resources: ["nodes"]
- level: None
userGroups: ["system:nodes"]
verbs: ["get"]
resources:
- group: "" # コア
resources: ["nodes"]
- level: None
users:
- system:kube-controller-manager
- system:kube-scheduler
- system:serviceaccount:kube-system:endpoint-controller
verbs: ["get", "update"]
namespaces: ["kube-system"]
resources:
- group: "" # コア
resources: ["endpoints"]
- level: None
users: ["system:apiserver"]
verbs: ["get"]
resources:
- group: "" # コア
resources: ["namespaces"]
# /healthz*、/version*、/swagger* などの読み取り専用 URL のルールを None に設定します。
- level: None
nonResourceURLs:
- /healthz*
- /version
- /swagger*
# イベントのルールを None に設定します。
- level: None
resources:
- group: "" # コア
resources: ["events"]
# 機密情報やバイナリファイルを含む可能性のある Secrets、ConfigMaps、TokenReview API リクエストのルールを Metadata に設定します。
- level: Metadata
resources:
- group: "" # コア
resources: ["secrets", "configmaps"]
- group: authentication.k8s.io
resources: ["tokenreviews"]
# レスポンスには大量のデータが含まれる可能性があるため、ルールを Request に設定してレスポンスボディが収集されないようにします。
- level: Request
verbs: ["get", "list", "watch"]
resources:
- group: "" # コア
- group: "admissionregistration.k8s.io"
- group: "apps"
- group: "authentication.k8s.io"
- group: "authorization.k8s.io"
- group: "autoscaling"
- group: "batch"
- group: "certificates.k8s.io"
- group: "extensions"
- group: "networking.k8s.io"
- group: "policy"
- group: "rbac.authorization.k8s.io"
- group: "settings.k8s.io"
- group: "storage.k8s.io"
# 既知の Kubernetes API リクエストについては、リクエストとレスポンスのボディを収集するため、ルールはデフォルトで RequestResponse に設定されます。
- level: RequestResponse
resources:
- group: "" # コア
- group: "admissionregistration.k8s.io"
- group: "apps"
- group: "authentication.k8s.io"
- group: "authorization.k8s.io"
- group: "autoscaling"
- group: "batch"
- group: "certificates.k8s.io"
- group: "extensions"
- group: "networking.k8s.io"
- group: "policy"
- group: "rbac.authorization.k8s.io"
- group: "settings.k8s.io"
- group: "storage.k8s.io"
# その他のリクエストについては、ルールはデフォルトで Metadata に設定されます。
- level: Metadata
主な動作:
-
ログはリクエスト受信時ではなく、レスポンスヘッダー送信後に生成されます。
-
kube-proxy の watch リクエスト、kubelet および
system:nodesによるノードへの GET リクエスト、kube-system のエンドポイント操作、および API サーバーによる名前空間への GET リクエストは除外されます。 -
authentication、rbac、certificates、autoscaling、およびstorageAPI の読み取り操作 (get、list、watch) は、Requestレベルでログに記録されます。これらの API に対する書き込み操作はRequestResponseでログに記録されます。 -
Secret と ConfigMap は
Metadataにのみ記録されるため、その内容は監査ログに書き込まれることはありません。
監査バックエンド
監査イベントは、マスターノードのローカルファイルシステムに JSON ファイルとして書き込まれます。/etc/kubernetes/manifests/kube-apiserver.yaml の API サーバー設定が、次のフラグでバックエンドの動作を制御します:
| フラグ | 説明 | デフォルト |
|---|---|---|
--audit-log-maxbackup |
保持するローテーション済みログファイルの最大数 | 10 |
--audit-log-maxsize |
ローテーションされるまでのログファイルあたりの最大サイズ | 100 MB |
--audit-log-path |
監査ログファイルの出力パス | /var/log/kubernetes/kubernetes.audit |
--audit-log-maxage |
ローテーション済みログファイルの保持期間 | 7 日 |
--audit-policy-file |
監査ポリシーファイルへのパス | /etc/kubernetes/audit-policy.yml |
次のステップ
-
コンテナ内の
kubectl execコマンドを監査するには、「コンテナ監査を有効にする」をご参照ください。 -
エンタープライズセキュリティについては、「セキュリティのベストプラクティス」をご参照ください。