![DevSecOps และ CI/CD คู่หูที่ขาดไม่ได้ในการพัฒนาซอฟต์แวร์ที่ปลอดภัย](/content/images/size/w1120/format/webp/2024/11/devsecops-cicd-essential-partners-secure-software-development.webp)
DevSecOps และ CI/CD คู่หูที่ขาดไม่ได้ในการพัฒนาซอฟต์แวร์ที่ปลอดภัย
ก่อนจะลงลึกใน DevSecOps สิ่งสำคัญคือต้องเข้าใจแนวคิดพื้นฐานของ DevOps กันก่อน DevOps คือการเคลื่อนไหวทางวัฒนธรรมและเทคนิคที่ผสมผสานปรัชญา แนวทางปฏิบัติ และเครื่องมือต่างๆ เข้าด้วยกัน เพื่อเพิ่มความสามารถขององค์กรในการส่งมอบแอปพลิเคชันและบริการด้วยความเร็วและประสิทธิภาพสูง
ในโลกของการพัฒนาซอฟต์แวร์ที่เปลี่ยนแปลงอย่างรวดเร็ว ความปลอดภัยมักจะถูกละเลย ทำให้เกิดช่องโหว่และการละเมิดที่อาจเกิดขึ้นได้ เพื่อลดความเสี่ยงเหล่านี้ การบูรณาการความปลอดภัยเข้ากับกระบวนการ DevOps ถือเป็นสิ่งสำคัญ นี่คือจุดที่ DevSecOps เข้ามามีบทบาท
DevSecOps คืออะไร?
DevSecOps เป็นตัวแทนของการเปลี่ยนแปลงทางวัฒนธรรมที่สมาชิกในทีมทุกคนที่เกี่ยวข้องกับการพัฒนาแอปพลิเคชันให้ความสำคัญกับความปลอดภัยตลอดวงจรชีวิตการพัฒนาซอฟต์แวร์ (SDLC) DevSecOps มุ่งมั่นที่จะนำแนวทางปฏิบัติด้านความปลอดภัยเข้ามาใช้ในแต่ละขั้นตอนของการพัฒนา เพื่อให้แน่ใจว่าความปลอดภัยไม่ใช่เพียงแค่สิ่งที่คิดขึ้นทีหลังแต่เป็นองค์ประกอบพื้นฐานของกระบวนการ การบูรณาการนี้เกี่ยวข้องกับการนำการตรวจสอบความปลอดภัยที่จำเป็นมาใช้ภายในระบบอัตโนมัติ Continuous Integration และ Continuous Deployment (CI/CD) ซึ่งได้รับการสนับสนุนจากเครื่องมือที่เหมาะสม
ประโยชน์จากการใช้ DevSecOps คืออะไร?
- ค้นหาช่องโหว่และจุดบกพร่องในระยะเริ่มต้นของการพัฒนา
- ปฏิบัติตามข้อกำหนดอย่างมีประสิทธิภาพ
- กู้คืนข้อมูลได้อย่างรวดเร็ว
- มีความปลอดภัยทั้งกระบวนการพัฒนา
- ประหยัดต้นทุน
- ลดความเสี่ยงของการโจมตีจากภายนอกและเพิ่มความมั่นใจ
- มองเห็นภัยคุกคามที่อาจเกิดขึ้นได้อย่างชัดเจนและวิธีแก้ไขที่เป็นไปได้
Gitlab-ci DevSecOps pipeline
![ตัวอย่าง Gitlab-ci pipeline](https://snappytux.com/content/images/2024/11/gitlab-ci-pipeline.webp)
ในครั้งนี้ผมจะกล่าวถึงขั้นตอน CI/CD พื้นฐานต่อไปนี้ และวิธีการรักษาความปลอดภัยตั้งแต่ตอน Code ไปจนถึง Deploy เพื่อให้เข้าใจมากขึ้น โดยจะยังไม่พูดถึงขั้นตอน Monitor&Alert
![DevSecOps Flow](https://snappytux.com/content/images/2024/11/devsecops-flow.webp)
1) Develop
ขั้นตอนการพัฒนาเริ่มต้นด้วยการเขียนโค้ด และเราสามารถใช้ทำให้ปลอดภัยได้ตั้งแต่ขั้นตอนนี้เลย ถ้าตามรูป DevSecOps Flow ด้านบนจะอยู่ในส่วนของ vs-code และ pre-commit โดยจะขั้นตอนดังนี้
- ติดตั้งเครื่องมือตรวจสอบข้อผิดพลาดภายในตัวแก้ไขโค้ด เช่น Visual Studio Code หนึ่งในเครื่องมือตรวจสอบข้อผิดพลาดที่ได้รับความนิยมมากที่สุดคือ SonarLint ซึ่งจะเน้นที่จุดบกพร่องและช่องโหว่ด้านความปลอดภัยขณะที่คุณเขียนโค้ด
- ใช้ Pre-commit hooks เพื่อป้องกันการเพิ่มความลับใดๆ ลงในโค้ด
- ตั้งค่า Protect branch สำหรับ branch สำคัญๆ
![](https://snappytux.com/content/images/2023/12/check-the-quality-of-code-before-commit-with-pre-commit.webp)
2) Merge Request
โดยปกตินักพัฒนาจะไม่มีสิทธิ์ในการนำโค้ดเข้าไปยัง Branch หลัก และจำเป็นต้องมีการสร้าง Merge request เพื่อส่งคำขอไปยัง Tech lead ให้มาตรวจโค้ดก่อน เมื่อผ่านจึงจะปล่อยให้ Merge ลงไปยัง branch หลักได้
ซึ่งในขั้นตอนนี้เราก็จะเอา CI/CD มาช่วยในการแสกนหา Secret key ต่าง ๆ และจัดระเบียบโค้ดให้เรียบร้อยก่อน
2.1 Gitleaks
จะมาช่วยในการตรวจจับและป้องกันรหัสผ่านลับ, คีย์ API, โทเค็น, คีย์ส่วนตัว ฯลฯ ที่อยู่ในโค้ด ไม่ให้นำขึ้นมา
![](https://snappytux.com/content/images/2024/01/gitleaks-on-giltab-ci.webp)
2.2 Code lint
จะมาช่วยจัดระเบียบโค้ดให้เรียบร้อย โดยส่วนใหญ่จะใช้ Lint ของภาษานั้น ๆ เช่น eslint, Golang CI Lint เป็นต้น
eslint:
stage: test
dependencies: []
script:
- npm ci
- npm run lint
cache:
paths:
- node_modules
ตัวอย่าง eslint ใน gitlab-ci
3) Build และ Code analysis
ก่อน build เราจำเป็นต้องสแกนโค้ดของเราเพื่อหาช่องโหว่ต่าง ๆ เพื่อเป็นการป้องกันเบื้องต้นก่อนจะโดยเจาะระบบในภายหลัง
3.1 Dockerfile static scanning
จะทำการตัวสอบ Dockerfile ที่เราเขียนไว้ว่าได้เขียนถูกต้องการหลัก best practices แล้วหรือไม่
dockerfile_scan:
stage: scan
image:
name: bridgecrew/checkov:latest
entrypoint:
- "/usr/bin/env"
- "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
script:
- checkov -d . --framework dockerfile --compact
rules:
- if: $CI_COMMIT_BRANCH == 'dev'
exists:
- "**/Dockerfile"
ตัวอย่าง dockerfile scan ใน gitlab-ci
3.2 SAST
เป็นขั้นตอนการทำ SAST (Static Application Security Testing) เพื่อดูว่าเราเขียนโค้ดได้อย่างปลอดภัยหรือไม่
![](https://snappytux.com/content/images/2024/04/bearer-sast-free-tool-with-gitlab-ci.webp)
หรือเราจะติดตั้ง SonarQube เพื่อดูเป็นรายงานที่สวยงามก็ได้
![](https://snappytux.com/content/images/2024/04/install-sonarqube-with-docker-compose.webp)
sonar_sast:
stage: scan
image:
name: sonarsource/sonar-scanner-cli:latest
entrypoint: [""]
variables:
SONAR_USER_HOME: "${CI_PROJECT_DIR}/.sonar" # Defines the location of the analysis task cache
GIT_STRATEGY: clone # clone entire repo instead of reusing workspace
GIT_DEPTH: "0" # avoid shallow clone to give sonar all the info it needs
cache:
key: "${CI_JOB_NAME}"
paths:
- .sonar/cache
script:
- sonar-scanner
allow_failure: true
ตัวอย่างไฟล์ gitlab-ci ในการทำ sonar scan
3.3 Dependency Check
ขั้นตอนนี้จะทำการแสกนตรวจสอบ Dependency ของระบบที่เรานำมาใช้ว่ามีช่องโหว่เกิดขึ้นหรือไม่ หากพบมันจะสร้างรายงานที่เชื่อมโยงไปยังรายการ CVE ที่เกี่ยวข้อง เพื่อให้เราทราบถึงข้อมูลช่องโหว่ล่าสุด
![](https://snappytux.com/content/images/2024/01/dependency-check-with-trivy.webp)
3.4 Container image scan
เป็นการแสกน Docker image ที่เรา build เสร็จแล้วก่อนนำขึ้นไปเก็บยัง Docker registry จะทำให้ทราบถึงสถานะความปลอดภัยของ Container และช่วยให้เราสามารถดำเนินการต่างๆ ที่ทำให้ Container มีความปลอดภัยมากขึ้น เราควรหลีกเลี่ยงการติดตั้งแพ็คเกจที่ไม่จำเป็นและใช้วิธีการหลายขั้นตอน วิธีนี้จะช่วยให้ Container ปลอดภัย
![](https://snappytux.com/content/images/2024/01/scan-images-for-vulnerabilities-with-grype-gitlab-ci.webp)
4) Test
4.1 Smoke test
Smoke Test คือการทดสอบเบื้องต้นที่ใช้ตรวจสอบว่าฟังก์ชันหลักของซอฟต์แวร์ทำงานได้ตามที่คาดหวังหรือไม่ โดยมักจะใช้ในขั้นตอนหลังจากการติดตั้งหรือการอัปเดตซอฟต์แวร์ เพื่อให้แน่ใจว่าระบบสามารถทำงานได้โดยไม่มีข้อผิดพลาดที่สำคัญ
4.2 Unitest
เป็นการทดสอบระบบที่ใช้ในการตรวจสอบความถูกต้องของส่วนประกอบเล็กๆ ที่เรียกว่า "ยูนิต" ของระบบ โดยยูนิตนี้มักจะหมายถึงฟังก์ชัน, เมธอด, หรือคลาสในโค้ดของซอฟต์แวร์ ซึ่งการทดสอบนี้ช่วยให้มั่นใจได้ว่าส่วนประกอบเฉพาะนั้นทำงานตามที่คาดหวัง
5) Deploy
หลังจากที่เราตรวจสอบโค้ดของเรามาแล้วทั้งหมด ถ้าผ่านก็สามารถ Deploy ได้เลย ซึ่งการ Deploy ระบบนั้นอยู่ที่ว่าปลายทาง Server ของเราเป็นแบบไหนก็เขียน script ตามนั้น แต่โดยส่วนมากก็อาจจะเป็นการ ssh ไปยัง server เพื่อทำการ Deploy ก็สามารถนำ Gitlab-ci ไปจัดการได้เช่นกัน
![](https://snappytux.com/content/images/2024/09/Use-ssh-in-Gitlab-ci.webp)
สรุป
เพื่อสรุปสิ่งที่เราได้ดำเนินการในการสร้าง DevSecOps Pipeline เราเริ่มต้นด้วยการตรวจสอบ Secret key และการทดสอบความปลอดภัยของโค้ด (SAST) เพื่อค้นหาช่องโหว่ในโค้ดของเรา จากนั้นเราได้ทำการสแกน Dockerfile, Container image รวมถึงการทดสอบการตรวจสอบความถูกต้องของ Container เพื่อให้แน่ใจว่ามีความปลอดภัยและเชื่อถือได้ก่อนนำไป Deploy ระบบ
และได้ทำการทดสอบ Smoke, Unitest เพื่อยืนยันว่าไม่มีข้อผิดพลาดในระหว่างการติดตั้ง ระบบ ซึ่งเป็นสิ่งสำคัญที่ต้องจดจำว่า ความปลอดภัยต้องการการดูแลและปรับปรุงอย่างต่อเนื่อง อย่างไรก็ตาม นี่เป็นเพียงขั้นตอนแรกในเส้นทางที่ไม่มีที่สิ้นสุดสู่การสร้าง DevSecOps ที่มีประสิทธิภาพ
ก็หวังว่าบทความนี้จะทำให้ผู้ที่จะเริ่มต้น DevSecOps เข้าใจในการทำ Pipeline มากขึ้นว่าควรมีขั้นตอนไหนบ้าง ซึ่งต้องบอกก่อนว่าพอเราเข้าใจแล้ว ก็สามารถไปแก้ไขเป็นของตัวเองได้เลย จะทำ Job ไหนก่อนหลังก็ได้ตามแต่ตกลงกันในทีม...
Thank: https://www.infracloud.io/blogs/implement-devsecops-secure-ci-cd-pipeline