跳转至

SOP — hpc-submit TigerVNC 多用户远程桌面部署

项目 内容
目标主机 hpc-submit / 192.168.31.28(Rocky Linux 9.8,8 vCPU / 15 GB,SELinux Permissive)
变更类型 C 类生产变更(软件安装 + 服务配置 + 常驻服务启停 + 用户家目录初始化)
实施日期 2026-09-27
变更编号 见 backup/README.md 中的批次时间戳(首个成功批次 20260927-165433)
实施方式 deployer.py(幂等编排)+ assets/vnc-ldap-sync(用户同步器)

目录

  1. 背景 2. 目标 3. 前置条件 4. 影响范围 5. 分步操作 6. 验证 7. 回滚 8. 风险说明 9. 后续变更:rain01 桌面锁屏治理 10. 后续变更:桌面锁屏策略工程化 附录

1. 背景

hpc-submit 是 EDA 集群的提交节点,LDAP(dc=rainchen,dc=com,9 个 posixAccount 用户)通过 SSSD 统一认证,但节点上没有任何图形远程桌面入口:

  • tigervnc-server、Xvnc、vncpasswd 均不存在,/usr/share/xsessions 为空(无桌面环境);
  • 5900–5999 端口全部空闲,firewalld 未启用;
  • /home 是 NFS 挂载(192.168.31.249:/data/nfs/home,no_root_squash),9 个 LDAP 用户中只有 cy01/ldapadmin/rain01 3 个已有家目录。

EDA 工具(Virtuoso / ICC2 / Calibre 等)需要图形界面,因此需要一套多用户、可开机自启、随 LDAP 变更自动扩缩的 VNC 服务。

2. 目标

变更完成后应达到以下可验证状态:

  1. 9 个 LDAP 用户各自拥有独立的 TigerVNC 会话,监听 0.0.0.0:5901-5909,内网 VNC Viewer 可直连;
  2. 会话常驻且 systemctl is-enabled 为 enabled,节点重启后自动拉起;
  3. 每个用户的 VNC 密码按规则 <user>@<port> 生成,密码文件 ~/.vnc/passwd 权限 0600、属主为对应用户;
  4. 桌面环境为 Xfce4,9 个会话合计内存占用控制在 2 GB 以内;
  5. LDAP 新增用户后,无需人工干预即自动获得 display、密码与会话(周期 ≤ 10 分钟,或手动触发即时生效);
  6. 全流程幂等:重复执行第二次零变更、全跳过。

端口与用户映射(本方案的核心约定)

分配规则:按 LDAP uidNumber 升序,从 :1(端口 5901)起依次分配。display 号一经分配永不回收、不重排——因为密码规则内嵌了端口号,重排会导致所有用户密码失效。

display 端口 用户 uidNumber 组 规则密码(输入) 实际生效(前 8 字符)
:1 5901 rain01 2001 design(2000) rain01@5901 rain01@5
:2 5902 rain02 2002 design(2000) rain02@5902 rain02@5
:3 5903 rain03 2003 design(2000) rain03@5903 rain03@5
:4 5904 cloud01 3001 dv(3000) cloud01@5904 cloud01@
:5 5905 cy01 4001 custom(4000) cy01@5905 cy01@590
:6 5906 david01 5001 layout(5000) david01@5906 david01@
:7 5907 lws01 6001 cad(6000) lws01@5907 lws01@59
:8 5908 cq01 6101 sre(6100) cq01@5908 cq01@590
:9 5909 ldapadmin 9001 sre(6100) ldapadmin@5909 ldapadmi

8 字符截断是 RFB 协议固有限制(VncAuth 用 DES,密钥 8 字节),非配置可改。 实测证据:printf 'cy01@5905\ncy01@5905\n' | vncpasswd -f 与 printf 'cy01@590\ncy01@590\n' | vncpasswd -f 输出的密文 md5 完全相同。 客户端同样只取前 8 字符,因此用户在 VNC Viewer 中输入完整规则密码即可登录,无需记忆截断值。

3. 前置条件

以下条件全部落为 deployer.py precheck 的可执行检查,任一 BLOCK 即终止,不进入变更步骤:

类别 检查项 级别
通道 root@192.168.31.28 SSH 免密可登录 BLOCK
契约 ID=rocky 且 VERSION_ID 以 9 开头;架构 x86_64;SELinux ∈ BLOCK(--force 亦无效)
包源 dnf repolist --enabled 至少 1 个仓库 BLOCK
命令 ss / systemctl / ldapsearch / runuser / dnf 均可解析 BLOCK
认证 sssd.service 处于 active BLOCK
网络 LDAP 端点(从 /etc/sssd/sssd.conf 的 ldap_uri 解析)TCP 可达 BLOCK
资源 可用内存 ≥ 8 GB;/ 可用空间 ≥ 5 GB BLOCK
端口 5901–5999 无既有监听 WARN
包可用 tigervnc-server 可解析(已安装时跳过此检查) WARN

执行前置检查(只读,不做任何改动):

cd vnc-server-deploy
python3 deployer.py precheck

预期:预检查通过(告警 0 项),退出码 0。失败时逐条给出「检查项 / 实际值 / 期望值 / 修复建议」,并汇总全部不符合项后统一退出。

4. 影响范围

维度 内容
涉及主机 仅 hpc-submit(192.168.31.28)单机,无集群其它节点
是否停服 不需要。新增服务与既有业务(sssd、nfs 客户端、modulefiles)无交集;节点上 slurmctld/slurmd 均 inactive
窗口期 无强制窗口。npm 安装约 3–5 分钟,用户会话建立约 1 分钟,期间节点可正常使用
新增监听 TCP 5901–5909(0.0.0.0 与 [::])。firewalld 当前 inactive,未新增放行规则;若日后启用 firewalld,需放行 5901-5909/tcp
资源占用 实测 9 个会话:Xvnc 9 进程合计 820 MB + xfce4-session 9 进程合计 515 MB ≈ 1.3 GB(节点总量 15 GB,变更后可用 12.6 GB)
家目录 新建 6 个用户家目录(rain02/rain03/cloud01/david01/lws01/cq01),内容取自 /etc/skel,属主设为对应用户,权限 0700。这是本次唯一的「扩张型」改动
写入文件 /etc/tigervnc/ 下 2 个配置(覆盖包自带内容)、/etc/vnc-ldap-sync.conf、/usr/local/sbin/vnc-ldap-sync、/etc/systemd/system/vnc-ldap-sync.{service,timer}、各用户 ~/.vnc/
既有在跑作业 无(节点无调度器守护进程,无登录会话冲突;本机无 GDM,不存在「用户已登录图形会话」的冲突场景)

5. 分步操作

实现体:deployer.py(编排与生命周期)、assets/vnc-ldap-sync(用户同步器,落地到 /usr/local/sbin/)。 以下每步给出与实现体等价的底层命令,供人工复核与手工复现;幂等与错误处理由实现体保证,不在代码块内展开。 编排入口(仅作附注):python3 deployer.py deploy,预演 --dry-run。

步骤 1:安装软件包

安装 TigerVNC 服务端、桌面环境与字体。Xfce 组来自 EPEL(节点已启用 epel 仓库),必须用 groupinstall 且限定 mandatory,default,否则会连带安装 optional 中的大量无关组件。

坑: - 中文包名是 google-noto-sans-cjk-ttc-fonts(appstream),不是 google-noto-sans-cjk-fonts;wqy-zenhei-fonts 在 Rocky 9 已不可用,勿沿用 CentOS 7 时代的包名。 - 节点无桌面环境,Xfce 组会一并带入 xorg-x11-server-Xorg 等依赖,属正常。 - 安装耗时较长(下载约 3–5 分钟),实现体使用 1800 s 超时。

dnf -y install tigervnc-server dbus-x11 xterm
dnf -y groupinstall "Xfce" --setopt=group_package_types=mandatory,default
dnf -y install xorg-x11-fonts-misc xorg-x11-fonts-100dpi xorg-x11-fonts-75dpi \
               xorg-x11-fonts-Type1 google-noto-cjk-fonts-common \
               google-noto-sans-cjk-ttc-fonts

预期:安装结束 Complete!;rpm -q tigervnc-server 输出 tigervnc-server-1.15.0-7.el9_8.2.x86_64。 失败判断:No match for argument → 包名有误(对照上文坑点);Curl error → 检查网络与仓库可达性,重跑本步(dnf 自身幂等,已装包会自动跳过)。

步骤 2:写入 TigerVNC 全局配置

覆盖 RPM 包自带的两个配置。包自带 vncserver-config-defaults 的内容是 session=gnome,而本机未安装 GNOME,直接使用会导致会话启动失败——这是必须先改的原因。

session=xfce 的值必须与 /usr/share/xsessions/ 下的文件名(去掉 .desktop)一致,实测该目录下存在 xfce.desktop。

坑:写入前必须先 mkdir -p /etc/tigervnc(首次部署时目录尚未由包创建,虽然本步在步骤 1 之后,目录通常已存在,但保留该前置动作以支持独立重跑)。

# 全局默认配置
cat > /etc/tigervnc/vncserver-config-defaults <<'EOF'
session=xfce
securitytypes=vncauth
geometry=1920x1080
depth=24
alwaysshared
desktop=EDA-HPC
EOF

# 强制配置:优先级高于用户 ~/.vnc/config,用于锁死认证方式
cat > /etc/tigervnc/vncserver-config-mandatory <<'EOF'
securitytypes=vncauth
EOF

chmod 0644 /etc/tigervnc/vncserver-config-defaults /etc/tigervnc/vncserver-config-mandatory

未设置 localhost 选项,因此 Xvnc 监听全部网卡(实测 0.0.0.0:590N),满足内网直连需求;如需改为隧道模式,见 RUNBOOK 第 9 章。

预期:两文件内容如上,sha256sum 与 assets/ 下同名资产一致。 失败判断:若 session= 值写错,服务会 active 但端口不监听,~/.vnc/<host>:<display>.log 中出现 Session startup failed;改回正确值后 systemctl restart 即可。

步骤 3:部署 LDAP 用户同步器

同步器是本次变更的核心复用件,负责把 LDAP 用户增量映射为 VNC 会话。它不引入新的凭据文件——LDAP 绑定信息(ldap_uri / ldap_search_base / 绑定 DN 与口令)直接从 /etc/sssd/sssd.conf 继承,实现凭据单一来源。

坑: - LDAP 口令通过 ldapsearch -y <临时文件> 传入(不落进程命令行),临时文件建在 /run 下、权限 0600、用后即删; - 所有外部命令按候选路径探测(ss 在 Rocky 9 上是 /usr/sbin/ss,不是 /usr/bin/ss),避免硬编码路径在发行版间失效。

cat > /usr/local/sbin/vnc-ldap-sync <<'SCRIPT'
# 内容取自 vnc-server-deploy/assets/vnc-ldap-sync
SCRIPT
chmod 0755 /usr/local/sbin/vnc-ldap-sync

cat > /etc/vnc-ldap-sync.conf <<'EOF'
# LDAP 连接信息留空时自动从 /etc/sssd/sssd.conf 继承(凭据单一来源)
base_port = 5900
password_template = {user}@{port}
create_home = true
skeleton = /etc/skel
home_mode = 0700
exclude_users =
ldap_timeout = 30
EOF
chmod 0600 /etc/vnc-ldap-sync.conf

预期:/usr/local/sbin/vnc-ldap-sync info 可正常输出(映射为空时不报错);vnc-ldap-sync status 退出码 0。 失败判断:报 LDAP 连接信息不完整 → 检查 /etc/sssd/sssd.conf 是否含 ldap_uri 与 ldap_search_base;报 ldapsearch 失败 → 用 ldapsearch -x -H <uri> -b <base> -D <dn> -y <pwfile> '(objectClass=posixAccount)' 手工验证绑定。

步骤 4:部署并启用同步定时器

以 systemd timer 周期调用同步器,解决「LDAP 新增用户后自动补齐 VNC」的需求。

坑:vncserver@.service、vnc-ldap-sync.* 等单元文件写入 /etc/systemd/system/ 后必须 daemon-reload,否则 systemctl is-enabled 会返回空、enable 操作会失败。

cat > /etc/systemd/system/vnc-ldap-sync.service <<'EOF'
[Unit]
Description=Sync LDAP users into TigerVNC display instances
After=network-online.target sssd.service
Wants=network-online.target

[Service]
Type=oneshot
ExecStart=/usr/local/sbin/vnc-ldap-sync sync
Nice=10
IOSchedulingClass=idle
TimeoutStartSec=300
EOF

cat > /etc/systemd/system/vnc-ldap-sync.timer <<'EOF'
[Unit]
Description=Periodic LDAP -> TigerVNC user synchronization

[Timer]
OnBootSec=3min
OnUnitActiveSec=10min
Persistent=true
Unit=vnc-ldap-sync.service

[Install]
WantedBy=timers.target
EOF

systemctl daemon-reload
systemctl enable --now vnc-ldap-sync.timer

预期:systemctl list-timers vnc-ldap-sync.timer 显示下次触发时间(约 10 分钟后)。 失败判断:systemctl status vnc-ldap-sync.timer 报 not found → 检查单元文件是否写入并已 daemon-reload。

步骤 5:首次用户同步

一次性完成 display 分配、家目录初始化、密码生成、服务启用四件事。这是首次部署与日常增量同步走的同一段代码,因此本步同时也就是需求 6 的机制验证。

坑: - NFS 家目录属主:虽然该导出为 no_root_squash(实测 root 可写 /home),但为让文件属主天然正确,所有 ~/.vnc 的创建与写入一律通过 runuser -u <user> -- /bin/bash -c '...' 以目标用户身份执行,而不是 root 写完后 chown; - runuser 不切换工作目录(实测 pwd 仍为 /root),因此脚本内必须使用绝对路径,不能依赖相对路径或 ~; - 家目录缺失的用户(rain02/rain03/cloud01/david01/lws01/cq01)由同步器按 create_home 开关自动创建,内容取自 /etc/skel; - 服务就绪判定用端口真正进入监听(轮询 ss 输出)而非固定 sleep。

派生出的用户级命令序列(等价于同步器对单个用户所做的动作,以 cy01 / :5 / 5905 为例):

# 5.1 写入 display -> user 映射(同步器自动生成,格式如下)
cat > /etc/tigervnc/vncserver.users <<'EOF'
:1=rain01
:2=rain02
:3=rain03
:4=cloud01
:5=cy01
:6=david01
:7=lws01
:8=cq01
:9=ldapadmin
EOF
chmod 0644 /etc/tigervnc/vncserver.users

# 5.2 用户家目录缺失时初始化(此处示例为 cy01 已有家目录,故可跳过)
#     实际对 rain02/rain03/cloud01/david01/lws01/cq01 执行:
#       mkdir -p /home/<user> && cp -a /etc/skel/. /home/<user>/ \
#         && chown -R <uid>:<gid> /home/<user> && chmod 700 /home/<user>

# 5.3 生成 VNC 密码(以目标用户身份,密码经 stdin 传入,不出现在进程命令行)
runuser -u cy01 -- /bin/bash -c '
  umask 077
  mkdir -p "/home/cy01/.vnc"
  IFS= read -r p1; IFS= read -r p2
  printf "%s\n%s\n" "$p1" "$p2" | /usr/bin/vncpasswd -f > "/home/cy01/.vnc/passwd"
  chmod 700 "/home/cy01/.vnc"
  chmod 600 "/home/cy01/.vnc/passwd"
  printf "%s\n" "5" > "/home/cy01/.vnc/.sync-display"
  chmod 600 "/home/cy01/.vnc/.sync-display"
' <<'PW'
cy01@5905
cy01@5905
PW

# 5.4 启用并启动会话(每个用户重复一次,display 号对应映射)
systemctl enable --now vncserver@:1.service vncserver@:2.service vncserver@:3.service \
                     vncserver@:4.service vncserver@:5.service vncserver@:6.service \
                     vncserver@:7.service vncserver@:8.service vncserver@:9.service

.sync-display 是同步器用于判断「该用户密码是否对应当前 display」的标记文件;display 号不变时重复执行不会重写密码,用户自行修改过的密码因此不会被覆盖。

预期:每个 vncserver@:N.service 变为 active (running),主进程为 /usr/sbin/vncsession <user> :N;ss -tlnp | grep 590 列出 5901–5909。

失败判断: - 服务 active 但端口不监听 → 查 ~/.vnc/<host>:<display>.log(常见原因:session= 名称与 xsessions 不符); - 密码文件属主不是该用户 → 说明绕过了 runuser,需删除 ~/.vnc 后重跑(登记见 backup/README.md); - 端口被占用 → ss -tlnp | grep <port> 定位占用者,改用其它 display 或先释放端口。

6. 验证

6.1 一键验证(推荐)

cd vnc-server-deploy
python3 deployer.py verify

预期输出 9 行 [OK],末行 验证结果:通过,退出码 0。每行包含:用户名、display、端口、服务 active、开机自启、端口监听、密码文件权限与属主、规则密码与实际生效值。

6.2 分项验证命令

# 服务全景(同步器自带,与变更流程共用同一套探测逻辑)
/usr/local/sbin/vnc-ldap-sync status

# 映射关系
cat /etc/tigervnc/vncserver.users

# 端口监听
ss -tlnp | grep -E ':59[0-9][0-9]'

# Xvnc 会话进程与启动参数
pgrep -a Xvnc

# 开机自启(逐实例确认,模板单元本身显示 indirect 属正常)
systemctl is-enabled vncserver@:1.service

# 定时器
systemctl list-timers vnc-ldap-sync.timer --no-pager

# 内存水位
free -m | head -2

6.3 端到端连通性验证(从客户端执行)

RFB 协议握手:服务端在 TCP 建连后立即发送 12 字节版本串。

for p in 5901 5905 5909; do
  printf "port %-5s: " "$p"
  timeout 5 bash -c "exec 3<>/dev/tcp/192.168.31.28/$p && head -c 12 <&3" | tr -d '\000'
  echo
done

预期:每个端口返回 RFB 003.008。这证明 VNC 服务不仅监听、且协议层真实应答。

最终人工确认(一次性):用 VNC Viewer 连接 192.168.31.28:5905,用户 cy01,密码输入完整规则密码 cy01@5905,应能看到 Xfce 桌面。

6.4 幂等复核

systemctl start vnc-ldap-sync.service && journalctl -u vnc-ldap-sync.service -n 3 --no-pager

预期:变更 0 项:无,全部已就绪(幂等跳过)。重复执行第二次零变更即满足幂等验收标准。

7. 回滚

备份位置

类型 位置
本地权威台账与归档 vnc-server-deploy/backup/,逐条登记见 backup/README.md
目标机现场暂存 /root/vnc-server-deploy-backup/20260927-165433/(便于无网络时现场回滚,验证通过后可删)

备份命名:<原名>.bak.<YYYYmmdd-HHmmss>,按原路径层次存放。

回滚方式一:编排器(推荐)

cd vnc-server-deploy
python3 deployer.py rollback --force

该命令按序执行:disable --now 全部 vncserver@:N.service → disable --now 并删除同步器与定时器单元 → daemon-reload → 从本地归档恢复 /etc/tigervnc/ 配置。回滚动作属高危,必须显式 --force。

回滚方式二:手工

# 1) 停用并禁用全部会话
systemctl disable --now vncserver@:1.service vncserver@:2.service vncserver@:3.service \
                       vncserver@:4.service vncserver@:5.service vncserver@:6.service \
                       vncserver@:7.service vncserver@:8.service vncserver@:9.service

# 2) 下线同步器
systemctl disable --now vnc-ldap-sync.timer
rm -f /etc/systemd/system/vnc-ldap-sync.service /etc/systemd/system/vnc-ldap-sync.timer
rm -f /etc/vnc-ldap-sync.conf /usr/local/sbin/vnc-ldap-sync
systemctl daemon-reload

# 3) 恢复被覆盖的配置(高危:覆盖操作,先确认备份文件存在)
B=/root/vnc-server-deploy-backup/20260927-165433
cp -a "$B/vncserver-config-defaults.bak.20260927-165433" /etc/tigervnc/vncserver-config-defaults
cp -a "$B/vncserver-config-mandatory.bak.20260927-165433" /etc/tigervnc/vncserver-config-mandatory
cp -a "$B/vncserver.users.bak.20260927-165433"          /etc/tigervnc/vncserver.users

回滚范围与边界

对象 是否回滚 说明
vncserver@:N 会话 是 停用并禁用
/etc/tigervnc/ 配置 是 从备份恢复
同步器与定时器 是 删除单元与脚本
软件包(tigervnc-server / Xfce / 字体) 否(默认保留) 不自动卸载,避免影响其它潜在使用者;如需卸载:dnf remove tigervnc-server
各用户 ~/.vnc/ 否(保留现场) 含用户密码与会话日志,可能用于事后排障;确认无需后手工删除
6 个新建的家目录与 skel 内容 否(保留) 家目录一旦被用户使用即产生数据,不可逆,禁止自动删除

回滚后的验证

systemctl list-units 'vncserver@*' --no-legend    # 预期无输出
ss -tlnp | grep -E ':59[0-9][0-9]' || echo "无 VNC 监听(符合预期)"
systemctl is-active vnc-ldap-sync.timer          # 预期 inactive
cat /etc/tigervnc/vncserver-config-defaults      # 预期 session=gnome(包原始值)

8. 风险说明

风险 影响 缓解措施
VncAuth 密码内网明文传输 同网段抓包可获知会话口令;且密码规则可预测(<user>@<port>) 已按用户选择采用内网直连。如需加固,见 RUNBOOK 第 9 章 的「切换为 SSH 隧道模式」;vncserver-config-mandatory 已锁死 securitytypes=vncauth,防止用户自行关闭认证
密码截断为 8 字符 规则密码实际只生效前 8 位,cloud01 与 david01 等的生效值分别落在 cloud01@、david01@,可读性差 已实测确认(附录 C),并在本文档与 RUNBOOK 中明确标注;客户端输入完整密码即可,无功能影响
9 个常驻会话占内存 实测约 1.3 GB;若用户会话内跑重型 EDA 工具,单会话可增长到 1–2 GB 变更后可用内存 12.6 GB,余量充足;RUNBOOK 第 10 章给出水位监控与按需下线个别 display 的操作
display 号不可回收 用户离职/删除后其端口与映射保留,长期会累积空洞 这是有意设计:密码内嵌端口,回收会导致误配。空洞仅占用端口号不占资源;确需整理时按 RUNBOOK 的「回收 display」流程人工介入
新用户家目录自动创建 create_home=true 会在同步时创建家目录,可能与其它流程(如 pam_mkhomedir)产生竞争 创建逻辑为 exist_ok 幂等且只补缺失项;当前 /etc/pam.d/ 未启用 pam_mkhomedir(已核查),无竞争
SELinux 当前为 Permissive 切换为 Enforcing 后,~/.vnc 的 SELinux 上下文可能不匹配导致会话启动失败 当前状态下无影响;若日后切 Enforcing,先执行 restorecon -RFv /home/<user>/.vnc 再重启会话(已写入 RUNBOOK 故障场景)
firewalld 未启用 当前无防火墙,端口直接可达 符合内网直连预期;若启用 firewalld,务必放行 5901-5909/tcp,否则所有会话不可达
单机无冗余 该节点故障则所有会话中断 属既有架构约束,非本次变更引入;会话数据在 ~/.vnc,重启后 systemd 自动拉起
会话崩溃后无 systemd 级自动重启 包自带单元没有 Restart= 指令,且 vncsession 崩溃时以退出码 0 退出,Restart=on-failure 类策略也不会触发。服务静默变为 inactive,常规 --failed 巡检发现不了 由 vnc-ldap-sync.timer 承担自愈:inactive 被判为 pending 并自动 start,最迟 10 分钟恢复(已实测)。紧急场景用 systemctl restart 秒级恢复。监控须建在 pgrep -c Xvnc 或 PORT_LISTEN 列上,见 RUNBOOK 第 7 章。若需秒级自愈,可用 drop-in 加 Restart=always,但会导致用户主动 logout 后被立即拉起,需权衡后决定【待决策】

9. 后续变更:rain01 桌面锁屏治理(2026-09-27)

项目 内容
目标主机 hpc-submit / 192.168.31.28
变更类型 C 类生产变更(用户级桌面偏好调整 + 进程处置)
变更编号 20260927-173004(备份见 backup/README.md 对应批次)
实施方式 人工 shell。单机 3 步、无编排、不产出脚本,故未走 deployer.py

9.1 背景

rain01 的 VNC 桌面(:1/5901)被 xfce4-screensaver 锁屏,解锁要求输入其 LDAP 账户口令。该口令存于 LDAP 目录,本机 root 无法代为重置(SSSD 经 LDAP 改密须提供旧口令,只能由 LDAP 管理员在目录侧执行)。用户已遗忘该口令,桌面被锁屏阻塞而无法继续使用。

根因:Xfce 桌面默认开启空闲屏保与锁屏(/saver/enabled、/lock/enabled 默认 true)。但 VNC 会话以 VncAuth 口令认证、桌面由 vncserver@.service 自动拉起,日常使用根本不需要 LDAP 口令——锁屏在此场景下是纯阻塞项,且不带来安全收益(VncAuth 本身即内网明文口令,见第 8 章风险表)。

两类口令须分清:VNC 连接口令(规则固定 rain01@5901,存于 ~/.vnc/passwd)与 LDAP 账户口令(本次被卡住的是后者)。

9.2 目标

  • 解除 rain01 当前锁屏,且不中断桌面会话与未保存工作;
  • 永久关闭该用户的 Xfce 屏保与空闲锁屏;
  • 不影响 VNC 服务本体,不影响其它 8 个用户。

9.3 前置条件

  • 目标机 root(SSH)权限;
  • vncserver@:1.service 为 active,且其 DBus 会话总线 /run/user/2001/bus 存在;
  • xfconf-query 已安装(随 Xfce 桌面组一并安装)。
systemctl is-active vncserver@:1.service        # 预期 active
ls -l /run/user/2001/bus                        # 预期存在(rain01 的 uid=2001)
command -v xfconf-query                         # 预期 /usr/bin/xfconf-query

9.4 影响范围

项 内容
主机 hpc-submit 单台
组件 仅 rain01 用户的 Xfce 桌面偏好(~/.config/xfce4/xfconf/),不涉及 /etc/tigervnc/、同步器与其它会话
是否停服 否。不重启会话,不中断 Xvnc/xfce4-session
在跑作业 rain01 桌面内未保存的工作全部保留
窗口期 无需窗口期,秒级完成

9.5 分步操作

步骤 1:备份用户锁屏配置

变更前先留原文件,仅复制不改动。

DEST=vnc-server-deploy/backup/home/rain01/.config/xfce4/xfconf/xfce-perchannel-xml
mkdir -p "$DEST"
scp root@192.168.31.28:/home/rain01/.config/xfce4/xfconf/xfce-perchannel-xml/xfce4-screensaver.xml \
    "$DEST/xfce4-screensaver.xml.bak.20260927-173004"

预期:备份文件 218 字节,内容仅含 lock/sleep-activation=false。 失败判断:连不上或文件不存在 → 中止,先排查会话状态(vncserver@:1 是否 active)。

步骤 2:关闭屏保与空闲锁屏

经会话 DBus 修改 rain01 的偏好。xfconf-query 的 --create 用于首次创建键,重复执行设同值不会报错(幂等)。

ENVX="HOME=/home/rain01 XDG_RUNTIME_DIR=/run/user/2001 DISPLAY=:1 DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/2001/bus"
su -s /bin/bash rain01 -c "$ENVX xfconf-query -c xfce4-screensaver -p /saver/enabled -s false --create -t bool"
su -s /bin/bash rain01 -c "$ENVX xfconf-query -c xfce4-screensaver -p /lock/enabled  -s false --create -t bool"

注意事项与坑:

  • 必须以 rain01 身份、指向该用户的会话总线执行;root 直接跑 xfconf-query 找不到会话总线,会失败。
  • ENVX 必须显式带 HOME=/home/rain01:su -s /bin/bash 不会重置 HOME。若该用户的 xfconfd 已空闲退出(D-Bus 激活的服务会被回收),xfconf-query 会经 D-Bus 拉起一个新实例,而它按 HOME 定位配置目录——HOME 仍是 /root 时会读错目录,表现为 Channel "xfce4-screensaver" contains no properties;此时读到的值是假象,写入也会落到错误位置而命令仍返回 0。本轮实测已复现该现象(rain02 查询为空但配置文件内容正确)。
  • 直接编辑 XML 文件无效:xfconfd 常驻内存并在退出时回写,会覆盖手工改动;设值必须经 DBus。
  • rain01 的登录 shell 是 /bin/csh,su - rain01 -c 会交给 csh 解析命令串,故须显式 -s /bin/bash。
  • /saver/enabled 管屏保总开关,/lock/enabled 管"屏保激活时是否锁定",两项都关才彻底不锁。

预期:两条命令 rc=0;xfconf-query -c xfce4-screensaver -lv 显示三项均为 false。

步骤 3:终止锁屏进程,解除当前锁屏

配置改动只影响后续触发的锁屏,当前已显示的锁屏窗口须由终止进程消除。

pkill -u rain01 -f xfce4-screensaver

注意事项与坑:

  • 必须用 -f(匹配完整命令行)。进程名被内核截断为 xfce4-screensav(15 字符上限),pgrep -u rain01 -a xfce4-screensaver 会返回空、误判"进程不存在"。
  • 调换顺序有风险:先 kill 再改配置,守护进程可能被 DBus 重新拉起并再次锁屏;本流程先设配置、后 kill。
  • 该进程由 xfce4-session 会话管理,崩溃不会被自动重启,因此 kill 后不会立即复发。

预期:命令无输出;ps -u rain01 -o pid=,args= | grep -i screensaver | grep -v grep 无结果。 失败判断:锁屏仍在 → 用 -f 重新确认匹配;进程反复出现且仍锁屏 → 复查 /lock/enabled 是否确为 false。

9.6 验证

# 1) 配置值:预期 /lock/enabled、/lock/sleep-activation、/saver/enabled 三项均为 false
su -s /bin/bash rain01 -c "HOME=/home/rain01 XDG_RUNTIME_DIR=/run/user/2001 DISPLAY=:1 \
  DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/2001/bus \
  xfconf-query -c xfce4-screensaver -lv"

# 2) 配置已落盘
cat /home/rain01/.config/xfce4/xfconf/xfce-perchannel-xml/xfce4-screensaver.xml

# 3) 锁屏进程不存在
ps -u rain01 -o pid=,args= | grep -i screensaver | grep -v grep || echo "无锁屏进程(符合预期)"

# 4) 会话与桌面健康
ps -u rain01 -o comm= | grep -E "Xvnc|xfce4-session|xfwm4|xfce4-panel|xfdesktop" | sort -u
systemctl is-active vncserver@:1.service          # 预期 active

幂等复核:重复 9.5 步骤 2 两条 xfconf-query 与步骤 3 的 pkill。

实测结果(2026-09-27):三项值均为 false 且已落盘;锁屏进程消失、5 秒后复查未重生;桌面组件 Xvnc/xfce4-session/xfwm4/xfce4-panel/xfdesktop 全部存活;vncserver@:1.service 为 active;幂等复跑 saver_set_rc=0、lock_set_rc=0、pkill_rc=1(无进程可杀,符合预期)。

9.7 回滚

回滚目标:让 rain01 恢复默认锁屏行为。

# 方式一(推荐):经 DBus 把两项设回 true
ENVX="HOME=/home/rain01 XDG_RUNTIME_DIR=/run/user/2001 DISPLAY=:1 DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/2001/bus"
su -s /bin/bash rain01 -c "$ENVX xfconf-query -c xfce4-screensaver -p /saver/enabled -s true -t bool"
su -s /bin/bash rain01 -c "$ENVX xfconf-query -c xfce4-screensaver -p /lock/enabled  -s true -t bool"

# 方式二:按备份文件还原(高危:覆盖操作,先确认备份存在)
B=vnc-server-deploy/backup/home/rain01/.config/xfce4/xfconf/xfce-perchannel-xml
scp "$B/xfce4-screensaver.xml.bak.20260927-173004" \
    root@192.168.31.28:/home/rain01/.config/xfce4/xfconf/xfce-perchannel-xml/xfce4-screensaver.xml

方式二的坑:覆盖文件后不会立即生效,xfconfd 仍持有内存中的旧值并会回写;须让 xfconfd 重新加载(pkill -u rain01 xfconfd,由 DBus 自动拉起)或重启会话。优先用方式一。

回滚后验证:xfconf-query -c xfce4-screensaver -lv 显示 /saver/enabled true、/lock/enabled true;空闲超时后可观察到锁屏复现。

备份位置:vnc-server-deploy/backup/home/rain01/.config/xfce4/xfconf/xfce-perchannel-xml/xfce4-screensaver.xml.bak.20260927-173004,逐条台账见 backup/README.md。验证通过后由用户对照台账自行清理。

9.8 风险说明

风险 影响 缓解措施
关闭锁屏后桌面长期无人值守 能访问该 VNC 端口者可操作桌面 VNC 本身已有 VncAuth 口令(内网明文),锁屏并未实质提升安全;如需收紧见 RUNBOOK 第 9 章
仅覆盖 rain01 一个用户 其余 8 个用户仍可能被锁屏卡住 已作为待决策项登记于 docs/HANDOFF.md;批量处理即对每个 uid 重复 9.5 步骤 2–3
pkill 匹配过宽误杀 可能终止无关进程 命令同时限定 -u rain01 与 -f xfce4-screensaver;该用户下无同名其它进程
偏好随家目录持久化 该设置将长期随 rain01 的家目录(NFS)存在 属预期行为;回滚见 9.7

10. 后续变更:桌面锁屏策略工程化(2026-09-27)

项目 内容
目标主机 hpc-submit / 192.168.31.28
变更类型 C 类生产变更(存量用户配置收敛 + 部署工程代码改造 + 系统级配置交付)
变更编号 20260927-173555(用户级备份)、20260927-173928(编排器批次)
实施方式 批量人工收敛(8 用户)+ 改造后的 deployer.py deploy

10.1 背景

第 9 章只处理了 rain01 一个用户。根因在部署默认值本身:Xfce 桌面默认开启空闲屏保与锁屏(/saver/enabled、/lock/enabled 默认 true),而 VNC 会话以 VncAuth 口令认证、桌面由 vncserver@.service 自动拉起,日常使用并不需要 LDAP 账户口令。默认值不改,则每个新用户、每次新环境部署都会重现「用户忘密码即被锁死」的阻塞——属重复返工,须从交付物层面消除。

10.2 目标

  • 其余 8 个用户的在用会话立即禁用屏保与锁屏,并停用当时已激活的屏保;
  • 部署工程交付系统级默认,后续新建 LDAP 用户与新会话默认不锁屏;
  • 该交付物纳入既有框架:drift 可检出、rollback 可撤销、重复 deploy 零变更。

10.3 前置条件

  • 目标机 root(SSH)权限;各用户会话运行中且其 DBus 总线 /run/user/<uid>/bus 存在;
  • 本地可执行工程(Python 3 + PyYAML);
  • 目标机 /etc/xdg/xfce4/xfconf/xfce-perchannel-xml/ 已存在(随 Xfce 桌面组安装)。
python3 vnc-server-deploy/deployer.py precheck     # 预期通过,无 BLOCK

10.4 影响范围

项 内容
主机 hpc-submit 单台
组件 8 个用户的 Xfce 桌面偏好;新增 /etc/xdg/xfce4/xfconf/xfce-perchannel-xml/xfce4-screensaver.xml;部署工程代码(deployer.py、config/defaults.yaml、assets/xfce4-screensaver.xml)
是否停服 否。不重启任何 VNC 会话,不中断 Xvnc/xfce4-session
在跑作业 全部保留;本变更只改偏好并新增一个只读配置文件
窗口期 无需窗口期
附带影响 系统级默认对该机所有 Xfce 会话生效(含将来可能的本地图形登录):本机 Xfce 桌面不再自动锁屏

10.5 分步操作

步骤 1:备份 8 个用户的现有锁屏配置

TS=$(date +%Y%m%d-%H%M%S)
ssh root@192.168.31.28 'RB=/root/vnc-server-deploy-backup/'"$TS"'; mkdir -p "$RB"
  for u in rain02 rain03 cloud01 cy01 david01 lws01 cq01 ldapadmin; do
    f="/home/$u/.config/xfce4/xfconf/xfce-perchannel-xml/xfce4-screensaver.xml"
    if [ -f "$f" ]; then
      mkdir -p "$RB/home/$u/.config/xfce4/xfconf/xfce-perchannel-xml"
      cp -a "$f" "$RB/home/$u/.config/xfce4/xfconf/xfce-perchannel-xml/"
      echo "backed $u"
    else echo "absent $u"; fi
  done'
scp -r root@192.168.31.28:/root/vnc-server-deploy-backup/$TS/home vnc-server-deploy/backup/

预期:8 个用户均输出 backed,本地 backup/home/<user>/... 各得一份(历史文件移入保持原名)。 失败判断:任一用户 absent → 说明该用户尚无偏好文件,属正常,跳过即可;SSH 失败则中止。

步骤 2:批量禁用屏保与锁屏

<uid> 实取自 id -u,<display> 取自 /etc/tigervnc/vncserver.users;本机对照如下(换环境须重新取,勿照抄)。

# 本机实测对照:用户:uid:display
# rain02:2002:2  rain03:2003:3  cloud01:3001:4  cy01:4001:5
# david01:5001:6 lws01:6001:7   cq01:6101:8     ldapadmin:9001:9
for spec in rain02:2002:2 rain03:2003:3 cloud01:3001:4 cy01:4001:5 \
            david01:5001:6 lws01:6001:7 cq01:6101:8 ldapadmin:9001:9; do
  u=${spec%%:*}; r=${spec#*:}; uid=${r%%:*}; d=${r##*:}
  ENVX="HOME=/home/$u XDG_RUNTIME_DIR=/run/user/$uid DISPLAY=:$d DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/$uid/bus"
  su -s /bin/bash "$u" -c "$ENVX xfconf-query -c xfce4-screensaver -p /saver/enabled -s false --create -t bool"
  su -s /bin/bash "$u" -c "$ENVX xfconf-query -c xfce4-screensaver -p /lock/enabled  -s false --create -t bool"
done

坑:① 统一加 -s /bin/bash——EDA 用户登录 shell 多为 csh,su - <user> -c 默认交给 csh 解析;② 必须指向该用户自己的会话总线,root 无会话总线;③ ENVX 必须显式带 HOME=/home/<user>——su 不重置 HOME,该用户的 xfconfd 空闲退出后新激活的实例会按 HOME 定位配置目录,HOME 错时读到空 channel、写入也会落错位置而命令仍返回 0(详见 9.5 步骤 2 的坑,本轮已实测复现);④ 幂等:重复执行设同值,无副作用。

预期:每条命令 rc=0;xfconf-query -c xfce4-screensaver -lv 三项均为 false。

步骤 3:停用当时已激活的屏保

步骤 2 只影响后续触发;若屏保已激活(xfce4-screensaver-command -q 报 The screensaver is active),须显式停用,屏幕才恢复。

# 承步骤 2 的循环变量,对同一批用户执行:
su -s /bin/bash "$u" -c "$ENVX xfce4-screensaver-command -d"   # 停用屏保(不杀进程)
su -s /bin/bash "$u" -c "$ENVX xfce4-screensaver-command -q"   # 复查,预期 inactive

坑:-d 只是停用屏保,屏幕立即恢复且不杀守护进程;若改用 pkill -f xfce4-screensaver(第 9 章的做法),会连守护进程一并终止——两种方式都可行,-d 更温和,优先用 -d。

步骤 4:工程新增系统级策略交付物

改动集中在三处,不含同步器 vnc-ldap-sync:

文件 改动
vnc-server-deploy/assets/xfce4-screensaver.xml 新增模板:/saver/enabled、/lock/enabled 均为 false(含禁用理由与生效范围说明)
vnc-server-deploy/config/defaults.yaml 新增 paths.screensaver_policy(落地路径)与 desktop.disable_screensaver_lock: true(开关)
vnc-server-deploy/deployer.py sync_status() 增探测项(sha256 三态);backup() 增备份项;新增 _step_desktop_policy()(步骤 3/6);validate() 增校验;rollback() 增删除

为什么不改同步器:ensure_home() 在家目录缺失时套用 /etc/skel,但 skel 中不放该文件也可能;真正兜底的是系统级默认——它对「用户级未显式设置这两个键」的一切用户生效,因此新用户、新环境无需同步器介入即可不锁屏。

步骤 5:落地(编排器完成,等价命令如下)

ssh root@192.168.31.28 "mkdir -p /etc/xdg/xfce4/xfconf/xfce-perchannel-xml"
scp vnc-server-deploy/assets/xfce4-screensaver.xml \
    root@192.168.31.28:/etc/xdg/xfce4/xfconf/xfce-perchannel-xml/xfce4-screensaver.xml
ssh root@192.168.31.28 "chmod 0644 /etc/xdg/xfce4/xfconf/xfce-perchannel-xml/xfce4-screensaver.xml"

坑:手工 scp 不具备幂等与原子性;实际由编排器执行——先 sha256 比对、不一致才写、写入走同目录临时文件加 mv 原子替换。 实现体:vnc-server-deploy/deployer.py(_step_desktop_policy),实际执行以实现体为准。

python3 vnc-server-deploy/deployer.py deploy --dry-run   # 预期:仅 1 项 write_desktop_policy
python3 vnc-server-deploy/deployer.py deploy             # 预期 rc=0,后置验证通过

10.6 验证

# 1) 8 用户的配置值(预期 /lock/enabled、/lock/sleep-activation、/saver/enabled 三项均 false)
for spec in rain02:2002:2 rain03:2003:3 cloud01:3001:4 cy01:4001:5 \
            david01:5001:6 lws01:6001:7 cq01:6101:8 ldapadmin:9001:9; do
  u=${spec%%:*}; r=${spec#*:}; uid=${r%%:*}; d=${r##*:}
  ENVX="HOME=/home/$u XDG_RUNTIME_DIR=/run/user/$uid DISPLAY=:$d DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/$uid/bus"
  echo "== $u"; su -s /bin/bash "$u" -c "$ENVX xfconf-query -c xfce4-screensaver -lv"
done

# 2) 系统级交付物已就位
ls -l /etc/xdg/xfce4/xfconf/xfce-perchannel-xml/xfce4-screensaver.xml

# 3) 系统级默认对「无用户级配置的新会话」生效(隔离会话实测,不依赖 X server)
dbus-run-session -- env HOME=/tmp/xfconf-probe XDG_CONFIG_HOME=/tmp/xfconf-probe/.config \
  xfconf-query -c xfce4-screensaver -lv
rm -rf /tmp/xfconf-probe

# 4) 幂等与漂移归零
python3 vnc-server-deploy/deployer.py deploy     # 第二次:预期「变更 0 项」,验证通过
python3 vnc-server-deploy/deployer.py drift      # 预期 rc=0 无漂移

实测结果(2026-09-27):

检查 结果
8 用户配置值 全部三项 false(set_rc=0/0)
屏保状态 8 会话由 active 经 -d 转为 inactive
系统级文件 /etc/xdg/xfce4/xfconf/xfce-perchannel-xml/xfce4-screensaver.xml 1473 字节,root:root 0644
系统级默认生效 隔离会话读到 /lock/enabled false、/saver/enabled false,且未生成用户级文件(证明是继承系统级默认而非复制)
编排器部署 deploy rc=0,[OK] 桌面锁屏策略已就位,9 用户验证全通过
幂等 第二次 deploy:变更 0 项:无,全部已就绪(幂等跳过),验证通过
漂移检测 drift rc=0,无漂移:实机与期望态一致
HOME 陷阱复核 显式带 HOME=/home/<user> 复查 9 用户:全部三项 false;/root/.config 未被污染

10.7 回滚

回滚单个用户(恢复其锁屏偏好):

u=rain02; uid=2002; d=2      # 按 10.5 步骤 2 的对照表取值
ENVX="HOME=/home/$u XDG_RUNTIME_DIR=/run/user/$uid DISPLAY=:$d DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/$uid/bus"
su -s /bin/bash "$u" -c "$ENVX xfconf-query -c xfce4-screensaver -p /saver/enabled -s true -t bool"
su -s /bin/bash "$u" -c "$ENVX xfconf-query -c xfce4-screensaver -p /lock/enabled  -s true -t bool"

回滚系统级交付物(删除该文件,即回到变更前;deployer.py rollback 已包含此动作):

rm -f /etc/xdg/xfce4/xfconf/xfce-perchannel-xml/xfce4-screensaver.xml   # 高危:删除文件

整体回滚(连同整个 VNC 部署):

cd vnc-server-deploy && python3 deployer.py rollback --force

回滚后验证:xfconf-query -c xfce4-screensaver -lv 应显示 true(或属性消失,回落编译默认 true);python3 deployer.py drift 应报出 write_desktop_policy 漂移(证明期望态确实已撤销)。

备份位置:8 个用户的偏好备份见 vnc-server-deploy/backup/home/<user>/...,逐条台账见 backup/README.md 的批次 20260927-173555 / 173928;系统级文件为新增文件(原不存在),回滚即删除,无备份文件。验证通过后由用户对照台账自行清理。

10.8 风险说明

风险 影响 缓解措施
系统级默认波及全机 Xfce 会话 本机若有人做本地图形登录,同样不再自动锁屏 属有意设计(VNC 为主用入口);如需恢复,删除该系统级文件并对存量用户设 true
用户级优先于系统级 在桌面 GUI 中改过该项的用户不受系统级约束,也不会被自动纠偏 文档已明确该边界(见 assets/xfce4-screensaver.xml 注释);如需强制,可在同步器中加 DBus 收敛,属额外变更
模板文件由工程管理 手工修改目标机上的策略文件会被下次 deploy 覆盖回模板内容 属预期(交付物即代码);要改策略请改 assets/xfce4-screensaver.xml 后重跑 deploy
desktop.disable_screensaver_lock=false 时的行为 编排器不再交付该文件,但不会删除既有文件,机器上旧策略继续生效 关闭开关只影响新交付;要撤销既有策略须显式执行 10.7 的删除命令
8 用户批量命令依赖已运行会话 会话未运行的用户无法经 DBus 设值,命令静默失败 这些用户的会话全部 active(实测);若遇未运行者,其偏好可待会话启动后处理,或依赖系统级默认兜底

11. 后续变更:只读探测批量化(2026-10-08)

背景【已确认】:SSHRunner 每次 run() 都新起一个 ssh 进程,且 pre_check/sync_status 的只读探测逐条下发(无连接复用、无拼 shell、无缓存)。属「只读探测批量化」推广的最后一批工程之一。

改动:SSHRunner 加 ssh ControlMaster 连接复用、probe()(同主机多条拼一段 shell 一次往返, 带退出码回传)、run_cached()/invalidate()(进程内 (命令原文) 探测缓存,变更后自动失效); pre_check 环境契约 4 条 + 包源/命令/SSSD/资源 5 条各并为一条 shell;sync_status 包循环改一次 rpm -q 多包。

实测【已确认,2026-10-08】:plan 墙钟 16126 → 6011 ms(-62.7%),变更清单逐条一致 (仅日志/报告文件名时间戳不同),rc=0。真机探针冒烟:exit 3 → rc=3、test -f 不存在 → rc=1。

完整变更档案(八章 + 离线自测 + 备份台账):probe_batch_20261008/SOP.md。

附录

附录 A 交付物清单

路径(相对项目根) 说明
vnc-server-deploy/deployer.py 部署编排器(precheck / plan / deploy / verify / drift / rollback)
vnc-server-deploy/utils/common.py SSH 执行通道、配置分层加载、备份台账
vnc-server-deploy/assets/vnc-ldap-sync 用户同步器(落地到 /usr/local/sbin/vnc-ldap-sync)
vnc-server-deploy/assets/vnc-ldap-sync.service / .timer 同步器 systemd 单元
vnc-server-deploy/assets/vncserver-config-defaults / -mandatory TigerVNC 全局配置
vnc-server-deploy/assets/xfce4-screensaver.xml Xfce 系统级锁屏策略(落地到 /etc/xdg/xfce4/xfconf/xfce-perchannel-xml/)
vnc-server-deploy/config/defaults.yaml / site.yaml 配置分层(基线 + 站点覆盖)
vnc-server-deploy/docs/SOP.md 本文档
vnc-server-deploy/docs/RUNBOOK.md 服务运行与使用手册
docs/HANDOFF.md(项目根) 交接快照,由 SessionStart Hook 自动注入
vnc-server-deploy/backup/ 备份归档与台账
vnc-server-deploy/reports/plan-*.yaml 变更计划留档
vnc-server-deploy/logs/ 每次执行的完整日志

附录 B 关键决策记录

决策点 结论 理由
服务模型 系统级 vncserver@.service 模板 + /etc/tigervnc/vncserver.users 静态映射 TigerVNC 1.13+ 官方模型(RHEL/Fedora 系标准做法),一用户一 display,support 开机自启
端口分配 按 uidNumber 升序,从 :1/5901 起 uidNumber 是 LDAP 中的稳定标识,新增用户天然落在末尾,规则可重现
桌面环境 Xfce4 实测 9 会话仅约 1.3 GB;GNOME Classic 预计 9–13 GB,与业务抢内存
监听方式 0.0.0.0:590N 内网直连 按用户明确选择;EDA 内网团队习惯,免隧道
密码规则 <user>@<port>,接受 8 字符截断 按用户明确选择;已实测截断行为并写入文档
用户发现 直接 ldapsearch(非 getent) 域配置为 enumerate = false,getent passwd 不返回 LDAP 用户
凭据来源 从 /etc/sssd/sssd.conf 继承 避免新增凭据文件,保持单一来源
家目录创建 复用 /etc/skel,runuser 以用户身份写入 属主天然正确;避免 NFS 场景下 root 写导致的属主漂移

附录 C 实测记录(已确证的关键事实)

事实 验证命令 结果
VNC 密码截断到 8 字符 printf 'cy01@5905\ncy01@5905\n' \| vncpasswd -f \| md5sum 对比 cy01@590 md5 完全相同 → 确认截断
ss 实际路径 ls -l /usr/bin/ss /usr/sbin/ss /usr/sbin/ss(/usr/bin/ss 不存在,曾导致端口探测误判)
包自带 session=gnome grep -v '^#' /etc/tigervnc/vncserver-config-defaults session=gnome(必须覆盖)
runuser 不切换 cwd runuser -u cy01 -- /bin/bash -c 'echo $HOME; pwd' HOME=/home/cy01 但 pwd=/root → 脚本必须用绝对路径
内网直连已生效 ss -tlnp \| grep 590 0.0.0.0:5901-5909 与 [::]:5901-5909
协议层可用 RFB 握手测试 返回 RFB 003.008
会话内存占用 ps -o rss= -C Xvnc \| awk ... Xvnc 9 进程 820 MB + xfce4-session 9 进程 515 MB
幂等 systemctl start vnc-ldap-sync.service 变更 0 项:全部已就绪(幂等跳过)
崩溃后服务状态 kill -9 <Xvnc> 后查 is-active / is-failed 两者均返回 inactive(不是 failed);vncsession 检测到子进程退出后以退出码 0 退出
残留锁是否阻挡重启 带 stale lock(锁内 PID 已死)执行 systemctl restart vncserver@:9 rc=0 成功;/tmp/.X9-lock 被新 Xvnc PID 接管,日志无锁相关报错
崩溃自愈链路 systemctl start vnc-ldap-sync.service 日志 变更 1 项:start vncserver@:9.service;端口恢复、9 会话全部 done,未误伤其它会话
xfce4-screensaver 进程名被截断 pgrep -u rain01 -a xfce4-screensaver vs ps -u rain01 -o comm= pgrep 无输出而 ps 有进程 → comm 被截断为 xfce4-screensav(15 字符上限),匹配须用 pgrep -f
锁屏偏好落盘路径 cat /home/rain01/.config/xfce4/xfconf/xfce-perchannel-xml/xfce4-screensaver.xml xfconf-query 设值经 DBus 生效,由 xfconfd 持久化到该文件;直接改文件不生效(会被回写覆盖)
关闭锁屏不影响会话 变更后 ps -u rain01 -o comm= 与 systemctl is-active vncserver@:1 Xvnc/xfce4-session/xfwm4/xfce4-panel/xfdesktop 全部存活,服务 active
系统级 xfconf 默认生效 dbus-run-session -- env HOME=/tmp/xfconf-probe XDG_CONFIG_HOME=/tmp/xfconf-probe/.config xfconf-query -c xfce4-screensaver -lv 隔离会话读到 /lock/enabled false、/saver/enabled false,且未生成用户级文件 → 系统级默认机制有效,新用户/新会话默认不锁屏
屏保「激活」与「锁定」是两态 xfce4-screensaver-command -q 8 个会话报 The screensaver is active(无 and locked)→ 屏保已弹出但未锁定,动鼠标即可恢复;-d 可立即停用
su 不重置 HOME 导致 xfconf 读错目录 不带 HOME 的 su -s /bin/bash <user> -c "xfconf-query -c xfce4-screensaver -lv" vs 带 HOME=/home/<user> 的同一命令 前者对 rain02 报 Channel "xfce4-screensaver" contains no properties(假象:该用户 xfconfd 已空闲退出,新实例按 HOME=/root 读目录);后者读到正确的三项 false。配置本身始终正确,且 /root/.config 未被污染
/tmp 挂载性质 findmnt -no SOURCE,FSTYPE /tmp 非独立挂载(属根文件系统)→ 机器重启不会清空锁文件;但实测残留无害

注:日志中 xfce4-power-manager 的 No outputs have backlight property 与 Xlib: extension "DPMS" missing 属虚拟机无背光/DPMS 硬件的正常告警,不影响桌面功能。


来源:/home/rain/Documents/services/vncserver/vnc-server-deploy/docs/SOP.md | 最后更新:2026-10-08 12:10(由 build/sync.py 同步,请勿在站点侧修改)