
核心要点(TL;DR)
- 主机防护的第一步是摸清监听端口,关闭一切非必要的高危服务。
- 防火墙应默认拒绝入站,只按白名单放行必要端口。
- SSH 禁用 root 直登与密码登录,改密钥并限制来源 IP。
- 最小权限落地靠文件权限、sudo 细粒度授权与服务账户隔离。
很多主机被攻破,不是因为漏洞多高明,而是因为暴露面太大:一个忘记关的 6379、一个允许 root 密码登录的 SSH、一个 777 权限的上传目录。主机防护的本质不是堆工具,而是把「不必要的东西」一项项拿掉。下面这份 7 步清单,面向要立刻动手的运维和站长,每一步都给出可执行命令,照着做一遍就能明显缩小攻击面。
第 1 步:摸清家底,列出所有监听端口与自启服务
加固前先看清自己暴露了什么,否则关闭高危端口就是盲操作。
ss -tulnp
systemctl list-unit-files --state=enabled
ps aux --sort=-%mem | head -20
把 ss 输出里的每个端口对应到进程和业务,标记三类:必须对外、只应内网访问、完全不需要。第二类后续改为监听 127.0.0.1,第三类直接停用并禁用开机自启:
systemctl stop 服务名 && systemctl disable 服务名
第 2 步:关闭高危端口,优先处理数据库与缓存
下列端口默认不应暴露在公网,除非有明确的访问控制:
| 端口 | 服务 | 建议 |
|---|---|---|
| 22 | SSH | 保留但限制来源 IP |
| 3306 / 5432 | MySQL / PostgreSQL | 仅本机或内网 |
| 6379 | Redis | 仅本机,务必设密码 |
| 27017 | MongoDB | 仅内网并开启认证 |
| 9200 | Elasticsearch | 禁止公网,加认证 |
| 2375 | Docker API | 绝对禁止暴露 |
以 Redis 为例,改配置文件绑定本机:
bind 127.0.0.1
protected-mode yes
requirepass 强密码
第 3 步:防火墙默认拒绝,只按白名单放行
原则是「默认拒绝入站、按需放行」,而不是先全开再逐个关。firewalld 下:
firewall-cmd --set-default-zone=public
firewall-cmd --permanent --add-service=ssh
firewall-cmd --permanent --add-port=443/tcp
firewall-cmd --reload
firewall-cmd --list-all
若使用 iptables/nftables,先设置 INPUT DROP 再插入放行规则,并放行已建立连接 -m state --state ESTABLISHED,RELATED -j ACCEPT,否则会把自己锁在门外。云主机上安全组与主机防火墙应双层配置,安全组配错时主机侧仍能兜底。在防护建议层面,AegisX 的资产暴露面梳理与端口变更告警能力,可以帮助把「谁在什么时候新开了端口」这类漂移及时发现。
第 4 步:加固 SSH,禁 root 直登与密码爆破
SSH 是最常见入口,改动集中在 /etc/ssh/sshd_config:
PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes
MaxAuthTries 3
AllowUsers deploy ops
ClientAliveInterval 300
改完先 sshd -t 校验语法,再 systemctl reload sshd,并保留一个已登录会话防止配置错误锁死。公网 SSH 建议改非默认端口并限制来源 IP。
上线前务必用新终端验证密钥登录成功,再关闭旧会话。
第 5 步:收敛文件权限,堵住提权与篡改
权限过宽是提权的温床。检查并修正:
find / -xdev -perm -4000 -type f 2>/dev/null
find /var/www -type d -perm -o+w 2>/dev/null
chmod 600 ~/.ssh/authorized_keys
chmod 700 ~/.ssh
重点确认 SUID 文件是否都认识,Web 目录不应有全局可写;配置文件如 /etc/passwd 应为 644,/etc/shadow 为 000 或 640。上传目录应禁止执行脚本。
第 6 步:最小权限落地,账户与 sudo 细粒度授权
最小权限要同时管住账户、进程和提权三件事。禁止多人共用 root,按角色建普通用户;用 visudo 只授予必要命令:
deploy ALL=(root) NOPASSWD: /bin/systemctl restart nginx, /usr/bin/tail
服务进程使用独立低权限账户运行,例如 Nginx worker 用 www-data,数据库用 mysql。禁用长期不用的账户:usermod -L 用户名,并检查 /etc/passwd 中 UID 为 0 的账户是否只有 root。
第 7 步:建立基线核查与巡检,防止配置回退
加固不是一次性动作。建议固化一份基线脚本,定期比对:
- 从外部机器复扫:
nmap -sT -p- 目标IP,确认仅剩预期端口; - 检查登录失败:
grep "Failed password" /var/log/secure | tail; - 检查新增账户与 sudo 变更:
diff备份的/etc/passwd、/etc/sudoers; - 用 lynis 等工具做基线评分,跟踪分数变化。
行动建议:今天先完成第 1、2 步摸清并关闭高危端口,本周内完成 SSH 与防火墙改造,之后把第 7 步的巡检加入月度例行。主机防护的收益来自持续收敛,而不是一次性的「加固完毕」。
常见问题(FAQ)
主机防护第一步到底该做什么?
先做资产与端口清点,再做加固。用 ss -tulnp 列出所有监听端口并对应到进程,用 systemctl list-unit-files 查看开机自启服务,把不认识的服务逐个确认。很多入侵入口就是遗留的测试服务、数据库端口或调试接口,先看清自己暴露了什么,后面的关闭高危端口与防火墙策略才有依据。
关闭高危端口会不会影响业务?
只要先确认端口归属再操作,风险可控。做法是先 ss -tulnp 找到监听进程,确认它属于哪个业务,再决定是停服务、改监听地址为 127.0.0.1,还是仅用防火墙限制来源 IP。建议在变更窗口操作并保留回滚方案,优先用防火墙拦截而非直接杀进程,避免误停核心服务。
云服务器有安全组了,还需要主机防火墙吗?
需要,两者是不同层级的防护。安全组在云网络层过滤,主机防火墙在操作系统层过滤,前者配置错误、实例被迁移或内网横向访问时都可能失效。建议安全组只放行必要端口,主机侧再用 firewalld 或 iptables 设置默认拒绝入站,形成双层校验,内网横向移动也会被拦住。
最小权限在单台服务器上怎么落地?
从账户、文件、提权三条线同时收敛。账户上禁止多余人共用 root,按角色建普通用户;文件上用 chmod 收紧敏感目录、用 chown 明确归属,密钥文件设为 600;提权上用 visudo 只授予必要命令而非 ALL。服务进程使用独立低权限账户运行,避免一个 Web 漏洞直接拿到系统权限。
加固做完后怎么验证有没有效果?
用外部视角复扫加日志审计来验证。从另一台机器执行 nmap -sT -p- 目标IP 确认仅剩预期端口开放,检查 sshd 配置是否生效(sshd -T),查看 /var/log/secure 或 auth.log 是否仍有大量失败登录,用 lynis 或自建基线脚本定期比对配置漂移。建议每月复扫一次,变更后立即复查。