Linux 系统安全加固
大约 20 分钟约 6048 字
Linux 系统安全加固
简介
Linux 系统安全加固是保障服务器安全运行的基础工作。在互联网环境中,服务器面临着暴力破解、漏洞利用、权限提升、恶意软件等多种安全威胁。系统安全加固通过一系列配置措施,从账户管理、密码策略、SSH 安全、防火墙、服务最小化、内核参数、文件权限、审计日志、入侵检测等多个维度提升系统的安全基线,降低被攻击的风险。
本文基于 CentOS 7/8 系统,参考 CIS Benchmark 和等保 2.0 标准,提供一套完整实用的 Linux 系统安全加固方案,涵盖加固操作、验证方法和回退步骤。
核心特点
| 特点 | 说明 |
|---|---|
| 纵深防御 | 多层安全措施,无单点依赖 |
| 最小权限 | 遵循最小权限原则,减少攻击面 |
| 安全基线 | 基于行业标准(CIS、等保)制定 |
| 可审计 | 所有安全事件可追踪、可审计 |
| 可恢复 | 每项加固操作均有回退方案 |
| 自动化 | 可通过 Ansible 等工具批量执行 |
安全加固清单概览
| 类别 | 加固项 | 优先级 |
|---|---|---|
| 账户管理 | 禁用默认账户、删除无用账户 | 高 |
| 密码策略 | 复杂度、有效期、历史记录 | 高 |
| SSH 加固 | 禁用密码登录、修改端口、限制用户 | 高 |
| 防火墙 | 仅开放必要端口、默认拒绝 | 高 |
| 服务最小化 | 关闭不必要的服务和端口 | 中 |
| 内核参数 | 禁用 IP 转发、SYN Cookie 等 | 中 |
| 文件权限 | 关键文件权限、SUID/SGID 检查 | 中 |
| 审计系统 | auditd 配置、日志审计 | 中 |
| 入侵检测 | AIDE 文件完整性、Rootkit 检测 | 低 |
| 漏洞管理 | 定期更新、CVE 扫描 | 低 |
账户管理
用户账户安全
# 1. 查看系统中所有用户
cat /etc/passwd | awk -F: '{print $1, $3, $7}'
# 2. 检查具有登录权限的用户
cat /etc/passwd | grep -E '/bin/(bash|sh|zsh)$'
# 3. 检查空密码账户
awk -F: '($2 == "" || $2 == "!") {print $1}' /etc/shadow
# 4. 锁定不需要登录的系统账户
# 系统账户(UID < 1000)不应有登录权限
for user in $(awk -F: '($3 < 1000 && $3 != 0 && $7 !~ /nologin|false/) {print $1}' /etc/passwd); do
echo "Locking system user: ${user}"
usermod -s /sbin/nologin ${user}
passwd -l ${user}
done
# 5. 锁定默认账户
passwd -l games 2>/dev/null
passwd -l nobody 2>/dev/null
passwd -l ftp 2>/dev/null
passwd -l mail 2>/dev/null
# 6. 删除不需要的用户
userdel -r games 2>/dev/null
userdel -r gopher 2>/dev/null
userdel -r ftp 2>/dev/null
# 7. 删除不需要的组
groupdel games 2>/dev/null
groupdel gopher 2>/dev/null
groupdel ftp 2>/dev/null
groupdel dip 2>/dev/null
# 8. 检查 UID 为 0 的账户(除 root 外不应有其他)
awk -F: '($3 == 0) {print $1}' /etc/passwd
# 预期输出只有 root
# 9. 检查重复 UID
awk -F: 'dup[$3]++ {print $1, $3}' /etc/passwd
# 10. 检查重复 GID
awk -F: 'dup[$3]++ {print $1, $3}' /etc/group创建管理账户
# 创建专用的管理账户(替代直接使用 root)
useradd -m -s /bin/bash -G wheel sysadmin
# 设置强密码
echo "Sysadmin@2024!" | passwd --stdin sysadmin
# 配置 sudo 权限
cat > /etc/sudoers.d/sysadmin << 'EOF'
# 管理员账户 sudo 配置
sysadmin ALL=(ALL) NOPASSWD: /usr/bin/systemctl, /usr/bin/journalctl
sysadmin ALL=(ALL) /usr/bin/yum, /usr/bin/dnf
sysadmin ALL=(ALL) /usr/sbin/iptables, /usr/sbin/firewalld
sysadmin ALL=(ALL) /usr/bin/cat, /usr/bin/tail, /usr/bin/less
sysadmin ALL=(ALL) /opt/scripts/*
# 禁止执行的命令
sysadmin ALL=(ALL) !/usr/bin/su, !/usr/sbin/visudo, !/usr/bin/passwd root
EOF
chmod 440 /etc/sudoers.d/sysadmin
visudo -c # 验证语法密码策略加固
密码复杂度配置
# 安装密码质量检查模块
yum install -y libpwquality
# 配置密码复杂度策略
cat > /etc/security/pwquality.conf << 'EOF'
# 最小密码长度
minlen = 12
# 至少包含的大写字母数
ucredit = -1
# 至少包含的小写字母数
lcredit = -1
# 至少包含的数字数
dcredit = -1
# 至少包含的特殊字符数
ocredit = -1
# 最大连续相同字符数
maxrepeat = 3
# 不能包含用户名
usercheck = 1
# 不能包含的真实姓名(GECOS 字段)
enforcing = 1
# 密码中与旧密码不同的最少字符数
difok = 5
# 新密码不能包含旧密码的字符数
maxclassrepeat = 4
# 拒绝包含的单词列表
reject = ""
# 字符序列检查(如 abc, 123)
maxsequence = 3
EOF密码有效期配置
# 修改 /etc/login.defs
cat >> /etc/login.defs << 'EOF'
# 密码最大有效期(天)
PASS_MAX_DAYS 90
# 密码最小有效期(天),防止频繁修改绕过历史检查
PASS_MIN_DAYS 7
# 密码过期前警告天数
PASS_WARN_AGE 14
# 新用户密码加密算法
ENCRYPT_METHOD SHA512
EOF
# 对已有用户应用密码有效期策略
chage -M 90 root
chage -m 7 root
chage -W 14 root
# 查看密码策略
chage -l root
# 设置密码历史记录(防止重复使用旧密码)
echo "password requisite pam_pwhistory.so remember=24 use_authtok" >> /etc/pam.d/system-auth
# 设置账户锁定策略(连续失败 5 次锁定 30 分钟)
cat > /etc/pam.d/system-auth-ac << 'EOF'
# 在 auth 段添加
auth required pam_env.so
auth required pam_faillock.so preauth audit deny=5 even_deny_root fail_interval=900 unlock_time=1800
auth sufficient pam_unix.so try_first_pass nullok
auth required pam_faillock.so authfail audit deny=5 even_deny_root fail_interval=900 unlock_time=1800
auth required pam_deny.so
# 在 account 段添加
account required pam_faillock.so
account required pam_unix.so
account sufficient pam_localuser.so
account sufficient pam_succeed_if.so uid < 1000 quiet
account required pam_permit.so
# 在 password 段添加
password requisite pam_pwquality.so try_first_pass local_users_only retry=3 authtok_type=
password sufficient pam_unix.so sha512 shadow nullok try_first_pass use_authtok remember=24
password required pam_deny.so
EOF
# 查看失败登录记录
faillock --user root
faillock --user sysadmin
# 手动解锁账户
faillock --user sysadmin --resetSSH 安全加固
SSH 服务端配置
# 备份原始配置
cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak
cat > /etc/ssh/sshd_config << 'EOF'
# 基础配置
Port 2222
AddressFamily inet
ListenAddress 0.0.0.0
Protocol 2
# 主机密钥
HostKey /etc/ssh/ssh_host_ed25519_key
HostKey /etc/ssh/ssh_host_rsa_key
# 日志级别
SyslogFacility AUTH
LogLevel VERBOSE
# 登录控制
PermitRootLogin no
MaxAuthTries 3
MaxSessions 5
LoginGraceTime 60
# 认证方式(仅密钥登录)
PubkeyAuthentication yes
AuthorizedKeysFile .ssh/authorized_keys
PasswordAuthentication no
PermitEmptyPasswords no
ChallengeResponseAuthentication no
KbdInteractiveAuthentication no
UsePAM yes
# 仅允许特定用户/组登录
AllowUsers sysadmin deploy
# 或
# AllowGroups ssh-users
# 禁用的认证方式
GSSAPIAuthentication no
X11Forwarding no
PrintMotd no
PrintLastLog yes
Banner /etc/issue.net
# 会话控制
ClientAliveInterval 300
ClientAliveCountMax 3
# 加密算法(仅使用安全算法)
Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes128-gcm@openssh.com
MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com
KexAlgorithms curve25519-sha256,curve25519-sha256@libssh.org,diffie-hellman-group16-sha512
# 禁用不必要的功能
PermitTunnel no
AllowTcpForwarding no
AllowAgentForwarding no
PermitUserEnvironment no
# 子系统
Subsystem sftp /usr/libexec/openssh/sftp-server
EOF
# 创建登录 Banner
cat > /etc/issue.net << 'EOF'
*******************************************************************
* WARNING: Unauthorized access to this system is prohibited. *
* All connections are monitored and recorded. *
* Disconnect IMMEDIATELY if you are not an authorized user. *
*******************************************************************
EOF
# 生成强密钥对
ssh-keygen -t ed25519 -C "sysadmin@server" -f /home/sysadmin/.ssh/id_ed25519
# 配置 authorized_keys
mkdir -p /home/sysadmin/.ssh
cp /path/to/public_key.pub /home/sysadmin/.ssh/authorized_keys
chown -R sysadmin:sysadmin /home/sysadmin/.ssh
chmod 700 /home/sysadmin/.ssh
chmod 600 /home/sysadmin/.ssh/authorized_keys验证并重启 SSH
# 验证配置语法
sshd -t
# 重启 SSH 服务
systemctl restart sshd
# 验证监听端口
ss -tlnp | grep sshd
# 测试新配置(在另一个终端,不要关闭当前连接)
ssh -p 2222 sysadmin@192.168.1.10fail2ban 防暴力破解
# 安装 fail2ban
yum install -y epel-release
yum install -y fail2ban fail2ban-firewalld
# 主配置文件
cat > /etc/fail2ban/jail.local << 'EOF'
[DEFAULT]
# 封禁时间(秒)
bantime = 3600
# 检测时间窗口(秒)
findtime = 600
# 最大失败次数
maxretry = 3
# 封禁动作
banaction = firewallcmd-rich-rules[actiontype=<multiport>]
# 邮件通知(可选)
# destemail = admin@example.com
# sender = fail2ban@example.com
# action = %(action_mwl)s
# 白名单 IP
ignoreip = 127.0.0.1/8 192.168.1.0/24 10.0.0.0/8
# 后端日志
backend = systemd
[sshd]
enabled = true
port = 2222
filter = sshd
logpath = /var/log/secure
maxretry = 3
bantime = 7200
findtime = 600
[sshd-ddos]
enabled = true
port = 2222
filter = sshd-ddos
logpath = /var/log/secure
maxretry = 5
bantime = 86400
[nginx-http-auth]
enabled = true
filter = nginx-http-auth
port = http,https
logpath = /var/log/nginx/error.log
maxretry = 5
[nginx-badbots]
enabled = true
filter = nginx-badbots
port = http,https
logpath = /var/log/nginx/access.log
maxretry = 2
[recidive]
enabled = true
filter = recidive
logpath = /var/log/fail2ban.log
action = firewallcmd-rich-rules[actiontype=<multiport>]
bantime = 604800
findtime = 86400
maxretry = 5
EOF
# 启动 fail2ban
systemctl start fail2ban
systemctl enable fail2ban
# 查看封禁状态
fail2ban-client status
fail2ban-client status sshd
# 手动解封 IP
fail2ban-client set sshd unbanip 192.168.1.100
# 查看日志
tail -f /var/log/fail2ban.log防火墙配置
firewalld 配置
# 确保 firewalld 已安装并启动
yum install -y firewalld
systemctl start firewalld
systemctl enable firewalld
# 查看默认区域
firewall-cmd --get-default-zone
# 查看当前规则
firewall-cmd --list-all
# 设置默认区域为 drop(拒绝所有未明确允许的连接)
firewall-cmd --set-default-zone=drop
# 在 public 区域放行必要服务
firewall-cmd --permanent --zone=public --change-interface=eth0
firewall-cmd --permanent --zone=public --add-port=2222/tcp # SSH
firewall-cmd --permanent --zone=public --add-port=80/tcp # HTTP
firewall-cmd --permanent --zone=public --add-port=443/tcp # HTTPS
# 放行 VRRP(如果使用 Keepalived)
firewall-cmd --permanent --add-rich-rule='rule protocol value="vrrp" accept'
# 限制 ICMP(禁止 ping)
firewall-cmd --permanent --add-icmp-block=echo-request
firewall-cmd --permanent --add-icmp-block=echo-reply
# 限制特定 IP 访问管理端口
firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.1.0/24" port port="2222" protocol="tcp" accept'
# 拒绝特定 IP 访问
firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="10.10.10.0/24" reject'
# 端口转发
firewall-cmd --permanent --add-forward-port=port=80:proto=tcp:toport=8080:toaddr=192.168.1.20
# 速率限制(防止 DDoS)
firewall-cmd --permanent --add-rich-rule='rule service name="http" limit value="100/s" accept'
# 重载配置
firewall-cmd --reload
# 验证规则
firewall-cmd --list-all --zone=public
firewall-cmd --list-rich-rulesiptables 配置(替代方案)
# 停止 firewalld,使用 iptables
systemctl stop firewalld
systemctl disable firewalld
yum install -y iptables-services
cat > /etc/sysconfig/iptables << 'EOF'
*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [0:0]
# 允许已建立连接和相关连接
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# 允许本地回环
-A INPUT -i lo -j ACCEPT
# 允许 ICMP(可限制类型)
-A INPUT -p icmp --icmp-type echo-request -m limit --limit 1/s -j ACCEPT
# 允许 SSH(自定义端口)
-A INPUT -p tcp -m state --state NEW -m tcp --dport 2222 -j ACCEPT
# 允许 HTTP/HTTPS
-A INPUT -p tcp -m state --state NEW -m tcp --dport 80 -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 443 -j ACCEPT
# 允许 VRRP
-A INPUT -p 112 -j ACCEPT
# 允许内网网段
-A INPUT -s 192.168.1.0/24 -j ACCEPT
# 记录丢弃的包
-A INPUT -j LOG --log-prefix "IPTables-Dropped: " --log-level 4
COMMIT
EOF
systemctl start iptables
systemctl enable iptables
# 查看规则
iptables -L -n -v --line-numbers服务最小化
检查和关闭不必要的服务
# 列出所有启用的服务
systemctl list-unit-files --type=service --state=enabled
# 检查正在运行的服务
systemctl list-units --type=service --state=running
# 关闭不必要的服务
SERVICES_TO_DISABLE=(
"avahi-daemon" # mDNS 服务
"cups" # 打印服务
"postfix" # 邮件服务(如不需要)
"rpcbind" # RPC 服务
"nfs-server" # NFS 服务
"bluetooth" # 蓝牙服务
"ModemManager" # 调制解调器管理
"abrt-ccpp" # 自动错误报告
"abrt-oops" # 自动错误报告
"abrtd" # 自动错误报告
"smartd" # 磁盘监控(按需)
"autofs" # 自动挂载
"rhnsd" # Red Hat 网络
)
for svc in "${SERVICES_TO_DISABLE[@]}"; do
if systemctl is-enabled "${svc}" 2>/dev/null | grep -q "enabled"; then
echo "Disabling: ${svc}"
systemctl stop "${svc}"
systemctl disable "${svc}"
fi
done
# 检查监听端口(确认不必要端口已关闭)
ss -tlnp
ss -ulnp检查定时任务
# 查看所有用户的 crontab
for user in $(cut -d: -f1 /etc/passwd); do
crontab_content=$(crontab -u ${user} -l 2>/dev/null)
if [ -n "${crontab_content}" ]; then
echo "=== ${user} ==="
echo "${crontab_content}"
fi
done
# 检查系统 cron 目录
ls -la /etc/cron.d/
ls -la /etc/cron.daily/
ls -la /etc/cron.hourly/
ls -la /etc/cron.weekly/
ls -la /etc/cron.monthly/
# 检查可疑的定时任务
find /etc/cron* -type f -mtime -7 -ls
find /var/spool/cron -type f -ls内核安全参数
sysctl 安全加固
cat > /etc/sysctl.d/99-security.conf << 'EOF'
# =================== 网络安全 ===================
# 禁用 IP 转发(非路由器场景)
net.ipv4.ip_forward = 0
net.ipv6.conf.all.forwarding = 0
# 禁用源路由
net.ipv4.conf.all.accept_source_route = 0
net.ipv4.conf.default.accept_source_route = 0
net.ipv6.conf.all.accept_source_route = 0
# 禁用 ICMP 重定向
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.default.accept_redirects = 0
net.ipv6.conf.all.accept_redirects = 0
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.default.send_redirects = 0
# 启用 SYN Cookie(防 SYN Flood)
net.ipv4.tcp_syncookies = 1
# 禁用 IP 源路由
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.default.rp_filter = 1
# 忽略 ICMP 广播请求
net.ipv4.icmp_echo_ignore_broadcasts = 1
# 忽略错误的 ICMP 响应
net.ipv4.icmp_ignore_bogus_error_responses = 1
# 记录可疑数据包
net.ipv4.conf.all.log_martians = 1
net.ipv4.conf.default.log_martians = 1
# TCP 连接队列
net.ipv4.tcp_max_syn_backlog = 2048
net.ipv4.tcp_synack_retries = 2
# 限制 TIME_WAIT 连接复用
net.ipv4.tcp_tw_reuse = 1
# 禁用 IPv6(如不需要)
net.ipv6.conf.all.disable_ipv6 = 1
net.ipv6.conf.default.disable_ipv6 = 1
# =================== 内核安全 ===================
# 禁用魔术键(SysRq)
kernel.sysrq = 0
# 禁用核心转储给非特权用户
fs.suid_dumpable = 0
# 限制核心转储
kernel.core_uses_pid = 1
# ASLR(地址空间随机化)
kernel.randomize_va_space = 2
# 限制 dmesg 输出
kernel.dmesg_restrict = 1
# 限制内核指针泄露
kernel.kptr_restrict = 2
# 限制 ptrace(反调试)
kernel.yama.ptrace_scope = 2
# 限制 /dev/mem 和 /dev/kmem 访问
kernel.kexec_load = 0
# 文件描述符限制
fs.file-max = 65536
# PID 限制
kernel.pid_max = 65536
EOF
# 应用配置
sysctl -p /etc/sysctl.d/99-security.conf
# 验证
sysctl -a | grep "net.ipv4.ip_forward"
sysctl -a | grep "kernel.randomize_va_space"文件权限加固
关键文件权限设置
# /etc/passwd 权限
chmod 644 /etc/passwd
chown root:root /etc/passwd
# /etc/shadow 权限
chmod 600 /etc/shadow
chown root:root /etc/shadow
# /etc/group 权限
chmod 644 /etc/group
chown root:root /etc/group
# /etc/gshadow 权限
chmod 600 /etc/gshadow
chown root:root /etc/gshadow
# SSH 配置目录
chmod 700 /root/.ssh
chmod 600 /root/.ssh/authorized_keys
chmod 600 /etc/ssh/sshd_config
# sudo 配置
chmod 440 /etc/sudoers
chmod 440 /etc/sudoers.d/*
# cron 目录
chmod 700 /var/spool/cron
chmod 600 /var/spool/cron/*
# 日志目录
chmod 755 /var/log
chmod 640 /var/log/secure
chmod 640 /var/log/messages
# 引导加载器
chmod 600 /boot/grub2/grub.cfg
chown root:root /boot/grub2/grub.cfg
# 验证关键文件权限
echo "Verifying file permissions..."
stat -c '%a %n' /etc/passwd /etc/shadow /etc/group /etc/gshadow
stat -c '%a %n' /etc/ssh/sshd_config /etc/sudoersSUID/SGID 检查
# 查找所有 SUID 文件
find / -perm -4000 -type f 2>/dev/null
# 查找所有 SGID 文件
find / -perm -2000 -type f 2>/dev/null
# 查找同时设置了 SUID 和 SGID 的文件
find / -perm -6000 -type f 2>/dev/null
# 常见需要保留 SUID 的文件
# /usr/bin/sudo
# /usr/bin/passwd
# /usr/bin/su
# /usr/bin/ping
# /usr/sbin/unix_chkpwd
# 移除不必要的 SUID 权限
# 注意:以下操作需谨慎,根据实际需求调整
chmod u-s /usr/bin/chsh 2>/dev/null
chmod u-s /usr/bin/chfn 2>/dev/null
chmod u-s /usr/bin/mount 2>/dev/null
chmod u-s /usr/bin/umount 2>/dev/null
chmod u-s /usr/bin/newgrp 2>/dev/null
# 查找世界可写文件(不应存在)
find / -perm -0002 -type f ! -path "/proc/*" ! -path "/sys/*" 2>/dev/null
# 查找无属主的文件
find / -nouser -o -nogroup 2>/dev/null
# 查找隐藏文件
find / -name ".*" -type f 2>/dev/null | grep -v "/proc\|/sys\|/dev"审计系统(auditd)
auditd 配置
# 安装 audit
yum install -y audit
# 主配置文件
cat > /etc/audit/auditd.conf << 'EOF'
# 日志文件
log_file = /var/log/audit/audit.log
# 日志格式
log_format = RAW
# 日志组
log_group = root
# 优先级提升
priority_boost = 4
# 空间不足时的动作
space_left = 75
space_left_action = SYSLOG
action_mail_acct = root
admin_space_left = 50
admin_space_left_action = SUSPEND
# 磁盘满时的动作
disk_full_action = SUSPEND
# 磁盘错误时的动作
disk_error_action = SUSPEND
# 最大日志文件大小(MB)
max_log_file = 100
# 达到最大大小后的动作
max_log_file_action = ROTATE
# 保留的日志文件数
num_logs = 10
# 写入策略
flush = INCREMENTAL_ASYNC
freq = 50
EOF
# 审计规则
cat > /etc/audit/rules.d/audit.rules << 'EOF'
# 删除所有现有规则
-D
# 设置缓冲区大小
-b 8192
# 失败模式
-f 1
# =================== 登录相关 ===================
# 监控登录事件
-w /var/log/secure -p wa -k logins
-w /var/log/lastlog -p wa -k logins
-w /var/run/faillock -p wa -k logins
# =================== 账户管理 ===================
-w /etc/passwd -p wa -k identity
-w /etc/shadow -p wa -k identity
-w /etc/group -p wa -k identity
-w /etc/gshadow -p wa -k identity
-w /etc/sudoers -p wa -k sudo
-w /etc/sudoers.d/ -p wa -k sudo
# =================== 网络配置 ===================
-w /etc/hosts -p wa -k network
-w /etc/resolv.conf -p wa -k network
-w /etc/sysconfig/network -p wa -k network
-w /etc/sysconfig/network-scripts/ -p wa -k network
# =================== 系统配置 ===================
-w /etc/ssh/sshd_config -p wa -k ssh
-w /etc/issue.net -p wa -k banner
-w /etc/crontab -p wa -k cron
-w /etc/cron.d/ -p wa -k cron
-w /etc/cron.daily/ -p wa -k cron
-w /etc/cron.hourly/ -p wa -k cron
-w /etc/cron.weekly/ -p wa -k cron
-w /etc/cron.monthly/ -p wa -k cron
-w /var/spool/cron/ -p wa -k cron
# =================== 权限变更 ===================
# 监控 chmod、chown 调用
-a always,exit -F arch=b64 -S chmod -S fchmod -S fchmodat -F auid>=1000 -F auid!=4294967295 -k perm_mod
-a always,exit -F arch=b64 -S chown -S fchown -S fchownat -S lchown -F auid>=1000 -F auid!=4294967295 -k perm_mod
# =================== 命令审计 ===================
# 监控特权命令执行
-a always,exit -F arch=b64 -S execve -F euid=0 -F auid>=1000 -F auid!=4294967295 -k privileged
# 监控关键命令
-w /usr/bin/sudo -p x -k sudo_exec
-w /usr/bin/su -p x -k su_exec
-w /usr/sbin/iptables -p x -k firewall
-w /usr/sbin/useradd -p x -k user_mgmt
-w /usr/sbin/usermod -p x -k user_mgmt
-w /usr/sbin/userdel -p x -k user_mgmt
-w /usr/sbin/groupadd -p x -k user_mgmt
-w /usr/sbin/groupmod -p x -k user_mgmt
# =================== 文件完整性 ===================
# 监控关键目录变更
-w /bin/ -p wa -k bin_changes
-w /sbin/ -p wa -k bin_changes
-w /usr/bin/ -p wa -k bin_changes
-w /usr/sbin/ -p wa -k bin_changes
-w /lib/ -p wa -k lib_changes
-w /lib64/ -p wa -k lib_changes
# =================== 内核模块 ===================
-a always,exit -F arch=b64 -S init_module -S delete_module -k kernel_modules
# =================== 系统调用 ===================
# 监控时间变更
-a always,exit -F arch=b64 -S settimeofday -S clock_settime -k time_change
# 监控挂载操作
-a always,exit -F arch=b64 -S mount -S umount2 -k mount
EOF
# 启动审计服务
systemctl start auditd
systemctl enable auditd
# 注意:auditd 不支持通过 systemctl restart 重启
# 需要使用 service 命令
service auditd restart
# 查看审计日志
ausearch -m USER_LOGIN -ts today
aureport -u # 用户报告
aureport -x # 可执行文件报告
aureport -f # 文件报告审计日志分析
# 搜索特定关键字的审计事件
ausearch -k identity
# 搜索今天的登录失败事件
ausearch -m USER_LOGIN -sv no -ts today
# 搜索 sudo 执行记录
ausearch -k sudo_exec
# 生成汇总报告
aureport --summary
# 查看文件变更报告
aureport -f -i
# 查看用户活动报告
aureport -u -i
# 实时监控审计事件
tail -f /var/log/audit/audit.log | ausearch -i入侵检测(AIDE)
AIDE 安装与初始化
# 安装 AIDE(Advanced Intrusion Detection Environment)
yum install -y aide
# 配置 AIDE
cat > /etc/aide.conf << 'EOF'
# 数据库位置
database=file:/var/lib/aide/aide.db.gz
database_out=file:/var/lib/aide/aide.db.new.gz
# 报告选项
report_url=stdout
report_url=file:/var/log/aide/aide.log
# 自定义规则
NORMAL = LINES+ATTRIBUTES+SHA512
PERMS = PERMISSIONS+INODE_NUMBER
DATAONLY = LINES+ATTRIBUTES+SHA512
# 监控范围
/etc NORMAL
/root NORMAL
/boot NORMAL
/bin NORMAL
/sbin NORMAL
/usr/bin NORMAL
/usr/sbin NORMAL
/usr/lib NORMAL
/usr/lib64 NORMAL
/var/spool/cron NORMAL
# 排除频繁变化的目录
!/etc/mtab
!/etc/.*~
!/var/log
!/var/spool
!/proc
!/sys
!/dev
!/tmp
!/run
EOF
# 创建日志目录
mkdir -p /var/log/aide
# 初始化数据库
aide --init
# 将新数据库设为当前数据库
cp /var/lib/aide/aide.db.new.gz /var/lib/aide/aide.db.gz
# 检查文件变更
aide --check
# 更新数据库(确认变更合法后)
aide --update
cp /var/lib/aide/aide.db.new.gz /var/lib/aide/aide.db.gz定期检查脚本
cat > /opt/scripts/aide_check.sh << 'SCRIPT'
#!/bin/bash
AIDE_LOG="/var/log/aide/aide-$(date +%Y%m%d).log"
ALERT_EMAIL="security@example.com"
# 执行检查
aide --check > "${AIDE_LOG}" 2>&1
# 检查是否有变更
if grep -q "Looks okay" "${AIDE_LOG}"; then
echo "$(date) - No changes detected" >> /var/log/aide/summary.log
else
# 发送告警
CHANGES=$(grep -c "Changed" "${AIDE_LOG}" 2>/dev/null || echo "unknown")
echo "$(date) - WARNING: ${CHANGES} changes detected!" >> /var/log/aide/summary.log
# 可选:发送邮件告警
# mail -s "AIDE Alert: File changes detected on $(hostname)" ${ALERT_EMAIL} < ${AIDE_LOG}
fi
SCRIPT
chmod +x /opt/scripts/aide_check.sh
# 添加每日检查定时任务
cat > /etc/cron.d/aide << 'EOF'
# 每天凌晨 3 点执行 AIDE 检查
0 3 * * * root /opt/scripts/aide_check.sh
EOFRootkit 检测
rkhunter 安装与使用
# 安装
yum install -y rkhunter
# 更新数据库
rkhunter --update
rkhunter --propupd
# 扫描系统
rkhunter --check --skip-keypress
# 查看报告
cat /var/log/rkhunter/rkhunter.log | grep -i warning
# 定期扫描
cat > /etc/cron.d/rkhunter << 'EOF'
0 4 * * 0 root /usr/bin/rkhunter --check --skip-keypress --report-warnings-only >> /var/log/rkhunter/cron.log 2>&1
EOFchkrootkit 使用
# 安装
yum install -y chkrootkit
# 扫描
chkrootkit
# 仅显示可疑结果
chkrootkit | grep "INFECTED\|WARNING\|suspicious"漏洞扫描与管理
系统更新策略
# 检查可用更新
yum check-update
dnf check-update
# 仅安装安全更新
yum install -y yum-plugin-security
yum updateinfo list security
yum update --security
# 检查已安装软件的已知漏洞
rpm -qa --changelog | grep -i "CVE"
# 使用 OpenSCAP 扫描
yum install -y scap-security-guide openscap-scanner
# 执行安全基线扫描
oscap xccdf eval --profile xccdf_org.ssgproject.content_profile_stig \
--report /tmp/scap-report.html \
/usr/share/xml/scap/ssg/content/ssg-centos7-ds.xml安全基线检查脚本
#!/bin/bash
# /opt/scripts/security_baseline.sh
# 安全基线自检脚本
RESULT_FILE="/var/log/security_baseline_$(date +%Y%m%d).log"
echo "========================================" > ${RESULT_FILE}
echo "Linux Security Baseline Check" >> ${RESULT_FILE}
echo "Date: $(date)" >> ${RESULT_FILE}
echo "Host: $(hostname)" >> ${RESULT_FILE}
echo "========================================" >> ${RESULT_FILE}
# 1. 检查密码策略
echo -e "\n[1] Password Policy" >> ${RESULT_FILE}
echo "Max password age: $(awk '/^PASS_MAX_DAYS/ {print $2}' /etc/login.defs)" >> ${RESULT_FILE}
echo "Min password length: $(awk '/^minlen/ {print $3}' /etc/security/pwquality.conf)" >> ${RESULT_FILE}
# 2. 检查 SSH 配置
echo -e "\n[2] SSH Configuration" >> ${RESULT_FILE}
echo "Root login: $(grep -E '^PermitRootLogin' /etc/ssh/sshd_config | awk '{print $2}')" >> ${RESULT_FILE}
echo "Password auth: $(grep -E '^PasswordAuthentication' /etc/ssh/sshd_config | awk '{print $2}')" >> ${RESULT_FILE}
echo "SSH port: $(grep -E '^Port' /etc/ssh/sshd_config | awk '{print $2}')" >> ${RESULT_FILE}
# 3. 检查防火墙状态
echo -e "\n[3] Firewall Status" >> ${RESULT_FILE}
systemctl is-active firewalld >> ${RESULT_FILE} 2>&1
firewall-cmd --list-services >> ${RESULT_FILE} 2>&1
# 4. 检查开放端口
echo -e "\n[4] Open Ports" >> ${RESULT_FILE}
ss -tlnp >> ${RESULT_FILE}
# 5. 检查 UID=0 账户
echo -e "\n[5] UID 0 Accounts" >> ${RESULT_FILE}
awk -F: '($3 == 0) {print $1}' /etc/passwd >> ${RESULT_FILE}
# 6. 检查空密码账户
echo -e "\n[6] Empty Password Accounts" >> ${RESULT_FILE}
awk -F: '($2 == "") {print $1}' /etc/shadow >> ${RESULT_FILE}
# 7. 检查 SUID 文件
echo -e "\n[7] SUID Files" >> ${RESULT_FILE}
find / -perm -4000 -type f 2>/dev/null >> ${RESULT_FILE}
# 8. 检查世界可写文件
echo -e "\n[8] World Writable Files" >> ${RESULT_FILE}
find / -perm -0002 -type f ! -path "/proc/*" ! -path "/sys/*" 2>/dev/null >> ${RESULT_FILE}
# 9. 检查关键文件权限
echo -e "\n[9] Critical File Permissions" >> ${RESULT_FILE}
stat -c '%a %n' /etc/passwd /etc/shadow /etc/ssh/sshd_config >> ${RESULT_FILE}
# 10. 检查内核参数
echo -e "\n[10] Kernel Security Parameters" >> ${RESULT_FILE}
echo "IP forwarding: $(sysctl -n net.ipv4.ip_forward)" >> ${RESULT_FILE}
echo "SYN cookies: $(sysctl -n net.ipv4.tcp_syncookies)" >> ${RESULT_FILE}
echo "ASLR: $(sysctl -n kernel.randomize_va_space)" >> ${RESULT_FILE}
echo -e "\n========================================" >> ${RESULT_FILE}
echo "Check completed: $(date)" >> ${RESULT_FILE}
echo "Report saved to: ${RESULT_FILE}"合规检查清单
等保 2.0 基本要求对应
| 安全域 | 检查项 | 对应操作 | 状态 |
|---|---|---|---|
| 身份鉴别 | 密码复杂度 | pwquality.conf 配置 | [ ] |
| 身份鉴别 | 登录失败锁定 | pam_faillock 配置 | [ ] |
| 身份鉴别 | 远程管理加密 | SSH 密钥认证 | [ ] |
| 访问控制 | 默认账户禁用 | 锁定/删除系统账户 | [ ] |
| 访问控制 | 最小权限 | sudo 分权管理 | [ ] |
| 安全审计 | 审计日志启用 | auditd 配置 | [ ] |
| 安全审计 | 日志留存 180 天 | ILM/日志轮转策略 | [ ] |
| 入侵防范 | 防火墙启用 | firewalld 规则 | [ ] |
| 入侵防范 | 暴力破解防护 | fail2ban 配置 | [ ] |
| 入侵防范 | 文件完整性 | AIDE 定期检查 | [ ] |
| 恶意代码 | 恶意软件检测 | rkhunter/chkrootkit | [ ] |
| 系统加固 | 补丁更新 | 定期安全更新 | [ ] |
| 系统加固 | 服务最小化 | 关闭不必要服务 | [ ] |
| 系统加固 | 内核参数 | sysctl 安全参数 | [ ] |
优点
- 大幅降低风险:系统性安全加固可消除 80% 以上的常见攻击向量
- 满足合规要求:符合等保 2.0 和 CIS Benchmark 标准
- 可审计追溯:完善的审计系统支持事后调查
- 标准化操作:可通过脚本和自动化工具批量执行
- 持续监控:AIDE + auditd 提供持续的安全监控能力
缺点
- 增加管理复杂度:严格的安全策略可能影响运维效率
- 可能导致兼容性问题:某些应用需要特定的 SUID 权限或端口
- 需要持续维护:安全加固不是一次性工作,需要定期审查和更新
- 性能开销:auditd 和 AIDE 会消耗一定的系统资源
总结
Linux 系统安全加固是一项系统性工程,需要从账户管理、密码策略、SSH 安全、防火墙、服务最小化、内核参数、文件权限、审计日志、入侵检测等多个维度综合施策。安全加固不是一次性工作,而是需要持续维护的过程。建议将安全加固脚本化、自动化,定期执行安全基线检查,及时发现和修复安全隐患。
关键知识点
- Linux 用户和组的权限管理模型
- PAM(Pluggable Authentication Modules)认证框架
- SSH 密钥认证的工作原理和安全配置
- firewalld/iptables 防火墙规则和区域管理
- sysctl 内核参数的安全调优
- SUID/SGID 的安全风险和检查方法
- auditd 审计规则的设计和日志分析
- AIDE 文件完整性检测的原理和实践
常见误区
- 加固一次就永久安全:安全是持续过程,需要定期审查和更新
- 只关注外部攻击:内部威胁同样严重,需要最小权限和审计
- 过度加固导致不可用:安全性和可用性需要平衡
- 忽略物理安全:GRUB 密码、磁盘加密同样重要
- 不验证加固效果:每项加固操作都应该验证其生效
- 没有回退方案:加固前必须备份,确保可以回退
进阶路线
- SELinux 深入学习:理解 MLS/MCS 策略和自定义策略开发
- 容器安全:学习 Docker/K8s 环境的安全加固
- 自动化合规:使用 OpenSCAP/Ansible 实现自动化安全基线检查
- 安全信息与事件管理(SIEM):集成 ELK/Wazuh 等平台
- 零信任架构:了解 BeyondCorp 模式在服务器安全中的应用
- 安全编排与自动化响应(SOAR):自动化安全事件响应
适用场景
- 新服务器上线前的安全初始化
- 等保合规安全整改
- 生产环境定期安全审查
- 安全事件后的加固整改
- 混合云/多云环境的安全基线统一管理
- 金融、政府等高安全等级行业的合规要求
落地建议
- 建立安全基线文档:根据业务需求制定安全基线标准
- 分批实施:先在测试环境验证,再分批推广到生产环境
- 自动化执行:使用 Ansible Playbook 批量执行加固操作
- 定期审计:每月执行安全基线自检,每季度进行安全评估
- 变更管理:安全策略变更需要经过审批和测试
- 应急准备:每项加固操作记录回退步骤,确保可快速恢复
排错清单
| 现象 | 可能原因 | 排查方法 |
|---|---|---|
| SSH 登录被拒 | 密钥/配置错误 | sshd -t 检查配置 |
| sudo 执行失败 | sudoers 配置错误 | visudo -c 验证语法 |
| 防火墙阻断服务 | 规则未放行 | firewall-cmd --list-all |
| 密码修改失败 | 复杂度不够 | 查看 pwquality.conf |
| 账户被锁定 | faillock 触发 | faillock --user xxx |
| auditd 无法启动 | 配置语法错误 | auditd -f 前台调试 |
| AIDE 误报 | 正常变更未更新库 | aide --update |
| 服务启动失败 | SELinux 阻断 | ausearch -m avc |
复盘问题
- 如何在不影响业务可用性的前提下,逐步实施 SSH 密钥认证?
- fail2ban 的封禁策略如何避免误封合法用户?
- auditd 的审计规则如何平衡安全监控需求和系统性能?
- AIDE 检测到文件变更后,如何判断是合法变更还是入侵行为?
- SELinux 和 AppArmor 有什么区别?生产环境应该选择哪个?
- 如何设计一套完整的安全事件响应流程(从发现到处置)?
