文章目录
SonarQube代码质量分析
安全检查
- 拉起代码后进行扫描
- 对运行中的代码和环境进行扫描
| 何时使用 | 代码安全检查工具 | 说明 | 用法 |
|---|---|---|---|
| 部署前 | Sonarqube (开源,商业) | 安全质量检查. | 部署 service,Jenkins 通过 sonar 命令调用. |
| 部署前 | OWASP Dependency-Check | 根据漏洞库。然后做漏洞扫描对比. | jenkins 插件. |
| 运行中 | AppScan (商业) | 漏扫工具 | - |
| 运行中 | awvs (商业) | 漏扫业务漏洞。应用漏洞 | 部署. |
| 运行中 | nessus (商业) | 漏扫系统漏洞. | 部署. |
| 运行中 | hm (河马)(开源) | 漏扫,webshell (网站后门) | 部署。二进制. |
| 运行中 | 绿盟,奇安信,云安全中心... 很多类似的... | - | - |
| 运行中 | trivy,clair,xxxx 容器 | 容器环境扫描 | 容器 |
SonarQube简介
SonarQube是一款开源的代码质量管理系统,支持代码自动审查,用于检测代码中的错误、漏洞和代码异味,它集成到现有的工作流程,以便在项目分支和拉取(PR)请求之间进行连续的代码检查
SonarQube有四个关键组件
| 核心组件 | 子组件 / 关联说明 | 核心功能 |
|---|---|---|
| SonarQube Server | 1. Web Server2. Search Server3. Compute Engine Server | 1. Web Server:提供 UI 界面; 2. Search Server:基于 ElasticSearch,支持 UI 搜索; 3. Compute Engine Server:处理代码分析报告并存储到数据库 |
| SonarQube Database | - | 存储 SonarQube 系统配置、项目质量快照等数据 |
| SonarQube Plugin | - | 扩展 SonarQube 功能(如支持更多编程语言、集成外部工具) |
| Scanner(代码扫描器) | - | 扫描项目代码,生成分析报告,并提交给 SonarQube Server 进行后续处理 |
部署SonarQube
最小硬件需求
-
小规模应用场景中,至少需要2GB的RAM,且额外要有至少1G的空闲内存
-
磁盘空间取决于SonarQube分析的代码量
-
必须部署在读写性能较好的磁盘上
- 存储数据的目录中包含了ElasticSearch的索引,服务器启动并运行时,将会在该索引上进行大量I/O操作
生成环境硬件需求
-
8核心的CPU:更好地支持并行运行多个Compute Engine工作线程
-
16GB的内存:更高效地完成数据存储和索引处理
系统初始化和优化配置
启动 SonarQube 时优化 内核参数 和 文件句柄数
核心原因是:Linux 系统默认的资源限制和内核配置是为 "通用场景" 设计的,无法满足 SonarQube 高并发、多文件操作、多线程处理的运行需求。
不优化会导致 SonarQube 启动失败、运行卡顿、扫描超时甚至崩溃
shell
#修改文件句柄数
cat > /etc/security/limits.conf <<EOF
* - nofile 100000
* - nproc 100000
* - memlock 60000
EOF
#内核参数优化
echo 'vm.max_map_count=262114' >> /etc/sysctl.conf
sysctl -p
安装JDK21
shell
#1.检查是否已安装 Java
java --version
#2.若未安装(根据 Tomcat 版本选择兼容的 Java 版本)
yum install -y wget ; mkdir -p /download ; wget https://download.java.net/java/GA/jdk21.0.2/f2283984656d49d69e91c558476027ac/13/GPL/openjdk-21.0.2_linux-x64_bin.tar.gz -O /download/openjdk-21.0.2_linux-x64_bin.tar.gz
#3.解压并链接到/usr/local/jdk21
tar -zxvf /download/openjdk-21.0.2_linux-x64_bin.tar.gz -C /usr/local/
ln -s /usr/local/jdk-21.0.2 /usr/local/java
#4.配置jdk环境变量
echo 'export JAVA_HOME=/usr/local/java' >> /etc/profile
echo 'export PATH=${PATH}:$JAVA_HOME/bin' >> /etc/profile
source /etc/profile
#查看jdk版本
java --version
编译安装Postgresql-16
官方源码包:PostgreSQL: File Browser
shell
#0.安装依赖包
yum install -y gcc make readline-devel zlib-devel
#1.安装数据库
wget https://ftp.postgresql.org/pub/source/v16.0/postgresql-16.0.tar.gz -P /download
#2.解压
tar xf /download/postgresql-16.0.tar.gz -C /download/
#3.编译三部曲
cd /download/postgresql-16.0
./configure --prefix=/app/pgsql --with-pgport=5432 && echo $?
make -j 2 world && echo $? #默认 make 不包括文档和其他模块
make install-world && echo $? #默认make install 不包括安装文档
#4.创建数据库用户和组
##PostgreSQL默认不支持以root身份启动服务,虽然也可以修改源码实现root启动
##基于安全考虑不建议,因此必须创建一个用于启动Postgresql的普通用户
###创建数据库用户和组,注意此用户需要可以交互登陆
useradd -s /bin/bash -m -d /home/postgresql postgresql
###修改postgresql密码
echo -e 'Abc@1234csq\nAbc@1234csq' | passwd postgresql
#5.创建数据目录并授权
mkdir -p /pgsql/data
chown postgresql:postgresql /pgsql/data/
#6.设置环境变量
cat > /etc/profile.d/pgsql.sh <<'EOF'
export PGHOME=/app/pgsql
export PATH=$PGHOME/bin/:$PATH
export PGDATA=/pgsql/data
export PGUSER=postgresql
export MANPATH=/app/pgsql/share/man:$MANPATH
EOF
###测试
su - postgresql -c 'psql --version'
#7.初始化数据库
su - postgresql
initdb -A md5 -D $PGDATA -E utf8 --locale=C -U postgresql -W
-A #指定local connections默认的身份验证方法
-D #指定数据目录
-E #指定字符集
--locale=c #指定语言环境
-U #指定数据库superuser用户名
-W #指定数据库superuser用户密码
#8.配置sytemctl文件
cat > /lib/systemd/system/postgresql.service <<EOF
[Unit]
Description=PostgreSQL database server
After=network.target
[Service]
Type=forking
User=postgresql
Group=postgresql
# Environment variables
Environment=PGDATA=/var/lib/postgresql/data
# Commands to manage the service
ExecStart=/app/pgsql/bin/pg_ctl start -D /pgsql/data
ExecStop=/app/pgsql/bin/pg_ctl stop -D /pgsql/data/
ExecReload=/app/pgsql/bin/pg_ctl reload -D /pgsql/data
# Restart settings
Restart=on-failure
RestartSec=5
# Limits
LimitNOFILE=65536
LimitNPROC=65536
[Install]
WantedBy=multi-user.target
EOF
#9.修改配置文件pgsql
#/pgsql/data/pg_hba.conf
# "local" is for Unix domain socket connections only
local all all md5
# IPv4 local connections:
host all all 127.0.0.1/32 md5
#10.启动postgresql
#切换到 postgresql 系统用户
su - postgresql
psql -U postgresql -d postgres
systemctl daemon-reload && systemctl enable --now postgresql.service
#11.登陆postgresql超级用户
#(1). 创建SonarQube专用数据库(名称必须是 sonarqube,与 JDBC URL 中的数据库名一致)
CREATE DATABASE sonarqube;
#(2). 创建 SonarQube 专用用户(用户名 sonar,密码自定义,建议用 sonar@123456,后续 SonarQube 配置需对应)
CREATE USER sonar WITH PASSWORD 'sonar@123456';
#(3). 授予 sonar 用户对 sonarqube 数据库的所有权限(确保能创建表、索引等)
GRANT ALL PRIVILEGES ON DATABASE sonarqube TO sonar;
#(4). 切换到 sonarqube 数据库(后续操作针对该库)
\c sonarqube
#(5). 创建自定义模式 my_schema(与 JDBC URL 中的 currentSchema=my_schema 一致)
CREATE SCHEMA my_schema AUTHORIZATION sonar;
#(6). 确认 my_schema 归 sonar 用户所有(避免权限不足)
ALTER SCHEMA my_schema OWNER TO sonar;
#(7). 授予 sonar 用户对 my_schema 模式的所有操作权限
GRANT ALL PRIVILEGES ON SCHEMA my_schema TO sonar;
#(8). 设置 sonar 用户的默认搜索路径为 my_schema(可选,避免后续连接需手动指定)
ALTER USER sonar SET search_path TO my_schema;
#(9). 退出 PostgreSQL 交互模式
\q
#验证 my_schema 模式是否存在(用 sonar 用户登录,输入密码 sonar@123456)
psql -U sonar -d sonarqube -c "SELECT schema_name FROM information_schema.schemata WHERE schema_name = 'my_schema';"
#12.重启postgresql生效(root用户)
systemctl restart postgresql
配置Sonarqube
下载:https://www.sonarsource.com/products/sonarqube/downloads/
shell
#1.下载sonarqube(sonarqube-25.12.0.117093)
#2.解压
mkdir -p /app/tools
unzip sonarqube-25.12.0.117093.zip -d /app/tools/
#3.创建软链接
ln -s /app/tools/sonarqube-25.12.0.117093/ /app/tools/sonar
#4.修改权限
chown -R sonar:sonar /app/tools/sonar
#5.修改sonarqube配置 让sonarqube连接数据
# JDBC URL:与创建的数据库名(sonarqube)、模式(my_schema)一致
sonar.jdbc.url=jdbc:postgresql://localhost/sonarqube?currentSchema=my_schema&useUnicode=true&characterEncoding=utf8
# 数据库用户名:sonar(与创建的用户一致)
sonar.jdbc.username=sonar
# 数据库密码:sonar@123456(与创建时的密码一致)
sonar.jdbc.password=sonar@123456
#6.启动sonarqube(不能root启动,只能普通用户)
su - sonar -c '/app/tools/sonar/bin/linux-x86-64/sonar.sh start'
#7.查看端口是否开启
ss -tulnp |grep 9000
浏览器访问
- 用户名:admin
- 密码:admin
IP:9000

中文插件
发行版 · xuhuisheng/sonar-l10n-zh
- 下载插件到
/app/tools/sonar/extensions/plugins即可
安装sonar-canner
Sonar Scanner是独立的组件,需要单独部署,并配置其能够关联到SonarQube之上
下载地址: https://binaries.sonarsource.com/?prefix=Distribution/sonar-scanner-cli/
下载合适版本的sonar-scanner-cli程序,直接展开后简单配置即可使用
shell
wget https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-8.0.1.6346-linux-x64.zip -P /download
unzip sonar-scanner-cli-8.0.1.6346-linux-x64.zip -d /app/tools/
ln -s /app/tools/sonar-scanner-8.0.1.6346-linux-x64/ /app/tools/sonar-scanner
ln -s /app/tools/sonar-scanner/bin/sonar-scanner /usr/local/bin/
sonar-scanner 全局配置文件(conf/sonar-scanner.properties)
| 配置分类 | 属性名 | 说明 | 示例 / 备注 |
|---|---|---|---|
| 服务器连接 | sonar.host.url | 指定 SonarQube 服务器地址(必填,全局核心配置) | http://localhost:9000(本地服务器)/ http://192.168.1.100:9000 |
| 认证参数 | sonar.login | 认证 SonarQube 的用户名(或使用管理员 Token,优先级高于用户名密码) | admin(用户名)/sqp_1234567890abcdef(Token) |
| 认证参数 | sonar.password | 对应用户名的认证密码(若用 Token,此参数可省略) | 123456(用户名对应的密码) |
| 分析日志配置 | sonar.log.level | 日志级别(默认 INFO,问题排查时可改为 DEBUG) | INFO(默认)/ DEBUG(调试用) |
| 分析日志配置 | sonar.verbose | 是否启用详细日志(默认 false,DEBUG 模式下建议开启) | false(默认)/true(详细输出日志) |
| 项目基础配置 | sonar.projectName | 项目名称(可被项目级配置覆盖,Maven 项目可自动读取) | 我的 Java 项目(自定义名称) |
| 项目基础配置 | sonar.projectVersion | 项目版本(不可用 Build ID,可被项目级配置覆盖) | 1.0.0(正式版本)/not provided(无明确版本时) |
| 项目基础配置 | sonar.sources | 项目源码目录(可被项目级配置覆盖,全局配置建议留空,项目内单独指定) | ./src(全局默认目录)/.(当前目录,多目录用逗号分隔:src,api/src) |
SonarQube使用
本地扫描
(1)创建项目


- 遵循实例的默认配置:用系统默认规则(当前默认是 "以上一个版本为界限,之后的代码算新代码")。
- 自定义:自己选新代码的划分依据(比如 "上一个版本""最近 N 天的代码""某个分支的代码")

(2)选择本地创建令牌


(3)分析项目

shell
#1.同网段主机找个装了maven的节点,测试编译
mvn clean verify org.sonarsource.scanner.maven:sonar-maven-plugin:sonar \
-Dsonar.projectKey=test \
-Dsonar.projectName='test' \
-Dsonar.host.url=http://10.0.0.123:9000 \
-Dsonar.token=sqp_1ed511752650d97432a0c55aa5d48c23bb8247fd
##测试完成自动弹出如下页面

(4)查看分析结果


在Jenkins接入SonarQube
可以看到上面本地设置的,projectName是上面Sonarqube项目名字就是什么,如果说想让它自动设置为Jenkins项目名字,可以用到Jenkins的全局环境变量
(1)创建项目



(2)Jenkins环境准备
- Jenkins开启Docker API
- 准备dockerfile所需基础镜像
- Jenkins安装ansible环境
(3)gitlab新建代码仓库

(4)上传代码
shell
#0.在gitlab上传公钥(使用Linux就上传Linux的公钥,windows就上传windows的公钥)
cat ~/.ssh/id_ed25519.pub
#1.解压代码
mkdir src/docker-java-hello
unzip code.zip -d src/docker-java-hello/
cd src
###配置setting文件
###配置dockerfile
FROM harbor.chenshiquan.xyz/library/maven:3-eclipse-temurin-11-alpine AS build
ENV CODE_DIR=/app/code
ARG NAME=test
ENV pord_NAME=${NAME}
WORKDIR ${CODE_DIR}
COPY settings.xml /usr/share/maven/conf/
COPY docker-java-hello ./
RUN mvn clean verify org.sonarsource.scanner.maven:sonar-maven-plugin:sonar \
-Dsonar.projectKey=${pord_NAME} \
-Dsonar.projectName=${pord_NAME} \
-Dsonar.host.url=http://10.0.0.123:9000 \
-Dsonar.sources=. \
-Dsonar.token=squ_6ec3aa500b872c85e62e5705d5fd87e0bea32e4d
FROM harbor.chenshiquan.xyz/library/tomcat:9.0-jdk8
LABEL author=csq destcation="tomcat war包"
COPY --from=build /app/code/target/*.war webapps/ROOT.war
EXPOSE 8080
CMD ["catalina.sh","run"]
#2.Git本地配置
git config --global user.name 'csq'
git config --global user.email '2033717617@qq.com'
git config --global color.ui true
#3.初始化仓库
git init
#4.关联gitlab远程仓库(记得域名解析)
git remote add gitlab git@gitlab.chenshiquan.xyz:root/docker-java-hello.git
#5.上传代码
git add .
git commit -m 'docker java code'
git push -u gitlab master
#6.上传标签
git tag -a 'v1.0' -m 'java code'
#7.上传指定标签
git push -u gitlab v1.0
(5)Jenkins创建任务

shell
##1.构建步骤shell构建docker镜像,并上传到harbor仓库
echo '#0.由于镜像是在library仓库无需登录'
echo '#1.构建镜像'
docker build --build-arg NAME=${JOB_NAME} -t harbor.chenshiquan.xyz/library/java-hello:${GIT_TAG} .
echo '#2.上传镜像'
docker push harbor.chenshiquan.xyz/library/java-hello:${GIT_TAG}
echo "3.执行ansible-playbook"
##2.ansible剧本
cat > /ansible/playbook/05-java-hello.yaml <<'EOF'
- hosts: web
tasks:
- name: "0.安装docker模块python库"
yum:
name: "python3-docker"
state: present
- name: "1.删除docker容器"
docker_container:
name: "java_hello"
image: "harbor.chenshiquan.xyz/library/java-hello:{{ git_tag }}"
state: absent
- name: "2.启动docker容器"
docker_container:
name: "java_hello"
image: "harbor.chenshiquan.xyz/library/java-hello:{{ git_tag }}"
ports: ["8082:8080"]
state: started
restart_policy: always
EOF

然后进行构建

sonarqube查看,和Jenkins项目名字相同

