30、注册中心与负载均衡加固

等保2.0三级微服务底座三件套加固手册:Nacos加固覆盖鉴权三开关(默认关闭的 nacos.core.auth.enabled)、token.secret.key 与 server.identity 强随机密钥、默认账户治理、命名空间授权、外置 MySQL、端口收敛与日志外送;HAProxy加固覆盖 stats 认证与 userlist 加密口令、stats admin 限 LOCALHOST、TLS 版本收敛、后端证书校验与日志外送;Keepalived加固覆盖 VRRP 认证 8 位限制、unicast_peer 收敛、脚本提权防护与协议 112 网络控制;附联动变更顺序与恢复通道。

定位:微服务底座三件套(Nacos 注册中心/配置中心 + HAProxy 负载均衡 + Keepalived VIP 高可用)等保三级安全加固手册。Nacos 集中保管服务注册信息与配置数据(普遍存放数据库口令、密钥与连接串),HAProxy 与 Keepalived 承载其入口流量与 VIP 冗余——三件套一荣俱荣、一损俱损,故按"一册通改"编排:00 版本与支持线,0104 Nacos(鉴权、账户授权、持久化、网络与审计),0507 HAProxy(stats 认证、TLS 暴露面、日志与校验),08~09 Keepalived(VRRP 认证与通告收敛、脚本提权防护),10 三件套联动变更顺序与恢复通道,11 版本差异速查。每节附核查方法、加固操作与预期现象。

适用版本:Nacos 2.x / 3.x(配置键与默认值核验自官方 distribution/conf/application.properties)、HAProxy 2.6 / 3.0 LTS 线(以官方 master 配置手册为准)、Keepalived 2.x(Debian/EL 发行版打包,手册页核验自 manpages.debian)。 配套测评:Nacos 注册与配置中心测评、HAProxy 负载均衡器测评、Keepalived 高可用组件测评——本册加固动作与三篇测评篇的判定口径逐项衔接。

使用说明:

  • 本文为加固操作手册:systemctl restart nacos、HAProxy 重载、systemctl restart keepalived 均可能造成注册闪断或 VIP 漂移,实施前必须完成变更审批、确认业务低峰窗口、备份 application.properties/haproxy.cfg/keepalived.conf 与数据库,并准备可执行的回滚预案(恢复备份文件即回滚)。
  • 先在测试环境或集群单节点灰度验证:Nacos 开鉴权必须按第 10 节顺序先给全部客户端配置凭据,否则注册/配置拉取批量 403;每完成一项立即用文中「核查方法」复核。
  • 示例中的地址、账户、口令、密钥均为演示值(如 192.168.10.5、VGhpc0lz... 类串),现场须替换为真实值并脱敏留档;严禁直接沿用示例口令与示例密钥。
  • 命令回显与本文不一致时,先确认版本与部署形态(Nacos 2.x/3.x 键名迁移、HAProxy 版本线、Keepalived v2/v3),换用对应键名与等效命令;版本差异不得直接作为「无法整改」的结论,须给出替代措施并评估实际效果(详见 11 节)。
  • 三件套任一误配都可能"改把自己锁死"或"VIP 丢失":实施前保留一条已验证的恢复通道(节点 IP 直连、带外控制台、另一台可用备机),并确认 HAProxy/Keepalived 的 -c/-t 校验通过后才提交重启。
  • 加固完成后按「16、安全评估加固记录表3.0」逐项留痕并纳入复测;测评判定口径以 GB/T 28448-2019 与《高风险判定指引》为准。

不适用标识说明:

  • 使用 【不适用】 明确标记现场可判定为不适用的控制点,并写明判定依据与承载该能力的上位组件。
  • 依据 GB/T 28448-2019「按测评对象实际承载功能与数据处理范围判定」原则:能力由云托管注册配置服务、统一网关、负载均衡云产品或统一日志平台承载时,应注明测评单元边界后判定不适用或转由上位组件核查。
  • 产品版本确实不提供该能力时(如 VRRPv3 无协议认证字段),须核查替代措施(网络侧控制)并按实际效果定档,不得直接判不适用。

测评项对照表

控制点(GB/T 22239-2019 安全计算环境)对应章节
身份鉴别 8.1.4.1:鉴权开关、密钥强度、默认账户、stats 认证、VRRP 认证01、02、05、08
访问控制 8.1.4.2:命名空间授权、管理面收敛、脚本提权防护02、04、06、08、09
安全审计 8.1.4.3:访问日志/流量日志/切换事件外送与留存 ≥6 个月04、07、09
入侵防范 8.1.4.4:版本支持线、暴露面收敛、伪造通告防抢占00、04、06、08
数据完整性/保密性 8.1.4.7、8.1.4.8:外置 MySQL、TLS 与密钥文件管控03、06、07
数据备份恢复 8.1.4.9:配置与数据备份、主备冗余、联动变更顺序03、10
剩余信息保护 8.1.4.10:旧配置、明文凭据与退役实例清理02、05、09

边界联动注记:HAProxy/Keepalived 兼佐证 8.1.2 安全通信网络/区域边界(8.1.2.1 e) 冗余、8.1.2.3 边界防护、8.1.2.2 传输保密性),VRRP 协议 112 源控制与端口策略在边界设备落地,标注"兼 8.1.2 联动"处须同步取证。

00 版本与支持线

对应控制点:GB/T 22239-2019 8.1.4.4 入侵防范 a) b)(最小安装、及时补丁)

加固要点:三件套统一建立版本台账并跟踪官方支持线——Nacos 跟随 alibaba/nacos Releases 与安全公告(历史鉴权绕过漏洞多集中在 2.0~2.2.2 一代,须确认已升级或给出补偿);HAProxy 以 haproxy -v 回显的 “Status: long-term supported branch” 提示对照官方下载页支持期(2.6/3.0 为 LTS 线),已 EOL 版本须排升级计划或前置 WAF/IPS 补偿;Keepalived 跟随发行版打包(Debian bookworm 为 2.2.8 一代)与官方 keepalived.org 发布;Nacos 部署依赖 JDK 版本同步受控。

验证方法:三组件版本回显、与官方支持期页对照截图、补丁/升级台账、漏扫报告整改记录。

核查方法

sh /path/to/nacos/bin/startup.sh -h 2>/dev/null | head -n 5   # 或控制台「关于」页
ps -ef | grep [n]acos | head -n 2; java -version
haproxy -v; haproxy -vv | grep -E "Version|Built with"
keepalived -v; rpm -q keepalived 2>/dev/null || dpkg -l keepalived
ss -lntp | grep -E "8848|9848|9849|haproxy"
  • 预期现象:三组件版本均在官方支持窗口或有升级计划;haproxy -vv 显示 Built with OPENSSL(否则 TLS 小节转由前端承载并注明);端口清单与架构一致。

01 Nacos 鉴权开启(三开关 + 密钥 + identity)

对应控制点:GB/T 22239-2019 8.1.4.1 身份鉴别 a)~d)

加固要点:官方 distribution/conf/application.properties 模板默认 nacos.core.auth.enabled=false——不开鉴权即全 API 匿名可读写,这是 Nacos 加固的第一动作。开启并配齐密钥:

  • 三开关:nacos.core.auth.enabled=true(控制 SDK/gRPC 请求鉴别)、nacos.core.auth.admin.enabled=true(控制 /v3/admin/* HTTP 管理接口,模板默认 true)、nacos.core.auth.console.enabled=true(控制 /v3/console/* 控制台接口,模板默认 true),三者保持 true 且与版本对应;
  • 令牌密钥:3.x 首选键 nacos.plugin.auth.nacos.token.secret.key(Base64 强随机,模板默认为空;旧键 nacos.core.auth.plugin.nacos.token.secret.key 仍作别名支持、由启动脚本迁移,新旧并存时新键优先)——模板注释示例值 VGhpc0lzTXlDdXN0b21TZWNyZXRLZXkwMTIzNDU2Nzg= 属演示值,空值或沿用示例值都必须整改,否则可被伪造 JWT 绕过鉴权;
  • 服务端间互信:nacos.core.auth.server.identity.key/value 模板默认为空,须配置为非默认随机对(key/value 不得为 example 类占位值,官方历史漏洞即源于固定占位),集群各节点必须一致,否则节点间请求被 403;
  • 令牌有效期 nacos.plugin.auth.nacos.token.expire.seconds=18000(默认 5 小时,可按策略收紧);鉴权缓存 nacos.plugin.auth.nacos.caching.enabled=true 开启时授权变更最长约 15 秒生效延迟(官方手册注释口径),验证权限时留意;
  • nacos.security.ignore.urls 默认仅含静态资源与健康端点,不得为省事扩大白名单。

验证方法:application.properties 鉴权段回显(密钥脱敏)、无凭据访问受保护 API 返回 401 实测、携带凭据/登录后访问成功实测、集群节点间同步日志正常。

核查方法

grep -nE "nacos.core.auth.enabled|nacos.core.auth.admin.enabled|nacos.core.auth.console.enabled|nacos.plugin.auth.type" \
  /path/to/nacos/conf/application.properties
grep -nE "token.secret.key|token.expire.seconds|server.identity" \
  /path/to/nacos/conf/application.properties | sed -E 's/(=).{6,}/=****/'
stat -c "%a %U:%G %n" /path/to/nacos/conf/application.properties
curl -s -o /dev/null -w "%{http_code}\n" \
  "http://127.0.0.1:8848/nacos/v1/console/namespaces"          # 无凭据实测(经授权)
示例输出(节选)
$ grep -nE "auth.enabled|token.secret.key|server.identity" conf/application.properties
nacos.core.auth.enabled=true
nacos.core.auth.admin.enabled=true
nacos.core.auth.console.enabled=true
nacos.core.auth.server.identity.key=opsid            # 非默认键名
nacos.core.auth.server.identity.value=****           # 随机值
nacos.plugin.auth.nacos.token.secret.key=****        # Base64 强随机,非空非示例
$ curl -s -o /dev/null -w "%{http_code}\n" http://127.0.0.1:8848/nacos/v1/console/namespaces
401                                                  # 开启鉴权后匿名被拒

加固操作(维护窗口;集群滚动重启,顺序与客户端先配凭据见第 10 节——跳过第 10 节直接开鉴权属高频翻车操作)

# 1) 备份
cp -a /path/to/nacos/conf/application.properties /backup/nacos/application.properties.$(date +%F)
# 2) 生成强随机密钥(Base64,≥32 字节随机量)与非默认 identity 对
openssl rand -base64 48                       # 填给 nacos.plugin.auth.nacos.token.secret.key
openssl rand -hex 16                          # 填给 nacos.core.auth.server.identity.value
# 3) 编辑 application.properties(三开关、密钥、identity 各节点一致;密钥入密码库受控)
# 4) 滚动重启单节点并验证后再推下一节点
sh /path/to/nacos/bin/shutdown.sh; sh /path/to/nacos/bin/startup.sh -p clustered
curl -s -X POST "http://127.0.0.1:8848/nacos/v1/auth/login" \
  -d "username=nacos&password=<强口令>" | head -c 120
  • 预期现象:重启后无凭据 API 返回 401;登录返回 accessToken;集群列表接口三节点均为 UP(身份互信配置一致时);回滚=还原备份文件重启。

02 Nacos 账户与命名空间授权

对应控制点:GB/T 22239-2019 8.1.4.1 c) d)、8.1.4.2 访问控制 a)~f)

加固要点:鉴权开启后治理"谁凭据、多大权":

  • 默认账户:历史版本内置默认账户 nacos/nacos(2.2+ 首启要求设置初始口令)——现场以登录实测为准,默认口令未改判不符合;超级管理员口令改为强口令并纳入密码库,日常运维另建个人/职能账户;
  • 命名空间按环境隔离:以 namespace(tenant)划分 dev/test/生产与业务域(public 不作为生产租户),配置与服务列表天然按 namespaceId 隔离;
  • 角色授权:控制台「管理-权限控制」页配置 用户-角色(admin/reader/writer)-命名空间 三元授权,按最小权限发放——应用侧服务账户只给对应命名空间 writer/reader,不给全局 admin;人员账户按职责分权并定期复核(数据存于 users/roles/permissions 表,外置 MySQL 时可直接 SQL 取证);
  • 凭据分发:应用接入统一使用独立账户(每应用一账户可审计),禁止共享超级账户;人员离岗即禁用;
  • 剩余凭据清理:退役命名空间、下线服务与作废配置定期处置留痕。

验证方法:低权限账户执行删除/跨命名空间读被拒实测、users/roles/permissions 表或权限控制页截图、账户复核记录。

核查方法

# 账户与授权数据(外置 MySQL,经授权只读;derby 模式转控制台页取证)
mysql -h <dbhost> -u nacos_ro -p -e \
  "select username from nacos.users; select * from nacos.roles; select * from nacos.permissions;" | head -n 20
curl -s -u reader_demo:*** "http://127.0.0.1:8848/nacos/v1/console/namespaces" | head -c 300
curl -s -o /dev/null -w "%{http_code}\n" -u reader_demo:*** -X DELETE \
  "http://127.0.0.1:8848/nacos/v1/cs/configs?dataId=demo.yml&group=PROD&tenant=demo-app"  # 预期 403
示例输出(节选)
mysql> select * from nacos.roles;
nacos     | global admin
app-order | demo-app | writer       # 应用账户仅本命名空间 writer
$ curl -u reader_demo:*** -X DELETE ...
403                                 # 越权删除被拒

加固操作(控制台操作为主,属账户变更,走审批并双人复核)

  1. 登录控制台 →「权限控制-用户列表」:修改默认账户口令为强口令(或新建管理账户后禁用默认账户);
  2. 「权限控制-权限列表」:按命名空间 × 角色矩阵为每应用/每运维角色授权(reader 只读、writer 读写、admin 仅限平台组);
  3. 应用侧配置改用独立账户(username/password 经配置加密或环境变量注入,不落明文仓库);
  4. 建立账户季度复核:清理无人认领账户与退役命名空间授权。
  • 预期现象:默认口令登录失败、新口令成功;reader 账户写操作 403;权限矩阵与申请单一致。

03 Nacos 数据持久化与 MySQL 外置

对应控制点:GB/T 22239-2019 8.1.4.7 数据完整性 a) b)、8.1.4.8 数据保密性、8.1.4.9 数据备份恢复 a) c)

加固要点:生产弃用内嵌 derby(官方文档长期口径:derby 仅限测试用途;derby 模式下数据库层无独立访问控制,须按部分符合记录并给网络补偿)——外置 MySQL 承载配置与账户数据:

  • 3.x 键 nacos.plugin.datasource.db.num/url.0/user/password(2.x 为 db.* 与 spring.sql.init.platform=mysql,官方注释确认旧键仍作别名、nacos.plugin.datasource.db.* 优先);
  • 数据库账户最小权限:nacos 应用账户仅授 nacos 库 DML/SELECT 等运行所需权限,建表 DDL 由初始化时一次性执行;口令强随机并纳入密码库,application.properties 因含 DB 口令须 600;
  • 跨网段访问 MySQL 时启用连接串 useSSL=true(或网络层加密/严格 ACL),库端口 3306 仅对集群节点开放;
  • 备份:外置 MySQL 以数据库备份为准(mysqldump + binlog 增量,异地存放,联动数据库测评单元);derby 恢复对象为 conf/ + data/derby-data,迁移外置后归档留存;
  • 完整性:配置历史(his_config_info/控制台「历史版本」)是变更追溯与回滚依据,保留策略满足现场审计要求。

验证方法:datasource 段回显(口令脱敏)、conf 权限、config_info 表计数与控制台配置数一致、备份文件与恢复演练记录。

核查方法

grep -nE "^nacos.plugin.datasource.db|^db\.|^spring\.sql\.init" /path/to/nacos/conf/application.properties \
  | sed -E 's/(password|pwd)=.*/\1=****/i'
stat -c "%a %U:%G %n" /path/to/nacos/conf/application.properties
ls -ld /path/to/nacos/data/derby-data 2>/dev/null && echo "生产 derby 须整改"
mysql -h <dbhost> -u nacos -p -e "show grants; select count(*) from nacos.config_info;"
ls -l /backup/nacos/ | tail -n 3
示例输出(节选)
$ grep -nE "^nacos.plugin.datasource" conf/application.properties | sed -E 's/password=.*/password=****/'
nacos.plugin.datasource.db.num=1
nacos.plugin.datasource.db.url.0=jdbc:mysql://192.168.20.7:3306/nacos?characterEncoding=utf8&...
nacos.plugin.datasource.db.user=nacos
nacos.plugin.datasource.db.password=****
$ stat -c "%a %n" conf/application.properties
600 conf/application.properties

加固操作(涉及数据迁移,须专项窗口:先建库导表→停集群改配置→起单节点验证计数→全量起)

# 1) 初始化外置库(官方 mysql-schema.sql 建表)
mysql -u root -p < /path/to/nacos/conf/mysql-schema.sql
# 2) application.properties 启用 datasource 段(键名按版本对应,见上)
# 3) 数据库账户收敛(MySQL 8 先建账户再授权)
mysql -u root -p -e "CREATE USER IF NOT EXISTS 'nacos'@'192.168.10.%' IDENTIFIED BY '<强口令>';
GRANT SELECT,INSERT,UPDATE,DELETE ON nacos.* TO 'nacos'@'192.168.10.%'; FLUSH PRIVILEGES;"
# 4) derby 存量数据经官方迁移工具/导出导入后,备份 conf+data 再切换
  • 预期现象:配置读写落 MySQL(config_info 计数与控制台一致);derby 目录已归档清理;mysqldump 备份按期生成且校验可恢复。

04 Nacos 网络收敛与日志审计

对应控制点:GB/T 22239-2019 8.1.4.2 d)、8.1.4.3 安全审计 a)~d)、8.1.4.4 b);兼 8.1.2 边界联动(端口策略在边界设备落地)

加固要点:

  • 端口收敛:nacos.server.main.port 默认 8848、nacos.server.contextPath=/nacos;2.x 起客户端 gRPC 端口为主端口偏移(默认 9848/9849,以现场 ss -lntp 实测为准,官方部署文档口径)——防火墙/安全组仅放行应用网段(8848/9848/9849)与运维网段(8848 管理),其余来源拒绝;集群节点间端口按 cluster.conf 清单互放行;
  • 监听面:不以 0.0.0.0 全开对外网卡,公网方向零放行;
  • 日志审计:官方模板默认 server.tomcat.accesslog.enabled=true(max-days=30 本地轮转)——本地 30 天不满足留存要求,须经 rsyslog/采集器外送日志审计系统留存不少于 6 个月(《网络安全法》第 21 条(三)口径);配置变更以「历史版本/his_config_info」留痕,核心日志(core.log/远端通信日志)一并外送;
  • 审计管理:Nacos 无独立审计员角色,审计记录由管理员维护,与三权分立联动时记录补偿证据。

验证方法:非授权网段探测端口超时实测、ss 监听地址、防火墙规则与 cluster.conf 对照、日志平台检索 Nacos 访问日志(最早时间戳 ≥6 个月)。

核查方法

grep -nE "^nacos.server.main.port|^nacos.server.contextPath|accesslog" /path/to/nacos/conf/application.properties
cat /path/to/nacos/conf/cluster.conf
ss -lntp | grep java | grep -E "8848|9848|9849"
iptables -S 2>/dev/null | grep -E "8848|9848"; nft list ruleset 2>/dev/null | grep -E "8848|9848"
ls -l /path/to/nacos/logs/ | grep -E "access_log|core|config-|naming-"
示例输出(节选)
$ ss -lntp | grep -E "8848|984"
LISTEN 0 100 *:8848 users:(("java",pid=1101))   # 结合防火墙来源控制
$ tail -n 2 logs/access_log.log
192.168.10.31 GET /nacos/v1/cs/configs?dataId=order-db.yml&group=PROD&tenant=demo-app 200 4ms 2026-09-01 10:22:31

加固操作(防火墙变更属边界操作,走审批;本机示例为 firewalld,其他按现场设备)

# 仅应用网段与运维网段可达(示例,按现场网段替换;9848/9849 同法逐端口放行)
for p in 8848 9848 9849; do firewall-cmd --permanent --add-rich-rule="rule family=ipv4 source address=192.168.30.0/24 port port=$p protocol=tcp accept"; done
firewall-cmd --permanent --add-rich-rule='rule family=ipv4 source address=192.168.10.250/32 port port=8848 protocol=tcp accept'  # 运维跳板
firewall-cmd --reload
# rsyslog 外送 access log(imfile 采集后转发日志审计系统)
cat > /etc/rsyslog.d/nacos.conf <<'EOF'
module(load="imfile" mode="inotify")
input(type="imfile" File="/path/to/nacos/logs/access_log.log" Tag="nacos-access:" severity="info")
if $syslogtag contains 'nacos-access' then @@192.168.20.10:6514
EOF
systemctl restart rsyslog
  • 预期现象:办公网/公网来源探测 8848 超时;日志平台可检索 6 个月以上访问与变更事件;cluster.conf 节点与放行清单一致。

05 HAProxy stats 管理面与 userlist

对应控制点:GB/T 22239-2019 8.1.4.1 a)~d)、8.1.4.2 a) c);兼 8.1.2.3 边界联动(管理面来源收敛)

加固要点:stats 界面是 HAProxy 唯一"控制台",按官方配置手册逐项收敛:

  • stats bind/listen 段绑定 127.0.0.1 或内网运维地址,禁止全网卡对业务/公网开放;
  • 认证用 stats auth <user>:<passwd>,账户口令优先落在 userlist:user <name> password $6$<crypt-SHA-512>(password 为 crypt(3) 加密形态)——优于 insecure-password 明文形态(官方手册原文命名即警示"insecure";现场若保留明文须配 600 权限与配置管理补偿;注意 8 位截断是 Keepalived auth_pass 的特性,与 HAProxy 口令无关,两组件口径勿混);
  • 管理动作(上线/下线后端):stats admin if LOCALHOST(官方示例形态,仅本机可执行写操作)优于 stats admin if TRUE 无条件放行;确有远程运维需要时以受限 ACL(运维网段 src)替代 TRUE 并审批留痕;
  • 官方手册提示加密口令逐请求计算有 CPU 代价,高并发场景可将 stats 收敛为单一低流量入口。

验证方法:无凭据访问 stats 返回 401、错误口令 401、非本机执行 admin 动作被拒实测、配置回显无 insecure-password 或已给补偿证据。

核查方法

grep -n -A8 "listen stats\|^userlist" /etc/haproxy/haproxy.cfg | sed -E 's/(auth|password|insecure-password).*/\1 ****/'
grep -nE "stats admin|insecure-password" /etc/haproxy/haproxy.cfg
stat -c "%a %U:%G %n" /etc/haproxy/haproxy.cfg
curl -s -o /dev/null -w "%{http_code}\n" http://127.0.0.1:8404/          # 预期 401
curl -s -o /dev/null -w "%{http_code}\n" -u demo:wrongpass http://127.0.0.1:8404/
示例输出(节选)
$ grep -n -A8 "listen stats" /etc/haproxy/haproxy.cfg
listen stats
    bind 127.0.0.1:8404
    stats enable
    stats uri /stats
    stats refresh 10s
$ grep -n -A3 "^userlist" /etc/haproxy/haproxy.cfg
userlist stats-auth
    group  admin    users opsadmin
    user   opsadmin password $6$k6y3o.eP$JlKBx...xHSwRv6J.C0/D7cV91
    stats admin if LOCALHOST

加固操作(维护窗口;改前先 haproxy -c 校验、备份 cfg,回滚=还原 cfg 重载)

cp -a /etc/haproxy/haproxy.cfg /backup/haproxy/haproxy.cfg.$(date +%F)
openssl passwd -6 '<强口令>'        # 生成 $6$ crypt 口令填入 userlist
# 编辑 /etc/haproxy/haproxy.cfg:listen stats 段 bind 收敛 + userlist + stats admin if LOCALHOST
haproxy -c -f /etc/haproxy/haproxy.cfg            # 必须输出 "Configuration file is valid"
systemctl reload haproxy                          # master-worker 平滑重载,不中断存量连接
  • 预期现象:stats 仅回环/运维地址可达;匿名 401;非本机无上下线权限;配置中无明文口令或已给补偿记录。

06 HAProxy TLS 终止与暴露面收敛

对应控制点:GB/T 22239-2019 8.1.4.8 数据保密性 a) b)、8.1.4.4 b);兼 8.1.2.2 通信传输保密性联动

加固要点:

  • 前端 HTTPS 终止:bind <VIP>:443 ssl crt /etc/haproxy/certs/site.pem(PEM 内含私钥,权限 600、属主 root 或 haproxy);80 明文入口仅做 http-request redirect scheme https,不直接承载敏感业务;
  • 协议收敛:global 段 ssl-default-bind-options ssl-min-ver TLSv1.2——官方手册 ssl-min-ver 默认即 TLSv1.2,重点是现场不得显式放宽(出现 ssl-min-ver SSLv3.0/TLSv1.0/TLSv1.1 即为整改项);
  • 后端加密:server s1 10.0.0.11:8443 ssl verify required ca-file /etc/haproxy/certs/backend-ca.crt(server 侧 verify=required 校验后端证书,勿与 bind 侧校验客户端证书的 verify 语义混淆,后者默认 none、按需开启);后端明文链路须限定同安全域内网并说明边界控制;
  • 暴露面:仅监听业务所需端口(80/443 或 Nacos 转发端口),ss 对照架构清单,多余 frontend 删除。

验证方法:openssl s_client -tls1/-tls1_1 握手被拒、-tls1_2 成功、证书有效期、bind 私钥权限、backend verify 配置回显。

核查方法

grep -n "bind .*ssl\|ssl-default-bind-options\|ssl-min-ver" /etc/haproxy/haproxy.cfg
grep -n -A3 "^backend" /etc/haproxy/haproxy.cfg | grep -E "server .*ssl|verify|ca-file"
stat -c "%a %U:%G %n" /etc/haproxy/certs/*.pem
openssl s_client -connect 192.168.10.5:443 -tls1 </dev/null 2>&1 | grep -E "alert|error" | head -n 2
openssl x509 -in /etc/haproxy/certs/site.pem -noout -dates
示例输出(节选)
$ grep -n "bind\|ssl-min-ver" /etc/haproxy/haproxy.cfg
22:    ssl-default-bind-options ssl-min-ver TLSv1.2
41:    bind 192.168.10.5:443 ssl crt /etc/haproxy/certs/site.pem
42:    bind 192.168.10.5:80 -> redirect https
$ stat -c "%a %n" /etc/haproxy/certs/site.pem
600 /etc/haproxy/certs/site.pem

加固操作(窗口同 05 节,-c 校验 + reload 两段式;证书轮换须提前分发信任链)

global
    ssl-default-bind-options ssl-min-ver TLSv1.2
    ssl-default-bind-ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384
frontend web
    bind 192.168.10.5:80
    http-request redirect scheme https unless { ssl_fc }
    bind 192.168.10.5:443 ssl crt /etc/haproxy/certs/site.pem
backend nacos_cluster
    server n1 192.168.10.11:8848 check
    # 后端跨安全域时:server n1 192.168.10.11:8443 ssl verify required ca-file /etc/haproxy/certs/backend-ca.crt
chmod 600 /etc/haproxy/certs/*.pem; chown root:root /etc/haproxy/certs/site.pem
haproxy -c -f /etc/haproxy/haproxy.cfg && systemctl reload haproxy
  • 预期现象:TLS1.0/1.1 探测失败、1.2+ 成功;私钥 600;明文 80 跳转 HTTPS;后端加密或内网边界说明在案。

07 HAProxy 日志外送与配置校验

对应控制点:GB/T 22239-2019 8.1.4.3 安全审计 a)~d)、8.1.4.7 a)

加固要点:HAProxy 无内置审计,日志三路落地:

  • 流量日志:log <target> [format] <facility>(global 段,如 log 127.0.0.1:514 local0,defaults log global)+ HTTP 前端 option httplog、TCP 前端 option tcplog——未配 log 行则日志静默丢弃,属高频缺配项;
  • 外送与留存:rsyslog 按 programname 匹配转发日志审计系统(@@<审计机>:6514 TLS 形态更佳),留存不少于 6 个月(《网络安全法》第 21 条(三));
  • 配置完整性:每次变更前后执行 haproxy -c -f(只读语法校验,回显 “Configuration file is valid” 才允许 reload);haproxy.cfg 与证书纳入备份与版本管理;auditd watch /etc/haproxy 留配置变更痕迹。

验证方法:日志平台检索 httplog 字段(来源 IP/请求行/状态码/计时)、最早时间戳 ≥6 个月、-c 校验记录与变更单对应、auditd 规则回显。

核查方法

grep -nE "^ *log |log global|option httplog|option tcplog" /etc/haproxy/haproxy.cfg
grep -rn "haproxy" /etc/rsyslog.d/ 2>/dev/null
journalctl -u haproxy --no-pager | tail -n 5
auditctl -l 2>/dev/null | grep haproxy; haproxy -c -f /etc/haproxy/haproxy.cfg
示例输出(节选)
$ haproxy -c -f /etc/haproxy/haproxy.cfg
Configuration file is valid
$ grep -n "log " /etc/haproxy/haproxy.cfg
3:    log 127.0.0.1:514 local0
8:    log global
9:    option httplog

加固操作(rsyslog 与 auditd 属主机变更,窗口执行;缺 log 行按上节格式补齐)

# rsyslog 外送(/etc/rsyslog.d/30-haproxy.conf)
cat > /etc/rsyslog.d/30-haproxy.conf <<'EOF'
input(type="imudp" port="514")
if $programname startswith "haproxy" then @@192.168.20.10:6514
& stop
EOF
systemctl restart rsyslog
# 配置目录审计规则
printf '%s\n' '-w /etc/haproxy -p wa -k haproxy_cfg' > /etc/audit/rules.d/haproxy.rules
augenrules --load
  • 预期现象:新请求日志即时出现在审计平台;本地 syslog 无长期滞留;-c 校验纳入变更流程留痕。

08 Keepalived VRRP 认证与通告收敛

对应控制点:GB/T 22239-2019 8.1.4.2、8.1.4.4;兼 8.1.2.1 e) 冗余与 8.1.2.3 边界联动(VRRP 源控制在交换机落地)

加固要点:

  • 通告认证:VRRPv2 实例配 auth_type PASS + auth_pass <口令>,主备两侧必须完全一致(不一致即脑裂高频根因);官方手册明示 auth_pass 仅取前 8 个字符且明文落盘——按"8 位口令"评估强度、以文件 600 权限与配置管理补偿;8 位截断是 Keepalived 特性,勿套用到 HAProxy/Nacos 口令口径;
  • 版本选择:vrrp_version 默认 2;IPv6 实例协议固定走 v3,而 VRRPv3 无认证字段——此类实例必须改以网络侧控制替代(见下)并如实说明,不得判"已认证";
  • 通告收敛:unicast_src_ip <本节点IP> + unicast_peer { <对端IP> } 把通告点对点收敛到主备对端,优于默认组播(224.0.0.18 全网段可收);确需组播时以交换机端口隔离/IGMP 控制补偿;
  • 网络侧防线:VRRP 为 IP 协议号 112,同网段任何主机伪造 priority 255 通告即可抢走 VIP——交换机端口安全/ACL 限定 112 报文仅源自主备两网卡是本项的最后防线,与主机防火墙(iptables -p vrrp 限定来源)互为补偿;
  • 抢占规划:主备 priority 一侧高一侧低(100/90 常见),备侧按需 nopreempt 防回切抖动(版本支持以现场手册为准)。

验证方法:主备配置对照(virtual_router_id/priority/auth 一致)、ip addr 主有 VIP 备无、备机 journalctl 出现 MASTER 切换与回退记录、非授权主机发伪造通告不改变主备状态(tcpdump 取证)。

核查方法

grep -nE "vrrp_instance|virtual_router_id|interface|priority|auth_type|auth_pass|unicast" \
  /etc/keepalived/keepalived.conf | sed -E 's/auth_pass.*/auth_pass ****/'
keepalived -t -f /etc/keepalived/keepalived.conf            # 只读校验(man 8 keepalived)
stat -c "%a %U:%G %n" /etc/keepalived/keepalived.conf
ip -4 addr show | grep -E "inet 192"                        # 主备两侧各执行
iptables -S 2>/dev/null | grep -i vrrp; nft list ruleset 2>/dev/null | grep -iE "vrrp|112"
journalctl -u keepalived --no-pager | grep -cE "MASTER STATE|BACKUP STATE"
示例输出(节选)
$ grep -n -A3 "auth" /etc/keepalived/keepalived.conf
52:    auth_type PASS
53:    auth_pass ****          # 主备一致,仅前 8 位有效(官方手册原文)
$ keepalived -t -f /etc/keepalived/keepalived.conf
Configuration file /etc/keepalived/keepalived.conf is valid
$ ip -4 addr show | grep 192.168.10.5      # 主侧
    inet 192.168.10.5/32 scope global VIP

加固操作(先备后主:备侧改→校验→重启验证,低峰切换后再改原主侧;两侧同步维护防漂移)

cp -a /etc/keepalived/keepalived.conf /backup/keepalived/keepalived.conf.$(date +%F)
# 编辑 keepalived.conf(主侧示例;备侧仅 state/priority 不同):
vrrp_instance VI_1 {
    state MASTER                 # 备侧 BACKUP
    interface bond0
    virtual_router_id 51
    priority 100                 # 备侧 90
    advert_int 1
    auth_type PASS
    auth_pass <随机8位>           # 主备一致;入密码库受控
    unicast_src_ip 192.168.10.5
    unicast_peer {
        192.168.10.6
    }
    virtual_ipaddress {
        192.168.10.5/32 dev bond0 label VIP
    }
}
chmod 600 /etc/keepalived/keepalived.conf
keepalived -t -f /etc/keepalived/keepalived.conf && systemctl restart keepalived   # 备侧先行
# 网络侧:交换机对互连端口做端口安全/ACL,仅允许主备 MAC 发送协议 112;主机侧补充
iptables -I INPUT -p vrrp ! -s 192.168.10.6 -j DROP && iptables -I INPUT -p vrrp -s 192.168.10.6 -j ACCEPT
  • 预期现象:-t 校验通过;主有 VIP 备无;备机日志可见受控切换;伪造源通告被网络侧丢弃(主侧状态与 VIP 不动);回滚=还原备份重启。

09 Keepalived 脚本安全与提权防护

对应控制点:GB/T 22239-2019 8.1.4.2 f)(提权控制)、8.1.4.4、8.1.4.3(运行日志外送)

加固要点:Keepalived 以 root 运行且会执行任意配置脚本(vrrp_script 健康检查、notify_master/backup/fault),是其最大的本地提权面:

  • enable_script_security(官方手册原文:“Don’t run scripts configured to be run as root if any part of the path is writable by a non-root user”)——全局开启后,路径任一段存在非 root 可写即拒绝以 root 执行脚本;
  • script_user <user> [group]:为脚本指定专用非 root 运行账户(读 VIP 不需要 root 的检查脚本一律降权);
  • 脚本与所在目录权限:root 独占写(目录 755 root:root、文件 750/755 root:root,禁止 others 可写),健康检查脚本中不得内嵌明文凭据(改读 600 权限的受控环境文件);
  • 配置明文凭据(auth_pass、脚本引用口令)以文件 600 + 备份介质同等管控补偿;
  • 审计:log_facility localX 与 journal/syslog 的切换/脚本故障事件(Entering MASTER STATE、VRRP_Script(...) failed)经 rsyslog 外送留存 ≥6 个月;auditd watch /etc/keepalived 与脚本目录。

验证方法:两开关配置回显、脚本与目录 ls -l 属主权限、脚本实际运行用户(ps/日志)、切换事件在日志平台可检索。

核查方法

grep -nE "script_user|enable_script_security|vrrp_script|notify_|log_facility" /etc/keepalived/keepalived.conf
ls -l /etc/keepalived/ /usr/local/bin/keepalived_* 2>/dev/null
find /etc/keepalived /usr/local/bin -perm /o+w -user root 2>/dev/null | head
journalctl -u keepalived --no-pager | tail -n 6
auditctl -l 2>/dev/null | grep keepalived
示例输出(节选)
$ grep -nE "script_user|enable_script_security" /etc/keepalived/keepalived.conf
4:    script_user keepalived_script
5:    enable_script_security
$ ls -l /usr/local/bin/keepalived_check.sh
-rwxr-x--- 1 root root 214 Sep 01 10:00 /usr/local/bin/keepalived_check.sh
$ journalctl -u keepalived --no-pager | tail -n 2
Sep 03 08:12:01 lb01 Keepalived_vrrp[1122]: VRRP_Instance(VI_1) Entering MASTER STATE

加固操作(重启 keepalived 会触发通告抖动,低峰窗口、先备后主,同 08 节)

useradd -r -s /sbin/nologin keepalived_script
# keepalived.conf global 段(块)追加:
#   script_user keepalived_script
#   enable_script_security
#   vrrp_script chk_haproxy { script "/usr/local/bin/keepalived_check.sh" interval 5 fall 2 rise 2 }
chown root:root /usr/local/bin/keepalived_check.sh; chmod 750 /usr/local/bin/keepalived_check.sh
printf '%s\n' '-w /etc/keepalived -p wa -k keepalived_cfg' '-w /usr/local/bin/keepalived_check.sh -p wa -k keepalived_script' \
  > /etc/audit/rules.d/keepalived.rules
augenrules --load
keepalived -t -f /etc/keepalived/keepalived.conf && systemctl restart keepalived
  • 预期现象:脚本以降权账户运行(异常路径可写时日志出现拒绝 root 执行的告警);目录 600/750 无 others 可写;切换事件外送可查。

10 三件套联动变更顺序与恢复通道

对应控制点:GB/T 22239-2019 8.1.4.9 数据备份恢复;兼 8.1.2.1 e) 冗余与安全管理中心/变更管理(8.1.5 管理制度联动留痕)

加固要点:三件套互为依赖(应用→HAProxy VIP→Nacos 集群→MySQL),单组件"正确"的加固动作叠加错序会放大为可用性事故。推荐变更链(一个窗口内按序执行,每步有验证点与回滚点):

  1. 全量备份:application.properties+cluster.conf(及 derby data)、haproxy.cfg+证书、keepalived.conf、外置 MySQL 全库;
  2. 客户端先配凭据(开鉴权前置,高频翻车点):先给所有接入应用与运维脚本配置 Nacos username/password(Spring Cloud 走 spring.cloud.nacos.username/password,nacos-client/SDK 走对应凭据参数,经配置加密下发)并发布灰度批次——若先开 nacos.core.auth.enabled=true 再改客户端,注册与配置拉取将批量 403,服务列表雪崩式清空;
  3. Nacos 集群滚动开鉴权:逐节点改配置(三开关+密钥+identity 各节点一致)→重启→验证该节点 UP、注册实例计数不降、跨节点同步日志正常,再推下一节点;
  4. HAProxy:配置修改(05~07 节)一律 haproxy -c 校验后 systemctl reload 平滑生效(master-worker -sf 形态不断流);验证 stats 与 443 转发;
  5. Keepalived 先备后主:改备侧→keepalived -t→重启备→低峰受控切换(停主侧服务或重启使 VIP 漂移)→业务探测通过→再改原主侧;主备 auth/priority 成对核验;
  6. 恢复通道全程在案:全程保留不经 VIP 的节点 IP 直连验证路径、带外/控制台登录、备份还原脚本;每步回滚=还原该组件备份文件并重启/重载。

验证闭环:变更后连续观察注册实例数、VIP 归属、stats 后端状态、伪造通告测试(08 节)与匿名 API 探测(01 节)四项指标。

验证方法:变更单按上述步序签字;各步验证点截图(实例计数、ip addr、stats 页、401 实测);切换演练记录(每半年至少一次)。

核查方法

# 变更窗口内的持续验证链(只读)
curl -s -u opsa:*** "http://192.168.10.5:8848/nacos/v1/core/cluster/nodes" | head -c 300
curl -s -u opsadmin:*** http://127.0.0.1:8404/stats | grep -cE "UP"
ip -4 addr show | grep "192.168.10.5"; journalctl -u keepalived --since "-10min" | tail -n 10

加固操作(无新增配置项——本节固化前两列动作的执行顺序,示例脚本骨架)

# 每组件变更前统一动作:备份 → 只读校验(keepalived -t / haproxy -c / Nacos 配置检查)→ 生效
cp -a <目标配置> /backup/<组件>/$(basename <目标配置>).$(date +%F-%H%M)
<灰度批次生效> && <验证点通过> || <还原备份回滚>
  • 预期现象:全程注册实例数无骤降;VIP 单点持有无脑裂;任一环节回滚后 5 分钟内恢复原状;演练与变更台账归档。

11 版本差异速查

对应控制点:综合(防止"版本差异"被误判为"无法整改",口径见使用说明第四条)

加固要点:下表为本文全部键名的版本迁移关系(均核验自对应官方源);现场以 grep 实际文件为准取对应键,两代键并存时以生效键为准,不得据键缺失直接下不符合/无法整改结论。

组件旧形态新形态迁移说明
Nacos 2.x → 3.xnacos.core.auth.plugin.nacos.token.secret.keynacos.plugin.auth.nacos.token.secret.key官方模板注释:启动脚本自动迁移已配置的旧密钥;新旧并存时新键优先;模板注释示例值 VGhpc0lz... 两代都属演示值必须更换
Nacos 2.x → 3.xspring.sql.init.platform、db.num/db.url.0/db.user/db.passwordnacos.plugin.datasource-dialect.type、nacos.plugin.datasource.db.num/url.0/user/password官方模板注释:旧 db.* 仍作别名支持,nacos.plugin.datasource.db.* 优先
Nacos 2.x 早期模板仅 nacos.core.auth.enabled 单开关+ auth.admin.enabled / auth.console.enabled、nacos.plugin.auth.type(可接 ldap/oidc)2.x 后期与 3.x 并存迁移,按现场文件 grep 结果取证
Nacos 端口8848 HTTP2.x 起 gRPC 偏移 9848/9849偏移量以现场 ss -lntp 实测与官方部署文档为准
HAProxy 2.6/3.0userlist user … password/insecure-password、stats admin if LOCALHOST、ssl-min-ver语法同左2.x/3.0 LTS 关键语法一致;ssl-min-ver 默认 TLSv1.2 为现行手册口径,老版本实测协商结果以 openssl s_client 为准
Keepalived v2/v3vrrp_version 2(默认)+ auth_type PASS/auth_pass(8 位截断)vrrp_version 3(IPv6 实例固定 v3)v3 协议无认证字段,认证项不适用,必须转网络侧控制(协议 112 源限定)并记录补偿

参考依据

  • GB/T 22239-2019《信息安全技术 网络安全等级保护基本要求》(8.1.4 安全计算环境各控制点;8.1.2 安全通信网络/区域边界联动):http://openstd.samr.gov.cn/bzgk/gb/newGbInfo?hcno=BAFB47E8874764186BDB7865E8344DAF
  • GB/T 28448-2019《信息安全技术 网络安全等级保护测评要求》(测评对象边界认定、单元测评实施与结果判定):http://openstd.samr.gov.cn/bzgk/gb/newGbInfo?hcno=7E736CDF4502B6FF1258DD250AA3EC8C
  • Nacos 官方配置模板(alibaba/nacos 仓库 distribution/conf/application.properties,develop 分支——鉴权三开关/新旧密钥键/datasource 键/端口/accesslog 默认值逐条核验):https://github.com/alibaba/nacos/blob/develop/distribution/conf/application.properties
  • Nacos 官方站点(部署、鉴权、权限管理文档入口):https://nacos.io/;官方发布与安全公告:https://github.com/alibaba/nacos
  • HAProxy 官方配置手册(Configuration Manual,GitHub haproxy/haproxy master doc/configuration.txt——stats auth/userlist+password|insecure-password/stats admin/bind ssl crt/ssl-min-ver/server 侧 verify required ca-file/log+option httplog 逐条核验):https://raw.githubusercontent.com/haproxy/haproxy/master/doc/configuration.txt
  • keepalived.conf(5) 手册页(Debian bookworm——auth_type PASS/auth_pass 仅前 8 字符生效、unicast_src_ip/unicast_peer、script_user、enable_script_security 原文、vrrp_version 默认 2/IPv6 用 3 已核验):https://manpages.debian.org/bookworm/keepalived/keepalived.conf.5.en.html
  • keepalived(8) 手册页(-t/--config-test 配置校验、-v/--version 已核验):https://manpages.debian.org/bookworm/keepalived/keepalived.8.en.html
  • 《中华人民共和国网络安全法》第二十一条第(三)项(“采取监测、记录网络运行状态、网络安全事件的技术措施,并按照规定留存相关的网络日志不少于六个月”),国家互联网信息办公室官方全文:https://www.cac.gov.cn/2016-11/07/c_1119867116_2.htm
  • 《网络安全等级保护测评高风险判定指引》(中关村信息安全测评联盟团体标准),站内对照表:22、高风险判定指引与加固对照表
  • 命令核验说明:本文已于 2026-09 对照官方 distribution/conf/application.properties(alibaba/nacos develop 分支)、HAProxy 官方 Configuration Manual(haproxy/haproxy master doc/configuration.txt)、keepalived.conf(5) 与 keepalived(8) 手册页(manpages.debian bookworm)逐条核验,并与站内 Nacos、HAProxy、Keepalived 三篇测评篇的核验结论互证;四处须留意:① Nacos 令牌密钥旧键 nacos.core.auth.plugin.nacos.token.secret.key 由启动脚本迁移、3.x 首选新键 nacos.plugin.auth.nacos.token.secret.key(并存时新键优先),模板注释示例值 VGhpc0lzTXlDdXN0b21TZWNyZXRLZXkwMTIzNDU2Nzg= 属演示值——空值或沿用示例值都必须更换为强随机 Base64;② auth_pass 仅前 8 字符生效是 Keepalived VRRPv2 特性(且明文落盘、按 8 位评估强度并以 600 权限补偿),勿与 HAProxy userlist 的 password crypt 形态混用口径,v3(含 IPv6 实例)无认证字段须转网络侧控制;③ stats admin if LOCALHOST 为官方示例口径、优于 if TRUE,HAProxy 的 ssl-min-ver 官方默认即 TLSv1.2,现场显式放宽才构成整改项;④ Nacos 开鉴权前必须先给全部客户端配置 username/password 凭据再滚动开启(第 10 节变更链第 2~3 步),否则注册与配置拉取批量 403 引发雪崩;gRPC 端口 9848/9849 以现场 ss -lntp 实测为准。

关联文章