一、安全加固概述
服务器安全加固是运维工作中最核心的环节之一。面对日益复杂的网络攻击手段,单一的防护措施远远不够,必须建立**纵深防御(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_restrict2.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/gshadow2.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 0273.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 --reset3.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 = 04.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 = 04.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 nftables4.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.service5.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.dat6.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 NORMAL7.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/rkhunter7.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.sh8.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 # 无密码账户
# 查看加载的内核模块
lsmod9.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 "$@"总结
服务器安全加固是一个持续的过程,而非一次性任务。核心要点:
建议定期执行的检查周期:
每日:检查审计日志、fail2ban 封禁记录
每周:运行 Lynis 审计、AIDE 文件完整性检查
每月:Trivy 镜像扫描、用户权限审计、SUID 白名单核对
每季度:OpenVAS 漏洞扫描、安全基线评估、应急演练
📌 本文为「服务器运维笔记」系列第 21 篇,涵盖服务器安全加固的核心实践。如需了解更多细节,可参考各工具官方文档。