גיבויים של יומני ביקורת ב-Google Distributed Cloud (GDC) עם air gap שומרים רשומות היסטוריות בקטגוריות אחסון מרוחקות לצורך תאימות, ניתוח אבטחה והתאוששות מאסון. מגדירים פרטי כניסה לקטגוריה מרוחקת ומשימות העברה כדי לגבות את יומני הביקורת, או פורסים מכונה לשחזור כדי לשלוח שאילתות ליומנים ששוחזרו ב-Grafana.
לפני שמתחילים
חשוב לוודא שיש לכם גישה למקורות המידע הבאים:
- קטגוריה מרוחקת לגיבויים עם נקודת קצה, מפתח גישה סודי ומזהה של מפתח גישה.
- אישור של רשות אישורים (CA) למערכת האחסון.
- אשכול Kubernetes פעיל.
כדי לקבל את ההרשאות שנדרשות לניהול גיבויים, בקשו מהאדמין של Project IAM להקצות לכם את אחד מהתפקידים הבאים במרחב השמות של הפרויקט:
- יוצר קטגוריות לשחזור פלטפורמה של יומני ביקורת
- צפייה בקטגוריית פלטפורמה של יומני ביקורת
בהתאם לרמת הגישה וההרשאות שאתם צריכים, יכול להיות שתקבלו תפקידי יוצר או צופה למשאבים של קטגוריית הגיבוי במרחב השמות של הפרויקט. למידע נוסף על התפקידים האלה, ראו הכנת הרשאות IAM.
הגדרה של משתני סביבה: מגדירים את משתני הסביבה הבאים כדי להריץ את הפקודות מהדף הזה:
* The path of the kubeconfig file:
```sh
export KUBECONFIG=KUBECONFIG_PATH
```
Replace `KUBECONFIG_PATH` with the path to the
kubeconfig file for the Management API server.
* Your project namespace:
```sh
export PROJECT_NAMESPACE=PROJECT_NAMESPACE
```
אבטחת יומני ביקורת בגיבוי
בקטע הזה מוסבר איך יוצרים גיבוי של יומני ביקורת בקטגוריה מרוחקת.
הגדרת פרטי הכניסה לקטגוריה
צריך להגדיר את פרטי הכניסה לקטגוריות הבאות:
- קטגוריית המקור: הקטגוריה המקומית ב-GDC שמכילה את יומני הביקורת המקוריים שרוצים לאבטח.
- קטגוריית היעד: הקטגוריה המרוחקת שבה רוצים ליצור את הגיבוי של יומני הביקורת.
מגדירים את פרטי הכניסה לשני הקטגוריות:
קטגוריית המקור
מציגים את רשימת הקטגוריות במרחב השמות של הפרויקט משרת API של Management API:
kubectl --kubeconfig=${KUBECONFIG} get bucket -n ${PROJECT_NAMESPACE}השדה
DESCRIPTIONבפלט מציין אילו קטגוריות מכילות יומני ביקורת. בוחרים את הקטגוריה שמכילה את היומנים שרוצים לאבטח.מגדירים את משתני הסביבה הבאים לפי המידע מהפלט:
SRC_BUCKET= BUCKET_NAME SRC_ENDPOINT = ENDPOINT SRC_PATH= FULLY_QUALIFIED_BUCKET_NAMEמחליפים את מה שכתוב בשדות הבאים:
-
BUCKET_NAME: הערך שלBUCKET NAMEבפלט. -
ENDPOINT: הערך שלENDPOINTבפלט. -
FULLY_QUALIFIED_BUCKET_NAME: הערך שלFULLY-QUALIFIED-BUCKET-NAMEבפלט.
-
משיגים את שם הסוד של הקטגוריה:
kubectl get secret -n PROJECT_NAMESPACE -o json| jq --arg jq_src $SRC_BUCKET '.items[].metadata|select(.annotations."object.gdc.goog/subject"==$jq_src)|.name'מגדירים את המשתנה של פרטי הכניסה:
SRC_CREDENTIALS="PROJECT_NAMESPACE/SECRET_NAME"מחליפים את
SECRET_NAMEבשם הסוד שקיבלתם.יוצרים את הסוד של אישור ה-CA:
kubectl create secret generic -n PROJECT_NAMESPACE audit-log-loki-ca \ --from-literal=ca.crt=CERTIFICATEמחליפים את
CERTIFICATEבאישור ה-CA של מערכת האחסון.מגדירים את המשתנה של אישור ה-CA:
SRC_CA_CERTIFICATE=PROJECT_NAMESPACE/audit-log-loki-ca
קטגוריית היעד
מגדירים את משתני הסביבה הבאים לקטגוריית היעד המרוחקת:
DST_ACCESS_KEY_ID= ACCESS_KEY DST_SECRET_ACCESS_KEY= ACCESS_SECRET DST_ENDPOINT= REMOTE_ENDPOINT DST_PATH= REMOTE_BUCKET_NAMEמחליפים את מה שכתוב בשדות הבאים:
-
ACCESS_KEY: מפתח הגישה של הקטגוריה. -
ACCESS_SECRET: סוד הגישה של הקטגוריה. -
REMOTE_ENDPOINT: נקודת הקצה של הקטגוריה. -
REMOTE_BUCKET_NAME: שם הקטגוריה.
-
יוצרים סוד לקטגוריה המרוחקת:
kubectl create secret generic -n PROJECT_NAMESPACE s3-bucket-credentials \ --from-literal=access-key-id=$DST_ACCESS_KEY_ID \ --from-literal=secret-access-key=$DST_SECRET_ACCESS_KEYמחליפים את
PROJECT_NAMESPACEבמרחב השמות של הפרויקט.מגדירים את המשתנה של פרטי הכניסה:
DST_CREDENTIALS=PROJECT_NAMESPACE/s3-bucket-credentialsאם צריך, יוצרים סוד עם אישור ה-CA של הקטגוריה ומגדירים את המשתנה של אישור ה-CA:
kubectl create secret generic -n PROJECT_NAMESPACE s3-bucket-ca \ --from-literal=ca.crt=REMOTE_CERTIFICATEמחליפים את
REMOTE_CERTIFICATEבאישור ה-CA של קטגוריית היעד.מגדירים את המשתנה של אישור ה-CA:
DST_CA_CERTIFICATE=PROJECT_NAMESPACE/s3-bucket-ca
יומני ביקורת של העברות
מפעיל התשתית (IO) צריך ליצור משימת העברה כדי לייצא את יומני הביקורת מקטגוריית המקור לקטגוריית היעד לצורך הגיבוי. ה-IO משתמש בחשבון השירות audit-log-pa-backup-restore-sa שהוגדר מראש כדי להגדיר את שירות ההעברה לקטגוריות מוגדרות מראש של יומני ביקורת של הפלטפורמה.
כדי להעביר יומני ביקורת, משתמשים במשימה הבאה:
apiVersion: batch/v1
kind: Job
metadata:
name: audit-log-transfer-job
namespace: PROJECT_NAMESPACE
spec:
template:
spec:
serviceAccountName: audit-log-pa-backup-restore-sa
containers:
- name: storage-transfer-pod
image: gcr.io/private-cloud-staging/storage-transfer:latest
imagePullPolicy: Always
command:
- /storage-transfer
args:
- '--src_endpoint=$SRC_ENDPOINT
- '--dst_endpoint=$DST_ENDPOINT
- '--src_path=\$SRC_PATH
- '--dst_path=\$DST_PATH
- '--src_credentials=$SRC_CREDENTIALS
- '--dst_credentials=$DST_CREDENTIALS
- '--dst_ca_certificate_reference=$DST_CA_CERTIFICATE # Optional. Based on destination type.
- '--src_ca_certificate_reference=$SRC_CA_CERTIFICATE
- '--src_type=s3'
- '--dst_type=s3'
- '--bandwidth_limit=100M' # Optional of the form '10K', '100M', '1G' bytes per second
restartPolicy: OnFailure # Will restart on failure.
עוקבים אחרי העברת הנתונים באמצעות שם המשימה (audit-log-transfer-job) ומרחב השמות של הפרויקט.
המשימה מסתיימת כשכל הנתונים מועברים לקטגוריית היעד.
שחזור יומני ביקורת מגיבוי
בקטע הזה מוסבר איך לשחזר יומני ביקורת מגיבוי בקטגוריה מרוחקת.
יצירת קטגוריה ליומנים ששוחזרו
יוצרים קטגוריה לאחסון יומני הביקורת ששוחזרו:
יוצרים את קטגוריית השחזור:
apiVersion: object.gdc.goog/v1 kind: Bucket metadata: annotations: object.gdc.goog/audit-logs: PA labels: logging.private.gdch.goog/loggingpipeline-name: default name: audit-logs-loki-restore-pa namespace: PROJECT_NAMESPACE spec: bucketPolicy: lockingPolicy: defaultObjectRetentionDays: 1 description: Bucket for storing audit-logs-loki logs restore storageClass: Standardמחליפים את
PROJECT_NAMESPACEבמרחב השמות של הפרויקט.צפייה בקטגוריה:
kubectl get bucket audit-logs-loki-restore-pa -n PROJECT_NAMESPACEיצירת הקטגוריה עשויה להימשך כמה דקות.
מגדירים את משתני הסביבה הבאים לפי המידע מהפלט:
DST_BUCKET= RESTORE_BUCKET_NAME DST_ENDPOINT = RESTORE_ENDPOINT DST_PATH= RESTORE_FULLY_QUALIFIED_BUCKET_NAMEמחליפים את מה שכתוב בשדות הבאים:
-
RESTORE_BUCKET_NAME: הערך שלBUCKET NAMEבפלט. -
RESTORE_ENDPOINT: הערך שלENDPOINTבפלט. -
RESTORE_FULLY_QUALIFIED_BUCKET_NAME: הערך שלFULLY-QUALIFIED-BUCKET-NAMEבפלט.
-
משיגים את שם הסוד של הקטגוריה:
kubectl get secret -n PROJECT_NAMESPACE -o json| jq --arg jq_src $DST_BUCKET '.items[].metadata|select(.annotations."object.gdc.goog/subject"==$jq_src)|.name'מגדירים את המשתנים של פרטי הכניסה:
DST_SECRET_NAME=RESTORE_SECRET_NAME DST_CREDENTIALS="PROJECT_NAMESPACE/RESTORE_SECRET_NAME"מחליפים את
RESTORE_SECRET_NAMEבשם הסוד שקיבלתם.יוצרים את הסוד של אישור ה-CA:
kubectl create secret generic -n PROJECT_NAMESPACE audit-log-loki-restore-ca \ --from-literal=ca.crt=CERTIFICATEמחליפים את
CERTIFICATEבאישור ה-CA של מערכת האחסון.מגדירים את המשתנה של אישור ה-CA:
DST_CA_CERTIFICATE=PROJECT_NAMESPACE/audit-log-loki-restore-ca
הגדרת פרטי הכניסה של קטגוריית המקור
מגדירים את פרטי הכניסה של הקטגוריה שמכילה את הגיבוי של יומני הביקורת:
מגדירים את משתני הסביבה הבאים:
SRC_ACCESS_KEY_ID= ACCESS_KEY SRC_SECRET_ACCESS_KEY= ACCESS_SECRET SRC_ENDPOINT= REMOTE_ENDPOINT SRC_PATH= REMOTE_BUCKET_NAMEמחליפים את מה שכתוב בשדות הבאים:
-
ACCESS_KEY: מפתח הגישה של קטגוריית הגיבוי. -
ACCESS_SECRET: סוד הגישה של קטגוריית הגיבוי. -
REMOTE_ENDPOINT: נקודת הקצה של קטגוריית הגיבוי. -
REMOTE_BUCKET_NAME: השם של קטגוריית הגיבוי.
-
יוצרים סוד לקטגוריית הגיבוי:
kubectl create secret generic -n PROJECT_NAMESPACE s3-backup-bucket-credentials \ --from-literal=access-key-id=$SRC_ACCESS_KEY_ID \ --from-literal=secret-access-key=$SRC_SECRET_ACCESS_KEYמגדירים את המשתנה של פרטי הכניסה:
SRC_CREDENTIALS=PROJECT_NAMESPACE/s3-backup-bucket-credentialsיוצרים סוד עם אישור ה-CA של הקטגוריה:
kubectl create secret generic -n PROJECT_NAMESPACE s3-backup-bucket-ca \ --from-literal=ca.crt=BACKUP_CERTIFICATEמחליפים את
BACKUP_CERTIFICATEבאישור ה-CA של קטגוריית הגיבוי.מגדירים את המשתנה של אישור ה-CA:
SRC_CA_CERTIFICATE=PROJECT_NAMESPACE/s3-backup-bucket-ca
העברת יומני ביקורת ששוחזרו
מפעיל התשתית (IO) צריך ליצור משימת העברה כדי לשחזר את יומני הביקורת מקטגוריית הגיבוי לקטגוריית השחזור. ה-IO משתמש בחשבון השירות audit-log-pa-backup-restore-sa שהוגדר מראש כדי להגדיר את שירות ההעברה לקטגוריות מוגדרות מראש של יומני ביקורת של הפלטפורמה.
כדי להעביר יומני ביקורת, משתמשים במשימה הבאה:
apiVersion: batch/v1
kind: Job
metadata:
name: audit-log-restore-job
namespace: PROJECT_NAMESPACE
spec:
template:
spec:
serviceAccountName: audit-log-pa-backup-restore-sa
containers:
- name: storage-transfer-pod
image: gcr.io/private-cloud-staging/storage-transfer:latest
imagePullPolicy: Always
command:
- /storage-transfer
args:
- '--src_endpoint=$SRC_ENDPOINT
- '--dst_endpoint=$DST_ENDPOINT
- '--src_path=\$SRC_PATH
- '--dst_path=\$DST_PATH
- '--src_credentials=$SRC_CREDENTIALS
- '--dst_credentials=$DST_CREDENTIALS
- '--dst_ca_certificate_reference=$DST_CA_CERTIFICATE
- '--src_ca_certificate_reference=$SRC_CA_CERTIFICATE # Optional. Based on destination type
- '--src_type=s3'
- '--dst_type=s3'
- '--bandwidth_limit=100M' # Optional of the form '10K', '100M', '1G' bytes per second
restartPolicy: OnFailure # Will restart on failure.
עוקבים אחרי העברת הנתונים באמצעות שם המשימה (audit-log-restore-job) ומרחב השמות של הפרויקט.
המשימה מסתיימת כשכל הנתונים מועברים לקטגוריית השחזור.
גישה ליומנים ששוחזרו
פורסים מכונה של Loki כדי לגשת ליומנים ששוחזרו, באמצעות מניפסטים של הגדרה ופריסה:
יוצרים אובייקט
ConfigMapלהגדרת המכונה.דוגמה לאובייקט
ConfigMap:apiVersion: v1 kind: ConfigMap metadata: name: audit-logs-loki-restore-pa namespace: PROJECT_NAMESPACE data: loki.yaml: |- auth_enabled: true common: ring: kvstore: store: inmemory chunk_store_config: max_look_back_period: 0s compactor: shared_store: s3 working_directory: /data/loki/boltdb-shipper-compactor compaction_interval: 10m retention_enabled: true retention_delete_delay: 2h retention_delete_worker_count: 150 ingester: chunk_target_size: 1572864 chunk_encoding: snappy max_chunk_age: 2h chunk_idle_period: 90m chunk_retain_period: 30s autoforget_unhealthy: true lifecycler: ring: kvstore: store: inmemory replication_factor: 1 heartbeat_timeout: 10m max_transfer_retries: 0 wal: enabled: true flush_on_shutdown: true dir: /wal checkpoint_duration: 1m replay_memory_ceiling: 20GB limits_config: retention_period: 48h enforce_metric_name: false reject_old_samples: false ingestion_rate_mb: 256 ingestion_burst_size_mb: 256 max_streams_per_user: 20000 max_global_streams_per_user: 20000 per_stream_rate_limit: 256MB per_stream_rate_limit_burst: 256MB shard_streams: enabled: false desired_rate: 3MB schema_config: configs: - from: "2020-10-24" index: period: 24h prefix: index_ object_store: s3 schema: v11 store: boltdb-shipper server: http_listen_port: 3100 grpc_server_max_recv_msg_size: 104857600 grpc_server_max_send_msg_size: 104857600 analytics: reporting_enabled: false storage_config: boltdb_shipper: active_index_directory: /data/loki/boltdb-shipper-active cache_location: /data/loki/boltdb-shipper-cache cache_ttl: 24h shared_store: s3 aws: endpoint: $DST_ENDPOINT bucketnames: $DST_PATH access_key_id: ${S3_ACCESS_KEY_ID} secret_access_key: ${S3_SECRET_ACCESS_KEY} s3forcepathstyle: trueפורסים את המכונה כאובייקט
StatefulSetעםServiceכדי לגשת ליומנים.דוגמה לאובייקטים מסוג
StatefulSetו-Service:apiVersion: apps/v1 kind: StatefulSet metadata: labels: app: audit-logs-loki-restore-pa logging.private.gdch.goog/loggingpipeline-name: default name: audit-logs-loki-restore-pa namespace: PROJECT_NAMESPACE spec: persistentVolumeClaimRetentionPolicy: whenDeleted: Retain whenScaled: Retain podManagementPolicy: OrderedReady replicas: 1 revisionHistoryLimit: 10 selector: matchLabels: app: audit-logs-loki-restore-pa serviceName: audit-logs-loki-restore-pa template: metadata: labels: app: audit-logs-loki-restore-pa app.kubernetes.io/part-of: audit-logs-loki-restore-pa egress.networking.gke.io/enabled: "true" istio.io/rev: default logging.private.gdch.goog/log-type: audit spec: affinity: nodeAffinity: preferredDuringSchedulingIgnoredDuringExecution: - preference: matchExpressions: - key: node-role.kubernetes.io/control-plane operator: DoesNotExist - key: node-role.kubernetes.io/master operator: DoesNotExist weight: 1 podAntiAffinity: preferredDuringSchedulingIgnoredDuringExecution: - podAffinityTerm: labelSelector: matchExpressions: - key: app operator: In values: - audit-logs-loki-restore-pa topologyKey: kubernetes.io/hostname weight: 100 containers: - args: - -config.file=/etc/loki/loki.yaml - -config.expand-env=true - -target=all env: - name: S3_ACCESS_KEY_ID valueFrom: secretKeyRef: key: access-key-id name: $DST_SECRET_NAME optional: false - name: S3_SECRET_ACCESS_KEY valueFrom: secretKeyRef: key: secret-access-key name: $DST_SECRET_NAME optional: false image: gcr.io/private-cloud-staging/loki:v2.8.4-gke.2 imagePullPolicy: Always livenessProbe: failureThreshold: 3 httpGet: path: /ready port: http-metrics scheme: HTTP initialDelaySeconds: 330 periodSeconds: 10 successThreshold: 1 timeoutSeconds: 1 name: audit-logs-loki-restore-pa ports: - containerPort: 3100 name: http-metrics protocol: TCP - containerPort: 7946 name: gossip-ring protocol: TCP readinessProbe: failureThreshold: 3 httpGet: path: /ready port: http-metrics scheme: HTTP initialDelaySeconds: 45 periodSeconds: 10 successThreshold: 1 timeoutSeconds: 1 resources: limits: ephemeral-storage: 2000Mi memory: 8000Mi requests: cpu: 300m ephemeral-storage: 2000Mi memory: 1000Mi securityContext: readOnlyRootFilesystem: true terminationMessagePath: /dev/termination-log terminationMessagePolicy: File volumeMounts: - mountPath: /etc/loki name: config - mountPath: /data name: loki-storage - mountPath: /tmp name: temp - mountPath: /tmp/loki/rules-temp name: tmprulepath - mountPath: /etc/ssl/certs/storage-cert.crt name: storage-cert subPath: ca.crt - mountPath: /wal name: loki-storage dnsPolicy: ClusterFirst priorityClassName: audit-logs-loki-priority restartPolicy: Always schedulerName: default-scheduler securityContext: fsGroup: 10001 runAsGroup: 10001 runAsUser: 10001 serviceAccount: audit-log-pa-backup-restore-sa serviceAccountName: audit-log-pa-backup-restore-sa terminationGracePeriodSeconds: 4800 volumes: - emptyDir: {} name: temp - configMap: defaultMode: 420 name: audit-logs-loki-restore-pa name: config - emptyDir: {} name: tmprulepath - name: storage-cert secret: defaultMode: 420 secretName: web-tls updateStrategy: type: RollingUpdate volumeClaimTemplates: - apiVersion: v1 kind: PersistentVolumeClaim metadata: creationTimestamp: null name: loki-storage spec: accessModes: - ReadWriteOnce resources: requests: storage: 50Gi storageClassName: standard-rwo volumeMode: Filesystem --- apiVersion: v1 kind: Service metadata: name: audit-logs-loki-restore-pa namespace: PROJECT_NAMESPACE spec: internalTrafficPolicy: Cluster ipFamilies: - IPv4 ipFamilyPolicy: SingleStack ports: - name: http-metrics port: 3100 protocol: TCP targetPort: http-metrics selector: app: audit-logs-loki-restore-pa sessionAffinity: None type: ClusterIP
הצגת היומנים ששוחזרו
מגדירים את Grafana כדי להציג את יומני הביקורת ששוחזרו מהמכונה של Loki:
- פותחים את נקודת הקצה של Grafana בפרויקט. איך שולחים שאילתות וצופים ביומנים?
- בתפריט הניווט של ממשק המשתמש, לוחצים על Administration (ניהול) > Data sources (מקורות נתונים).
- לוחצים על הוספה של מקור נתונים חדש.
- בדף Add data source, בוחרים באפשרות Loki.
- בדף Settings, מזינים את הערך
Audit Logs - Restoreבשדה Name. בקטע HTTP, מזינים את הערך הבא בשדה כתובת URL:
http://audit-logs-loki-restore-pa.PROJECT_NAMESPACE.svc:3100בקטע כותרות HTTP מותאמות אישית, מזינים את הערכים הבאים בשדות המתאימים:
- כותרת:
X-Scope-OrgID - ערך:
infra-obs
- כותרת:
בתמונה 1, Loki מוצג כאפשרות בדף Add data source.

איור 1. הדף Add data source בממשק המשתמש של המכונה לניטור.

איור 2. הדף Settings בממשק המשתמש של המכונה למעקב.
האפשרות Audit Logs - Restore זמינה עכשיו כמקור נתונים ב-Log Explorer.