Container & bảo mật trong Kubernetes

Hẳn mọi người đều đã nghe tới một sự kiện mang tính lịch sử vào năm 2013, đó là sự ra đời của Docker. Việc Docker ra đời đã làm cho việc sử dụng container chưa bao giờ dễ dàng đến thế. Nhưng container ra đời từ khi nào? Vâng, câu trả lời là… từ rất lâu rồi. Vì container là một tập hợp các mảnh ghép công nghệ, mảnh ghép đầu tiên được ra đời vào năm 1979 trên Unix version 7, đó là chroot system. Để rồi từ đó, các mảnh ghép khác lần lượt ra đời.

OK. Quay lại với Google, trước thời điểm 2013 với sự kiện Docker ra đời, thì Google cũng đã tự triển khai các ứng dụng của họ trong container rồi, như Gmail, Search. Từ các sản phẩm in-house (tự cung cấp nội bộ) là Borg, Omega phục vụ việc điều phối container cho các ứng dụng nội bộ, Google đã tạo ra một nền tảng mới có tên là Kubernetes (K8S), sau này tặng cho Cloud Native Computing Foundation (CNCF) như một dự án nguồn mở tuân theo giấy phép Apache 2.0 vào năm 2014. Kể từ đó, Kubernetes trở thành một công nghệ quan trọng bậc nhất trên hành tinh này.

Chắc hẳn tới thời điểm hiện tại, từ khoá “Kubernetes” đã không còn xa lạ gì với tất cả anh em.

Song hành với việc các ứng dụng ngày càng được triển khai rộng rãi trên nền tảng K8S, thì điều quan trọng là chúng ta phải biết cách bảo mật nó. Nhất là trong một nền tảng “năng động” như K8S, việc phát hiện sớm và giải quyết các mối đe doạ là quan trọng nhưng đồng thời cũng là một thách thức.

Falco là gì ? Falco làm gì ?

Falco là một công cụ mã nguồn mở phát hiện rủi ro và các mối đe doạ tốt nhất trên các nền tảng Kubernetes, containers, cloud & on premise. Falco được ví như một camera an ninh, liên tục phát hiện các hành vi đáng ngờ, các thay đổi về cấu hình, xâm nhập và đánh cắp dữ liệu. Dự án ban đầu được Sysdig, Inc tạo ra vào năm 2016. Sau đấy thì Falco được đóng góp cho Cloud Native Computing Foundation (CNCF) để tiếp tục nghiên cứu và phát triển. Falco.

 

Chính vì vậy mà Falco “được bảo kê” bởi CNCF, và tương lai nếu security container trên k8s được ưu tiên tích hợp Falco cũng là điều dễ hiểu =))

Trong phạm vi bài chia sẻ hôm nay mình sẽ không đề cập sâu về K8S, vì để trình bày hết về K8S thì có thể cần cả một series dài, nếu các bạn quan tâm thì mình sẽ làm những phần tiếp theo chia sẻ về nền tảng Ku-bơ-ne-tít này (dựa trên những kiến thức mà mình tự tìm hiểu & triển khai thực thế).

Vậy thì Falco làm được những gì ?

Theo như trên trang chủ của Falco thì nó có thể giải quyết được những vấn đề:

❖        Phát hiện và cảnh báo các hành vi liên quan tới thay đổi namespace Kubernetes.

❖        Phát hiện và cảnh báo đặc quyền liên quan tới privileged trong containers.

❖        Phát hiện hành vi đọc/ghi vào các thư mục như /etc, /usr/bin, /usr/sbin, etc…

❖        Phát hiện việc tạo các liên kết symlinks.

❖        Phát hiện hành vi thay đổi quyền sở hữu.

❖        Phát hiện kết nối bất thường (C&C).

❖        Phát hiện các hành vi thực thi executing shell dùng sh, bash, csh, zsh, etc

❖        Phát hiện hành vi executing SSH dùng ssh, scp, sftp, etc

❖        Phát hiện hành vi thực thi coreutils (touch, whoami, curl, etc)

❖        Phát hiện hay đổi thông tin login.

❖        Phát hiện spawned processes sử dụng execve.

❖        Phát hiện và cảnh báo việc sửa đổi shadowutil hoặc passwd qua thực thi shadowconfig, pwck, chpasswd, getpasswd, change, useradd, etc.

Chia sẻ thực tế thì mình cũng đã thử triển khai một giải pháp tương tự về audit logs là Auditd và có đưa ra đánh giá tổng quan của mình:

Auditd

Falco

– Giải pháp AuditD chỉ triển khai được trên Host/OS.

– Giải pháp AuditD cần phải giải mã logs để đọc được một số thông tin.

– Giải pháp AuditD một rules dùng kích hoạt cho nhiều sự kiện, dễ dẫn tới việc gây ra nhiều cảnh báo rác.

– Triển khai trên Host/OS dễ ảnh hưởng tới các service khác đang chạy.

– Falco triển khai trên cả Host/OS, Containers và Kubernetes.

– Falco được đẩy ra dạng clear text, rõ ràng và đầy đủ thông tin.

– Với Falco một rules được dùng để kích hoạt một sự kiện duy nhất giúp phát hiện chính xác vấn đề alert.

– Triển khai trên Containers và Kubernetes giúp scale và control hiệu quả.

– Falco rules cú pháp đơn giản và dễ hiểu.

Phần tiếp theo mình sẽ trình bày tổng quan về kiến trúc, rules, cách triển khai Falco trên nền tảng K8S và một số case thực nghiệm để xem “camera an ninh” Falco hoạt động như thế nào.

Kiến trúc & Rules

Mô hình kiến trúc Falco:

Sơ đồ kiến trúc hệ thống

Về cơ bản thì Falco được chia làm 3 thành phần chính:

1. Module eBPF: tương tác với Kernel hệ thống ghi lại các thao tác liên quan tới: chạy lệnh gì, thông tin ra sao, gọi tới các hàm nào…

Kiến trúc container tương tác với Kernel

  1. Filter Expression: cung cấp bộ module rule engine thực hiện chức năng lọc ra các thông tin sự kiện và xuất ra logs.
  • Falco rules là một file yaml chứa các thành phần:

Các thành phần của một file rules Falco

Trong đó:

  • rule: tên rules.
  • condition: filtering expression áp dụng cho event để xem có khớp với rules hay không.
  • desc: mô tả của rule.
  • output: đầu ra cho cảnh báo.
  • priority: mức độ nghiêm trọng của hành vi.
  • exceptions: ngoại lệ để rules ko tạo cảnh báo.
  • enabled: nếu set true thì rule sẽ được bật.
  • tags: đánh dấu rule.
  • warn_evttypes: nếu set false thì hệ thống sẽ bỏ qua các quy tắc ko có event_type.
  • skip-if-unknown-filter: nếu set true, nếu một rules chứa bộ lọc thì rule sẽ được áp dụng nhưng không thực hiện.
  • source: chọn nguồn cho event.

Các thành phần cơ bản và bắt buộc của một rule

  1. Alerting: Falco có 5 đầu ra cho các event của nó: stdout, file, gRPC, shell và http. Thêm vào đó có thể sử dụng công cụ Falcosidekick để mở rộng output.

Falco ouput alerting

Triển khai Falco trên Kubernetes

Yêu cầu:

Hạ tầng K8S đã được cài đặt sẵn. Bạn có thể sử dụng hạ tầng cloud Kubernetes offering from AWS/GCP hoặc cài nhanh local sử dụng minikube. Trong bài viết này mình sẽ hướng dẫn các bạn cách triển khai nhanh Falco bằng công cụ Helm (một trình quản lý gói ứng dụng cho Kubernetes, điều phối tải xuống, cài đặt và triển khai ứng dụng).

“Anh em ơi !! bắt đầu thôi ”

  1. Thêm falcosecurity repo trong Helm
$ helm repo add falcosecurity https://falcosecurity.github.io/charts
$ helm repo update
Hang tight while we grab the latest from your chart repositories......
Successfully got an update from the "falcosecurity" chart repository...
Successfully got an update from the "stable" chart repository
Update Complete. ⎈Happy Helming!⎈

2. Cài đặt chart

$ helm install falco falcosecurity/falco
NAME: falco
LAST DEPLOYED: Mon Sep 9 22:09:28 2022
NAMESPACE: default
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
Falco agents are spinning up on each node in your cluster. After a few
seconds, they are going to [start monitoring your containers](/observability-consulting/) looking for
security issues.
No further action should be required.

3. Chờ vài giây để việc triển khai hoàn tất

Kiểm tra triển khai thành công bằng lệnh:

$ helm ls
$ kubectl get pods

Như vậy là chúng ta đã triển khai thành công Falco trên nền tảng K8S thông qua công cụ Helm. Bây giờ cùng mình test xem nó hoạt động như thế nào nhé !!

Thiết lập môi trường

Chúng ta sẽ cần phải thiết lập môi trường để mô phỏng lại một cuộc tấn công và phát hiện chúng. Ở đây mình sẽ dùng Helm để triển khai.

Thêm Helm repository và cài đặt mysql-db chart:

$ helm repo add stable https://charts.helm.sh/stable
$ helm repo update
Hang tight while we grab the latest from your chart repositories...
...Successfully got an update from the "falcosecurity" chart repository
...Successfully got an update from the "stable" chart repository
Update Complete. ⎈Happy Helming!⎈

$ helm install mysql-db stable/mysql
NAME: mysql-db
LAST DEPLOYED: Mon Sep 9 22:11:07 2022
NAMESPACE: default
STATUS: deployed
REVISION: 1
NOTES:
MySQL can be accessed via port 3306 on the following DNS name from within your cluster:
mysql-db.default.svc.cluster.local
…

Giờ cùng xem qua một lượt về logs Falco xem nhé:

$ kubectl get pods
NAME                      READY  STATUS   RESTARTS  AGE
falco-6rr9r               1/1    Running  0         49m
mysql-db-d5dc6b85d-77hrm  1/1    Running  0         47m
ubuntu                    1/1    Running  0         43m
$ kubectl logs -f falco-6rr9r # Thay tên Falco pod ở đây

Phân tích Falco logs :

Các bước đầu tiên mà kẻ tấn công thực hiện sau khi chúng có quyền truy cập vào một cụm Kubernetes là sử dụng các lệnh an toàn để có thể thu thập được nhiều thông tin chi tiết về cụm. Ở đây mình sẽ thực hiện lại một vài thao tác mô phỏng các hành động mà kẻ tấn công có thể làm để xem các cảnh báo có thể nhận được từ Falco, rules này có thể được điều chỉnh theo yêu cầu của bạn. Bạn có thể tìm thấy các quy tắc mặc định của Falco tại đây: https://github.com/falcosecurity/falco/tree/master/rules.

Case 1: Terminal shell in container

Description: Detecting terminal shells being spawned in pods. We open a terminal shell on a running pod to replicate the scenario.

$ kubectl exec -it mysql-db-d5dc6b85d-77hrm -- bash -il # Thay pods name của bạn ở đây

Detection:

18:08:40.584075795: Notice A shell was spawned in a container with an attached terminal (user=root user_loginuid=-1 k8s.ns=default k8s.pod=mysql-db-d5dc6b85d-77hrm container=3fc8155f9d1a shell=bash parent=runc cmdline=bash -il terminal=34816 container_id=3fc8155f9d1a image=mysql) k8s.ns=default k8s.pod=mysql-db-d5dc6b85d-77hrm container=3fc8155f9d1a

Case 2: Kết nối tới máy chủ Kubernetes API Server từ container

Description: We run kube-recon, which is a tool which does initial reconnaissance in a Kubernetes environment. This rule detects attempts to contact the Kubernetes API Server from a container.

$ kubectl run kuberecon --tty -i --image octarinesec/kube-recon
/ # ./kube-recon2022/09/09 18:21:22 Testing K8S API permissions
2022/09/09 18:21:23 Your K8S API Server is configured properly
2022/09/09 18:21:23 Running Nmap on the discovered IPs
2022/09/09 18:21:23 Getting local ip address and subnet
2022/09/09 18:21:23 Trying to download EICAR file.
2022/09/09 18:21:23 Downloaded EICAR successfully. No malware protection is in place

Detection:

18:20:45.927730981: Notice A shell was spawned in a container with an attached terminal (user=root user_loginuid=-1 k8s.ns=<NA> k8s.pod=<NA> container=4f63870599d0 shell=sh parent=<NA> cmdline=sh terminal=34816 container_id=4f63870599d0 image=octarinesec/kube-recon) k8s.ns=<NA> k8s.pod=<NA> container=4f63870599d0
18:21:22.657590195: Warning Docker or kubernetes client executed in container (user=root user_loginuid=-1 k8s.ns=default k8s.pod=kuberecon container=4f63870599d0 parent=kube-recon cmdline=kubectl get pods image=octarinesec/kube-recon:latest) k8s.ns=default k8s.pod=kuberecon container=4f63870599d0
18:21:22.723707794: Notice Unexpected connection to K8s API Server from container (command=kubectl get pods k8s.ns=default k8s.pod=kuberecon container=4f63870599d0 image=octarinesec/kube-recon:latest connection=172.17.0.5:56972->10.96.0.1:443) k8s.ns=default k8s.pod=kuberecon container=4f63870599d0

Case 3: Kiểm tra xem shell có phải là môi trường container hay không (phát hiện thay đổi namespace)

Description: amicontained is a tool to check whether the shell is a containerized environment. The rule detects an attempt to change a program/thread’s namespace.

$ cd /tmp;
 curl -L -o amicontained https://github.com/genuinetools/amicontained/releases/download/v0.4.7/amicontained-linux-amd64;
 chmod 555 amicontained;
 ./amicontained
 Output:
 Container Runtime: docker
 Has Namespaces:  pid: true  user: false
 AppArmor Profile: kernel
 Capabilities:
  BOUNDING -> chown dac_override fowner fsetid kill setgid setuid setpcap net_bind_service net_raw sys_chroot mknod audit_write setfcap
 Seccomp: disabledBlocked Syscalls (19):  MSGRCV SYSLOG SETSID VHANGUP PIVOT_ROOT ACCT SETTIMEOFDAY UMOUNT2 SWAPON SWAPOFF REBOOT SETHOSTNAME SETDOMAINNAME INIT_MODULE DELETE_MODULE LOOKUP_DCOOKIE KEXEC_LOAD OPEN_BY_HANDLE_AT FINIT_MODULE

Detection:

18:43:37.288344192: Notice Namespace change (setns) by unexpected program (user=root user_loginuid=-1 command=amicontained parent=bash k8s.ns=default k8s.pod=kuberecon container=c6112967b4f2 container_id=c6112967b4f2 image=octarinesec/kube-recon:latest) k8s.ns=default k8s.pod=kuberecon container=c6112967b4f2
Mon Nov 9 18:43:37 2020: Falco internal: syscall event drop. 9 system calls dropped in last second.
18:43:37.970973376: Critical Falco internal: syscall event drop. 9 system calls dropped in last second. (ebpf_enabled=0 n_drops=9 n_drops_buffer=0 n_drops_bug=0 n_drops_pf=9 n_evts=15232)

Như vậy là mình đã vừa test qua 3 case về một trong những hành động mà kẻ tấn công có thể làm sau khi vào được một cụm K8S. Falco đều có thể phát hiện và đưa ra cảnh báo. Những logs này thì đang được Falco ouput ra dưới dạng raw logs. À, nếu bạn muốn trực quan hoá nó thông qua giao diện thì Falco cũng có công cụ Falcosidekick-ui hỗ trợ luôn nhé.

Đại loại trông nó sẽ như thế này

Hiển thị event theo thời gian thực

Hiển thị dạng biểu đồ tròn tương quan sự kiện

Hy vọng qua bài này các bạn có cái nhìn tổng quan về công cụ Falco security Kubernetes này và có thể tự tìm hiểu thêm các tính năng advance hơn nữa để áp dụng vào hệ thống của các bạn.

Mình sẽ để đường link ở đây cho bạn nào quan tâm nhé. Chào thân ái !!

250 lượt xem