美国服务器安全加固清单:SSH、防火墙与最小权限怎么做?
美国服务器交付时,能通过 SSH 登录并不代表已经完成安全验收。真正需要确认的是:公网只暴露必要端口,SSH 使用可追溯的身份认证,防火墙规则与云平台边界策略一致,管理员和服务账号没有超出工作范围的权限,系统补丁和审计日志能够持续维护。
美国机房、美国云区域或美国独立服务器并不会自动改变这些技术要求。验收时还要额外关注公网 IPv4 与 IPv6 是否同时开放、云平台安全组是否覆盖主机防火墙、管理来源 IP 是否明确,以及日志时间是否统一。不要把“只允许美国 IP”当成安全控制,国家或地区级 IP 段过于宽泛,优先使用固定办公出口、跳板机或明确的管理网段。
交付验收先确认范围
建议把服务器分为三类对象分别验收,而不是用一组“安全配置”笼统判断:

| 关键对象 | 主要核对项 | 通过依据 |
|---|---|---|
| 公网入口 | 监听端口、云安全组、主机防火墙、IPv4/IPv6 | 只有业务必需端口可达,管理端口不对公网任意开放 |
| SSH 管理面 | 密钥认证、root 登录、密码认证、登录来源、配置生效状态 | 管理账号可用密钥登录,root 不能直接登录,未经授权的密码认证被拒绝 |
| 账号与文件 | 账号用途、sudo 权限、服务账号、关键目录权限 | 每个账号只拥有完成工作所需的权限,服务不使用日常管理员账号运行 |
| 系统软件 | 操作系统支持状态、OpenSSH、内核和安全更新 | 没有长期积压的关键安全更新,补丁变更可安排和回溯 |
| 审计与留证 | 登录、sudo、配置变更、防火墙、时间同步、日志保存 | 能回答“谁在什么时间从哪里做了什么”,日志不会因重启立即消失 |
交付验收应保留配置快照和命令结果,但不要保存私钥、密码、云平台密钥或包含敏感令牌的完整配置。记录时至少包括主机名、操作系统版本、服务器公网 IPv4/IPv6、验收时间、开放端口、SSH 有效配置、防火墙规则和例外项。
公网端口与防火墙
先区分“正在监听”和“公网可达”
主机存在监听端口,不一定代表互联网可以访问;反过来,云平台安全组放行端口,也不代表应用一定在监听。两层都要检查。
在 Linux 服务器上,可先查看 TCP 和 UDP 监听:
sudo ss -lntup
重点记录以下信息:
0.0.0.0:端口表示服务监听所有 IPv4 网卡;[::]:端口通常表示监听所有 IPv6 网卡,是否真正对外可达还取决于系统和云平台配置;- 监听地址为
127.0.0.1或::1的服务通常只接受本机访问; - 业务进程名称和端口用途必须能够对应,无法解释的监听项应列为异常;
- 数据库、缓存、管理面板等内部服务不应因为“方便调试”直接暴露公网。
常见业务服务器可能只需要:
- TCP 80:HTTP 跳转或明文站点,确有业务需求时开放;
- TCP 443:HTTPS 业务入口;
- TCP 22:SSH 管理入口,但应限制来源;
- DNS、邮件、数据库或其他端口:只有服务器实际承担对应服务时才开放。
端口号改成非标准值只能减少自动化扫描噪声,不能代替身份认证、来源限制和补丁维护。验收结论应写成“该端口由什么服务使用、允许哪些来源、为什么需要”,而不是只记录端口数字。
云安全组与主机防火墙要保持一致
公网服务器通常存在两层入口控制:
- 云平台安全组、边界 ACL 或上游防火墙;
- 服务器本机的 UFW、firewalld 或 nftables 规则。
两层规则不要求完全相同,但不能出现明显冲突。例如云安全组允许全网访问 22,而主机防火墙只允许办公出口访问,虽然主机当前仍可能挡住连接,但云侧暴露范围已经扩大;如果主机防火墙被误清空,风险会立即暴露。
验收时至少确认:
- IPv4 和 IPv6 是否分别有入站规则;
- TCP 22 是否限制到管理出口 IP 或管理网段;
- TCP 80/443 是否只由业务需要决定;
- 入站默认策略是否为拒绝或丢弃;
- 出站策略是否与更新、DNS、时间同步、日志上报和业务依赖匹配;
- 云平台规则是否存在临时放行的
0.0.0.0/0或::/0; - 规则的名称、负责人、用途和失效时间是否明确。
如果管理人员使用动态公网 IP,不要直接放开整个国家或城市的地址段。可以使用固定办公出口、云控制台的临时管理规则或其他已审批的管理入口,并为临时规则设置回收时间。
使用 UFW 的服务器
以下示例适用于使用 UFW 管理主机防火墙的 Debian/Ubuntu 类系统。执行默认拒绝或启用防火墙前,应确认已有第二个 SSH 会话、云控制台串行终端或带外控制台可用于回滚。否则规则写错可能导致远程失联。
203.0.113.10/32 是文档示例地址,应替换成实际管理出口 IP:
sudo ufw status verbose
sudo ufw status numbered
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow from 203.0.113.10/32 to any port 22 proto tcp
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable
sudo ufw status numbered
判断标准如下:
- SSH 规则只允许批准的源地址,不能用
sudo ufw allow 22/tcp对全网放行; - 80 和 443 只有在服务器承载 Web 服务时才保留;
- 不要因为使用 IPv4 规则就默认认为 IPv6 已受保护,应检查 UFW 的 IPv6 设置和实际状态;
- 出站默认允许是较常见的起点,但如果业务要求限制出站,应先列出 DNS、NTP、软件仓库、对象存储和日志服务依赖,不能直接一刀切。
变更前应保存当前规则输出:
sudo ufw status numbered > ~/ufw-before.txt
如果新规则造成误封,优先通过控制台恢复原规则。删除规则时以编号或完整规则为准,避免删除了业务端口:
sudo ufw status numbered
sudo ufw delete <规则编号>
使用 firewalld 的服务器
RHEL、Rocky Linux、AlmaLinux 等系统常见 firewalld。先确认活动区域,不要直接假定使用 public:
sudo firewall-cmd --get-active-zones
sudo firewall-cmd --get-default-zone
sudo firewall-cmd --list-all
如果 SSH 只允许固定 IPv4 管理地址,可以使用 rich rule。下面的 public 和示例 IP 需要按实际环境替换:
sudo firewall-cmd --permanent --zone=public --remove-service=ssh
sudo firewall-cmd --permanent --zone=public \
--add-rich-rule='rule family="ipv4" source address="203.0.113.10/32" service name="ssh" accept'
sudo firewall-cmd --permanent --zone=public --add-service=https
sudo firewall-cmd --reload
sudo firewall-cmd --zone=public --list-all
执行前要确认原有 SSH 规则、业务端口和活动区域,并保留当前配置。--reload 后应立即从已批准来源验证 SSH 和业务访问。如果服务器启用了 IPv6,IPv6 管理地址需要配置对应的 family="ipv6" 规则,不能用 IPv4 规则代替。
防火墙变更的回滚方式应写入交接记录,例如恢复变更前导出的规则、重新添加原有 ssh 服务规则,或通过云控制台临时放行管理地址。不要在没有控制台或第二会话的情况下删除 SSH 规则。
防火墙验收不只看“规则存在”
一条规则处于配置文件中,不代表一定已经生效。验收应同时检查:

- 主机当前生效规则;
- 云平台当前生效规则;
- 进程实际监听端口;
- 从外部网络发起的连通性;
- 从未授权来源访问管理端口时的拒绝结果。
若有外部探测环境,可从不在允许列表中的网络检查 22 端口;若没有扫描工具,也可以使用受控的 TCP 连接测试。测试次数应有限,避免触发安全设备封禁或影响业务。对公网开放的 80/443 则要确认确实能到达预期 Web 服务,而不是误暴露管理面板。
SSH 配置与认证
先保留恢复通道,再改认证策略
SSH 是最容易把管理员锁在服务器外的配置对象。修改前应满足三个条件:
- 当前已有一个可用 SSH 会话,不要只依赖即将修改的单一连接;
- 至少有一个已经验证过的管理员公钥;
- 云平台控制台、串行终端或其他带外恢复方式可用。
备份当前配置:
sudo cp -a /etc/ssh/sshd_config \
"/etc/ssh/sshd_config.before-hardening.$(date -u +%Y%m%dT%H%M%SZ)"
不同发行版的服务名可能是 ssh 或 sshd,先核对:
systemctl list-unit-files | grep -E '^(ssh|sshd)\.service'
不要直接覆盖整个 SSH 配置文件。应先检查 Include 指令和已有配置片段,确认最终生效位置,再修改主配置或对应的片段文件。OpenSSH 对部分配置采用“先读取到的值生效”的规则,文件名靠后不一定能够覆盖前面的设置。
密钥、root 和密码认证
常见的基础加固目标如下:
PermitRootLogin no
PubkeyAuthentication yes
PasswordAuthentication no
KbdInteractiveAuthentication no
PermitEmptyPasswords no
MaxAuthTries 3
LoginGraceTime 30
X11Forwarding no
这些配置不能机械粘贴,尤其是 KbdInteractiveAuthentication no。如果企业使用基于 PAM 的多因素认证,关闭 keyboard-interactive 可能会同时关闭现有认证流程,应先确认认证链路。X11Forwarding no 适用于不需要图形转发的服务器;需要该功能时应记录例外,不要为了清单而破坏运维流程。
建议按以下顺序处理:

- 使用普通管理员账号导入公钥,并验证该账号能正常登录;
- 在当前会话不退出的情况下,打开新会话验证公钥登录;
- 确认该账号能够按需使用
sudo,且不依赖 root 直接登录; - 再关闭 root 直接登录;
- 最后关闭密码认证,并再次用新会话验证;
- 配置生效后,保留当前会话一段时间,确认没有遗漏的自动化任务或监控连接。
公钥目录和文件权限也要验收:
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
chown -R "$(id -un)":"$(id -gn)" ~/.ssh
如果目录中存在多个公钥,应为每把钥匙记录用途、持有人和过期时间。离职、项目结束或管理范围变化后,及时删除对应公钥。不要把同一把私钥复制给多人,否则日志只能追溯到同一个密钥,无法定位实际操作者。
密钥类型应遵循操作系统和组织密码策略。Ed25519 在许多现代 OpenSSH 环境中较常见,但处于 FIPS 模式或特殊合规策略的系统可能不允许某些算法;此时应使用环境支持的强密钥类型,并以服务器实际接受结果为准。不要只因为“能生成”就认定算法适用。
限制管理账号和来源
当服务器只由少数固定账号管理时,可以使用 AllowUsers 或 AllowGroups 限制 SSH 登录范围。例如:
AllowUsers opsadmin deploy
或者:
AllowGroups sshusers
两者只选择符合现有账号模型的一种。启用前要确认应急账号、自动化账号和监控账号是否被误排除。来源限制也可以通过云安全组和主机防火墙完成,SSH 配置中的用户限制主要解决“谁可以登录”,防火墙主要解决“哪些网络可以连接”。
不建议把 AllowUsers 当成唯一安全措施。如果账号仍允许弱密码、拥有过大的 sudo 权限或公钥长期不轮换,限制用户名并不能消除风险。
检查配置是否真正生效
修改后先做语法验证:
sudo sshd -t
验证有效配置:
sudo sshd -T | egrep \
'^(port|listenaddress|permitrootlogin|pubkeyauthentication|passwordauthentication|kbdinteractiveauthentication|maxauthtries|logingracetime|allowusers|allowgroups)'
只有 sshd -t 通过,才继续重新加载服务。Debian/Ubuntu 常见服务名为 ssh:
sudo systemctl reload ssh
RHEL 系统常见服务名为 sshd:
sudo systemctl reload sshd
重新加载后,应使用新 SSH 会话验证以下结果:
| 测试项 | 通过判断 |
|---|---|
| 允许的管理员使用正确私钥登录 | 登录成功,用户身份和主机符合预期 |
| root 直接登录 | 被拒绝,管理员通过普通账号和 sudo 完成提权 |
| 未授权账号登录 | 被拒绝 |
| 密码认证 | 在确认没有依赖后被拒绝 |
| 错误认证次数 | 达到 MaxAuthTries 后连接被关闭或拒绝 |
| 业务自动化连接 | 使用专用账号和专用密钥,不因策略调整中断 |
若 sshd -t 失败,不要重载服务,先根据报错恢复备份或修正配置。若重载后失联,应通过带外控制台恢复变更前文件,再执行语法检查。恢复命令会覆盖配置,必须确认备份文件来源和时间,避免把更早的错误配置重新写回去。
最小权限:账号、sudo 与服务文件
建立账号用途表
交付验收不能只看服务器上有多少账号,还要判断每个账号为什么存在。可以按下面的方式登记:
| 账号类型 | 是否允许 SSH | 是否允许 sudo | 文件权限范围 | 典型用途 |
|---|---|---|---|---|
| 日常管理员 | 是 | 按职责授权 | 系统管理范围 | 运维和故障处理 |
| 部署账号 | 是或仅自动化使用 | 仅允许部署所需命令 | 应用发布目录 | 发布、回滚和服务重载 |
| 应用服务账号 | 否 | 否 | 应用数据和运行目录 | 启动 Web 或后台服务 |
| 备份账号 | 视方案而定 | 通常否 | 指定备份目录 | 读取或写入备份数据 |
| 应急账号 | 受控启用 | 按制度授权 | 最小范围 | 账号恢复和带外处置 |
查看本地账号时,不要把系统服务账号和真实登录人员混在一起:
getent passwd
getent group
重点核对:
- 不再使用的管理员账号是否已锁定或删除;
- 服务账号的登录 Shell 是否符合用途;
- 普通账号是否错误地加入
sudo、wheel或其他高权限组; - 是否多人共用一个有 sudo 权限的账号;
- 应急账号是否有负责人、启用条件和复核周期。
如果服务不需要交互登录,可以使用系统提供的 nologin Shell,但变更前确认服务启动脚本、监控和故障处理不依赖该账号进入 Shell。不要对所有非管理员账号批量修改 Shell,这类操作可能中断现有服务。
sudo 只授权具体任务
下面是一个仅允许部署账号重启和查看某个服务的示例。实际 systemctl 路径应先用 command -v systemctl 核对:
deploy ALL=(root) /usr/bin/systemctl restart app.service, /usr/bin/systemctl status app.service
编辑 sudo 规则时使用:
sudo visudo -f /etc/sudoers.d/deploy
sudo visudo -c
sudo -l -U deploy
通过标准包括:
- 不给部署账号配置
ALL=(ALL) ALL; - 不为了免密方便就普遍使用
NOPASSWD; - 能限制具体命令时,不授权整个解释器、编辑器或任意脚本目录;
- 检查被授权命令是否允许用户通过参数间接执行任意命令;
- 变更后用
sudo -l -U 用户名留证。
例如,允许执行任意 Shell、Python、Perl、编辑器或容器管理命令,往往等价于授予 root 权限。docker 等可管理宿主机的高权限组也不能简单视为普通业务组,加入前必须按 root 等价权限评估。
检查关键文件和目录
最小权限不仅是 sudo 规则,还包括应用目录、配置文件、密钥和日志文件的所有权。典型目标是:
- 应用运行目录由服务账号或专用发布组拥有;
- 配置文件可被服务读取,但不应被所有本地用户读取;
- 私钥、数据库密码和云平台凭据不能设置为全局可读;
- 上传目录与执行目录分离,避免用户上传内容被当作脚本执行;
- 不使用
chmod -R 777作为故障处理手段。
可以针对重点目录查看权限:
namei -l /srv/app/config/app.conf
stat -c '%A %U:%G %n' /srv/app/config/app.conf
如果需要创建目录,应明确所有者和权限,而不是创建后再反复放宽:
sudo install -d -m 0750 -o app -g app /srv/app
sudo install -m 0640 -o app -g app app.conf /srv/app/config/app.conf
其中 app 用户和组必须已经存在,目录结构也要符合应用实际需求。权限调整会影响正在运行的服务,变更前应记录原权限,并在变更后验证应用能读到必需配置、普通用户不能读取敏感文件。
补丁、服务面与重启要求
盘点系统和关键软件
补丁验收至少包括操作系统、OpenSSH、内核、Web 服务、运行时和业务依赖。不要只检查“系统显示最新”,还要确认软件仓库、支持周期和重启状态。
Debian/Ubuntu 类系统可以查看:
cat /etc/os-release
uname -r
dpkg -l openssh-server
apt list --upgradable 2>/dev/null
RHEL 系统可以查看:
cat /etc/redhat-release
uname -r
rpm -q openssh-server
dnf check-update
dnf check-update 在发现可更新包时可能返回状态码 100,这不一定代表命令失败,应结合输出内容判断。
验收标准应区分三种情况:
- 没有待安装的安全更新;
- 有更新,但已登记维护窗口、影响范围和负责人;
- 有关键更新且没有处理计划,应判为未通过或带高风险例外。
安装内核、OpenSSH、glibc 等基础组件的更新可能需要重启或重新加载服务。不要在业务高峰直接执行大范围升级。变更前应确认备份、快照或回滚能力,升级后检查服务状态、监听端口、SSH 登录和应用健康检查。
不要忽略“更新后需要重启”
部分补丁虽然已经安装,正在运行的进程仍可能使用旧库,内核也可能仍是旧版本。交付时应记录:
- 当前运行内核版本;
- 最近一次系统重启时间;
- 是否存在需要重启的服务或内核;
- 重启窗口和回滚方案;
- 重启后需要验证的业务清单。
如果服务器使用自动安全更新,应明确它的更新范围、重启策略、失败通知和日志位置。自动更新不是免验收配置,尤其要确认它不会在未审批的时间重启生产业务。
关闭不需要的服务
开放端口背后通常对应一个服务。对无法解释来源的进程,应检查服务状态、启动方式和所属软件包:
sudo systemctl --type=service --state=running
sudo systemctl --failed
sudo ss -lntup
确认服务确实不需要后,再考虑停止或禁用。停止、禁用服务属于有影响的变更,执行前应确认业务依赖、保存当前状态并准备回滚:
sudo systemctl disable --now example.service
不要仅凭服务名称判断可以删除。一个看似无关的服务可能被备份、监控、日志或应用启动流程依赖。无法确认用途时,应先标记为“待确认”,而不是直接停止。
审计、日志与时间
日志要能回答三个问题
最低限度应能通过日志回答:
- 谁登录或尝试登录了服务器;
- 谁执行了 sudo、修改了防火墙或变更了关键配置;
- 操作发生在什么时间、来自什么地址、是否成功。
Debian/Ubuntu 常见 SSH 日志查询方式:
sudo journalctl -u ssh --since "24 hours ago"
sudo grep -E 'sshd|sudo' /var/log/auth.log | tail -n 100
RHEL 类系统常见方式:
sudo journalctl -u sshd --since "24 hours ago"
sudo grep -E 'sshd|sudo' /var/log/secure | tail -n 100
服务名和日志路径应以实际系统为准。检查内容包括成功登录、失败登录、密钥指纹或用户、来源地址、sudo 执行记录,以及配置重载和服务重启记录。
保证重启后仍有日志
仅保存在内存中的 journald 日志可能在重启后丢失。可以检查当前日志占用和持久化目录:
sudo journalctl --disk-usage
sudo test -d /var/log/journal && echo "persistent journal exists"
如果组织要求使用持久化 journald,可按磁盘容量和保留政策配置,例如:
[Journal]
Storage=persistent
SystemMaxUse=1G
MaxRetentionSec=30day
这里的 1G 和 30 天只是示例,不能脱离磁盘容量、日志量和审计要求直接套用。日志保留时间过短会影响调查,设置过大则可能挤占业务磁盘。修改后需要确认日志写入、轮转和磁盘告警正常。
生产环境还应考虑把关键日志发送到独立日志系统。远程日志不能替代本机日志,但可以降低攻击者获得主机权限后清理本地记录的影响。日志传输中不要包含私钥、数据库密码、访问令牌等敏感内容。
时间同步是审计基础
服务器、云平台、日志系统和运维人员使用不同时间基准,会导致事件顺序难以还原。建议服务器统一使用 UTC 记录,展示层再按美国运维团队所在时区转换,并在交接文档中写明口径。
检查时间同步状态:
timedatectl status
如果系统使用 chrony,还可以检查:
chronyc tracking
通过标准包括:
- 系统时间同步服务处于正常状态;
- 日志时间与云平台事件时间不存在明显偏差;
- 维护窗口和审计记录注明时区;
- 没有手工频繁修改系统时间的操作。
一页式验收清单
可以把最终结果按“通过、带例外、未通过”记录:
公网与防火墙
- [ ] 已列出全部 TCP/UDP 监听端口,并能说明用途。
- [ ] 80/443 以外的公网业务端口有明确审批和来源范围。
- [ ] SSH 不对全网开放,或有书面例外、补偿措施和到期时间。
- [ ] 云安全组与主机防火墙均已核对。
- [ ] IPv4 和 IPv6 的入站规则均已检查。
- [ ] 默认入站策略符合预期,出站策略没有误伤更新和业务依赖。
- [ ] 防火墙变更前的规则和回滚方法已留存。
SSH 与认证
- [ ] 普通管理员可以使用已登记的公钥登录。
- [ ]
PermitRootLogin不允许 root 直接远程登录。 - [ ] 密码认证已关闭,或有明确业务理由和额外控制。
- [ ] 未使用的公钥、账号和旧密钥已清理。
- [ ]
sshd -t通过,sshd -T显示的有效配置符合预期。 - [ ] 认证策略变更后,新 SSH 会话和自动化任务均已验证。
- [ ] 服务器保留可用的带外恢复渠道。
最小权限
- [ ] 每个可登录账号都有负责人和用途。
- [ ] 部署账号、日常管理员和应用服务账号分离。
- [ ] sudo 权限限制到具体命令,不使用无理由的全量授权。
- [ ] 服务账号没有不必要的交互登录能力。
- [ ] 应用配置、密钥和日志文件的所有权及权限符合用途。
- [ ] 没有使用
777、共享管理员账号或共享私钥解决问题。
补丁与审计
- [ ] 操作系统、OpenSSH、内核和关键运行时已完成版本盘点。
- [ ] 安全更新没有长期积压,待更新项有维护窗口。
- [ ] 需要重启的内核或服务已登记。
- [ ] 登录、sudo、服务和配置变更日志可查询。
- [ ] 日志在重启后仍然保留,磁盘使用量有监控。
- [ ] 系统时间同步正常,日志时区口径明确。
- [ ] 例外项包含负责人、风险、补偿控制和复核日期。
交付后的复核节奏
安全加固不是交付当天一次性完成。建议按变化频率安排复核:
- 防火墙和云安全组:每次新增业务、变更来源或调整端口后复核;
- SSH 公钥和登录账号:人员、项目或供应商变更后立即复核,平时按月或按季度清点;
- sudo 与服务文件权限:应用发布、账号职责变化后复核;
- 安全补丁:按组织风险等级设定期限,关键漏洞不应等待常规季度窗口;
- 审计日志:定期检查是否持续产生、是否成功集中保存、是否存在异常失败登录;
- IPv6 规则:每次启用公网 IPv6、迁移网络或更换云平台时重新核对。
如果业务确实需要全网开放管理端口、保留密码认证或授予较大 sudo 权限,不要把它直接标记为“通过”。应记录具体业务原因、替代控制、风险负责人和失效日期,到期后重新验证。这样交付验收留下的不只是几条配置命令,而是一套能够被复查、能够解释异常、也能够在变更后恢复的服务器安全基线。



