Skip to content

系统安全加固

Linux 安全加固的几个重点工作:收紧 SSH 入口、管理账号和 sudo 权限、控制服务暴露面、配置防火墙和强制访问控制、保留审计日志。

一、SSH 加固

SSH 是远程管理最主要的入口。加固的优先级一般是:先确保密钥登录可用,再关闭密码登录和 root 登录,最后限制来源 IP。直接关密码登录之前,务必确认密钥登录没有问题。

配置文件路径:

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关闭密码认证,防止暴力破解
PubkeyAuthentication yes启用公钥认证
AllowUsers白名单——只允许列出的用户登录

修改 SSH 端口(如改成 2222)只能减少自动化扫描的日志噪音,不能当作核心安全措施。真正有效的是:禁用 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 暴露公网会持续承受扫描和暴力尝试,从架构层面通过 VPN 或堡垒机收敛入口更安全。

四、SELinux

SELinux(Security-Enhanced Linux)是 Linux 内核的强制访问控制模块。它独立于传统的 UGO 权限,给进程和文件打上安全标签(context),按预设策略控制哪些进程能访问哪些类型的资源。

查看当前状态:

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 过来,它的上下文可能还是原来的,和目标目录不匹配。恢复目录的默认上下文:

bash
restorecon -Rv /var/www/html

排查时不建议上来就永久关闭 SELinux。先用 Permissive 验证是不是它导致的,再根据审计日志(ausearch -m avc)补策略或调上下文。如果确认问题确实在 SELinux 策略,再有针对性地调整。

五、AppArmor

Ubuntu 上默认使用 AppArmor 而非 SELinux,功能类似但管理方式不同。SELinux 基于标签(label),AppArmor 基于路径(path-based profile)。

bash
aa-status                        # 查看 AppArmor 状态和已加载的 profile
systemctl status apparmor

配置目录:

bash
ls /etc/apparmor.d/

服务莫名其妙没有权限,而文件权限设置看着没问题时,除了 SELinux 也要想到 AppArmor。不同发行版用的访问控制模块不同,处理方式也不同。

六、最小化服务

服务器上运行的服务越多,暴露面越大。定期审查不必要的服务和监听端口。

查看所有监听的端口和对应进程:

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 端拦的,而是云安全组没有放行。排查时两层一起看。

常用端口策略原则:

端口策略
SSH(22)限制来源 IP,或通过堡垒机/VPN 接入
HTTP/HTTPS(80/443)按业务对外开放
数据库(3306、5432)内网访问,不暴露公网
Redis(6379)内网访问,绑定内网 IP 或受控入口

数据库和 Redis 暴露在公网且没有额外认证措施的,基本是面向攻击者开放的。

八、账号和 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。业务必需的免密场景,也限制到具体的几条命令,比全放开可追溯得多。

九、日常安全检查清单

几个快速查看当前安全面信息的命令:

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 被关了等等。

安全加固不是一次性做完就完了。上线前收紧一轮,运行中靠日志监控、定期审计、补丁更新和权限复查来持续维护。