本页内容
任何拥有公网 IP 的服务器,都会被全天候不间断地探测 SSH 登录和开放的服务。下面这份清单,是全新的 Ubuntu 24.04 LTS 或 Debian 12/13 服务器在安装任何其他软件之前,都应先完成的安全基线。整个过程大约需要 15 分钟;即使某一步出了差错,你仍然可以通过带外管理控制台登录。
请以 root 身份运行这些命令;创建好你自己的用户之后,则改用 sudo 运行。将 deploy 替换为你的用户名,将 203.0.113.10 替换为你服务器的 IP 地址。
| 步骤 | 用时 |
|---|---|
| 系统更新与自动安全更新 | 3 分钟 |
| 创建带 SSH 密钥的 sudo 用户 | 2 分钟 |
| SSH 仅允许密钥登录,禁止 root 登录 | 2 分钟 |
| 防火墙基线 | 2 分钟 |
| fail2ban | 1 分钟 |
| 时间同步与服务审查 | 2 分钟 |
| 监控、IPMI 安全管理与备份 | 3 分钟 |
全面更新系统
先把软件包更新到最新版本,然后重启一次,因为新镜像的首次升级通常会包含新内核:
apt update && apt full-upgrade -y
rebootUbuntu Server 默认已启用 unattended-upgrades 来自动安装安全更新。在 Debian 上,需要手动安装并启用它:
apt install -y unattended-upgrades
dpkg-reconfigure -plow unattended-upgrades # answer Yes
unattended-upgrade --dry-run --debug 2>&1 | tail -n 5重新配置这一步会写入 /etc/apt/apt.conf.d/20auto-upgrades。如果希望内核更新后在业务低峰时段自动重启服务器,请添加一个本地覆盖文件,而不要直接修改软件包自带的文件:
cat > /etc/apt/apt.conf.d/52unattended-upgrades-local <<'EOF'
Unattended-Upgrade::Automatic-Reboot "true";
Unattended-Upgrade::Automatic-Reboot-Time "04:00";
EOF创建带 SSH 密钥的 sudo 用户
如果你还没有密钥,先在本地工作站上生成一个:
ssh-keygen -t ed25519 -C "you@workstation"为私钥设置密码短语(passphrase)加以保护,并将其加载到 ssh-agent 中,这样每个会话只需输入一次。如果你有 FIDO2 安全密钥,可以用 ssh-keygen -t ed25519-sk 生成一个只有插入该硬件令牌时才能使用的密钥。
在服务器上创建用户并授予 sudo 权限。如果是最小化安装的 Debian,请先运行 apt install sudo。
adduser deploy
usermod -aG sudo deploy如果你是用密钥以 root 身份登录的,把密钥复制到新账户:
install -d -m 700 -o deploy -g deploy /home/deploy/.ssh
install -m 600 -o deploy -g deploy /root/.ssh/authorized_keys /home/deploy/.ssh/authorized_keys如果你是用密码登录的,则改为在工作站上运行 ssh-copy-id deploy@203.0.113.10;这两种情况在 SSH 访问文档中都有说明。然后打开第二个终端,确认 ssh deploy@203.0.113.10 可以正常登录,并且 sudo -v 能接受你的密码。在下一步验证通过之前,请保持 root 会话不要关闭。
仅允许密钥登录,禁止 root 登录
在 Ubuntu 24.04 和 Debian 上,/etc/ssh/sshd_config 在文件开头附近引入了 /etc/ssh/sshd_config.d/*.conf,而且每项设置都以最先读取到的值为准。因此,文件名排序靠前的文件会覆盖排在后面的文件,包括在启用了密码登录的镜像中存在的 50-cloud-init.conf:
cat > /etc/ssh/sshd_config.d/00-hardening.conf <<'EOF'
PermitRootLogin no
PasswordAuthentication no
KbdInteractiveAuthentication no
PubkeyAuthentication yes
MaxAuthTries 3
X11Forwarding no
AllowUsers deploy
EOF
sshd -t && systemctl restart ssh
sshd -T | grep -Ei 'permitrootlogin|passwordauthentication|allowusers'在关闭任何会话之前,先从另一个终端测试一次全新登录。万一真的把自己锁在了外面,仍然可以通过带外管理工具中的 KVM 控制台或救援模式登录。
把 SSH 改到其他端口可以减少日志噪音,但算不上安全措施。如果你在 Ubuntu 24.04 上这样做(该系统通过 ssh.socket 启动 SSH),修改后需要运行 systemctl daemon-reload 并重启 ssh.socket。
防火墙基线
只选一种工具,不要同时运行两种。在 Ubuntu 和 Debian 上,UFW 最简单;如果你更喜欢显式编写规则,nftables 更合适。
UFW
apt install -y ufw
ufw default deny incoming
ufw default allow outgoing
ufw limit 22/tcp
ufw allow 80,443/tcp
ufw enable
ufw status verboselimit 会拒绝在 30 秒内发起 6 次或以上连接的源地址。UFW 会把相同的规则同样应用于 IPv6。
nftables
在 /etc/nftables.conf 中实现同样的策略:
flush ruleset
table inet filter {
chain input {
type filter hook input priority filter; policy drop;
ct state established,related accept
ct state invalid drop
iif "lo" accept
ip protocol icmp accept
meta l4proto ipv6-icmp accept
tcp dport { 22, 80, 443 } accept
}
chain forward {
type filter hook forward priority filter; policy drop;
}
}nft -c -f /etc/nftables.conf && systemctl enable --now nftables
nft list rulesetnft -c 会在应用任何规则之前先检查语法。放行 ICMPv6 才能保证 IPv6 邻居发现正常工作;否则 IPv6 将无法使用。
fail2ban
fail2ban 会封禁反复认证失败的地址。读取 systemd 日志(journal)的方式在两个发行版上都适用,包括没有 /var/log/auth.log 的 Debian 系统:
apt install -y fail2ban python3-systemd
cat > /etc/fail2ban/jail.local <<'EOF'
[DEFAULT]
bantime = 1h
findtime = 10m
maxretry = 5
ignoreip = 127.0.0.1/8 ::1 198.51.100.7
[sshd]
enabled = true
backend = systemd
EOF
systemctl restart fail2ban
fail2ban-client status sshd把你自己的办公室或 VPN 地址加入 ignoreip。在 SSH 仅允许密钥登录的情况下,fail2ban 的作用主要是减少日志噪音和无效握手;对于仍接受密码的服务(例如邮件或 Web 登录,它们各有自己的 jail),它的作用更为重要。
时间同步
正确的时间对 TLS、日志以及任何使用令牌或证书的系统都很重要:
timedatectl
timedatectl set-timezone UTC确认输出中包含 System clock synchronized: yes。两个发行版通常都使用 systemd-timesyncd 同步时间。如果 NTP service 显示为 n/a,请安装它,或者安装 chrony,它可以取而代之,并提供用于诊断的 chronyc tracking。统一使用 UTC,便于对照不同服务器上的日志。
尽量精简服务
每个监听端口都是攻击面。查看有哪些端口在监听、哪些服务在运行:
ss -tulpn
systemctl list-units --type=service --state=running用 systemctl disable --now NAME 停用不需要的服务,并卸载永远用不到的软件包。只与其他服务器通信的服务,例如数据库、指标导出器(exporter)和管理面板,应监听在 127.0.0.1 或你的内网上,绝不能监听公网地址。
从外部检查
纸面上的规则和实际生效的规则可能并不一致。从另一台机器扫描服务器,把开放的端口与你预期的列表进行对比:
nmap -Pn -p- 203.0.113.10 # every TCP port; takes a few minutes任何计划外的开放端口,要么是需要改为绑定内网地址的服务,要么是需要修正的防火墙规则。FlexDedi 始终开启的 DDoS 防护会在攻击流量到达服务器之前将其过滤,但它并不决定哪些端口开放;这由主机防火墙决定。
监控基础
- 磁盘健康: 安装
smartmontools和nvme-cli。之后smartd会持续监控硬盘,nvme smart-log /dev/nvme0可以显示磨损程度(percentage_used)和介质错误。如果使用软 RAID,请按照用 mdadm 配置软 RAID 中的说明设置告警。 - 指标:
apt install prometheus-node-exporter会在 9100 端口提供 CPU、内存、磁盘和网络指标。只允许你的监控主机访问该端口,例如ufw allow from 10.0.0.5 to any port 9100 proto tcp。 - 外部检查: 从你的网络外部发起的可用性探测,能发现本地工具发现不了的问题,例如路由中断或证书过期。
- 日志:
journalctl -p warning -b会列出本次启动以来的警告和错误。把日志发送到另一台机器上,这样入侵者就无法抹去痕迹。
IPMI 与 KVM 凭据
带外管理控制器可以对服务器断电重启、挂载 ISO 和打开控制台,因此请像对待 root 凭据一样对待它的凭据:
- 如果你持有 IPMI 凭据,请把初始密码换成一个足够长、独一无二的密码,并保存在密码管理器中。访问方式请参阅 IPMI 与 KVM 文档。
- 切勿把这个密码重复用于 SSH、控制面板或其他任何地方。
- 严格限制掌握该密码的人员,有人离开时及时收回访问权限,用完控制台后关闭会话。
- 用同样的方式保护控制面板的登录,因为通过它可以重装服务器。
备份
即使服务器已经加固,仍可能因为一次失败的部署或一块损坏的硬盘而丢失数据。请备份到另一台机器上,最好位于另一个机房,并测试恢复。restic 可以通过 SFTP 提供加密、去重的备份:
apt install -y restic
openssl rand -base64 32 > /root/.restic-password && chmod 600 /root/.restic-password
export RESTIC_REPOSITORY="sftp:backup@10.0.0.20:/srv/restic/web01"
export RESTIC_PASSWORD_FILE=/root/.restic-password
restic init
restic backup /etc /home /var/www --exclude-caches
restic forget --keep-daily 7 --keep-weekly 4 --keep-monthly 6 --prune
restic restore latest --target /tmp/restore-test --include /etc/ssh在服务器之外的地方保存一份密码副本,因为没有它就无法读取备份仓库。每次备份前先把数据库导出为文件(pg_dump、mysqldump),而不是直接复制正在使用的数据文件;用 systemd timer 或 cron 运行备份任务,并在任务失败时发出告警。同一机房的存储服务器可以通过免费内网接收备份。
15 分钟之后
清单管一次,脚本管每一次。把这些步骤固化到 Ansible 或 cloud-init 等配置管理工具中,让每台新服务器都从同一基线起步,配置漂移也会一目了然。然后再看看这份基线没有覆盖哪些方面:
- 运行 Lynis 等审计工具(先执行
apt install lynis,再运行lynis audit system),并逐条处理它给出的建议。 - 保持 AppArmor 处于启用状态。Ubuntu 和 Debian 默认已启用它,
aa-status可以列出已加载的配置文件。 - 每当有人加入或离开团队,都要审查用户账户、sudo 权限和
authorized_keys文件。
在 FlexDedi 上运行
FlexDedi 的每台服务器都具备这份基线所依赖的各项能力:SSH 无法连接时可用的 IPMI 和 HTML5 KVM 控制台,控制面板中的救援模式和一键重装,覆盖每个 IP 的始终开启的 DDoS 防护,以及可承载备份流量的免费内网。对于典型的 Web 或 API 服务器,Core 16($299/月)通常是起步之选;再搭配 Storage 264($699/月)或第二台 Core 16 作为备份目标即可。