jenkins配置保存-重启无效(XML保存异常)-Plugins(ssh-server)-保存了,重启又还原了,是怎么回事.


异常日志 tail -f /jenkins/apache-tomcat-10.1.50/logs/catalina.out -n500

这个密码 看起来是明文,而其他配置都是加密格式({AQAAABAAAA…})!
根本问题:这个明文密码可能包含不可见字符,或者在保存时被错误解析,导致产生了 0x00 空字符。

1
2
3
4
05-Feb-2026 14:42:19.252 警告 [Handling POST /jenkins/manage/configSubmit from 192.168.0.75 : http-nio-8080-exec-1] hudson.model.Descriptor.save Failed to save /jenkins/jenkins_home/jenkins.plugins.publish_over_ssh.BapSshPublisherPlugin.xml
java.io.IOException: java.lang.RuntimeException: Failed to serialize jenkins.plugins.publish_over_ssh.descriptor.BapSshPublisherPluginDescriptor#hostConfigurations for class jenkins.plugins.publish_over_ssh.BapSshPublisherPlugin$Descriptor
at hudson.XmlFile.write(XmlFile.java:223)
at hudson.model.Descriptor.save(Descriptor.java:964)
1
2
3
4
5
6
java.io.IOException: java.lang.RuntimeException: Failed to serialize jenkins.plugins.publish_over_ssh.descriptor.BapSshPublisherPluginDescriptor#hostConfigurations for class jenkins.plugins.publish_over_ssh.BapSshPublisherPlugin$Descriptor
at hudson.XmlFile.write(XmlFile.java:223)
at hudson.model.Descriptor.save(Descriptor.java:964)
at PluginClassLoader for publish-over-ssh//jenkins.plugins.publish_over_ssh.descriptor.BapSshPublisherPluginDescriptor.configure(BapSshPublisherPluginDescriptor.java:158)
at jenkins.model.Jenkins.configureDescriptor(Jenkins.java:4049)
at jenkins.model.Jenkins.doConfigSubmit(Jenkins.java:4013)

Caused by: com.thoughtworks.xstream.io.StreamException: Invalid character 0x0 in XML stream
Invalid character 0x0 表示 SSH 配置的代理密码字段 (proxyPassword) 包含空字符(NULL character),这是 XML 不允许的字符!
这不是权限问题,而是 数据污染问题!

🔍 问题分析

错误链:
Jenkins 尝试保存 Publish Over SSH 配置
序列化 BapSshHostConfiguration#proxyPassword 字段时失败
密码中包含 0x0(空字符),XML 写入器拒绝写入
导致整个配置文件无法保存
可能原因:
之前配置的代理密码包含特殊字符或空字符
配置文件损坏,密码字段被污染
从其他环境复制配置时编码问题

这个密码 看起来是明文,而其他配置都是加密格式({AQAAABAAAA…})!
根本问题:这个明文密码可能包含不可见字符,或者在保存时被错误解析,导致产生了 0x00 空字符。

看到了关键信息!您是用 Tomcat 启动 Jenkins,而且注意到这个参数:

-Dorg.apache.catalina.security.SecurityListener.UMASK=0027
这就是问题根源!

1
2
3
4
5
6
7
ps -ef | grep jenkins
avahi 677 1 0 13:35 ? 00:00:01 avahi-daemon: running [jenkins171.local]
root 8020 1 62 14:16 ? 00:00:53 /usr/local/jdk//bin/java -Djava.util.logging.config.file=/jenkins/apache-tomcat-10.1.50/conf/logging.properties -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Xmx14G -Djava.awt.headless=true -DJENKINS_HOME=/jenkins/jenkins_home -Duser.timezone=GMT+08 -Difile.encoding=utf-8 -Dorg.jenkinsci.plugins.gitclient.Git.timeOut=1200 -Djdk.tls.ephemeralDHKeySize=2048 -Djava.protocol.handler.pkgs=org.apache.catalina.webresources -Dsun.io.useCanonCaches=false -Dorg.apache.catalina.security.SecurityListener.UMASK=0027 --add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.lang.reflect=ALL-UNNAMED --add-opens=java.base/java.io=ALL-UNNAMED --add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.base/java.util.concurrent=ALL-UNNAMED --add-opens=java.rmi/sun.rmi.transport=ALL-UNNAMED -DJENKINS_HOME=/jenkins/jenkins_home -classpath /jenkins/apache-tomcat-10.1.50/bin/bootstrap.jar:/jenkins/apache-tomcat-10.1.50/bin/tomcat-juli.jar -Dcatalina.base=/jenkins/apache-tomcat-10.1.50 -Dcatalina.home=/jenkins/apache-tomcat-10.1.50 -Djava.io.tmpdir=/jenkins/apache-tomcat-10.1.50/temp org.apache.catalina.startup.Bootstrap start
ubuntu 8159 3314 0 14:17 pts/1 00:00:00 grep --color=auto jenkins

-Dorg.apache.catalina.security.SecurityListener.UMASK=0027
-Dorg.apache.catalina.security.SecurityListener.UMASK=0027

问题分析
UMASK=0027 是 Tomcat 的安全机制,它会:
覆盖 root 用户的默认 umask(通常是 0022)
强制新创建文件的权限为 640(即 -rw-r—–)
移除其他用户的写权限
虽然进程是 root,但 Jenkins 在写入配置文件时,Tomcat 的安全监听器会强制应用这个 umask,导致:
文件权限被限制为 640
Jenkins 无法再次写入(因为实际运行中 Jenkins 会检查并尝试重写)


查看文件是否被锁定

1
2
3
4
5
6
7
8
# 检查文件是否被其他进程占用
lsof /jenkins/jenkins_home/jenkins.plugins.publish_over_ssh.BapSshPublisherPlugin.xml

# 检查文件属性(是否有 immutable 标志)
lsattr /jenkins/jenkins_home/jenkins.plugins.publish_over_ssh.BapSshPublisherPlugin.xml

# 如果有 i 标志,移除它
chattr -i /jenkins/jenkins_home/jenkins.plugins.publish_over_ssh.BapSshPublisherPlugin.xml

查看SSH-Server配置是否生效 Publish Over SSH

1
sudo cat /jenkins/jenkins_home/jenkins.plugins.publish_over_ssh.BapSshPublisherPlugin.xml | grep -A5 "jenkins(prod-online)"

查询配置文件权限

1
2
3
4
5
6
7
ls -lh *sh*
-rwxr-x--- 1 root root 366 8月 18 2022 com.dabsquared.gitlabjenkins.GitLabPushTrigger.xml
-rw-r----- 1 root root 4.3K 2月 5 14:11 hudson.plugins.emailext.ExtendedEmailPublisher.xml
-rw-r----- 1 root root 683 1月 21 19:07 hudson.plugins.powershell.PowerShellInstallation.xml
-rw-r----- 1 root root 1.9K 2月 5 14:11 jenkins.plugins.publish_over_ssh.BapSshPublisherPlugin.xml
-rwxr-xr-x 1 root root 42K 2月 5 13:53 jenkins.plugins.publish_over_ssh.BapSshPublisherPlugin.xml260205
-rwxr-xr-x 1 root root 42K 2月 5 14:05 jenkins.plugins.publish_over_ssh.BapSshPublisherPlugin.xml260205003

Tomcat 部署修复

1
2
3
4
5
6
7
8
9
10
11
12
13
# 找到 Tomcat 的 setenv.sh(如果没有则创建)
sudo vi /jenkins/apache-tomcat-10.1.50/bin/setenv.sh

# 添加以下内容
export JENKINS_HOME=/jenkins/jenkins_home
export CATALINA_OPTS="-DJENKINS_HOME=/jenkins/jenkins_home"

# 确保目录存在且有权限
sudo mkdir -p /jenkins/jenkins_home
sudo chown -R tomcat:tomcat /jenkins/jenkins_home

# 重启 Tomcat
sudo systemctl restart tomcat9