Cluster Security by Sysdig

Chan Suttichujit
NonTechCompany
Published in
5 min readDec 7, 2021

ปัจจุบันนี้มีการใช้งาน platform อย่าง Openshift หรือ Kubernetes อย่างแพร่หลายทั้งแบบบน cloud และแบบ on-premise แต่คำถามที่หลายๆคนอาจจะมีอยู่ในใจก็คือเราจะแน่ใจได้อย่างไรว่า cluster ของเรานั้นปลอดภัย? ปัญหาหลักของการจัดการ security ของ cluster และ application ที่ถูก deploy แบ่งได้เป็น 5 ข้อหลักๆ

  1. การป้องกัน Image ที่มี Vulnerability เข้าสู่ cluster
  2. การตรวจจับ Vulnerability บน runtime
  3. การทำ cluster security compliance
  4. การ monitor cluster
  5. การ monitor application

ในวันนี้เราจะมาลองใช้ tool ที่ชื่อ Sysdig เพื่อแก้ปัญหาข้างต้นกัน

Prerequisite

  1. Sysdig instance
  2. Docker
  3. Kubernetes|Openshift cluster
  4. Helm

Image Scanning

อย่างแรกเลยคือเราจะยืนยันได้อย่างไรว่า image ที่เราสร้างขึ้นมานั้นปลอดภัย? การสร้าง image ปรกติแล้วจะมีการใช้ image อันอื่นมาเป็น base ในการ build อีกทีทำให้เราไม่มีทางรู้ได้เลยว่าตัว base image นั้นวางใจได้หรือไม่ อีกทั้งเวลาที่มีการลง package เพิ่มเติมเราจะยืนยันได้อย่างไรว่า package เวอร์ชั่นนั้นๆปราศจากช่องโหว่? เราจึงต้องทำการ scan image ก่อนที่จะนำไป deploy ลงบน cluster เพื่อเป็นการป้องกัน

Inline Image Scanning

เราสามารถทำ active แสกนเมื่อใดก็ได้ที่เราต้องการ อาทิ เช่น

  1. ใน CICD pipeline
  2. บนเครื่องตัวเองหลังทดสอบการ build image

ขั้นตอนการ scan นั้นง่ายมากเนื่องจาก Sysdig มี image ที่ไว้ใช้ในการ scan image อยู่แล้ว (งงไหม?XD) ฉะนั้นขั้นตอนแรกที่เราต้องทำคือการดึง image นั้นลงมาบนเครื่องเราก่อนโดยใช้คำสั่ง

docker pull quay.io/sysdig/secure-inline-scan:2

ทำการ export API token ของ Sysdig secure โดนทำตามขั้นตอนที่ระบุใน Retrieve the Sysdig API token

export SYSDIG_API_TOKEN={API_TOKEN}
export SYSDIG_URL={SYSDIG_SECURE_URL}

รัน container เพื่อ scan image ที่เราต้องการได้เลยซึ่งในตัวอย่างนี้ผมจะทำการ scan image nginx:1.17.1

docker run --rm -u root --privileged \
-v /var/run/docker.sock:/var/run/docker.sock \
quay.io/sysdig/secure-inline-scan:2 \
--sysdig-url $SYSDIG_URL \
--sysdig-token $SYSDIG_API_TOKEN \
nginx:1.17.1

หลังจาก scan เสร็จ report ก็จะออกมาในหน้าตาคล้ายๆแบบนี้

cli scan report

ซึ่งเราสามารถกดที่ link หลัง View the full result เพื่อไปดู report อย่างละเอียดบน Sysdig ได้เลย

Sysdig scan report

Runtime Scan

คำถามก็คือถ้าหาก Scan ผ่านแล้วเรามั่นใจได้ 100% ตลอดไปเลยหรือไม่ว่าเราปลอดภัยแล้ว? คำตอบคือยังครับ เหตุผลเพราะว่า CVE ใหม่ๆนั้นถูกค้นพบโดย community ของ developer ทุกวันเพราะฉะนั้นการที่เราไม่เจอ vulnerability ใน image ของเราในวันนี้ หากเรา scan image เดิมอีกทีในอีก 1 เดือนข้างหน้า ก็อาจจะมี CVE ตัวใหม่โผล่มาก็เป็นได้ เพราะงั้นนอกจากป้องกันแล้วเรายังต้องสามารถจะตรวจจับ image ที่ถูกรันอยู่บน cluster ได้ใน runtime เช่นกัน

ขั้นแรกเราจะลง Sysdig Node Analyzer ซึ่งมาในรูปแบบของ Daemonset หน้าที่ของมันคือก็การไล่ scan image ที่ถูก Kubernetes ดึงลงมาตอน deploy pod นั่นเองซึ่ง image พวกนี้จะถูกเก็บไว้ตาม container runtime ของแต่ละ node

helm repo add sysdig https://charts.sysdig.com
helm repo update
helm install --create-namespace \
--namespace sysdig-agent sysdig-agent \
--set sysdig.accessKey=$SYSDIG_API_TOKEN \
--set sysdig.settings.collector=$SYSDIG_COLLECTOR_ENDPOINT \
--set sysdig.clusterName=thtechgarage \
--set nodeAnalyzer.apiEndpoint=$SYSDIG_URL \
sysdig/sysdig

เมื่อลงเสร็จทำการรัน command เพื่อเช็คสถานะ agent เราจะเห็นว่ามี daemonset 2 ตัวถูก deploy

kubectl get pod -n sysdig-agent

หลังจากลง agent เสร็จเรียบร้อยให้รอ agent ทำการ scan สักครู่หนึ่งแล้วให้เราไปที่เมนู Scanning แล้วกดเลือกที่ชื่อ cluster ของเราซึ่งในที่นี่ผมใช้ชื่อ thtechgarage เราก็จะเห็น result ของการทำ runtime image scan

Cluster Policy

ถึงแม้เราจะ scan image และเลือก deploy เฉพาะตัวที่ไม่มี vulerability ได้แล้ว แต่ไม่ได้หมายความว่า image นั้นจะปลอดภัย 100% เพราะการ scan นั้นสามารถตรวจจับได้แค่ CVE ของ package ที่ลงใน image นั้นๆ ถ้าหากว่ามีการ execute command หรือ action ที่สุ่มเสี่ยงต่อความปลอดภัยหรือ hijack resource ของ cluster เช่นการที่ที่รัน container มาขุด Bitcoin หรือการที่พยายาม execute network command หลายๆตัวบน container นั่นเอง กรณีนี้การ scan image จะไม่ช่วยอะไร แต่เป็น runtime policy ที่จะดักจับ behavior ของ container เหล่านี้ผ่าน audit log ของ operating system หรือ Kubernetes

Sysdig ใช้ Falco ในการทำ Cluster Policy Enforcement ซึ่งตัว Falco เองนั้นเป็นโปรเจ็คที่ทาง Sysdig สร้างและบริจาคให้ทาง CNCF นำไป incubating เรียบร้อยแล้วเช่นเดียวกับโปรเจ็คดังๆอย่างเช่น ArgoCD, Cri-O, Grpc, Opentelemetry, และอีกหลายๆโปรเจ็ค CNCF incubating

วิธีที่จะเปิดใช้ Cluster Policy นั้นง่ายมากเพียงแค่เราลง Sysdig agent อย่างที่เราได้ทำกันไปในขั้นตอนก่อนหน้านี้เท่านั้นเอง ตัว agent จะทำตัวเป็น enforcer เพื่อเก็บ audit log และ enforce policy ต่างๆที่เราตั้งไว้

Sysdig Policies

เราสามารถเลือกเปิดหรือปิด policy ได้ผ่านหน้า UI ของ Sysdig โดยไปที่เมนู Policies -> Runtime Policies จะเห็นได้ว่ามี predefined template ถูกสร้างไว้เรียบร้อยแล้ว ที่เราต้องทำคือสับ switch เพื่อเปิดแล้วปิด policy ที่ต้องการเท่านั้นเอง

Falco rules

ซึ่งตัว Sysdig policies นั้นก็สร้างขึ้นมาครอบ Falco rule หลายๆตัวอีกทีนั่นเอง เพราะว่าจะมีหลายกรณีที่เราต้องการเปิดปิด Falco rule หลายๆตัวพร้อมกัน เราจึงสามารถสร้าง Sysdig policies มาทำการ group rule เหล่านั่นไว้ด้วยกันเพื่ออำนวยความสะดวกในการเปิดและปิด

แล้วถ้าหาก Policy ที่มีให้ไม่เพียงพอต่อการใช้งาน? เราสามารถเขียน Falco rule ของเราเองและ assign เข้าไปใน policy แต่ละตัวได้

Custom Falco Rules

เราจะมาลองสร้าง Falco Rule เพื่อเอาไว้ตรวจจับเวลามี container ตัวไหนก็ตามพยายามรันคำสั่ง ls แล้วเราจะมาดูกันว่าเมื่อเกิดขึ้นแล้วเราสามารถทำอะไรกับมันได้บ้าง

ขั้นแรกสร้าง Falco list ที่มีคำสั่ง ls อยู่ โดยไปที่เมนู Policies -> Falco Lists และกดปุ่ม Add ทางด้านขวาบน

Add new Falco Lists

ใส่ชื่อ list custom_command และ ls เป็น item และกด save

ต่อมาสร้าง Falco Marcros เพื่อกำหนด condition ในการ trigger rule ซึ่งในที่นี้จะกำหนดให้ trigger ก็ต่อเมื่อมีการรัน command ls (ซึ่งถูกระบุอยู่ใน Falco Lists ที่เราสร้างขึ้นมา) บน container ใดก็ตาม โดยให้ไปที่เมนู Policies -> Falco Macros

ขั้นสุดท้ายสร้าง Falco Rule โดยไปที่ Policies -> Rules Library และกด Add Rule แล้วเลือก Workload

ใส่ Condition ที่ต้องการ trigger โดยใช้ Falco Macros custom_command_procs ที่เราสร้างไปก่อนหน้านี้เป็นหนึ่งใน condition

spawned_process and custom_command_procs

ใส่ Output ที่ต้องการแสดงเมื่อ Rule ถูก trigger

Custom command launched in container (userid=%user.uid user_loginuid=%user.loginuid command=%proc.cmdline parent_process=%proc.pname container_id=%container.id container_name=%container.name image=%container.image.repository:%container.image.tag)
Falco rule creation

เมื่อสร้างเสร็จแล้ว Rule จะยังไม่ active ทันที หากต้องการให้ rule ทำงานจะต้อง add rule ที่เราสร้างขึ้นมาเข้าไปใน Policy ตัวใดตัวหนึ่งก่อน ในที่นี้เราจะเลือกใส่มันเข้าไปที่ Policy ชื่อว่า Suspicious Container Activity โดยไปที่ Policies -> Runtime Policies -> Suspicious Container Activity และกดที่รูปดินสอเพื่อ edit policy

จากนั้นให้กด Import from Library และเลือก import rule ที่เราสร้างขึ้นมาและกด Save แค่นี้ก็เป็นอันเรียบร้อย

Import Custom Rule

รอให้ agent อัพเดท policy ใหม่สักพักแล้วลองเข้าไปใน shell ของ pod ใดก็ได้บน cluster และลองรัน ls ดู

kubectl exec ${POD_NAME} ls

เราสามารถเห็น event ที่ถูก rule นี้ trigger ได้โดยไปที่เมนู Events และใส่ filter นี้เราสามารถมองเห็นแต่ event ของ custom rule ที่เราสร้างขึ้นมา

ruleName=Launch Custom Command in Container

เราก็จะเห็น event หน้าตาคล้ายๆแบบนี้เพื่อตรวจจับเวลามี container ตัวไหนพยายามจะรัน command ls นั่นเอง

Cluster Policy Compliance

หลังจากเราสร้าง Policy เรียบร้อยแล้ว เราจะรู้ได้อย่างไรว่าเราเปิด policy ที่เพียงพอต่อมาตราฐานต่างๆอาทิ เช่น NIST, CIS, PCI เป็นต้น ด้วยเหตุนี้จึงต้องมีการเช็ค Cluster Policy Compliance อยู่เรื่อยๆเพื่อดูว่ามี Policy อะไรที่ขาดตกหายไปหรือเพิ่มเติมหรือไม่

เราสามารถเช็ค compliance ได้โดยไปที่เมนู Posture แล้วเลือก มาตราฐานที่ต้องการเช็ค อย่างเช่นถ้าเกิดว่า Cluster ของ Financial company ก็อาจจะใช้ PCI

เข้ามาในหน้า report เราสามารถดูได้ว่าเรายังขาดอะไรบ้างและสามารถกด expand เพื่อดูรายละเอียดและวิธีแก้ตามที่ Sysdig แนะนำได้เลย หรือบางอันที่ต้องทำก็แค่เปิด Policy บางตัวเท่านั้นเอง

Cluster Benchmark

ถ้าหากมีการ setup on-premise cluster เองโดยการสร้างและ config node หรือ Kubelet เอง สามารถเช็ค Compliance ของ config พวกนี้ได้โดยไปที่เมนู Posture -> Benchmark -> Tasks และเลือก New Task ตรงมุมขวาบน

จากนั้นเลือกมาตราฐานและชื่อ Cluster ของเราผ่าน Kubernetes Label ได้ นอกจากนั้นเรายังสามารถ Schedule ให้รันใหม่อาทิทุกๆเดือนได้อัตโนมัติอีกด้วย

รอให้ task รันสักพัก (ค่อนข้างนาน) จนเสร็จแล้วกดเข้ามาดู เราจะพบว่าตัว Benchmark นั้นมีการเช็คทั้ง work node config และ​ Kubelet config พร้อมคำแนะนำให้เราว่าต้องทำอย่างไรถึงจะ complie กับมาตราฐานที่เลือก

Conclusion

สรุปแล้วครั้งนี้เราได้ Cover 3 ข้อแรกในการทำ Cluster Security ไปได้แก่

  1. การป้องกัน Image ที่มี Vulnerability เข้าสู่ cluster
  2. การตรวจจับ Vulnerability บน runtime
  3. การทำ cluster security compliance

ซึ่งหากเราทำโดยไม่ใช้ tool ใดๆช่วยเลยจะเป็นงานที่ค่อนข้างลำบากโดยเฉพาะสำหรับทีม SRE หรือ DevSecOps เวลาที่ต้องดูแลหลายๆ cluster พร้อมกัน ซึ่งหากเราใช้ tool ที่ช่วยทุนแรงเราอย่าง Sysdig ในวันนี้นอกจากจะช่วยในการทำให้ security ของ cluster เราแข็งแรงยิ่งขึ้น เราจะสามารถลดปริมาณงานที่เราต้องทำรวมถึง Human Error ที่จะเกิดขึ้น และเอาเวลาส่วนนี้ไปทำการ innovate อย่างอื่นที่มีประโยชน์มากกว่างาน operation นั่นเองครับ

Contact

Email: chan.suttichujit@gmail.com

--

--