背景
我是一家互联网公司的 DevOps 工程师,平常负责公司服务的上线发布流程。我和墨菲安全的这款开源的漏洞检测工具结缘,主要是因为前段时间log4j2 的漏洞,最近我们公司的研发频繁的上线基本上都是修复 log4j2 的漏洞,我被他们整烦了。就找他们研发的负责人讨论是不是能够在上线前集成一些自动化的工具来检测这样的漏洞,比如 log4j2 或者 fastjson 类似这样的问题。
经过一番调研,公司刚好有几个研发正在用墨菲安全的IDE插件,我看他也有一个命令行的工具,可以集成到 Jenkins 里面,于是就试了试,效果还不错。
核心问题解决
将代码安全检测能力集成至CI流程,在代码打包前即对代码进行安全扫描,保证公司代码库内项目的质量,同时也会减少项目发布时的压力。且持续集成中的任何一个环节都是自动完成的,无需太多人工干预,有利于减少重复过程以节省时间和工作量。
目前实现的效果
1、每次 Jenkins 构建的时候自动检测代码中存在的三方开源组件,并识别漏洞
2、配置规则,识别到严重漏洞就中断构建
3、结果推送到飞书群里,相关研发都能看到
集成流程
1.Jenkinsfile
在项目根目录放一个 Jenkinsfile 文件(因为 Jenkins 为单节点,为了防止机器故障造成数据丢失,所以 Jenkinsfile 文件都会存在项目里,而不是存在 Jenkins 这台机器上)**
pipline 内容:该逻辑为代码下拉后,通过墨菲安全 CLI 对代码进行检测,然后通过 Linux 工具 jq 来对检测出的数据进行解析,如检测结果存在’强烈建议修复’则终止打包流程。
pipeline{ agent { label "xxxxx"} // 指定在哪台节点上执行构建操作,这里指定执行节点的标签 options { timestamps() // 日志记录时间 buildDiscarder(logRotator(numToKeepStr: '10')) // 只保留10个构建历史 timeout(time: 1, unit: 'HOURS') //流水线超时设置1h } stages { stage("pull code"){ // 拉取代码阶段 steps{ script{ git credentialsId: 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxx', url: 'https://xxx.xxxxxx.com/xxxx/xxxxxxxxxxx.git' } } } stage("Test"){ // 代码测试阶段,因各种因素影响,不能直接将公司测试代码发出来,参照即可 steps{ sh 'echo "build project"' } } stage("murphysec scan") { // 墨菲安全CLI检测阶段 environment { API_TOKEN = credentials('murphysec-token') // {murphusec-token}是Jenkins内创建的墨菲安全访问令牌凭据,墨菲安全CLI工具默认会读取{API_TOKEN}这个变量名当作自己的{--token}参数 } steps{ sh ''' NUM=`murphysec scan . --server http://xxx.xxxxx.com/ --json | jq . | jq ".comps | map(select(.show_level == 1)) | length"` if [ $NUM -ne 0 ];then false fi ''' } } stage("build"){ // 代码构建阶段,因各种因素影响,不能直接将公司测试代码发出来,参照即可 steps{ sh 'echo "build project"' } } stage("publish project"){ // 代码上传阶段,因各种因素影响,不能直接将公司测试代码发出来,参照即可 steps{ sh 'echo "publish project"' } } } post { // 构建后的操作 success { // 步骤全部执行成功后执行 script{ currentBuild.description = "\n 打包成功!" sh ''' DATE=`date "+%Y-%m-%d_%H:%M:%S"` sh /usr/local/script/feishu.sh "项目:'$JOB_NAME'\\n结果:打包成功!已触发发布流程\\n时间:'$DATE'\\n节点:'$NODE_NAME'" ''' } } failure { // 步骤只要有一个执行失败就执行 script{ // feishu.sh脚本是一个简单的shell脚本,存放在构建机器上,用于将构建返回的结果信息通过脚本发送至飞书群内 currentBuild.description = "\n 打包失败!" sh ''' DATE=`date "+%Y-%m-%d_%H:%M:%S"` sh /usr/local/script/feishu.sh "项目:'$JOB_NAME'\\n结果:打包失败!\\n时间:'$DATE'\\n节点:'$NODE_NAME'\\n原因:项目中存在强烈建议修复组件!" ''' } } } }
feishu.sh内容
#!/bin/bash ## 调用飞书群机器人的webhooks接口将信息发送至群内 api=https://open.feishu.cn/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx curl -X POST \ $api \ -H 'Content-Type: application/json' \ -d '{ "msg_type": "post", "content": { "post": { "zh_cn": { "title": "Jenkins", "content": [ [ { "tag": "text", "un_escape": true, "text": "'$1'" } ], [ ] ] } } } }'
调用飞书群机器人的webhooks接口将信息发送至群内
2. 在Jenkins上设置脚本路径
在Jenkins后台找到项目后,配置管理 Advanced Project Options -> Pipeline -> Script Path = Jenkinsfile ,这样Jenkisn CI 执行的时候,pipline流程就会执行Jenkinsfile里的逻辑。
3. 配置Webhooks
项目配置Webhooks,以便项目在更新后,能够自动触发Jenkins
注意:Jenkins需安装插件,Git、Gitlab Plugin
Jenkins配置
构建触发器勾选 Build when a changs is …选项,该URL在gitlab项目webhooks中会用到
创建Secret token,用于Gitlab Webhooks做验证
Gitlab 配置
网址是 GItlab [构建触发器] Build when a changs is …处的 URL
Sercet 令牌为 Jenkins 项目内创建的 Secret token
4.飞书通知
做好异常处理,某个stage抛出异常后,要及时做出通知,避免影响打包。
下图为构建流程:
通过post来对不同的构建结果做出通知,我这里采用的飞书群组机器人,调用机器人webhooks将构建结果发送到群内。项目检测未通过时,可以在后台将检测结果导入发送给开发人员做修复参考。
关于墨菲安全CLI
墨菲安全推出的一款开源工具,用于在命令行检测指定目录代码的依赖安全问题,也可以基于 CLI 工具实现在 CI 流程的检测。
开源地址 :https://github.com/murphysecurity/murphysec
欢迎大家的反馈和交流!