Аудит кластера Kubernetes с помощью Wazuh
Wazuh, как SIEM система является мощным компонентом обеспечивающим безопасность кластера K8s. Он анализирует данные журналов в реальном времени, обеспечивая раннее обнаружение угроз и способствуя быстрому реагированию на инциденты. Способность Wazuh собирать и интерпретировать данные из среды Kubernetes позволяет командам безопасности выявлять угрозы и оперативно реагировать на них, сводя к минимуму потенциальный ущерб.
Кроме анализа угроз, Wazuh помогает продемонстрировать соответствие отраслевым стандартам безопасности, создавая подробные отчеты о событиях и мерах безопасности. После инцидента он предоставляет ценные данные для детальной экспертизы, позволяя командам понять причину инцидента и предотвратить его повторение в будущем.
В этой статье мы рассмотрим основной процесс создания оповещений о событиях Kubernetes с помощью Wazuh, в частности для кластера RKE2.
План работ - Создадим Webhook listener на сервере Wazuh, чтобы получать логи из кластера K8s.
- Включим аудит в кластере K8s, и настроим отправку логов на сервер Wazuh
- Создадим правила обработки событий, полученных сервером Wazuh от кластера K8s.
Требования - Сервер Wazuh
- Кластер Kubernetes
Настраиваем сервер Wazuh
- Сервер Wazuh
- Кластер Kubernetes
Настраиваем сервер Wazuh
Создадим webhook listener на сервере Wazuh, для получения логов с нашего сервера. Так же в этой части мы создадим сертификаты для обеспечения условно-безопасного взаимодействия между сервером Wazuh и кластером K8s.
Логинимся в сервер Wazuh:
ssh user@wazuhServer
Создаём директорию для webhook endpoint:
mkdir -p /var/ossec/integrations/kubernetes-webhook/
Создаём конфигурационный файл сертификата - /var/ossec/integrations/kubernetes-webhook/csr.conf
:
Файл можно использовать как есть, только заменив <wazuh_server_ip>
на адрес своего сервера.
[ req ]prompt = nodefault_bits = 2048default_md = sha256distinguished_name = req_distinguished_namex509_extensions = v3_req[req_distinguished_name]C = USST = CaliforniaL = San JoseO = WazuhOU = Research and developmentemailAddress = Этот адрес электронной почты защищён от спам-ботов. У вас должен быть включен JavaScript для просмотра. = <wazuh_server_ip>[ v3_req ]authorityKeyIdentifier=keyid,issuerbasicConstraints = CA:FALSEkeyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEnciphermentsubjectAltName = @alt_names[alt_names]IP.1 = <wazuh_server_ip>
Создаём публичный и приватны ключи:
openssl req -x509 -new -nodes -newkey rsa:2048 -keyout /var/ossec/integrations/kubernetes-webhook/rootCA.key -out /var/ossec/integrations/kubernetes-webhook/rootCA.pem -batch -subj "/C=US/ST=California/L=San Jose/O=Wazuh"
Создаём запрос на подписание ключей:
openssl req -new -nodes -newkey rsa:2048 -keyout /var/ossec/integrations/kubernetes-webhook/server.key -out /var/ossec/integrations/kubernetes-webhook/server.csr -config /var/ossec/integrations/kubernetes-webhook/csr.conf
Генерируем сертификат сервера:
openssl x509 -req -in /var/ossec/integrations/kubernetes-webhook/server.csr -CA /var/ossec/integrations/kubernetes-webhook/rootCA.pem -CAkey /var/ossec/integrations/kubernetes-webhook/rootCA.key -CAcreateserial -out /var/ossec/integrations/kubernetes-webhook/server.crt -extfile /var/ossec/integrations/kubernetes-webhook/csr.conf -extensions v3_req
Создаём Webhook listener
Установим Flask (впрочем лучшим вариантом будет сделать это с помощью пакетного менеджера)
/var/ossec/framework/python/bin/pip3 install flask
Создадим Python webhook listener /var/ossec/integrations/custom-webhook.py
. <wazuh_server_ip>
здесь так же будет заменяться вашим IP.
#!/var/ossec/framework/python/bin/python3 import json from socket import socket, AF_UNIX, SOCK_DGRAM from flask import Flask, request PORT = 8080 CERT = ‘/var/ossec/integrations/kubernetes-webhook/server.crt’ CERT_KEY = ‘/var/ossec/integrations/kubernetes-webhook/server.key’ socket_addr = ‘/var/ossec/queue/sockets/queue’ def send_event(msg): string = ‘1:k8s:{0}’.format(json.dumps(msg)) sock = socket(AF_UNIX, SOCK_DGRAM) sock.connect(socket_addr) sock.send(string.encode()) sock.close() return True app = Flask(__name__) context = (CERT, CERT_KEY) @app.route(’/’, methods=[’POST’]) def webhook(): if request.method == ‘POST’: if send_event(request.json): print("Request sent to Wazuh") else: print("Failed to send request to Wazuh") return "Webhook received!" if __name__ == ‘__main__’: app.run(host=’<wazuh_server_ip>’, port=PORT, ssl_context=context)
Создаём сервис systemd
[Unit] Description=Wazuh webhook Wants=network-online.target After=network.target network-online.target [Service] ExecStart=/var/ossec/framework/python/bin/python3 /var/ossec/integrations/custom-webhook.py Restart=on-failure [Install] WantedBy=multi-user.target
И сразу запускаем его:
systemctl daemon-reloadsystemctl enable wazuh-webhook.servicesystemctl start wazuh-webhook.service
Если на сервере Wazuh запущен firewall, то не забудьте разрешить подключения по порту 8080
Настройка кластера K8s Create log directory: mkdir -p -m 700 /var/lib/rancher/k3s/server/logs
Создаём политику аудита /var/lib/rancher/k3s/server/audit.yaml
:
apiVersion: [audit.k8s.io/v1](http://audit.k8s.io/v1)kind: Policyrules:# Don’t log requests to the following API endpoints- level: NonenonResourceURLs:- ‘/healthz*’- ‘/logs’- ‘/metrics’- ‘/swagger*’- ‘/version’ # Limit requests containing tokens to Metadata level so the token is not included in the log - level: Metadata omitStages: - RequestReceived resources: - group: authentication.k8s.io resources: - tokenreviews # Extended audit of auth delegation - level: RequestResponse omitStages: - RequestReceived resources: - group: authorization.k8s.io resources: - subjectaccessreviews # Log changes to pods at RequestResponse level - level: RequestResponse omitStages: - RequestReceived resources: # core API group; add third-party API services and your API services if needed - group: ‘’ resources: [’pods’] verbs: [’create’, ‘patch’, ‘update’, ‘delete’] # Log everything else at Metadata level - level: Metadata omitStages: - RequestReceived
Создадим конфигурационный файл Webhook /var/lib/rancher/k3s/server/audit-webhook.yaml,
не забыв заменить в нём <wazuh_server_ip>
своим ip:
apiVersion: v1 kind: Config preferences: {} clusters: - name: wazuh-webhook cluster: insecure-skip-tls-verify: true server: https://<wazuh_server_ip>:8080 # kubeconfig files require a context. Provide one for the API server. current-context: webhook contexts: - context: cluster: wazuh-webhook user: kube-apiserver # Replace with name of API server if it’s different name: webhook
Добавим параметры Kubeapi, для загрузки конфигурации аудита и webhook (путь к сервису systemd для rke2-server.service - /usr/lib/systemd/system/rke2-server.service)
ExecStart=/usr/local/bin/rke2 \server \’--kube-apiserver-arg=audit-log-path=/var/lib/rancher/rke2/server/logs/audit.log’ \’--kube-apiserver-arg=audit-policy-file=/var/lib/rancher/rke2/server/audit.yaml’ \’--kube-apiserver-arg=audit-webhook-config-file=/var/lib/rancher/rke2/server/audit-webhook.yaml’ \’--kube-apiserver-arg=audit-webhook-batch-max-size=1’ \
Создаём правило обнаружения на сервере Wazuh
Добавляем следующие правила на сервер Wazuh в/var/ossec/etc/rules/local_rules.xml
:
<group name="k8s_audit,"> <rule id="110002" level="0"> <location>k8s</location> <field name="apiVersion">audit</field> <description>Kubernetes audit log.</description> </rule> <rule id="110003" level="5"> <if_sid>110002</if_sid> <regex type="pcre2">requestURI\":.+", \"verb\": \"create</regex> <description>Kubernetes request to create resource</description> </rule> <rule id="110004" level="5"> <if_sid>110002</if_sid> <regex type="pcre2">requestURI\":.+", \"verb\": \"delete</regex> <description>Kubernetes request to delete resource</description> </rule> </group>
Перезапускаем сервис wazuh-manager
systemctl restart wazuh-manager
Тестируем конфигурацию и правила, создавая и удаляя деплойменты на кластере. Например запустим на мастер-ноде команду:
kubectl create deployment hello-minikube --image=[k8s.gcr.io/echoserver:1.4](http://k8s.gcr.io/echoserver:1.4)
И сразу же, после того как дождёмся создания деплоймента, удаляем его:
kubectl delete deployment hello-minikube
В целом всё готово. Можно настроить уведомления в почту, телеграм и так далее, но это уже темы для отдельной статьи.