一、安全加固概述

服务器安全加固是运维工作中最核心的环节之一。面对日益复杂的网络攻击手段,单一的防护措施远远不够,必须建立**纵深防御(Defense in Depth)体系,并遵循最小权限(Least Privilege)**原则。

1.1 纵深防御体系

纵深防御的核心思想是:即使某一层防线被突破,仍然有其他层可以阻止攻击者进一步渗透。

┌─────────────────────────────────────────┐
│  物理安全层:机房门禁、BIOS密码、磁盘加密  │
├─────────────────────────────────────────┤
│  网络安全层:防火墙、IDS/IPS、网络隔离     │
├─────────────────────────────────────────┤
│  系统安全层:内核加固、文件权限、最小化安装  │
├─────────────────────────────────────────┤
│  应用安全层:AppArmor/SELinux、输入验证     │
├─────────────────────────────────────────┤
│  数据安全层:加密存储、备份、访问审计       │
└─────────────────────────────────────────┘

1.2 最小权限原则

  • 用户权限最小化:禁用 root 直接登录,使用 sudo 按需提权

  • 服务权限最小化:服务以低权限用户运行,限制文件系统访问范围

  • 网络权限最小化:仅开放必要端口,默认拒绝所有入站连接

  • 进程权限最小化:使用 capabilities 代替完整 root 权限


二、系统加固

2.1 内核参数加固

通过 sysctl 调整内核参数,是系统加固的基础操作。

创建文件 /etc/sysctl.d/99-security.conf

# ========== 内核安全参数 ==========

# 禁用 IP 转发(非路由器场景)
net.ipv4.ip_forward = 0

# 禁用 ICMP 重定向接受
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.default.accept_redirects = 0
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.default.send_redirects = 0

# 启用反向路径过滤(防 IP 欺骗)
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.default.rp_filter = 1

# 忽略 ICMP 广播请求(防 Smurf 攻击)
net.ipv4.icmp_echo_ignore_broadcasts = 1

# 启用 SYN Cookie(防 SYN Flood)
net.ipv4.tcp_syncookies = 1

# 记录可疑数据包
net.ipv4.conf.all.log_martians = 1
net.ipv4.conf.default.log_martians = 1

# ========== 内核地址空间随机化(KASLR) ==========
kernel.kptr_restrict = 2
kernel.dmesg_restrict = 1
kernel.yama.ptrace_scope = 1

# ========== 文件系统安全 ==========
# 限制 core dump
fs.suid_dumpable = 0

# 限制 dmesg 访问
kernel.unprivileged_bpf_disabled = 1

应用配置:

# 验证配置语法
sudo sysctl --system

# 检查特定参数
sysctl net.ipv4.tcp_syncookies
sysctl kernel.dmesg_restrict

2.2 文件权限审计

# 查找全局可写的文件(排除 /proc、/sys、/dev)
sudo find / -xdev -type f -perm -0002 -not -path "/proc/*" -not -path "/sys/*" 2>/dev/null

# 查找全局可写的目录
sudo find / -xdev -type d -perm -0002 -not -path "/proc/*" -not -path "/tmp" -not -path "/var/tmp" 2>/dev/null

# 查找无属主的文件
sudo find / -xdev -nouser -o -nogroup 2>/dev/null

# 检查关键目录权限
sudo stat -c "%a %U %G %n" /etc/passwd /etc/shadow /etc/group /etc/gshadow
# 预期输出:
# 644 root root /etc/passwd
# 600 root root /etc/shadow
# 644 root root /etc/group
# 600 root root /etc/gshadow

2.3 SUID/SGID 审计

SUID/SGID 程序是提权攻击的常见入口,需要定期审计。

# 列出系统中所有 SUID 文件
sudo find / -xdev -type f -perm -4000 -ls 2>/dev/null

# 列出系统中所有 SGID 文件
sudo find / -xdev -type f -perm -2000 -ls 2>/dev/null

# 与白名单对比(推荐维护一份 SUID 白名单)
SUID_WHITELIST="/usr/bin/sudo /usr/bin/passwd /usr/bin/su /usr/bin/newgrp /usr/bin/chsh /usr/bin/chfn /usr/bin/gpasswd /usr/lib/openssh/ssh-keysign"

for f in $(find / -xdev -type f -perm -4000 2>/dev/null); do
    if ! echo "$SUID_WHITELIST" | grep -qw "$f"; then
        echo "[ALERT] 非白名单 SUID 文件: $f"
    fi
done

# 移除不需要的 SUID 位
sudo chmod u-s /path/to/unauthorized/suid/binary

三、用户安全

3.1 密码策略强化

编辑 /etc/security/pwquality.conf

# 最小密码长度
minlen = 12

# 至少包含的大写字母数
ucredit = -1

# 至少包含的小写字母数
lcredit = -1

# 至少包含的数字数
dcredit = -1

# 至少包含的特殊字符数
ocredit = -1

# 密码中允许的最大连续相同字符
maxrepeat = 3

# 新密码与旧密码至少不同的字符数
difok = 5

# 密码最大有效期(天)
maxdays = 90

# 密码最小使用天数(防止频繁更改后恢复旧密码)
mindays = 1

# 密码过期前警告天数
warndays = 14

编辑 /etc/login.defs

# 密码有效期
PASS_MAX_DAYS   90
PASS_MIN_DAYS   1
PASS_MIN_LEN    12
PASS_WARN_AGE   14

# 登录失败锁定
LOGIN_RETRIES   5
LOGIN_TIMEOUT   60

# 默认 umask
UMASK 027

3.2 PAM 配置加固

编辑 /etc/pam.d/common-auth(Ubuntu/Debian):

# 登录失败锁定:5次失败后锁定10分钟
auth required pam_tally2.so deny=5 unlock_time=600 onerr=fail

# 密码强度检查
auth required pam_pwquality.so retry=3
# 查看用户登录失败计数
sudo pam_tally2 --user username

# 重置用户锁定
sudo pam_tally2 --user username --reset

3.3 SSH 加固

编辑 /etc/ssh/sshd_config

# ========== SSH 安全加固 ==========

# 禁用 root 直接登录
PermitRootLogin no

# 仅允许指定用户登录
AllowUsers deployer admin

# 禁用密码认证,强制使用密钥
PasswordAuthentication no
PubkeyAuthentication yes

# 修改默认端口
Port 2222

# 限制认证尝试次数
MaxAuthTries 3

# 设置登录超时
LoginGraceTime 30

# 禁用空密码
PermitEmptyPasswords no

# 禁用 X11 转发
X11Forwarding no

# 禁用 TCP 转发(按需开启)
AllowTcpForwarding no

# 使用强加密算法
KexAlgorithms curve25519-sha256@libssh.org,diffie-hellman-group-exchange-sha256
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

# 限制访问来源(结合防火墙更佳)
# ListenAddress 10.0.0.1

# 启用严格模式
StrictModes yes

# 日志级别
LogLevel VERBOSE
# 验证配置
sudo sshd -t

# 重启服务
sudo systemctl restart sshd

四、网络加固

4.1 内核网络参数加固

/etc/sysctl.d/99-network-security.conf 中配置:

# ========== TCP/IP 栈加固 ==========

# SYN Cookie 防护(防 SYN Flood 攻击)
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_max_syn_backlog = 4096
net.ipv4.tcp_synack_retries = 2
net.ipv4.tcp_syn_retries = 2

# TIME_WAIT 优化
net.ipv4.tcp_fin_timeout = 15
net.ipv4.tcp_tw_reuse = 1

# 连接跟踪优化
net.netfilter.nf_conntrack_max = 65536
net.netfilter.nf_conntrack_tcp_timeout_established = 3600

# 限制 ICMP 速率(防 ICMP Flood)
net.ipv4.icmp_ratelimit = 100
net.ipv4.icmp_ratemask = 88089

# 禁用源路由
net.ipv4.conf.all.accept_source_route = 0
net.ipv4.conf.default.accept_source_route = 0

4.2 IPv6 安全处理

如果不需要 IPv6,建议禁用以减小攻击面:

# /etc/sysctl.d/99-disable-ipv6.conf
net.ipv6.conf.all.disable_ipv6 = 1
net.ipv6.conf.default.disable_ipv6 = 1
net.ipv6.conf.lo.disable_ipv6 = 1

如果需要保留 IPv6:

# 禁用 IPv6 路由器通告自动配置
net.ipv6.conf.all.accept_ra = 0
net.ipv6.conf.default.accept_ra = 0

# 禁用 IPv6 重定向
net.ipv6.conf.all.accept_redirects = 0
net.ipv6.conf.default.accept_redirects = 0

4.3 防火墙配置(iptables/nftables)

使用 nftables(推荐):

#!/usr/sbin/nft -f

flush ruleset

table inet filter {
    chain input {
        type filter hook input priority 0; policy drop;

        # 允许已建立连接
        ct state established,related accept

        # 允许 loopback
        iif lo accept

        # 允许 ICMP(限速)
        ip protocol icmp limit rate 10/second accept
        ip6 nexthdr icmpv6 limit rate 10/second accept

        # 允许 SSH(自定义端口)
        tcp dport 2222 ct state new limit rate 5/minute accept

        # 允许 HTTP/HTTPS
        tcp dport { 80, 443 } accept

        # 记录并丢弃其他流量
        log prefix "[nft-drop] " counter drop
    }

    chain forward {
        type filter hook forward priority 0; policy drop;
    }

    chain output {
        type filter hook output priority 0; policy accept;
    }
}
# 应用规则
sudo nft -f /etc/nftables.conf

# 查看当前规则
sudo nft list ruleset

# 持久化
sudo systemctl enable nftables

4.4 端口扫描防护

# 使用 iptables 限制端口扫描
# 检测到端口扫描后封禁 IP
sudo iptables -A INPUT -p tcp --tcp-flags ALL NONE -j DROP
sudo iptables -A INPUT -p tcp --tcp-flags ALL ALL -j DROP
sudo iptables -A INPUT -p tcp --tcp-flags ALL FIN,URG,PSH -j DROP
sudo iptables -A INPUT -p tcp --tcp-flags ALL SYN,RST,ACK,FIN,URG -j DROP
sudo iptables -A INPUT -p tcp --tcp-flags SYN,RST SYN,RST -j DROP
sudo iptables -A INPUT -p tcp --tcp-flags SYN,FIN SYN,FIN -j DROP

# 使用 fail2ban 自动封禁
sudo apt install -y fail2ban
sudo systemctl enable fail2ban

五、服务加固

5.1 systemd 服务安全配置

systemd 提供了丰富的安全特性,可以在服务单元文件中直接配置:

# /etc/systemd/system/myapp.service
[Unit]
Description=My Application
After=network.target

[Service]
Type=simple
User=www-data
Group=www-data

# ========== 安全加固配置 ==========

# 文件系统保护
ProtectSystem=strict
ProtectHome=true
ReadWritePaths=/var/lib/myapp /var/log/myapp
PrivateTmp=true

# 内核保护
ProtectKernelTunables=true
ProtectKernelModules=true
ProtectKernelLogs=true
ProtectControlGroups=true

# 能力限制
CapabilityBoundingSet=CAP_NET_BIND_SERVICE
AmbientCapabilities=CAP_NET_BIND_SERVICE
NoNewPrivileges=true

# 系统调用过滤
SystemCallFilter=@system-service
SystemCallArchitectures=native

# 网络限制
RestrictAddressFamilies=AF_INET AF_INET6 AF_UNIX
SocketBindDeny=any
SocketBindAllow=tcp:8080

# 其他限制
RestrictNamespaces=true
RestrictRealtime=true
RestrictSUIDSGID=true
LockPersonality=true
MemoryDenyWriteExecute=true
RemoveIPC=true

ExecStart=/usr/local/bin/myapp
Restart=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.target
# 重新加载 systemd 配置
sudo systemctl daemon-reload

# 查看服务安全状态
systemctl show myapp.service | grep -E "Protect|Restrict|Private|NoNew"

# 分析服务安全评分
sudo systemd-analyze security myapp.service

5.2 AppArmor 配置

AppArmor 是 Ubuntu/Debian 默认的强制访问控制系统:

# 查看 AppArmor 状态
sudo aa-status

# 为 Nginx 创建自定义配置文件
sudo aa-genprof /usr/sbin/nginx

手动编写 AppArmor 配置文件 /etc/apparmor.d/usr.local.bin.myapp

#include <tunables/global>

/usr/local/bin/myapp {
  #include <abstractions/base>
  #include <abstractions/nameservice>
  #include <abstractions/openssl>

  # 程序二进制
  /usr/local/bin/myapp mr,

  # 配置文件(只读)
  /etc/myapp/** r,

  # 数据目录(读写)
  /var/lib/myapp/** rw,
  /var/log/myapp/** rw,

  # 临时文件
  /tmp/myapp.* rw,

  # 网络访问
  network inet stream,
  network inet dgram,

  # 拒绝危险操作
  deny /etc/shadow r,
  deny /etc/passwd w,
  deny /proc/*/mem rw,
  deny capability sys_ptrace,
  deny capability sys_admin,
}
# 加载配置
sudo apparmor_parser -r /etc/apparmor.d/usr.local.bin.myapp

# 切换到 enforce 模式
sudo aa-enforce /usr/local/bin/myapp

# 查看拒绝日志
sudo journalctl -k | grep apparmor="DENIED"

5.3 SELinux 配置(CentOS/RHEL)

# 查看 SELinux 状态
getenforce
sestatus

# 启用 SELinux(需要重启)
sudo sed -i 's/SELINUX=disabled/SELINUX=enforcing/' /etc/selinux/config

# 查看进程安全上下文
ps auxZ | grep httpd

# 修改文件安全上下文
sudo semanage fcontext -a -t httpd_sys_content_t "/var/www/myapp(/.*)?"
sudo restorecon -Rv /var/www/myapp

# 允许特定网络连接
sudo setsebool -P httpd_can_network_connect 1

# 查看 SELinux 拒绝日志
sudo ausearch -m avc -ts recent
sudo sealert -a /var/log/audit/audit.log

六、漏洞扫描

6.1 Lynis 系统审计

# 安装 Lynis
sudo apt install -y lynis    # Debian/Ubuntu
# 或
sudo yum install -y lynis    # CentOS/RHEL

# 执行完整系统审计
sudo lynis audit system

# 仅检查安全加固项
sudo lynis audit system --tests-from-group "security"

# 查看建议
sudo lynis audit system --quick 2>&1 | grep "Suggestion"

# 输出报告到文件
sudo lynis audit system --logfile /var/log/lynis.log --report-file /var/log/lynis-report.dat

6.2 OpenVAS 漏洞扫描

# 安装 OpenVAS(Greenbone Community Edition)
sudo apt install -y gvm
sudo gvm-setup

# 启动服务
sudo gvm-start

# 通过 Web 界面(https://127.0.0.1:9392)配置扫描任务
# 或使用命令行
sudo gvm-cli --gmp-username admin --gmp-password <password> \
  socket --xml "<create_target><name>Server Group</name><hosts>10.0.0.0/24</hosts></create_target>"

6.3 Trivy 容器镜像扫描

# 安装 Trivy
sudo apt install -y trivy

# 扫描本地镜像
trivy image myapp:latest

# 扫描远程镜像
trivy image registry.example.com/myapp:v1.2.3

# 扫描文件系统漏洞
trivy fs --security-checks vuln,config /path/to/project

# 扫描 Kubernetes 集群
trivy k8s --report summary cluster

# 扫描 IaC 配置(Terraform/CloudFormation)
trivy config /path/to/terraform/

# 输出 JSON 格式报告
trivy image --format json --output report.json myapp:latest

# 仅显示高危和严重漏洞
trivy image --severity HIGH,CRITICAL myapp:latest

七、入侵检测

7.1 AIDE 文件完整性监控

# 安装 AIDE
sudo apt install -y aide

# 初始化数据库
sudo aideinit

# 将新数据库设为正式数据库
sudo cp /var/lib/aide/aide.db.new /var/lib/aide/aide.db

# 手动检查
sudo aide.wrapper --check

# 配置定时任务(每天凌晨 2 点)
echo '0 2 * * * root /usr/bin/aide.wrapper --check | mail -s "AIDE Report" admin@example.com' | sudo tee /etc/cron.d/aide

# AIDE 配置文件 /etc/aide/aide.conf 关键规则示例:
# NORMAL = p+i+n+u+g+s+m+c+acl+selinux+xattrs+sha256
# /boot NORMAL
# /bin NORMAL
# /sbin NORMAL
# /lib NORMAL
# /etc NORMAL
# /var/log NORMAL

7.2 Wazuh 主机入侵检测

# 安装 Wazuh Agent
curl -sO https://packages.wazuh.com/4.x/wazuh-install.sh
sudo bash wazuh-install.sh --wazuh-agent

# 配置 agent 连接 Wazuh Manager
sudo sed -i 's/MANAGER_IP/10.0.0.100/' /var/ossec/etc/ossec.conf

# 启动服务
sudo systemctl enable wazuh-agent
sudo systemctl start wazuh-agent

# Wazuh 配置关键规则示例(/var/ossec/etc/ossec.conf):
<ossec_config>
  <global>
    <logall>yes</logall>
    <logall_json>yes</logall_json>
  </global>

  <syscheck>
    <frequency>3600</frequency>
    <directories check_all="yes" realtime="yes">/etc,/usr/bin,/usr/sbin</directories>
    <directories check_all="yes">/bin,/sbin</directories>
    <ignore>/etc/mtab</ignore>
    <ignore>/etc/hosts.deny</ignore>
  </syscheck>

  <localfile>
    <log_format>syslog</log_format>
    <location>/var/log/auth.log</location>
  </localfile>

  <localfile>
    <log_format>syslog</log_format>
    <location>/var/log/syslog</location>
  </localfile>
</ossec_config>

7.3 rkhunter Rootkit 检测

# 安装 rkhunter
sudo apt install -y rkhunter

# 更新检测数据库
sudo rkhunter --update

# 执行系统检查
sudo rkhunter --check --skip-keypress

# 查看日志
sudo cat /var/log/rkhunter.log | grep "Warning"

# 配置定时检查
echo '0 3 * * * root /usr/bin/rkhunter --check --skip-keypress --report-warnings-only | mail -s "rkhunter Report" admin@example.com' | sudo tee /etc/cron.d/rkhunter

7.4 auditd 审计系统

# 安装 auditd
sudo apt install -y auditd audispd-plugins

# 配置审计规则 /etc/audit/rules.d/security.rules
# 监控关键文件修改
-w /etc/passwd -p wa -k identity
-w /etc/group -p wa -k identity
-w /etc/shadow -p wa -k identity
-w /etc/sudoers -p wa -k sudoers
-w /etc/ssh/sshd_config -p wa -k sshd_config

# 监控命令执行
-a always,exit -F arch=b64 -S execve -k commands

# 监控特权操作
-a always,exit -F arch=b64 -S chmod -S fchmod -S fchmodat -k perm_mod
-a always,exit -F arch=b64 -S chown -S fchown -S lchown -k owner_mod

# 监控网络连接
-a always,exit -F arch=b64 -S connect -k network_connect

# 监控内核模块加载
-a always,exit -F arch=b64 -S init_module -S finit_module -k modules

# 设置审计缓冲区大小
-b 8192

# 使配置不可更改(需要重启才能修改)
-e 2
# 重新加载审计规则
sudo augenrules --load

# 搜索审计日志
sudo ausearch -k identity -ts today
sudo ausearch -k commands -x /bin/su
sudo ausearch -k network_connect

# 生成审计报告
sudo aureport --summary
sudo aureport --auth --summary
sudo aureport --login --summary
sudo aureport --file --summary

八、安全基线

8.1 CIS 基线

CIS(Center for Internet Security)基准是业界公认的安全配置标准:

# 使用 CIS-CAT 工具评估
# 下载 CIS-CAT Pro 或使用开源替代

# 使用 Lynis 进行 CIS 相关检查
sudo lynis audit system --profile /etc/lynis/cis.prf

# CIS 关键检查项手动验证
# 1. 文件系统配置
mount | grep -E "nodev|nosuid|noexec" /tmp
mount | grep -E "nodev|nosuid|noexec" /var/tmp

# /etc/fstab 中配置
# tmpfs /tmp tmpfs defaults,nosuid,nodev,noexec 0 0
# tmpfs /var/tmp tmpfs defaults,nosuid,nodev,noexec 0 0

# 2. 确保核心转储受限
echo "* hard core 0" | sudo tee -a /etc/security/limits.d/99-core.conf

# 3. 确保默认 umask 为 027
echo "umask 027" | sudo tee -a /etc/profile.d/umask.sh

8.2 等保 2.0 合规

等保 2.0(网络安全等级保护 2.0)是国内信息安全的重要合规标准:

# ========== 等保 2.0 技术要求检查 ==========

# 身份鉴别
# 1. 密码复杂度策略
grep -E "^(minlen|ucredit|lcredit|dcredit|ocredit)" /etc/security/pwquality.conf

# 2. 登录失败处理
grep "pam_tally2" /etc/pam.d/common-auth

# 3. 远程管理加密
grep "Protocol" /etc/ssh/sshd_config

# 访问控制
# 4. 最小权限检查
grep "^PermitRootLogin" /etc/ssh/sshd_config

# 5. 默认账户检查
awk -F: '$3 == 0 {print $1}' /etc/passwd
awk -F: '$2 == "" {print $1}' /etc/shadow

# 安全审计
# 6. 审计日志完整性
sudo systemctl status auditd
sudo ausearch -ts today | wc -l

# 7. 日志保留策略(至少 6 个月)
grep -E "max_log_file_action|max_log_file " /etc/audit/auditd.conf

# 入侵防范
# 8. 最小化服务检查
sudo systemctl list-unit-files --type=service --state=enabled

# 9. 端口开放检查
sudo ss -tlnp

九、应急响应

9.1 应急响应流程

发现异常 → 初步研判 → 隔离主机 → 证据保全 → 深入分析 → 清除威胁 → 恢复服务 → 复盘总结

9.2 应急响应命令速查

# ========== 第一时间:快速排查 ==========

# 查看当前登录用户
w
who
last -20

# 查看最近登录记录
lastlog
lastb -20    # 失败的登录

# 查看可疑进程
ps auxf
ps aux | grep -v "^\[" | sort -nrk 3 | head -20    # CPU Top 20
ps aux | grep -v "^\[" | sort -nrk 4 | head -20    # 内存 Top 20

# 查看网络连接
ss -tlnp                    # 监听端口
ss -tnp                     # 已建立连接
ss -tnp | awk '{print $5}' | cut -d: -f1 | sort | uniq -c | sort -rn  # 连接数 Top

# 查看定时任务
crontab -l
sudo crontab -l
ls -la /etc/cron.*
cat /var/spool/cron/*

# 查看最近修改的文件
find / -xdev -mmin -60 -type f 2>/dev/null
find /etc -xdev -mtime -1 -type f 2>/dev/null

# 查看可疑用户
awk -F: '$3 == 0 {print $1}' /etc/passwd
grep -E "^[^:]+::" /etc/shadow    # 无密码账户

# 查看加载的内核模块
lsmod

9.3 证据保全

# 创建内存镜像(需要 LiME 或 AVML)
sudo avml /evidence/memory.lime

# 保存关键日志
sudo mkdir -p /evidence/$(hostname)-$(date +%Y%m%d%H%M%S)
EVIDENCE_DIR="/evidence/$(hostname)-$(date +%Y%m%d%H%M%S)"

sudo cp /var/log/auth.log $EVIDENCE_DIR/
sudo cp /var/log/syslog $EVIDENCE_DIR/
sudo cp /var/log/audit/audit.log $EVIDENCE_DIR/
sudo cp /var/log/kern.log $EVIDENCE_DIR/

# 保存网络状态
sudo ss -tlnp > $EVIDENCE_DIR/ss_listening.txt
sudo ss -tnp > $EVIDENCE_DIR/ss_connections.txt
sudo iptables -L -n -v > $EVIDENCE_DIR/iptables.txt

# 保存进程状态
sudo ps auxf > $EVIDENCE_DIR/ps_auxf.txt
sudo lsmod > $EVIDENCE_DIR/lsmod.txt

# 计算哈希(保证证据完整性)
cd $EVIDENCE_DIR && sha256sum * > checksums.sha256

# 打包并加密
sudo tar czf - $EVIDENCE_DIR | gpg --encrypt -r admin@example.com > $EVIDENCE_DIR.tar.gz.gpg

十、安全加固自动化脚本

以下是一个综合性的安全加固自动化脚本,可用于批量服务器加固:

#!/bin/bash
# ============================================================
# 服务器安全加固脚本
# 适用系统:Ubuntu 20.04+ / Debian 11+
# 使用方法:sudo bash harden.sh
# ============================================================

set -euo pipefail
LOG_FILE="/var/log/security-hardening-$(date +%Y%m%d%H%M%S).log"

log() {
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE"
}

check_root() {
    if [[ $EUID -ne 0 ]]; then
        echo "错误:请使用 root 权限运行此脚本"
        exit 1
    fi
}

# ========== 1. 系统更新 ==========
harden_system_update() {
    log "[1/10] 更新系统软件包..."
    apt update -qq && apt upgrade -y -qq
    apt autoremove -y -qq
    log "系统更新完成"
}

# ========== 2. 内核参数加固 ==========
harden_kernel() {
    log "[2/10] 加固内核参数..."
    cat > /etc/sysctl.d/99-security.conf << 'EOF'
net.ipv4.ip_forward = 0
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.default.accept_redirects = 0
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.default.send_redirects = 0
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.default.rp_filter = 1
net.ipv4.icmp_echo_ignore_broadcasts = 1
net.ipv4.tcp_syncookies = 1
net.ipv4.conf.all.log_martians = 1
net.ipv4.conf.default.log_martians = 1
net.ipv6.conf.all.accept_ra = 0
net.ipv6.conf.default.accept_ra = 0
net.ipv6.conf.all.accept_redirects = 0
net.ipv6.conf.default.accept_redirects = 0
kernel.kptr_restrict = 2
kernel.dmesg_restrict = 1
kernel.yama.ptrace_scope = 1
fs.suid_dumpable = 0
kernel.unprivileged_bpf_disabled = 1
EOF
    sysctl --system > /dev/null 2>&1
    log "内核参数加固完成"
}

# ========== 3. SSH 加固 ==========
harden_ssh() {
    log "[3/10] 加固 SSH 配置..."
    cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak.$(date +%Y%m%d)

    cat > /etc/ssh/sshd_config.d/99-hardening.conf << 'EOF'
PermitRootLogin no
PasswordAuthentication no
PermitEmptyPasswords no
X11Forwarding no
MaxAuthTries 3
LoginGraceTime 30
ClientAliveInterval 300
ClientAliveCountMax 2
Protocol 2
LogLevel VERBOSE
EOF

    sshd -t && systemctl restart sshd
    log "SSH 加固完成"
}

# ========== 4. 密码策略 ==========
harden_password() {
    log "[4/10] 配置密码策略..."
    cat > /etc/security/pwquality.conf << 'EOF'
minlen = 12
ucredit = -1
lcredit = -1
dcredit = -1
ocredit = -1
maxrepeat = 3
difok = 5
EOF

    sed -i 's/^PASS_MAX_DAYS.*/PASS_MAX_DAYS   90/' /etc/login.defs
    sed -i 's/^PASS_MIN_DAYS.*/PASS_MIN_DAYS   1/' /etc/login.defs
    sed -i 's/^PASS_MIN_LEN.*/PASS_MIN_LEN    12/' /etc/login.defs
    sed -i 's/^PASS_WARN_AGE.*/PASS_WARN_AGE   14/' /etc/login.defs
    log "密码策略配置完成"
}

# ========== 5. 文件权限加固 ==========
harden_permissions() {
    log "[5/10] 加固文件权限..."
    chmod 644 /etc/passwd
    chmod 600 /etc/shadow
    chmod 644 /etc/group
    chmod 600 /etc/gshadow
    chmod 600 /etc/ssh/sshd_config
    chmod 700 /root

    # 设置 umask
    echo "umask 027" > /etc/profile.d/umask.sh
    log "文件权限加固完成"
}

# ========== 6. 安装安全工具 ==========
harden_install_tools() {
    log "[6/10] 安装安全工具..."
    apt install -y -qq \
        fail2ban \
        aide \
        rkhunter \
        lynis \
        auditd \
        audispd-plugins \
        unattended-upgrades \
        apt-listchanges
    log "安全工具安装完成"
}

# ========== 7. 配置自动更新 ==========
harden_auto_updates() {
    log "[7/10] 配置自动安全更新..."
    cat > /etc/apt/apt.conf.d/50unattended-upgrades << 'EOF'
Unattended-Upgrade::Allowed-Origins {
    "${distro_id}:${distro_codename}-security";
};
Unattended-Upgrade::AutoFixInterruptedDpkg "true";
Unattended-Upgrade::Remove-Unused-Kernel-Packages "true";
Unattended-Upgrade::Remove-Unused-Dependencies "true";
Unattended-Upgrade::Automatic-Reboot "false";
EOF

    cat > /etc/apt/apt.conf.d/20auto-upgrades << 'EOF'
APT::Periodic::Update-Package-Lists "1";
APT::Periodic::Unattended-Upgrade "1";
APT::Periodic::AutocleanInterval "7";
EOF
    log "自动安全更新配置完成"
}

# ========== 8. 配置 auditd ==========
harden_auditd() {
    log "[8/10] 配置审计系统..."
    cat > /etc/audit/rules.d/99-security.rules << 'EOF'
-w /etc/passwd -p wa -k identity
-w /etc/group -p wa -k identity
-w /etc/shadow -p wa -k identity
-w /etc/sudoers -p wa -k sudoers
-w /etc/ssh/sshd_config -p wa -k sshd_config
-a always,exit -F arch=b64 -S execve -k commands
-a always,exit -F arch=b64 -S chmod -S fchmod -k perm_mod
-a always,exit -F arch=b64 -S connect -k network_connect
-a always,exit -F arch=b64 -S init_module -S finit_module -k modules
-b 8192
-e 2
EOF

    systemctl enable auditd
    systemctl restart auditd
    log "审计系统配置完成"
}

# ========== 9. 配置 fail2ban ==========
harden_fail2ban() {
    log "[9/10] 配置 fail2ban..."
    cat > /etc/fail2ban/jail.local << 'EOF'
[DEFAULT]
bantime = 3600
findtime = 600
maxretry = 5
banaction = nftables-multiport

[sshd]
enabled = true
port = ssh
filter = sshd
logpath = /var/log/auth.log
maxretry = 3
bantime = 7200
EOF

    systemctl enable fail2ban
    systemctl restart fail2ban
    log "fail2ban 配置完成"
}

# ========== 10. 清理和验证 ==========
harden_cleanup() {
    log "[10/10] 清理和验证..."

    # 禁用不需要的服务
    for svc in avahi-daemon cups bluetooth; do
        if systemctl is-enabled "$svc" 2>/dev/null | grep -q enabled; then
            systemctl disable --now "$svc" 2>/dev/null || true
            log "已禁用服务: $svc"
        fi
    done

    # 初始化 AIDE
    aideinit 2>/dev/null && log "AIDE 数据库初始化完成" || log "AIDE 初始化跳过"

    # 验证关键配置
    log "========== 加固验证 =========="
    log "SSH PermitRootLogin: $(grep -c 'PermitRootLogin no' /etc/ssh/sshd_config.d/*.conf 2>/dev/null || echo '未配置')"
    log "审计服务状态: $(systemctl is-active auditd)"
    log "fail2ban 状态: $(systemctl is-active fail2ban)"
    log "加固完成!详细日志:$LOG_FILE"
}

# ========== 主流程 ==========
main() {
    echo "=========================================="
    echo "  服务器安全加固脚本"
    echo "  $(date)"
    echo "=========================================="

    check_root
    harden_system_update
    harden_kernel
    harden_ssh
    harden_password
    harden_permissions
    harden_install_tools
    harden_auto_updates
    harden_auditd
    harden_fail2ban
    harden_cleanup

    echo ""
    echo "=========================================="
    echo "  安全加固完成!"
    echo "  请确保已配置 SSH 密钥后再重启 sshd"
    echo "=========================================="
}

main "$@"

总结

服务器安全加固是一个持续的过程,而非一次性任务。核心要点:

维度

关键措施

系统层

内核参数、文件权限、SUID 审计

用户层

密码策略、PAM、SSH 加固

网络层

防火墙、SYN Cookie、端口最小化

服务层

systemd 安全、AppArmor/SELinux

检测层

漏洞扫描、入侵检测、审计日志

合规层

CIS 基线、等保 2.0

应急层

响应流程、证据保全

建议定期执行的检查周期:

  • 每日:检查审计日志、fail2ban 封禁记录

  • 每周:运行 Lynis 审计、AIDE 文件完整性检查

  • 每月:Trivy 镜像扫描、用户权限审计、SUID 白名单核对

  • 每季度:OpenVAS 漏洞扫描、安全基线评估、应急演练


📌 本文为「服务器运维笔记」系列第 21 篇,涵盖服务器安全加固的核心实践。如需了解更多细节,可参考各工具官方文档。