
1. 项目概述为什么你的VPS需要一个“安全体检”最近在折腾一台新的VPS准备部署点个人项目。服务器刚到手系统是最新的发行版一切看起来都很干净。但作为一个老运维我心里清楚这种“干净”只是表象。默认配置里可能藏着不安全的服务未更新的软件包可能存在已知漏洞甚至防火墙规则都可能过于宽松。手动去检查每一项那太费时了而且容易遗漏。这时候一个自动化、系统性的安全审计脚本就成了刚需。这个“7分钟上手VPS安全审计脚本”项目核心就是帮你快速给Linux服务器做一次全面的“安全体检”。它不是一个复杂的入侵检测系统而是一个主动的、预防性的检查工具。通过运行一系列预定义的检查项它能帮你快速发现系统配置中常见的安全隐患比如不必要的开放端口、弱密码策略、存在漏洞的软件版本、可疑的用户和进程等等。对于刚拿到手的VPS、或者定期维护的服务器来说花几分钟跑一遍这个脚本就像给服务器做一次快速健康检查能有效降低被“黑”的风险。尤其对于个人开发者、初创团队或者运维新手可能没有精力去部署企业级的安全方案但这个脚本提供了一个轻量级、可立即上手的起点。它基于Bash编写几乎兼容所有主流的Linux发行版如Ubuntu, CentOS, Debian无需安装复杂的依赖下载即用。接下来我会详细拆解这个脚本的设计思路、核心检查项、如何定制它以适应你的环境以及在实际操作中我踩过的那些坑。2. 脚本核心设计与检查逻辑拆解一个有效的安全审计脚本其价值不在于代码有多复杂而在于检查项是否切中要害以及逻辑是否清晰可扩展。我设计的这个脚本其核心思想是“分层检查结果聚合”主要分为以下几个层面2.1 系统信息与基础配置审计这是审计的起点目的是了解你的“战场”。脚本会首先收集并展示系统的基本信息如主机名、内核版本、发行版、运行时间等。这不仅能让你确认审计对象某些信息本身也是安全线索。例如一个运行了非常久却没有重启过的系统可能意味着内核从未更新过存在潜在风险。更关键的是对基础安全配置的检查密码策略检查通过检查/etc/login.defs和etc/pam.d/common-password等文件审计密码最小长度、过期时间、历史记录等策略是否符合安全规范。很多默认安装的系统密码策略是极其宽松的。SSH配置审计SSH是进入服务器的首要通道也是攻击者的首要目标。脚本会检查/etc/ssh/sshd_config重点关注PermitRootLogin是否允许root直接登录。最佳实践是设置为no或prohibit-password。PasswordAuthentication是否允许密码认证。在配置了SSH密钥后建议关闭能极大抵御暴力破解。Port是否使用默认的22端口。修改为非常用端口能减少自动化扫描的滋扰。AllowUsers/DenyUsers是否设置了访问白名单或黑名单。2.2 网络与服务暴露面分析服务器对外开放了什么决定了攻击面有多大。这部分审计至关重要。网络连接与监听端口使用netstat或更现代的ss命令列出所有活跃的网络连接和监听端口。重点是找出那些监听在0.0.0.0即所有接口上的服务。你需要问自己这个端口上的服务是必须对外提供的吗如果不是应该将其绑定到127.0.0.1或直接关闭。防火墙规则检查检查iptables、firewalld或ufw的规则。确认是否有默认的DROP或REJECT策略开放的必要端口是否精确是否存在允许任意源IP访问的宽松规则。一个常见的错误是只设置了输出规则却忘了设置严格的输入规则。非必要服务排查使用systemctl或service命令检查系统启动的服务。对于像telnet、rsh、vsftpd如果不需要FTP等古老或不安全的服务以及像cups打印服务这种在服务器上通常用不到的服务应考虑禁用并停止。2.3 文件系统与权限安全扫描攻击者提权或维持访问往往依赖于不当的文件权限。SUID/SGID文件查找查找设置了SUIDSet User ID或SGIDSet Group ID位的文件。这些文件在执行时会以文件所有者或所属组的权限运行。如果像find、vim、bash这样的常见命令被设置了SUID将是严重的提权漏洞。脚本会找出这些文件并由你判断其合理性。世界可写文件检查查找任何用户都可写ow的文件和目录特别是在系统路径如/usr/bin、/etc或用户主目录下。这可能导致恶意软件植入或配置被篡改。关键配置文件权限检查/etc/passwd、/etc/shadow、/etc/sudoers等关键文件的权限。/etc/shadow应仅对root可读/etc/sudoers通常应为440权限。2.4 用户账户与日志监控异常的用户和寂静的日志都是入侵的迹象。用户账户审计检查/etc/passwd寻找UID为0root权限的非root用户、空密码用户x字段后无内容、或者默认的、不使用的测试账户如test,guest。最近登录记录通过last、lastb命令查看成功和失败的登录记录分析是否有来自异常IP或时间的登录尝试。日志文件检查提示你检查重要的日志文件如/var/log/auth.logDebian/Ubuntu或/var/log/secureCentOS/RHEL以查看认证信息/var/log/syslog或journalctl查看系统日志。脚本可以引导你使用grep过滤错误、失败等关键词。注意审计脚本本身不应直接修改系统配置。它的职责是“发现并报告”。所有修复操作都应在你明确理解影响后手动或在受控的自动化流程中完成。脚本的输出应该是清晰、可读的报告明确指出问题、位置和建议操作。3. 脚本实操从下载到生成审计报告理论讲完了我们直接上手。假设你有一台刚初始化好的Ubuntu 22.04 VPS。3.1 获取与运行审计脚本首先登录你的VPS。我强烈建议在一个非生产环境或刚创建的快照上先测试。# 1. 下载脚本这里假设脚本托管在一个安全的raw链接中请务必从可信来源获取 wget -O security_audit.sh https://your-trusted-domain/path/to/security_audit.sh # 2. 赋予脚本执行权限 chmod x security_audit.sh # 3. 以root权限运行因为很多检查需要root权限才能读取所有信息 sudo ./security_audit.sh如果脚本是你自己编写的或者是从GitHub等平台克隆的确保先浏览一下代码理解它将要执行什么命令这是一种基本的安全习惯。3.2 解读脚本输出报告脚本运行后会在终端输出彩色如果支持的格式化报告并通常建议将结果重定向到文件以便仔细审查sudo ./security_audit.sh | tee audit_report_$(date %Y%m%d_%H%M%S).txt一份典型的报告会按章节划分例如[] 系统概览主机名: myserver 发行版: Ubuntu 22.04.3 LTS 内核版本: 5.15.0-91-generic 运行时间: 0 days, 1 hour, 23 minutes这部分正常显示这是一台新机器。[!] SSH 配置检查发现潜在问题 - /etc/ssh/sshd_config: PermitRootLogin 设置为 yes (建议设置为 no) - /etc/ssh/sshd_config: PasswordAuthentication 设置为 yes (建议在配置密钥后设置为 no)这里标出了两个高风险项。允许root密码登录是很大的风险。[] 网络监听端口LISTEN 端口 0.0.0.0:22 - sshd (必须但需加固) 0.0.0.0:80 - nginx (业务需要) 127.0.0.1:631 - cupsd (建议非必要服务监听在公网)这里发现cups打印服务监听在本地回环地址虽然不在公网但在服务器上通常无用可以考虑关闭。[!] 文件权限检查发现世界可写文件 - /tmp/test_file (临时目录风险较低但需注意内容) - /var/www/html/upload (业务上传目录需结合业务评估) 发现SUID文件 - /usr/bin/passwd (正常) - /usr/bin/sudo (正常) - /usr/bin/find (异常常见命令不应设SUID)最后一个find命令的SUID位非常可疑很可能是之前被入侵留下的后门需要立即调查。3.3 根据报告进行安全加固报告不是终点根据报告采取行动才是。以上述输出为例加固SSHsudo vim /etc/ssh/sshd_config # 找到并修改 # PermitRootLogin no # PasswordAuthentication no # 可选Port 2222 修改后需在防火墙开放新端口 sudo systemctl restart sshd重要在关闭密码认证和重启SSH前请务必确认你的SSH公钥已正确添加到~/.ssh/authorized_keys中否则你将无法再次登录关闭非必要服务# 禁用并停止cups服务 sudo systemctl stop cups sudo systemctl disable cups # 使用ss -tulnp再次确认端口631已关闭处理可疑的SUID文件# 首先检查这个find命令的完整性 ls -la /usr/bin/find # 对比其大小、修改时间与同版本系统是否一致 # 使用dpkg -S /usr/bin/find(Debian/Ubuntu)或rpm -qf /usr/bin/find(RHEL/CentOS)查看它属于哪个包 # 如果确认被篡改从官方软件源重新安装 sudo apt install --reinstall findutils # Ubuntu/Debian # 或者直接移除SUID位如果业务确实不需要 sudo chmod u-s /usr/bin/find设置防火墙以UFW为例sudo ufw default deny incoming # 默认拒绝所有入站 sudo ufw default allow outgoing # 允许所有出站 sudo ufw allow 22/tcp # 或你修改后的SSH端口 sudo ufw allow 80/tcp sudo ufw allow 443/tcp sudo ufw enable sudo ufw status verbose # 查看规则4. 高级定制与脚本扩展基础脚本提供了通用检查但每台服务器的环境不同。让脚本适应你的需求才是发挥其最大威力的关键。4.1 添加自定义检查项假设你的服务器上运行着一个特定的应用其配置文件在/opt/myapp/config.ini且该文件不应被Web用户修改。你可以在脚本的“文件权限检查”部分后添加echo -e \n[] 自定义应用配置检查 CONFIG_FILE/opt/myapp/config.ini if [ -f $CONFIG_FILE ]; then perms$(stat -c %a $CONFIG_FILE) if [ $perms -ne 600 ]; then echo [!] 发现配置问题$CONFIG_FILE 权限为 $perms建议设置为 600 (仅所有者可读写)。 else echo [√] $CONFIG_FILE 权限检查通过。 fi else echo [i] 自定义配置文件 $CONFIG_FILE 不存在。 fi4.2 集成软件漏洞扫描基础版本检查软件是否更新但我们可以集成像lynis这样的专业审计工具或调用系统包管理器的安全更新检查。echo -e \n[] 系统安全更新检查 # 对于Ubuntu/Debian if command -v apt-get /dev/null; then echo 检查可用安全更新... apt list --upgradable 2/dev/null | grep -i security fi # 对于CentOS/RHEL if command -v yum /dev/null; then echo 检查安全更新... yum check-update --security fi你也可以在脚本中调用lynis audit system并解析其关键建议但注意lynis本身需要安装。4.3 实现日志分析与告警让脚本不仅能检查当前状态还能分析历史日志发现入侵尝试的蛛丝马迹。echo -e \n[] 近期失败登录尝试分析 FAILED_LOGINS$(grep Failed password /var/log/auth.log | tail -50) if [ -n $FAILED_LOGINS ]; then echo 最近50条失败登录记录 echo $FAILED_LOGINS | awk {print $1,$2,$3,来自,$11,用户,$9} | sort | uniq -c | sort -nr echo 提示频繁的失败尝试可能意味着暴力破解。 else echo 未在默认日志中找到失败记录。 fi更进一步你可以让脚本在发现极端情况如单IP大量失败尝试时自动调用iptables或fail2ban-client临时封禁IP。4.4 生成HTML或邮件报告对于需要定期巡检多台服务器的情况文本报告可能不够直观。可以修改脚本使其生成HTML报告并通过邮件发送。# 在脚本开头定义报告文件 REPORT_HTML/tmp/security_audit_$(hostname)_$(date %Y%m%d).html # 输出HTML头部 cat $REPORT_HTML EOF htmlheadtitle安全审计报告 - $(hostname)/title/headbody h1服务器安全审计报告/h1 p主机$(hostname)/p p时间$(date)/p hr EOF # 在每个检查环节将echo输出重定向并格式化为HTML echo h2SSH配置检查/h2 $REPORT_HTML if [ $permit_root yes ]; then echo p stylecolor:red;[!] PermitRootLogin 为 yes建议修改。/p $REPORT_HTML fi # ... 其他检查 # 结束HTML echo /body/html $REPORT_HTML # 使用mail命令发送需要配置好邮件系统 # mail -s 安全审计报告 $(hostname) adminyourdomain.com $REPORT_HTML5. 常见问题、排查技巧与避坑指南在实际使用和定制脚本的过程中我遇到了不少典型问题这里总结一下希望能帮你少走弯路。5.1 脚本运行报错或输出不完整问题执行脚本时提示“Permission denied”或某些命令找不到。排查权限问题确保用sudo运行或者你当前是root用户。许多系统信息文件如/etc/shadow只有root可读。命令路径问题脚本中尽量使用命令的绝对路径如/usr/bin/netstat或者在最开始使用export PATH/usr/bin:/bin:/sbin...定义PATH变量。不同的Linux发行版或容器环境命令位置可能不同。解释器问题脚本首行必须是#!/bin/bash。在某些极简系统如Alpine Linux中默认shell可能是ash某些Bash特性会不支持。问题输出混乱颜色代码显示为乱码。排查脚本中使用了ANSI颜色代码如\e[31m来高亮显示。如果终端不支持或者你将输出重定向到文件后再用cat查看就会显示乱码。可以在脚本中增加一个判断# 判断是否在支持颜色的终端中运行 if [ -t 1 ]; then RED\033[0;31m GREEN\033[0;32m NC\033[0m # No Color else RED GREEN NC fi echo -e ${RED}[!] 警告信息${NC}5.2 审计结果误报与漏报问题脚本报告某个服务“不安全”但该服务是我的业务核心不能关闭。处理这是审计脚本的常态。脚本的职责是提示风险而不是做出决策。例如它报告Nginx正在监听80端口。对于Web服务器这是正常的。你需要结合上下文判断。一个好的脚本应该在报告时给出理由和通用建议最终的处置权在你手中。你可以在自定义脚本时将已知的业务必要服务如nginx、mysql加入白名单避免重复告警。问题脚本没有发现某个已知的安全漏洞。排查检查点过时安全威胁在变化脚本的检查项也需要定期更新。例如新的漏洞如Log4j需要特定的检查命令。你需要关注安全社区更新你的脚本逻辑。深度不足基础脚本主要做“配置审计”无法进行“漏洞扫描”如软件0day或“行为分析”如检测挖矿进程。对于更深度的需求需要集成专业工具如ClamAV查毒、rkhunter查rootkit或者部署HIDS主机入侵检测系统。5.3 安全加固后的副作用问题按照脚本建议修改SSH配置并重启后自己也被锁在服务器外面了。避坑指南这是最危险的坑务必遵循以下顺序先测试后生效在修改sshd_config前先在一个新的SSH会话中测试配置是否正确sudo sshd -t。保持活动连接在重启SSH服务 (sudo systemctl restart sshd) 时确保你当前用来操作的SSH连接不要断开。先在新窗口测试新配置如用新端口、新密钥登录成功再关闭旧会话。使用连接保活在客户端的~/.ssh/config里为这台服务器设置ServerAliveInterval 60防止长时间无操作导致连接中断而你还没来得及修复登录问题。问题关闭了某个服务后发现另一个依赖它的服务报错了。避坑指南在禁用或停止一个服务前使用systemctl list-dependencies service-name查看它被哪些服务依赖或者使用netstat -tulnp | grep :端口号查看是哪个进程在监听确认其作用。对于不熟悉的系统服务最好先搜索一下其功能。5.4 脚本自身的维护与安全问题脚本放在哪里如何更新建议将脚本放在版本控制系统如Git中管理。这样你可以追踪更改方便回滚也能在多台服务器间同步更新。可以在服务器上通过cron任务定期从Git仓库拉取最新脚本并执行注意做好认证和通信安全。问题脚本内容会不会被恶意篡改建议这是安全脚本的悖论。确保你从可信源获取脚本并定期校验其完整性如对比哈希值。如果脚本需要通过网络下载尽量使用HTTPS链接。对于自己编写的脚本也要严格控制其存放目录的权限。最后我想强调的是这个7分钟的安全审计脚本是一个强大的起点和辅助工具但它绝不是安全的终点。真正的服务器安全是一个涵盖网络防火墙、系统加固、最小权限、持续监控、漏洞管理、数据备份和应急响应的完整体系。定期运行这个脚本能帮你养成良好的安全巡检习惯及时发现“低垂的果实”式的风险。把它集成到你的服务器初始化清单和定期维护计划中让它成为你运维工具箱里一件趁手的“听诊器”。