SonarQube là một nền tảng nguồn mở để kiểm tra bảo mật và chất lượng mã liên tục. Nó phân tích mã nguồn để tìm lỗi, lỗ hổng và mùi mã trên hơn 30 ngôn ngữ lập trình, khiến nó trở thành lựa chọn phổ biến cho DevSecOps pipeline dành cho doanh nghiệp.
Kiến trúc SonarQube
SonarQube bao gồm ba thành phần chính:
+------------------+ +------------------+ +------------------+
| SonarScanner | ---> | SonarQube | ---> | Database |
| (CI Runner) | | Server | | (PostgreSQL) |
+------------------+ +------------------+ +------------------+
Analyzes Processes Stores
source code results history
- SonarScanner - Chạy trong CI/CD pipeline của bạn, phân tích mã, gửi kết quả đến máy chủ
- SonarQube Server - Giao diện web, API, công cụ quy tắc và công cụ tính toán
- Database - PostgreSQL, Oracle hoặc SQL Server (không nhúng H2 cho production)
Thiết lập SonarQube với Docker
Cách nhanh nhất để bắt đầu là với Docker:
# Create a network for SonarQube and PostgreSQL
docker network create sonarnet
# Start PostgreSQL database
docker run -d --name sonar-postgres \\
--network sonarnet \\
-e POSTGRES_USER=sonar \\
-e POSTGRES_PASSWORD=sonar_password \\
-e POSTGRES_DB=sonarqube \\
-v sonar_postgres_data:/var/lib/postgresql/data \\
postgres:15-alpine
# Start SonarQube server
docker run -d --name sonarqube \\
--network sonarnet \\
-p 9000:9000 \\
-e SONAR_JDBC_URL=jdbc:postgresql://sonar-postgres:5432/sonarqube \\
-e SONAR_JDBC_USERNAME=sonar \\
-e SONAR_JDBC_PASSWORD=sonar_password \\
-v sonar_data:/opt/sonarqube/data \\
-v sonar_extensions:/opt/sonarqube/extensions \\
-v sonar_logs:/opt/sonarqube/logs \\
sonarqube:lts-community
Quan trọng: Đợi 1-2 phút để SonarQube khởi chạy, sau đó truy cập http://localhost:9000.
Thông tin đăng nhập mặc định: admin / admin (thay đổi ngay sau lần đăng nhập đầu tiên).
Cài đặt Docker Compose
Để thiết lập dễ bảo trì hơn, hãy sử dụng Docker Compose:
# docker-compose.yml
version: '3.8'
services:
sonarqube:
image: sonarqube:lts-community
container_name: sonarqube
depends_on:
- db
ports:
- "9000:9000"
environment:
SONAR_JDBC_URL: jdbc:postgresql://db:5432/sonarqube
SONAR_JDBC_USERNAME: sonar
SONAR_JDBC_PASSWORD: sonar_password
volumes:
- sonarqube_data:/opt/sonarqube/data
- sonarqube_extensions:/opt/sonarqube/extensions
- sonarqube_logs:/opt/sonarqube/logs
ulimits:
nofile:
soft: 65536
hard: 65536
db:
image: postgres:15-alpine
container_name: sonar-postgres
environment:
POSTGRES_USER: sonar
POSTGRES_PASSWORD: sonar_password
POSTGRES_DB: sonarqube
volumes:
- postgresql_data:/var/lib/postgresql/data
volumes:
sonarqube_data:
sonarqube_extensions:
sonarqube_logs:
postgresql_data:
Bắt đầu với docker compose up -d.
Định cấu hình dự án đầu tiên của bạn
Bước 1: Tạo dự án trong SonarQube
- Đăng nhập vào SonarQube tại
http://localhost:9000 - Nhấp vào Tạo dự án > Thủ công
- Nhập khóa dự án (ví dụ:
my-webapp) và tên hiển thị - Chọn Locally cho phương pháp phân tích (để thiết lập ban đầu)
- Tạo mã thông báo và lưu nó một cách an toàn
Bước 2: Tạo sonar-project.properties
Trong thư mục gốc dự án của bạn, hãy tạo một tệp cấu hình:
# sonar-project.properties
# Required: Unique project identifier
sonar.projectKey=my-webapp
# Optional but recommended
sonar.projectName=My Web Application
sonar.projectVersion=1.0.0
# Source code location (relative to this file)
sonar.sources=src
# Test code location
sonar.tests=tests
# Exclude files from analysis
sonar.exclusions=**/node_modules/**,**/vendor/**,**/*.min.js
# Language-specific settings (for Python example)
sonar.python.version=3.11
# Coverage report location (if using coverage tools)
sonar.python.coverage.reportPaths=coverage.xml
Bước 3: Chạy máy quét
Cài đặt và chạy SonarScanner:
# Install SonarScanner (macOS)
brew install sonar-scanner
# Or download from sonarqube.org and add to PATH
# Run the scan
sonar-scanner \\
-Dsonar.host.url=http://localhost:9000 \\
-Dsonar.token=your_generated_token
Sau khi quá trình quét hoàn tất, hãy xem kết quả trên giao diện web SonarQube.
Hiểu số liệu SonarQube
SonarQube phân loại vấn đề thành nhiều loại:
Loại vấn đề
| loại | Mô tả | Ví dụ |
|---|---|---|
| Bug | Mã rõ ràng là sai | Hủy bỏ tham chiếu con trỏ null |
| Lỗ hổng | Điểm yếu về bảo mật | SQL injection, XSS |
| Mã mùi | Vấn đề về khả năng bảo trì | Mã trùng lặp, phương thức dài |
| Điểm truy cập bảo mật | Cần xem xét thủ công | Địa chỉ IP được mã hóa cứng |
Mức độ nghiêm trọng
| Mức độ nghiêm trọng | Mô tả |
|---|---|
| Trình chặn | Phải khắc phục ngay |
| Critical | Tác động lớn, khắc phục sớm |
| Major | Vấn đề quan trọng |
| Minor | Tác động thấp |
| Info | Chỉ mang tính thông tin |
Số liệu chính
+-----------------------------------------------+
| Quality Gate: PASSED |
+-----------------------------------------------+
| Bugs: 3 Vulnerabilities: 1 |
| Code Smells: 47 Security Hotspots: 5 |
+-----------------------------------------------+
| Coverage: 78% Duplications: 2.3% |
+-----------------------------------------------+
- Coverage - Tỷ lệ phần trăm mã được kiểm tra
- Duplications — Tỷ lệ khối mã trùng lặp
- Technical Debt — Thời gian ước tính để khắc phục tất cả các lỗi mã
Cổng chất lượng
Cổng chất lượng xác định các tiêu chuẩn chất lượng tối thiểu cho dự án của bạn. Nếu mã không thành công ở cổng thì quá trình xây dựng sẽ không thành công.
Cổng chất lượng mặc định
Cổng chất lượng "Sonar way" mặc định của SonarQube yêu cầu:
- Không có lỗi mới
- Không có lỗ hổng mới
- Tất cả các điểm nóng bảo mật đã được xem xét
- Độ bao phủ mã trên mã mới >= 80%
- Trùng lặp mã mới < 3%
Tạo cổng chất lượng tùy chỉnh
- Đi tới Quality Gates trong giao diện người dùng SonarQube
- Nhấp vào Tạo
- Thêm điều kiện:
Condition: Coverage on New Code
Operator: is less than
Value: 80%
Status: Error
Ví dụ về cổng chất lượng tùy chỉnh cho các dự án tập trung vào bảo mật:
| tình trạng | Toán tử | Giá trị | Trạng thái |
|---|---|---|---|
| Lỗi mới | lớn hơn | 0 | Lỗi |
| Lỗ hổng mới | lớn hơn | 0 | Lỗi |
| Đã xem xét các điểm truy cập bảo mật mới | ít hơn | 100% | Lỗi |
| Bảo hiểm mã mới | ít hơn | 70% | Cảnh báo |
Tích hợp CI/CD
Hành động GitHub
# .github/workflows/sonarqube.yml
name: SonarQube Analysis
on:
push:
branches: [main, develop]
pull_request:
branches: [main]
jobs:
sonarqube:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0 # Required for blame information
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.11'
- name: Install dependencies and run tests
run: |
pip install -r requirements.txt
pip install pytest pytest-cov
pytest --cov=src --cov-report=xml
- name: SonarQube Scan
uses: SonarSource/sonarqube-scan-action@v5
env:
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
SONAR_HOST_URL: ${{ secrets.SONAR_HOST_URL }}
CI GitLab
# .gitlab-ci.yml
sonarqube-check:
stage: test
image: sonarsource/sonar-scanner-cli:latest
variables:
SONAR_USER_HOME: "${CI_PROJECT_DIR}/.sonar"
GIT_DEPTH: "0"
cache:
key: "${CI_JOB_NAME}"
paths:
- .sonar/cache
script:
- sonar-scanner
-Dsonar.projectKey=${CI_PROJECT_PATH_SLUG}
-Dsonar.host.url=${SONAR_HOST_URL}
-Dsonar.token=${SONAR_TOKEN}
allow_failure: true
rules:
- if: $CI_PIPELINE_SOURCE == 'merge_request_event'
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
Jenkins pipeline
// Jenkinsfile
pipeline {
agent any
environment {
SONAR_TOKEN = credentials('sonar-token')
}
stages {
stage('Checkout') {
steps {
checkout scm
}
}
stage('Build & Test') {
steps {
sh 'mvn clean verify'
}
}
stage('SonarQube Analysis') {
steps {
withSonarQubeEnv('SonarQube') {
sh 'mvn sonar:sonar'
}
}
}
stage('Quality Gate') {
steps {
timeout(time: 5, unit: 'MINUTES') {
waitForQualityGate abortPipeline: true
}
}
}
}
}
Quy tắc bảo mật Tìm hiểu sâu
SonarQube bao gồm các quy tắc bảo mật mở rộng dựa trên các tiêu chuẩn OWASP, CWE và SANS.
Danh mục lỗ hổng
| Danh mục | CWE | Quy tắc ví dụ |
|---|---|---|
| tiêm | CWE-89 | Các truy vấn SQL không dễ bị tấn công |
| XSS | CWE-79 | Phản hồi HTTP không dễ bị tấn công bởi XSS |
| CSRF | CWE-352 | Các yêu cầu phía máy chủ không dễ bị giả mạo |
| Bí mật được mã hóa cứng | CWE-798 | Thông tin xác thực không nên được mã hóa cứng |
| Tiền điện tử yếu | CWE-327 | Các thuật toán mã hóa phải an toàn |
Xem báo cáo bảo mật
- Điều hướng đến dự án của bạn trong SonarQube
- Nhấp vào Báo cáo bảo mật ở menu bên trái
- Xem báo cáo theo:
- OWASP Top 10 — Phân loại theo rủi ro OWASP 2021
- CWE Top 25 — Điểm yếu phần mềm nguy hiểm nhất
- Điểm truy cập bảo mật — Mã yêu cầu xem xét bảo mật thủ công
Tùy chỉnh quy tắc bảo mật
Administration > Quality Profiles > [Your Profile] > Activate More Rules
Lọc theo:
- Tag: bảo mật, lỗ hổng, cwe-top-25
- Loại: Lỗ hổng bảo mật, Điểm truy cập bảo mật
- **Mức độ nghiêm trọng:Trình chặn **, Quan trọng
Thực tiễn tốt nhất
1. Bắt đầu với Cổng chất lượng mặc định
Cổng "Sonar way" của SonarQube được hiệu chỉnh tốt. Chỉ tùy chỉnh sau khi hiểu được nhu cầu của dự án của bạn.
2. Tập trung vào mã mới
Đừng cố gắng khắc phục tất cả các vấn đề cũ cùng một lúc. Phương pháp "Sạch như bạn viết mã" của SonarQube tập trung vào việc giữ cho mã mới luôn sạch sẽ.
3. Thường xuyên xem xét các điểm truy cập bảo mật
Điểm phát sóng không phải là lỗ hổng đã được xác nhận—chúng cần có sự đánh giá của con người. Lên lịch đánh giá hàng tuần.
4. Tích hợp với pull request
Khối hợp nhất không đạt cổng chất lượng. Điều này ngăn chặn các lỗ hổng mới xâm nhập vào nhánh chính.
5. Loại trừ Mã đã Tạo
Đừng lãng phí thời gian phân tích các tệp được tạo tự động:
# sonar-project.properties
sonar.exclusions=**/generated/**,**/migrations/**,**/*.min.js
Phiên bản SonarQube
| tính năng | cộng đồng | Nhà phát triển | Doanh nghiệp |
|---|---|---|---|
| Giá | miễn phí | Đã trả tiền | Đã trả tiền |
| Ngôn ngữ | 19+ | 24+ | 30+ |
| Phân tích chi nhánh | Chỉ chính | Tất cả các chi nhánh | Tất cả các chi nhánh |
| Trang trí PR | Không | Có | Có |
| Độ sâu SAST | Cơ bản | Nâng cao | Nâng cao |
| Quản lý danh mục đầu tư | Không | Không | Có |
Phiên bản Cộng đồng là đủ cho hầu hết các dự án nguồn mở. Phiên bản dành cho nhà phát triển bổ sung thêm tính năng phân tích chi nhánh và tích hợp PR cần thiết cho quy trình làm việc của doanh nghiệp.
Khắc phục sự cố
Các vấn đề chung
Scanner không thể kết nối với máy chủ:
# Check server is running
curl -s http://localhost:9000/api/system/status | jq
# Verify token is valid
curl -u your_token: http://localhost:9000/api/projects/search
Hết bộ nhớ trong khi phân tích:
# Increase scanner memory
export SONAR_SCANNER_OPTS="-Xmx2048m"
sonar-scanner
Phân tích mất quá nhiều thời gian:
# Limit scope in sonar-project.properties
sonar.exclusions=**/test/**,**/docs/**
sonar.cpd.exclusions=**/test/**
Bài học chính
- SonarQube cung cấp phân tích toàn diện — Lỗi, lỗ hổng, mùi mã và phạm vi bảo hiểm trong một nền tảng
- Cổng chất lượng thực thi các tiêu chuẩn — Chặn các hoạt động hợp nhất không đáp ứng yêu cầu bảo mật của bạn
- Tích hợp CI/CD là điều cần thiết — Tự động phân tích trên mọi commit
- Tập trung vào mã mới — Đừng để bị choáng ngợp bởi các vấn đề cũ
- Đánh giá các điểm truy cập bảo mật — Những điểm này yêu cầu sự đánh giá của con người chứ không phải các bản sửa lỗi tự động
Tiếp theo, chúng ta sẽ khám phá Semgrep để quét bảo mật nhanh chóng, có thể tùy chỉnh.