上一篇 下一篇 分享链接 返回 返回顶部

加固美国服务器后,如何用命令验证SSH、防火墙与权限配置?

发布人:Minchunlin 发布时间:2026-10-07 09:00 阅读量:7

加固美国服务器后,验证是否成功,不能只看配置文件里有没有写入某个参数。需要同时确认:SSH 对指定用户实际生效的认证策略、服务器真正监听的端口、防火墙对不同来源的放行结果,以及账号和文件权限是否符合预期。配置检查、服务状态检查与外部连接测试,三者应当互相印证。

以下操作适用于使用 OpenSSH 和 systemd 的 Ubuntu、Debian、Rocky Linux、AlmaLinux 等常见服务器系统。防火墙部分分别提供 UFW 与 firewalld 的核验方法,按实际环境选择一条执行。服务器位于美国不会改变 Linux 命令的含义,但远程操作更依赖稳定的管理入口,因此必须保留现有 SSH 会话,并提前确认控制台或其他带外管理方式可用。

如果服务器方案尚未最终确定,A5数据的美国物理服务器可提供常规 Xeon、AMD EPYC 及多IP等产品方向,常规系列有 CN2 GIA 线路方案。不同套餐的线路、带宽和IP配置并不相同,执行后续验收前应以实际下单配置记录管理端口、授权来源和业务端口,避免把产品类别当成当前实例的网络条件。

一、准备条件:保留管理入口,记录当前状态

1. 确认执行环境和验证范围

服务器端命令在已有 SSH 会话中执行,需要 root 权限。可以先运行:

sudo -i
cat /etc/os-release
command -v sshd
systemctl status ssh.service sshd.service ssh.socket --no-pager

其中:

  • Ubuntu、Debian 通常使用 ssh.service。
  • Rocky Linux、AlmaLinux 通常使用 sshd.service。
  • 个别系统启用了 ssh.socket,监听端口可能由 systemd 套接字配置控制,不能仅凭 sshd_config 判断。

查询不存在的单元出现 Unit ... could not be found,不代表 SSH 故障。应以实际存在、正在使用的单元为准。

本文示例使用以下目标,执行前必须替换:

对象示例值用途
普通运维账号ops验证密钥登录和提权
SSH 端口22核对监听及防火墙规则
服务器公网 IPv4203.0.113.10从管理终端连接
管理终端公网 IPv4198.51.100.25验证来源白名单
运维私钥~/.ssh/id_ed25519_ops在管理终端使用,不上传服务器

以上 IP 为文档示例地址,不是可直接连接的服务器。管理终端经过地址转换时,防火墙应填写出口公网地址,而不是终端的内网地址。

建议明确本次验收目标:普通账号可用密钥登录、root 不可直接通过 SSH 登录、口令类认证关闭、SSH 只向授权来源开放、业务端口正常、非授权账号不能读取敏感文件。

2. 建立配置快照

即使本次主要执行只读验证,也应在修正配置前准备回滚资料。在服务器的 root 会话中执行:

umask 077
BACKUP="/root/security-check-$(date +%Y%m%d-%H%M%S)"
mkdir -p "$BACKUP"

for dir in /etc/ssh /etc/ufw /etc/firewalld; do
  if [ -d "$dir" ]; then
    tar -czf "$BACKUP/$(basename "$dir").tar.gz" -C / "${dir#/}"
  fi
done

ss -lntup > "$BACKUP/listeners.txt"
systemctl is-active ssh.service sshd.service ssh.socket \
  > "$BACKUP/ssh-units.txt" 2>&1

if command -v nft >/dev/null 2>&1; then
  nft list ruleset > "$BACKUP/nft-ruleset.txt"
fi

printf '备份目录:%s\n' "$BACKUP"

SSH 目录备份可能包含服务器主机私钥,因此备份目录只能由 root 访问,不要放在网站目录或公开下载位置。

nft-ruleset.txt 用于核对底层规则,不应直接作为 UFW 或 firewalld 的通用恢复脚本。这些工具有各自的配置与状态管理机制,混用恢复方式可能造成冲突。

操作边界:在新的管理终端尚未成功登录前,不关闭旧会话;在控制台不可用时,不进行可能切断管理入口的规则收紧或服务重启。

二、验证 SSH:从配置语法到真实登录

1. 检查语法,而不是直接重启

在服务器端执行:

/usr/sbin/sshd -t

正常情况下没有输出,退出码为 0。可以进一步确认:

/usr/sbin/sshd -t
printf '退出码:%s\n' "$?"

如果出现 Bad configuration option、缺少参数或无法加载主机密钥等报错,应停止加载配置,先处理报错指向的文件和行号。

语法通过只能证明配置可被解析,不能证明认证策略正确,也不能证明运行中的服务已经加载了这份配置。

2. 检查对指定用户实际生效的参数

使用 sshd -T 读取最终配置,并用 -C 提供匹配条件:

二、验证 SSH:从配置语法到真实登录配图

/usr/sbin/sshd -T \
  -C user=ops,addr=198.51.100.25,host=admin.example.net |
grep -E '^(port|listenaddress|permitrootlogin|pubkeyauthentication|passwordauthentication|kbdinteractiveauthentication|authenticationmethods|usepam|authorizedkeysfile|strictmodes|allowusers|allowgroups|denyusers|denygroups) '

这里的 addr 是服务器看到的客户端源地址;host 是客户端主机名匹配条件,不是服务器域名。如果配置使用了 Match Host,需要按真实匹配环境填写;IPv6 管理入口也应使用对应 IPv6 来源重新检查。

采用“普通账号密钥登录、禁止 root 直登、关闭口令类认证”的策略时,关键输出应接近:

permitrootlogin no
pubkeyauthentication yes
passwordauthentication no
kbdinteractiveauthentication no
strictmodes yes

这些是示例结果,不是实际执行记录。判断时注意以下区别:

  • PermitRootLogin prohibit-password 仍可能允许 root 使用密钥登录,不等于禁止 root 直登。
  • PasswordAuthentication no 只关闭密码认证;如果目标是关闭口令类登录,还应核对键盘交互认证。
  • UsePAM yes 不代表密码登录一定开放,PAM 也可参与账号和会话管理,不应为了“禁密码”盲目关闭。
  • AuthenticationMethods any 并不自动表示允许密码,仍要看启用了哪些认证方式。
  • AllowUsers、AllowGroups 与拒绝规则会影响普通账号是否能登录。

再单独检查 root 的有效策略:

/usr/sbin/sshd -T \
  -C user=root,addr=198.51.100.25,host=admin.example.net |
grep -E '^(permitrootlogin|passwordauthentication|kbdinteractiveauthentication|authenticationmethods) '

配置文件中的同名参数可能受到 Include、Match 和取值顺序影响。发现“文件写了 no,输出却不是 no”时,可定位相关定义:

grep -RnsE \
'^[[:space:]]*(Include|Match|PermitRootLogin|PasswordAuthentication|KbdInteractiveAuthentication|PubkeyAuthentication|AllowUsers|AllowGroups|DenyUsers|DenyGroups)' \
/etc/ssh/sshd_config /etc/ssh/sshd_config.d 2>/dev/null

不要简单在文件末尾追加一条相反配置后就认为已经覆盖。应以对应连接条件下的 sshd -T -C 输出为准。

3. 核对服务与监听端口

ss -lntp

找到 SSH 对应监听。例如:

LISTEN 0 128 0.0.0.0:22 0.0.0.0:* users:(("sshd",pid=1234,fd=3))
LISTEN 0 128 [::]:22    [::]:*    users:(("sshd",pid=1234,fd=4))

0.0.0.0:22 表示监听所有 IPv4 接口,[::]:22 表示 IPv6 通配监听。监听存在不代表公网已放行,也不代表只允许授权来源。

如果修改了 SSH 配置,先通过 sshd -t,再对实际使用的服务执行 reload:

# Ubuntu、Debian 常见服务名
systemctl reload ssh.service
# Rocky Linux、AlmaLinux 常见服务名
systemctl reload sshd.service

只执行适合当前系统的一条。若 ssh.socket 正在管理监听,修改端口后还需要单独核对套接字单元;不要为解决端口不一致而直接重启所有 SSH 单元。

4. 从新的管理终端进行正向与反向测试

以下命令在管理终端执行,而不是服务器端:

ssh -p 22 \
  -i ~/.ssh/id_ed25519_ops \
  -o IdentitiesOnly=yes \
  -o BatchMode=yes \
  ops@203.0.113.10 'id; hostname'

成功标准是命令正常结束,并返回 ops 的身份信息。BatchMode=yes 可以避免密钥失败后进入密码提示;它也不提供交互式私钥口令提示,使用加密私钥时,应提前解锁到 SSH agent。

首次连接需要核对主机密钥指纹。不要通过关闭主机密钥校验来让测试“成功”。

然后验证口令类认证未开放:

ssh -vv -p 22 \
  -o PubkeyAuthentication=no \
  -o PreferredAuthentications=password,keyboard-interactive \
  -o BatchMode=yes \
  ops@203.0.113.10

预期连接被拒绝。调试信息中,服务器提供的认证方式不应包含被禁止的 password 或 keyboard-interactive。仅看到“登录失败”还不够,因为错误密码、账号限制等因素也会导致失败。

root 登录也可以做反向测试,但“某把密钥登录 root 失败”不能单独证明 root 已被禁用:那把密钥可能本来就没有授权给 root。应结合 root 的有效配置一起判断。

三、验证防火墙:同时检查规则和外部结果

1. 先确定实际使用的管理工具

systemctl is-active ufw.service firewalld.service
command -v ufw
command -v firewall-cmd

工具已安装不代表规则正在生效。UFW 应继续查看 ufw status,firewalld 应查看自身运行状态。不要为执行教程而同时启用两套防火墙管理工具。

同时记录监听服务:

ss -lntup

例如,数据库监听 0.0.0.0:3306,即使防火墙目前阻断公网,也需要确认是否有必要绑定所有接口。防火墙限制与服务监听限制是不同层次,不能相互替代。

2. UFW:查看状态、默认策略和编号规则

适用于使用 UFW 管理防火墙的系统:

ufw status verbose
ufw status numbered
ufw show raw

需要确认:

  • 状态是 active,而不是 inactive。
  • 入站默认策略符合既定目标,常见加固场景为拒绝未授权入站。
  • SSH 放行规则的来源是管理地址或管理网段。
  • 业务端口按需求开放,没有无依据的全端口放行。
  • 如果服务器启用了公网 IPv6,应单独核对 IPv6 规则。

示例规则:

22/tcp  ALLOW IN  198.51.100.25
443/tcp ALLOW IN  Anywhere

如果 SSH 同时存在 22/tcp ALLOW IN Anywhere,新增来源白名单并不会让宽泛规则失效。要真正限制来源,还需识别并处理原有宽泛规则。

若授权来源缺少放行规则,可在备份完成、管理出口地址已确认后添加:

ufw allow from 198.51.100.25 to any port 22 proto tcp

这只添加指定 IPv4 来源的规则,不覆盖 IPv6 管理入口。添加后先进行新的 SSH 登录测试,再考虑移除多余规则。

只有确认该规则在本次操作前不存在,回滚时才使用:

ufw delete allow from 198.51.100.25 to any port 22 proto tcp

删除规则会改变管理入口。执行前必须确认另有可用入口,不要仅凭规则编号删除,因为编号会随其他规则删除而变化。

3. firewalld:核对区域、运行配置与永久配置

适用于使用 firewalld 的系统:

firewall-cmd --state
firewall-cmd --get-active-zones
firewall-cmd --list-all-zones

先确认公网入口接口或源地址被分配到哪个区域,再查询该区域。下面仅以实际入口位于 public 为例:

firewall-cmd --zone=public --list-all
firewall-cmd --permanent --zone=public --list-all

重点查看 interfaces、sources、services、ports、rich rules 和 target。区域名称叫 public 不等于规则一定安全;target: default 也不能单独证明所有非列出端口均被阻断。

若规则中存在 services: ssh,通常表示该区域按服务定义开放 SSH,并不自带管理来源限制。使用非默认 SSH 端口时,还需核对服务定义或明确端口规则,不能把服务名自动等同于实际端口。

需要补充管理来源放行时,可执行:

RULE='rule family="ipv4" source address="198.51.100.25/32" port port="22" protocol="tcp" accept'

firewall-cmd --zone=public --add-rich-rule="$RULE"
firewall-cmd --permanent --zone=public --add-rich-rule="$RULE"

两条命令分别修改运行配置和永久配置,不需要立即 reload。若宽泛的 SSH 放行仍然存在,来源限制尚未完成。

只有该规则确为本次新增时,反向操作才是:

firewall-cmd --zone=public --remove-rich-rule="$RULE"
firewall-cmd --permanent --zone=public --remove-rich-rule="$RULE"

firewalld 的 reload 会让永久配置重新进入运行状态。若原先存在未写入永久配置的运行规则,reload 后可能丢失,因此应提前保存:

firewall-cmd --list-all-zones > "$BACKUP/firewalld-runtime.txt"
firewall-cmd --permanent --list-all-zones > "$BACKUP/firewalld-permanent.txt"

4. 从外部验证允许与拒绝结果

服务器内部执行 curl localhost,不能证明公网防火墙正常。应在授权管理终端上测试 SSH,并用另一台不在白名单内、由自己管理的外部主机验证拒绝结果。

三、验证防火墙:同时检查规则和外部结果配图

Linux 管理终端安装了 Nmap 时,可以执行:

nmap -Pn -sT -p 22,80,443 203.0.113.10

只扫描自己管理或已获得授权的地址及必要端口。结果含义如下:

结果通常表示判断限制
openTCP 连接可建立不代表认证策略或应用响应正确
closed收到主动拒绝可能没有监听,也可能是规则主动拒绝
filtered探测被过滤或未获得有效响应可能发生在主机、上游或网络链路

授权来源的 SSH 应能完成真实登录;非授权来源应无法建立可用 SSH 连接。公网 IPv6 存在时,要对 IPv6 地址单独测试,不能用 IPv4 的结果替代。

如果服务器运行 Docker 等容器平台,还要检查端口映射和转发链。某些流量路径不经过普通主机入站规则,仅凭 UFW 状态不足以判断容器端口的公网暴露情况。

四、验证最小权限:检查身份、提权和关键路径

1. 查看账号实际权限

在服务器端执行:

id ops
sudo -l -U ops
visudo -c

分别确认账号所属组、允许执行的 sudo 命令,以及 sudoers 配置语法。

如果输出允许 (ALL : ALL) ALL,说明该账号拥有广泛管理权限。对于专用运维账号,这可能符合设计;对于网站进程、数据库服务或发布账号,则通常需要重新评估。

NOPASSWD: ALL 表示无需密码即可执行全部允许的管理操作。它不应被当作所有自动化账号的默认配置。还要注意:即便只放行少量命令,编辑器、解释器或能启动其他程序的工具也可能间接获得更大权限。

从新的 ops 会话验证提权:

sudo -k
sudo -v
sudo id

预期按既定策略完成认证,并输出 root 身份。不要用服务账号执行这组命令来“验证它可以提权”;服务账号的验收目标通常恰好相反。

2. 检查 SSH 密钥目录及整条路径

先确定账号真实家目录:

四、验证最小权限:检查身份、提权和关键路径配图

getent passwd ops

若家目录是 /home/ops:

namei -l /home/ops/.ssh/authorized_keys
stat -c '%U:%G %a %n' \
  /home/ops \
  /home/ops/.ssh \
  /home/ops/.ssh/authorized_keys

常见合理结果是 .ssh 属于 ops,权限为 700;authorized_keys 属于 ops,权限为 600。家目录和上级路径不应让非授权用户可写。

如果有效 AuthorizedKeysFile 指向其他位置,应检查那个实际路径,而不是只查默认文件。启用 ACL 的文件还应检查额外授权:

getfacl -p /home/ops/.ssh /home/ops/.ssh/authorized_keys

在确认路径正确、文件存在且确属该账号后,才考虑修正权限。先保存所有者、模式与 ACL:

getfacl -p /home/ops/.ssh /home/ops/.ssh/authorized_keys \
  > "$BACKUP/ops-ssh.acl"

OPS_GROUP="$(id -gn ops)"
chown ops:"$OPS_GROUP" /home/ops/.ssh /home/ops/.ssh/authorized_keys
chmod 700 /home/ops/.ssh
chmod 600 /home/ops/.ssh/authorized_keys

这些命令会改变文件属性,应逐项确认路径;若系统没有 getfacl,先准备可靠的属性备份,不要跳过备份直接修改。不要递归修改整个家目录或应用目录,也不要用 chmod 777 解决登录问题。

如需恢复上述属性:

setfacl --restore="$BACKUP/ops-ssh.acl"

若路径已经更换或文件被重建,应先确认恢复对象仍然正确。

3. 用服务账号验证业务文件访问

最小权限不能只看数字权限,应以实际服务账号测试必要访问和禁止访问。下面以存在 www-data 的系统为例:

getent passwd www-data
runuser -u www-data -- test -r /srv/site/public/index.html
printf '读取业务文件退出码:%s\n' "$?"

runuser -u www-data -- test -r /root/.ssh/authorized_keys
printf '读取root密钥文件退出码:%s\n' "$?"

业务文件读取返回 0,敏感文件读取返回非 0,才符合这个示例的目标。Rocky Linux、AlmaLinux 或自定义应用不一定使用 www-data,应从实际进程或服务单元确认运行身份。

定位关键目录中的可写风险时,可限制范围执行:

find /srv/site -xdev -type f -perm -0002 -print
find /srv/site -xdev -type d -perm -0002 -print

有输出表示存在其他用户可写对象,需逐个确认用途,不应批量执行 chmod。上传目录、缓存目录可能需要服务账号写入,但通常无需对所有本地用户开放写权限。

五、异常处理:按连接阶段缩小范围

现象优先检查结果解释
外部连接超时出口地址、上游规则、主机防火墙、监听地址尚未进入 SSH 认证阶段
Connection refusedss -lntp、端口、服务状态常见于无监听或主动拒绝
Permission denied (publickey)密钥、账号、有效配置、授权文件路径和权限网络连接通常已建立
有效配置正确,新连接仍不符合预期实际服务、reload 结果、套接字单元可能未加载新配置或连接了其他端口
当前正常,reload 后规则变化firewalld 运行配置与永久配置两者可能不一致
权限数字正确仍无法访问ACL、SELinux、AppArmor、父目录权限传统权限位不是唯一访问控制层

SSH 排查优先使用新的登录尝试,再在服务器端读取对应日志:

journalctl -u ssh.service -u sshd.service \
  --since "15 minutes ago" --no-pager

部分系统还会把认证信息写入 /var/log/auth.log 或 /var/log/secure。应以本机日志配置为准。

Rocky Linux、AlmaLinux 等启用 SELinux 的系统,如果出现密钥文件读取拒绝,可继续核对:

getenforce
ls -Zd /home/ops /home/ops/.ssh
ls -Z /home/ops/.ssh/authorized_keys

不要通过关闭 SELinux 或全局放宽权限来掩盖问题。自定义端口、自定义家目录和迁移后的文件标签,需要按具体拒绝记录处理。

日志可能包含账号、公网地址和路径,分享前应脱敏;不要把私钥内容粘贴到排障工单或公开页面。

六、验收与回滚检查项

验收:以新连接和实际访问结果为准

完成验证后,记录检查时间、来源地址、账号、端口及关键输出,避免只保存一份配置文件。

  • [ ] sshd -t 通过,指定用户的有效配置符合目标。
  • [ ] 普通运维账号可从授权来源使用密钥建立新会话。
  • [ ] root 直登策略和口令类认证策略已分别核对。
  • [ ] SSH 实际监听端口与防火墙规则一致。
  • [ ] 非授权来源无法建立可用 SSH 连接。
  • [ ] 公网 IPv4、IPv6 和上游访问规则分别验证。
  • [ ] UFW 或 firewalld 的实际状态已确认,没有混用管理工具。
  • [ ] firewalld 运行配置与永久配置的差异已解释。
  • [ ] sudo 权限符合账号职责,服务账号没有多余提权入口。
  • [ ] 业务文件可按需访问,敏感文件不可被非授权账号读取。
  • [ ] 业务端口完成应用层测试,不能仅以 open 作为验收。
  • [ ] 保留的旧会话在新入口确认可用后再关闭。

回滚:恢复具体变更,不扩大影响

SSH 配置变更失败时,优先通过旧会话或控制台恢复本次改动的文件。需要使用完整快照时,先确认备份目录正确,且恢复不会覆盖其他人同期的配置更新:

tar -tzf "$BACKUP/ssh.tar.gz"
tar -xzf "$BACKUP/ssh.tar.gz" -C /
/usr/sbin/sshd -t

解压会覆盖备份中已有的路径,但不会删除加固后新建的配置文件。若本次新增了片段,必须根据变更记录单独处理,否则残留片段仍可能生效。语法通过后,再对实际服务执行 reload,并从新终端复测。

防火墙回滚优先使用本次变更的反向命令。整目录恢复 UFW 或 firewalld 配置前,要确认原有启用状态和运行规则;firewalld 恢复永久配置并 reload,并不等于恢复此前全部临时规则。不要使用清空所有规则的方式处理单条错误放行或拒绝。

回滚前后还应核对:

  • [ ] 回滚涉及的文件、规则和权限已经明确,没有无关变更。
  • [ ] SSH 语法检查通过,管理账号可建立新的会话。
  • [ ] 防火墙恢复后,业务入口与管理入口均符合原定范围。
  • [ ] 文件属性恢复后,服务仍能完成必要读写。
  • [ ] 临时规则、临时测试账号和过期授权按记录清理。
  • [ ] 主机密钥备份、ACL 快照和操作日志存放在受限目录。

只有配置输出、真实连接和实际权限测试相互一致,才能确认这台美国服务器的加固措施已经按预期生效;任何单一命令的成功,都不应替代完整验收。