Jenkins升级

发布时间 2023-11-28 16:37:11作者: 热气球!

参考文档 ?

背景介绍 ?

公司部分机器用的是某云厂商机器,部署在大型客户内部方便为他们的业务做第三方服务。该客户会定期做基线检查以及安全漏洞检测。

近期被告知某机器中有关Java程序的漏洞,具体漏洞信息如下:

漏洞名称 CVE编号 漏洞等级 描述 端口号
Apache HTTP/2拒绝服务漏洞(CVE-2023-44487) CVE-2023-44487 高危 Apache HTTP/2是超文本传输​​协议或HTTP,浏览器用于与Web服务器通信。
Apache HTTP/2存在拒绝服务漏洞,攻击者可利用该漏洞导致目标系统停止响应。
8080
Eclipse Jetty 资源管理错误漏洞(CVE-2023-26048) CVE-2023-26048 中危 Eclipse Jetty是Eclipse基金会的一个开源的、基于Java的Web服务器和Java Servlet容器。

Eclipse Jetty 存在资源管理错误漏洞,该漏洞源于当攻击者客户端可能会发送一个大的多部分请求时,会导致服务器抛出OutOfMemoryError。受影响的产品和版本:Jetty-server 9.4.50及之前版本,10.0.13及之前版本,11.0.13及之前版本。
8080
Eclipse Jetty 信息泄露漏洞(CVE-2023-26049) CVE-2023-26049 中危 Eclipse Jetty是Eclipse基金会的一个开源的、基于Java的Web服务器和Java Servlet容器。

Eclipse Jetty 存在信息泄露漏洞,该漏洞源于非标准 cookie 解析可能允许攻击者在其他 cookie 中走私 cookie,或者通过篡改 cookie 解析机制来执行意外行为。受影响的产品和版本:Jetty-server 9.4.50及之前版本,10.013及之前版本,11.0.13及之前版本,12.0.0.alpha3及之前版本。
8080

经过调查发现该机器中的8080端口是Jenkins服务,并且Jenkins官网也已经发布了漏洞通知

系统环境 ?

  • OS:CentOS Linux 7 (Core)
  • Jenkins: 2.375.1
  • 安装方式:yum方式安装

Jenkins上已经有多个job在使用,和团队约定好时间后开始执行升级操作,升级版本:2.433

通过在该机器上调查Jenkins的配置环境(Jenkins不是我安装的,不是很清楚),信息如下

安装方式 工作路径 环境变量 ps -ef|grep jenkins 得到的进行命令 war包路径
yum方式安装 /var/lib/jenkins JENKINS_WEBROOT=/var/lib/jenkins/%C/jenkins/war
JENKINS_PORT=8080
/usr/lib/jvm/java-11//bin/java -Djava.awt.headless=true -Dorg.apache.commons.jelly.tags.fmt.timeZone=Asia/Shanghai -Xmx2512m -jar /usr/share/java/jenkins.war --webroot=%C/jenkins/war --httpPort=8080 --prefix=/jenkins /usr/share/java/jenkins.war

升级步骤 ?️

Step1 停止Jenkins ?

systemctl stop   jenkins

Step2 备份工作目录,方便出现错误时进行回滚 ?

cp -r /var/lib/jenkins /var/lib/jenkins_bak

Step3 备份旧包并获取新版Jenkins war包 ☢️

(此处使用清华源的Jenkins war包) https://mirrors.tuna.tsinghua.edu.cn/jenkins/war/2.428/

cd /usr/share/java/
cp jenkins.war jenkins.old_bak
wget https://mirrors.tuna.tsinghua.edu.cn/jenkins/war/2.428/jenkins.war

Step4 根据ps -ef得到的Jenkins启动进程命令手动启动 ?

/usr/lib/jvm/java-11//bin/java -Djava.awt.headless=true -Dorg.apache.commons.jelly.tags.fmt.timeZone=Asia/Shanghai -Xmx2512m -jar /usr/share/java/jenkins.war --webroot=%C/jenkins/war --httpPort=8080 --prefix=/jenkins --home=/var/lib/jenkins

进程显示已经启动成功,但是页面访问时发现和新安装Jenkins是一样的,没有看到之前的数据。

此时停掉手动启动的Jenkins进程,还原旧版本的war包 使用system启动Jenkins也无法启动了。

通过查询文档,怀疑是和工作路径有关,手动执行的进程应该是重新创建了工作路径导致没有原来的数据了。并且确实在执行命令的当前路径下出现了一个%C的目录。

Step5 参照/usr/lib/systemd/system/jenkins.service文件内容设置环境变量,使Jenkins读取原来工作路径数据 ?

vim /etc/profile
export JENKINS_HOME=/var/lib/jenkins
export JENKINS_WEBROOT=%C/jenkins/war
export JENKINS_PORT=8080
source /etc/profile

设置完环境变量后 手动启动Jenkins进程并使用绝对路径的方式指定工作路径

/usr/lib/jvm/java-11//bin/java -Djava.awt.headless=true -Dorg.apache.commons.jelly.tags.fmt.timeZone=Asia/Shanghai -Xmx2512m -jar /usr/share/java/jenkins.war --webroot=/var/lib/jenkins/%C/jenkins/war --httpPort=8080 --prefix=/jenkins

此时访问Jenkins发现之前的数据已经存在了。

Step6 备份并修改/usr/lib/systemd/system/jenkins.service ?️

cp /usr/lib/systemd/system/jenkins.service /usr/lib/systemd/system/jenkins_bak.service
vim /usr/lib/systemd/system/jenkins.service
[Unit]
Description=Jenkins Continuous Integration Server
Requires=network.target
After=network.target
[Service]
Type=notify
NotifyAccess=main
ExecStart=/usr/lib/jvm/java-11//bin/java -Djava.awt.headless=true -Dorg.apache.commons.jelly.tags.fmt.timeZone=Asia/Shanghai -Xmx2512m -jar /usr/share/java/jenkins.war --webroot=/var/lib/jenkins/%C/jenkins/war --httpPort=8080 --prefix=/jenkins
Restart=on-failure
SuccessExitStatus=143
User=root
Group=root
Environment="JENKINS_HOME=/var/lib/jenkins"
Environment="JENKINS_WEBROOT=/var/lib/jenkins/%C/jenkins/war"
Environment="JENKINS_PORT=8080"
[Install]
WantedBy=multi-user.target

修改前/usr/lib/systemd/system/jenkins.service文件内容:

[Unit]
Description=Jenkins Continuous Integration Server
Requires=network.target
After=network.target
[Service]
Type=notify
NotifyAccess=main
ExecStart=/usr/bin/jenkins
Restart=on-failure
SuccessExitStatus=143
User=jenkins
Group=jenkins
Environment="JENKINS_HOME=/var/lib/jenkins"
WorkingDirectory=/var/lib/jenkins
Environment="JENKINS_WEBROOT=%C/jenkins/war"
Environment="JAVA_HOME=/usr/lib/jvm/java-11/"
Environment="JAVA_OPTS=-Djava.awt.headless=true -Dorg.apache.commons.jelly.tags.fmt.timeZone=Asia/Shanghai -Xmx2512m"
Environment="JENKINS_PORT=8080"
[Install]
WantedBy=multi-user.target

升级验证 ?

启动Jenkins并访问页面

systemctl start jenkins

数据已经存在并且可以访问

补充说明 ?️‍?

通过查看文档,发现有些人是直接替换war包进行升级Jenkins,我在VMware Fusion环境中测试是可以的,但是对于我要升级的线上环境systemctl start jenkins启动是报错的,并且无法看到具体的日志,手动启动Jenkins进程又没有什么问题。猜测是和Jenkins所需要用户权限相关,由于个人觉得直接替换war的方式不够清晰又太过于暴力,没有继续研究。

在升级过程中出现了一个情况:可以访问登录页面但是密码总是提示错误(浏览器自动填充的密码 不存在密码输入错误或记错的情况),此时进行修改设置,步骤如下:

cp /var/lib/jenkins/config.xml /var/lib/jenkins/config_bak
vim /var/lib/jenkins/config.xml
# 删除下面的内容并重启Jenkins
<useSecurity>true</useSecurity>
  <authorizationStrategy class="hudson.security.FullControlOnceLoggedInAuthorizationStrategy">
    <denyAnonymousReadAccess>true</denyAnonymousReadAccess>
  </authorizationStrategy>
  <securityRealm class="hudson.security.HudsonPrivateSecurityRealm">
    <disableSignup>true</disableSignup>
    <enableCaptcha>false</enableCaptcha>
  </securityRealm>

访问页面此时是不需要登录的

设置Jenkins认证

点击应用后回到首页,此时右上角已经出现了登录的按钮,但是不要点击。因为此时你还没有重新设置账户密码。

修改密码后重新登录,就可以正常使用了。