Appearance
系统安全加固
Linux 安全加固的几个重点:收紧 SSH 入口、管好账号和 sudo 权限、控制服务暴露面、配置防火墙和强制访问控制、保留审计日志。安全加固不是一次性做完就完了,而是上线前收紧一轮,运行中靠监控、审计、补丁、权限复查持续维护。这篇按这几个重点过一遍。
一、SSH 加固
SSH 是远程管理最主要的入口,也是攻击者最爱扫的目标。加固优先级一般是:先确保密钥登录能用,再关闭密码登录和 root 登录,最后限制来源 IP。顺序很重要——直接关密码登录之前,务必先确认密钥登录没问题,不然就把自己也锁外面了。
配置文件路径 /etc/ssh/sshd_config,改之前先备份:
bash
cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak # 先备份
vim /etc/ssh/sshd_config推荐的安全配置:
sshconfig
PermitRootLogin no # 禁止 root 直接 SSH 登录
PasswordAuthentication no # 禁止密码认证,只允许密钥
PubkeyAuthentication yes # 允许公钥认证
Port 22 # SSH 监听端口
AllowUsers deploy # 仅允许 deploy 用户登录几个关键项解释一下:PermitRootLogin no 禁止 root 直接登录,要登录得用普通用户再 sudo 提权;PasswordAuthentication no 关掉密码认证,堵死暴力破解;AllowUsers 是白名单,只允许列出的用户登录,其他用户就算有账号也登不上。
改 SSH 端口(比如改成 2222)只能减少自动化扫描的日志噪音,不能当核心安全措施——扫描器扫 22 端口的最多,改了端口日志清净点,但定向扫描照样能扫到。真正有效的组合是:禁 root 登录 + 密钥认证 + 限制来源 IP + 审计日志。
改完配置先做语法检查再重载:
bash
sshd -t # 检查配置语法,没有输出表示通过
systemctl reload sshd远程改 SSH 配置有个黄金法则:保留一个已经登录的会话不要关。在新窗口测试能成功登录之后,再关掉旧会话。一旦改错被锁外面,旧会话还能救。这个习惯能避免无数次"把自己关在外面只能去机房"的事故。
二、密钥登录
SSH 密钥对由私钥(自己保管,绝不离开本机)和公钥(放到目标服务器)组成。推荐用 ed25519 算法——比 RSA 更短、更快、安全性相当,现在是首选。
生成密钥对:
bash
ssh-keygen -t ed25519 -C "deploy"上传公钥到目标服务器:
bash
ssh-copy-id deploy@server服务端 .ssh 目录和 authorized_keys 文件的权限必须严格控制,不然 sshd 会拒绝使用:
bash
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys密钥存在但登录失败时,先查权限,再看 /var/log/secure(RHEL 系)或 /var/log/auth.log(Ubuntu)。sshd 对权限极其敏感——authorized_keys 权限太宽(比如 644),sshd 会直接跳过这个文件不读,登录失败但日志里未必有明确提示,新人特别容易卡在这。
私钥不应该在服务器之间复制。如果多台机器都要访问同一个目标,每台机器生成自己的密钥对,目标服务器分别添加对应公钥。需要统一管理访问权限,用堡垒机托管凭据,而不是把同一把私钥复制得到处都是——私钥一旦泄露,所有用它的地方都暴露。
三、fail2ban
fail2ban 通过监控日志文件,检测到多次失败登录尝试后自动封禁来源 IP,是对暴力破解的辅助防护。
安装:
bash
yum install fail2ban -y
apt install fail2ban -y基础配置在 /etc/fail2ban/jail.local:
ini
[sshd]
enabled = true
port = ssh
filter = sshd
logpath = /var/log/secure # Ubuntu 上是 /var/log/auth.log
maxretry = 5 # 允许 5 次失败尝试
bantime = 1h # 封禁 1 小时启动和查看:
bash
systemctl enable --now fail2ban
fail2ban-client status # 查看总体状态
fail2ban-client status sshd # 查看 sshd jail 的封禁统计fail2ban 是辅助防护,不能替代 SSH 的基本安全配置。SSH 暴露公网会持续承受扫描和暴力尝试,fail2ban 只能减少噪音和挡掉明显的暴力破解。从架构层面,通过 VPN 或者堡垒机收敛入口,比在每台机器上跑 fail2ban 更安全。
四、SELinux
SELinux(Security-Enhanced Linux)是 Linux 内核的强制访问控制(MAC)模块。它独立于传统的 UGO 权限,给进程和文件打上安全标签(context),按预设策略控制哪些进程能访问哪些类型的资源——就算你是 root,SELinux 策略不让访问也访问不了。
查看当前状态:
bash
getenforce # 简洁输出:Enforcing / Permissive / Disabled
sestatus # 详细输出三种状态:Enforcing 强制执行策略,违规会被拦截并记录;Permissive 只记录不拦截,适合排查"是不是 SELinux 导致的问题";Disabled 完全关闭。
临时切到 Permissive 排查用:
bash
setenforce 0永久关闭要改 /etc/selinux/config,重启生效。
排查 Web 服务、数据库这类应用"权限明明对但就是不行"的时候,如果 UGO 权限和属主都没问题,就要怀疑 SELinux。看文件的安全上下文:
bash
ls -Z /var/www/html # 查看文件的安全上下文一个经典场景:文件从别处 mv 过来,它的 SELinux 上下文还是原来的,跟目标目录不匹配,服务就访问不了。恢复目录的默认上下文:
bash
restorecon -Rv /var/www/html排查时不建议上来就永久关闭 SELinux。先用 setenforce 0(Permissive)验证是不是它导致的,再根据审计日志(ausearch -m avc)补策略或者调上下文。一遇到问题就关 SELinux,等于放弃了这层防护,长期来看是降低安全性的。
五、AppArmor
Ubuntu 默认用 AppArmor 而不是 SELinux,功能类似但管理方式不同:SELinux 基于标签(label),AppArmor 基于路径(path-based profile)。
bash
aa-status # 查看 AppArmor 状态和已加载的 profile
systemctl status apparmor配置目录在 /etc/apparmor.d/。服务莫名其妙没权限、文件权限看着又没问题的时候,除了 SELinux 也要想到 AppArmor——不同发行版用的访问控制模块不同,处理方式也不同,在 Ubuntu 上排查权限问题别用 SELinux 那套思路。
六、最小化服务
服务器上跑的服务越多,攻击面越大。定期审查不必要的服务和监听端口,这是基本功。
查看所有监听端口和对应进程:
bash
ss -lntup查看设了开机自启的服务:
bash
systemctl list-unit-files --type=service --state=enabled关掉不需要的服务:
bash
systemctl disable --now service-name新机器初始化时,对监听端口做一次审计——看到认不出来的端口,查一下属于哪个服务、是不是业务需要的,不需要的就关。很多被入侵的服务器,突破口就是某个早就该关但一直开着的旧服务。
七、防火墙和云安全组
本机防火墙只解决一层,云环境还要配合云安全组——安全组是本机防火墙的上游,包先过安全组再到本机。两层都要放行,端口才真的通。
bash
iptables -L -n -v
firewall-cmd --list-all很多"端口不通"的问题不是 Linux 拦的,而是云安全组没放行。排查思路:本机 iptables -L -n -v 没看到对应端口的 DROP 计数增长,服务也在 0.0.0.0:端口 监听,但外部 curl 一直超时——更像安全组、云防火墙或者上游网络没放行;如果外部请求一来,本机 DROP 计数跟着涨,那问题就在主机防火墙这一层。
常用端口策略:
| 端口 | 策略 |
|---|---|
| SSH(22) | 限制来源 IP,或走堡垒机/VPN 接入 |
| HTTP/HTTPS(80/443) | 按业务需要对外开放 |
| 数据库(3306、5432) | 只内网访问,绝不暴露公网 |
| Redis(6379) | 只内网访问,绑定内网 IP |
数据库和 Redis 暴露公网且没有额外认证,基本等于面向攻击者开放——Redis 尤其危险,很多默认配置无密码,公网能连就能直接写文件拿 shell。这种事故每年都在发生。
八、账号和 sudo 审计
查看所有 UID 为 0 的用户(应该只有 root 一条,多了就有问题):
bash
awk -F: '$3 == 0 {print $1}' /etc/passwd查看 sudoers 里有哪些免密或全权限配置:
bash
grep -R "ALL" /etc/sudoers /etc/sudoers.d/临时账号(外包、合作方、临时访问)要设过期时间,别让它长期有效:
bash
chage -E 2026-06-01 tempuser # 账号在指定日期后自动失效sudo 权限尽量按命令授权,避免 NOPASSWD:ALL。业务确实需要免密的场景,也限制到具体的几条命令——出事的时候能追溯是谁、在什么时候、执行了什么,NOPASSWD:ALL 让这种追溯彻底失效。
九、日常安全检查清单
几个快速过一遍当前安全面的命令:
bash
hostnamectl # 主机信息
timedatectl # 时间是否正确(时间不对影响证书和审计)
ss -lntup # 所有监听端口
systemctl list-unit-files --type=service --state=enabled # 自启服务
last -n 10 # 最近登录记录
lastb -n 10 # 最近失败登录(暴力破解痕迹)
getenforce 2>/dev/null || true # SELinux 状态这套命令不算完整基线检查,但能快速扫一遍比较明显的问题:端口暴露不对、不该开的服务在跑、有异常登录记录、SELinux 被关了等等。养成定期跑一遍的习惯,很多安全隐患能提前发现。