一键生成Linux服务器巡检html报告
·

编辑脚本
vi generate_server_inspection_report.sh
内容如下:
#!/bin/bash
# 操作系统巡检工具
# 检查是否以root权限运行
if [ "$(id -u)" -ne 0 ]; then
echo "错误:此脚本需要以root权限运行,请使用sudo或切换到root用户"
exit 1
fi
# 检查必要工具是否安装
check_dependencies() {
local dependencies=("sysstat" "net-tools")
local missing=()
for dep in "${dependencies[@]}"; do
if ! command -v $dep &> /dev/null && ! dpkg -s $dep &> /dev/null && ! rpm -q $dep &> /dev/null; then
missing+=($dep)
fi
done
if [ ${#missing[@]} -gt 0 ]; then
echo "检测到缺少必要工具,正在尝试安装..."
if command -v apt &> /dev/null; then
sudo apt update -y &> /dev/null
sudo apt install -y "${missing[@]}" &> /dev/null
elif command -v yum &> /dev/null; then
sudo yum install -y "${missing[@]}" &> /dev/null
else
echo "无法自动安装依赖,请手动安装: ${missing[*]}"
exit 1
fi
fi
}
# 初始化HTML巡检报告
REPORT_FILE="$(hostname)_$(hostname -I | awk '{print $1}')_$(date +"%Y%m%d")_操作系统巡检报告.html"
{
cat << EOF
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>$(hostname)服务器操作系统综合巡检报告-$(hostname)-$(hostname -I | awk '{print $1}')-$(date +"%Y%m%d")</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<style>
:root {
--primary: #3498db;
--secondary: #2c3e50;
--success: #27ae60;
--warning: #f39c12;
--danger: #e74c3c;
--info: #17a2b8;
--light: #f8f9fa;
--dark: #343a40;
--background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
--card-bg: rgba(255, 255, 255, 0.95);
--header-bg: linear-gradient(135deg, #3498db 0%, #2c3e50 100%);
--shadow: 0 4px 20px rgba(0, 0, 0, 0.1);
--transition: all 0.3s ease;
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background: var(--background);
color: var(--dark);
line-height: 1.6;
padding: 20px;
min-height: 100vh;
}
.container {
max-width: 1400px;
margin: 0 auto;
background: var(--card-bg);
border-radius: 15px;
overflow: hidden;
box-shadow: var(--shadow);
animation: fadeIn 1s ease;
}
@keyframes fadeIn {
from { opacity: 0; transform: translateY(-20px); }
to { opacity: 1; transform: translateY(0); }
}
.header {
background: var(--header-bg);
color: white;
padding: 25px 30px;
text-align: center;
position: relative;
overflow: hidden;
}
.header::before {
content: '';
position: absolute;
transform: translateY( -50%;
left: -50%;
width: 200%;
height: 200%;
background: radial-gradient(circle, rgba(255,255,255,0.1) 0%, rgba(255,255,255,0) 60%);
transform: rotate(30deg);
}
.header h1 {
font-size: 2.5rem);
margin-bottom: 10px;
text-shadow: 2px 2px 4px rgba(0,0,0,0.3);
position: relative;
}
.header p {
font-size: 1.1rem;
opacity: 0.9;
margin-bottom: 15px;
position: relative;
}
.timestamp {
display: inline-block;
background: rgba(255, 255, 255, 0.2);
padding: 8px 15px;
border-radius: 50px;
font-size: 0.9rem;
backdrop-filter: blur(5px);
}
.tabs {
display: flex;
background: var(--secondary);
overflow-x: auto;
scrollbar-width: none;
}
.tabs::-webkit-scrollbar {
display: none;
}
.tab-btn {
padding: 15px 25px;
background: transparent;
border: none;
color: rgba(255, 255, 255, 0.7);
font-weight: 600;
cursor: pointer;
transition: var(--transition);
position: relative;
white-space: nowrap;
font-size: 1rem;
}
.tab-btn:hover {
color: white;
background: rgba(255, 255, 255, 0.1);
}
.tab-btn.active {
color: white;
background: var(--primary);
}
.tab-btn i {
margin-right: 8px;
}
.tab-content {
display: none;
padding: 25px;
animation: fadeEffect 0.5s;
}
@keyframes fadeEffect {
from { opacity: 0; }
to { opacity: 1; }
}
.section {
margin-bottom: 30px;
background: white;
border-radius: 10px;
padding: 20px;
box-shadow: 0 2px 10px rgba(0,0,0,0.05);
transition: var(--transition);
}
.section:hover {
box-shadow: 0 5px 15px rgba(0,0,0,0.1);
transform: translateY(-2px);
}
h2 {
color: var(--primary);
margin-bottom: 20px;
padding-bottom: 10px;
border-bottom: 2px solid #eee;
display: flex;
align-items: center;
}
h2 i {
margin-right: 10px;
background: var(--primary);
color: white;
width: 40px;
height: 40px;
display: flex;
align-items: center;
justify-content: center;
border-radius: 50%;
}
h3 {
color: var(--secondary);
margin: 15px 0;
padding-left: 10px;
border-left: 4px solid var(--info);
}
table {
width: 100%;
border-collapse: separate;
border-spacing: 0;
margin: 15px 0;
border-radius: 8px;
overflow: hidden;
box-shadow: 0 0 0 1px #ddd;
}
th {
background: linear-gradient(to bottom, #f8f9fa, #e9ecef);
color: var(--secondary);
padding: 15px;
text-align: left;
font-weight: 600;
border-bottom: 2px solid #ddd;
}
td {
padding: 12px 15px;
border-bottom: 1px solid #eee;
transition: var(--transition);
}
tr:hover td {
background: #f8f9fa;
}
.status {
display: inline-block;
padding: 5px 12px;
border-radius: 50px;
font-size: 0.85rem;
font-weight: 600;
}
.status-success {
background: #e8f5e9;
color: var(--success);
}
.status-warning {
background: #fff3e0;
color: var(--warning);
}
.status-danger {
background: #ffebee;
color: var(--danger);
}
.status-info {
background: #e3f2fd;
color: var(--info);
}
.card-container {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
gap: 20px;
margin: 20px 0;
}
.card {
background: white;
border-radius: 10px;
padding: 20px;
box-shadow: 0 3px 10px rgba(0,0,0,0.08);
transition: var(--transition);
text-align: center;
}
.card:hover {
transform: translateY(-5px);
box-shadow: 0 5px 15px rgba(0,0,0,0.1);
}
.card i {
font-size: 2.5rem;
margin-bottom: 15px;
display: block;
}
.card-primary i { color: var(--primary); }
.card-success i { color: var(--success); }
.card-warning i { color: var(--warning); }
.card-danger i { color: var(--danger); }
.card h3 {
font-size: 1.2rem;
margin: 10px 0;
border: none;
padding: 0;
}
.card p {
font-size: 2rem;
font-weight: bold;
margin: 0;
}
.progress-bar {
height: 10px;
background: #eee;
border-radius: 5px;
overflow: hidden;
margin: 10px 0;
}
.progress {
height: 100%;
border-radius: 5px;
}
.progress-success { background: var(--success); }
.progress-warning { background: var(--warning); }
.progress-danger { background: var(--danger); }
pre {
background: #2d3a4b;
color: #e2e8f0;
padding: 15px;
border-radius: 8px;
overflow: auto;
font-family: 'Fira Code', monospace;
line-height: 1.5;
margin: 15px 0;
}
.summary {
background: linear-gradient(135deg, #e3f2fd 0%, #bbdefb 100%);
border-radius: 10px;
padding: 25px;
margin-transform: translateY( 30px;
border-left: 5px solid var(--primary);
}
.summary h2 {
border-bottom: none;
color: var(--secondary);
}
.risk-tag {
display: inline-block;
padding: 3px 10px;
border-radius: 4px;
font-size: 0.8rem);
font-weight: 600;
margin-left: 10px;
}
.risk-low { background: #d4edda; color: #155724; }
.risk-medium { background: #fff3cd; color: #856404; }
.risk-high { background: #f8d7da; color: #721c24; }
.highlight-box {
background: linear-gradient(to right, #fefcea, #f1da36);
border-left: 4px solid #f39c12;
padding: 15px;
border-radius: 0 8px 8px 0;
margin: 15px 0;
}
@media (max-width: 768px) {
.container {
border-radius: 0;
}
.header h1 {
font-size: 1.8rem;
}
.tabs {
flex-direction: column;
}
.card-container {
grid-template-columns: 1fr;
}
.tab-btn {
width: 100%;
text-align: left;
}
}
</style>
</head>
<body>
<div class="container">
<div class="header">
<h1><i class="fas fa-server"></i> $(hostname) 服务器巡检报告</h1>
<p>全面系统健康检查与安全评估</p>
<div class="timestamp">
<i class="fas fa-calendar-alt"></i> $(date +"%Y年%m月%d日 %H:%M:%S")
</div>
</div>
<div class="tabs">
<button class="tab-btn active" onclick="openTab(event, 'Summary')" id="defaultOpen">
<i class="fas fa-home"></i>概览
</button>
<button class="tab-btn" onclick="openTab(event, 'SystemInfo')">
<i class="fas fa-desktop"></i>系统信息
</button>
<button class="tab-btn" onclick="openTab(event, 'Security')">
<i class="fas fa-shield-alt"></i>安全检查
</button>
<button class="tab-btn" onclick="openTab(event, 'Performance')">
<i class="fas fa-tachometer-alt"></i>性能分析
</button>
<button class="tab-btn" onclick="openTab(event, 'Services')">
<i class="fas fa-cogs"></i>服务状态
</button>
<button class="tab-btn" onclick="openTab(event, 'Logs')">
<i class="fas fa-clipboard-list"></i>日志分析
</button>
<button class="tab-btn" onclick="openTab(event, 'Network')">
<i class="fas fa-network-wired"></i>网络状态
</button>
</div>
EOF
} > $REPORT_FILE
# 添加内容到HTML报告
add_to_report() {
echo "$1" >> $REPORT_FILE
}
# 显示开始信息
echo "===== 操作系统综合巡检工具 ====="
echo "巡检时间: $(date)"
echo "报告将保存至: $REPORT_FILE"
echo "正在检查依赖工具..."
check_dependencies
echo "================================="
# 开始生成报告内容
add_to_report "<div id='Summary' class='tab-content' style='display:block'>"
add_to_report "<div class='section'>"
add_to_report "<h2><i class='fas fa-chart-pie'></i> 巡检概览</h2>"
# 获取一些基础信息用于概览
os_info=$(cat /etc/os-release | grep PRETTY_NAME | cut -d= -f2 | tr -d '"' 2>/dev/null || echo "未知")
kernel_version=$(uname -r)
cpu_cores=$(grep -c ^processor /proc/cpuinfo 2>/dev/null || echo "未知")
mem_total=$(free -h | grep Mem | awk '{print $2}' 2>/dev/null || echo "未知")
add_to_report "<div class='card-container'>"
add_to_report "<div class='card card-primary'>"
add_to_report "<i class='fas fa-desktop'></i>"
add_to_report "<h3>操作系统</h3>"
add_to_report "<p>$os_info</p>"
add_to_report "</div>"
add_to_report "<div class='card card-success'>"
add_to_report "<i class='fas fa-microchip'></i>"
add_to_report "<h3>CPU核心</h3>"
add_to_report "<p>$cpu_cores 核心</p>"
add_to_report "</div>"
add_to_report "<div class='card card-warning'>"
add_to_report "<i class='fas fa-memory'></i>"
add_to_report "<h3>总内存</h3>"
add_to_report "<p>$mem_total</p>"
add_to_report "</div>"
add_to_report "<div class='card card-danger'>"
add_to_report "<i class='fas fa-code-branch'></i>"
add_to_report "<h3>内核版本</h3>"
add_to_report "<p>$kernel_version</p>"
add_to_report "</div>"
add_to_report "</div>"
add_to_report "<h3>巡检信息</h3>"
add_to_report "<table>"
add_to_report "<tr><th>项目</th><th>值</th></tr>"
add_to_report "<tr><td>项目名称</td><td>运维中心</td></tr>"
add_to_report "<tr><td>项目编号</td><td>IT-SYS-2023-001</td></tr>"
add_to_report "<tr><td>巡检时间</td><td>$(date +"%Y-%m-%d %H:%M:%S")</td></tr>"
add_to_report "<tr><td>巡检单位</td><td>运维中心</td></tr>"
add_to_report "<tr><td>报告生成</td><td>$(whoami)@$(hostname)</td></tr>"
add_to_report "</table>"
add_to_report "</div>"
add_to_report "</div>"
# 1. 系统基本信息
echo "收集系统基本信息..."
add_to_report "<div id='SystemInfo' class='tab-content'>"
add_to_report "<div class='section'>"
add_to_report "<h2><i class='fas fa-info-circle'></i> 系统基本信息</h2>"
hostname=$(hostname)
uptime=$(uptime | awk '{print $3 " " $4}' | sed 's/,//')
ip_address=$(hostname -I | awk '{print $1}')
add_to_report "<table>"
add_to_report "<tr><th>属性</th><th>值</th><th>状态</th></tr>"
add_to_report "<tr><td>系统版本</td><td>$os_info</td><td><span class='status status-success'>正常</span></td></tr>"
add_to_report "<tr><td>内核版本</td><td>$kernel_version</td><td><span class='status status-success'>最新</span></td></tr>"
add_to_report "<tr><td>主机名</td><td>$hostname</td><td><span class='status status-info'>已配置</span></td></tr>"
add_to_report "<tr><td>IP地址</td><td>$ip_address</td><td><span class='status status-success'>已分配</span></td></tr>"
add_to_report "<tr><td>运行时间</td><td>$uptime</td><td><span class='status status-success'>稳定</span></td></tr>"
add_to_report "</table>"
add_to_report "</div>"
add_to_report "</div>"
# 2. 环境变量安全检测
echo "进行环境变量安全检测..."
add_to_report "<div id='Security' class='tab-content'>"
add_to_report "<div class='section'>"
add_to_report "<h2><i class='fas fa-shield-alt'></i> 安全检测</h2>"
# 2.1 PATH环境变量分析
add_to_report "<h3>PATH环境变量分析</h3>"
path_var=$PATH
IFS=':' read -ra path_array <<< "$path_var"
add_to_report "<p>PATH包含 <strong>${#path_array[@]}</strong> 个路径</p>"
dangerous_paths=("/" "/root" "/tmp" "/var/tmp" "/dev/shm")
dangerous_found=0
for path in "${path_array[@]}"; do
if [[ " ${dangerous_paths[@]} " =~ " $path " ]]; then
add_to_report "<div class='highlight-box'><i class='fas fa-exclamation-triangle'></i> 危险路径: $path (包含在PATH中)</div>"
dangerous_found=1
fi
if [ -d "$path" ] && [ -w "$path" ] && ! ls -ld "$path" 2>/dev/null | grep -qE '^drwxr-xr-x'; then
add_to_report "<div class='highlight-box'><i class='fas fa-exclamation-triangle'></i> 可写路径: $path (存在非授权写入风险)</div>"
dangerous_found=1
fi
done
if [ $dangerous_found -eq 0 ]; then
add_to_report "<p><span class='status status-success'><i class='fas fa-check-circle'></i> PATH环境变量检查正常</span></p>"
fi
# 2.2 敏感环境变量扫描
add_to_report "<h3>敏感环境变量扫描</h3>"
sensitive_vars=("PASSWORD" "SECRET" "KEY" "TOKEN" "CREDENTIAL" "PASS" "DB_PASS")
found_sensitive=0
for var in "${sensitive_vars[@]}"; do
matches=$(env | grep -i "$var" | grep -v -E '^SHLVL=|^PWD=|^_=|^LS_COLORS=')
if [ -n "$matches" ]; then
found_sensitive=1
add_to_report "<div class='highlight-box'><i class='fas fa-exclamation-triangle'></i> 潜在敏感变量:</div>"
add_to_report "<pre>"
echo "$matches" | awk -F= '{print $1 "=***(内容已隐藏)***"}' >> $REPORT_FILE
add_to_report "</pre>"
fi
done
if [ $found_sensitive -eq 0 ]; then
add_to_report "<p><span class='status status-success'><i class='fas fa-check-circle'></i> 未发现明显敏感环境变量</span></p>"
fi
# 2.3 环境配置文件检查
add_to_report "<h3>环境配置文件权限检查</h3>"
env_files=("/etc/profile" "/etc/bashrc" "$HOME/.bashrc" "$HOME/.bash_profile")
add_to_report "<table>"
add_to_report "<tr><th>文件</th><th>权限</th><th>状态</th></tr>"
for file in "${env_files[@]}"; do
if [ -f "$file" ]; then
perms=$(stat -c "%a" "$file" 2>/dev/null)
if [ "$perms" -gt 644 ]; then
add_to_report "<tr><td>$file</td><td>$perms</td><td><span class='status status-warning'><i class='fas fa-exclamation-triangle'></i> 不安全权限 (建议≤644)</span></td></tr>"
else
add_to_report "<tr><td>$file</td><td>$perms</td><td><span class='status status-success'><i class='fas fa-check-circle'></i> 安全权限</span></td></tr>"
fi
else
add_to_report "<tr><td>$file</td><td>N/A</td><td><span class='status status-info'>文件不存在</span></td></tr>"
fi
done
add_to_report "</table>"
# 3. 系统句柄数分析
echo "分析系统句柄数..."
add_to_report "<h3>系统句柄数分析</h3>"
# 3.1 句柄限制配置
sys_max_open=$(cat /proc/sys/fs/file-max 2>/dev/null || echo "未知")
sys_current_max=$(cat /proc/sys/fs/file-nr 2>/dev/null | awk '{print $1}' || echo "未知")
if [ "$sys_max_open" != "未知" ] && [ "$sys_current_max" != "未知" ]; then
sys_available=$((sys_max_open - sys_current_max))
else
sys_available="未知"
fi
add_to_report "<table>"
add_to_report "<tr><th>项目</th><th>值</th><th>状态</th></tr>"
add_to_report "<tr><td>系统级最大句柄数</td><td>$sys_max_open</td><td><span class='status status-info'>已配置</span></td></tr>"
add_to_report "<tr><td>当前系统已使用句柄</td><td>$sys_current_max</td><td><span class='status status-info'>正常</span></td></tr>"
add_to_report "<tr><td>系统句柄剩余可用</td><td>$sys_available</td><td><span class='status status-success'>充足</span></td></tr>"
user_soft=$(ulimit -Sn 2>/dev/null || echo "未知")
user_hard=$(ulimit -Hn 2>/dev/null || echo "未知")
add_to_report "<tr><td>用户级句柄限制(软)</td><td>$user_soft</td><td><span class='status status-info'>已设置</span></td></tr>"
add_to_report "<tr><td>用户级句柄限制(硬)</td><td>$user_hard</td><td><span class='status status-info'>已设置</span></td></tr>"
if [ "$sys_max_open" != "未知" ] && [ "$sys_current_max" != "未知" ] && [ "$sys_max_open" -ne 0 ]; then
usage_rate=$(echo "scale=2; $sys_current_max / $sys_max_open * 100" | bc)
add_to_report "<tr><td>系统句柄整体使用率</td><td>$usage_rate%</td><td>"
if (( $(echo "$usage_rate > 80" | bc -l 2>/dev/null) )); then
add_to_report "<span class='status status-danger'><i class='fas fa-exclamation-circle'></i> 超过80%</span>"
elif (( $(echo "$usage_rate > 60" | bc -l 2>/dev/null) )); then
add_to_report "<span class='status status-warning'><i class='fas fa-info-circle'></i> 超过60%</span>"
else
add_to_report "<span class='status status-success'><i class='fas fa-check-circle'></i> 正常</span>"
fi
add_to_report "</td></tr>"
add_to_report "<tr><td colspan='3'><div class='progress-bar'><div class='progress"
if (( $(echo "$usage_rate > 80" | bc -l 2>/dev/null) )); then
add_to_report " progress-danger' style='width: $usage_rate%'></div></div></td></tr>"
elif (( $(echo "$usage_rate > 60" | bc -l 2>/dev/null) )); then
add_to_report " progress-warning' style='width: $usage_rate%'></div></div></td></tr>"
else
add_to_report " progress-success' style='width: $usage_rate%'></div></div></td></tr>"
fi
else
add_to_report "<tr><td>系统句柄整体使用率</td><td>未知</td><td><span class='status status-info'>无法检测</span></td></tr>"
fi
add_to_report "</table>"
# 3.2 进程句柄TOP分析
add_to_report "<h3>句柄使用TOP 10进程</h3>"
add_to_report "<table>"
add_to_report "<tr><th>排名</th><th>PID</th><th>句柄数</th><th>进程名</th><th>状态</th></tr>"
if command -v lsof &> /dev/null; then
rank=0
lsof -n 2>/dev/null | awk '{print $2}' | sort | uniq -c | sort -nr | head -10 | while read count pid; do
if [ -n "$pid" ] && [ "$pid" -gt 0 ]; then
cmd=$(ps -p $pid -o comm= 2>/dev/null || echo "未知")
rank=$((rank+1))
# 根据句柄数量判断状态
if [ "$count" -gt 1000 ]; then
status="status-danger"
status_text="过高"
elif [ "$count" -gt 500 ]; then
status="status-warning"
status_text="偏多"
else
status="status-success"
status_text="正常"
fi
add_to_report "<tr><td>$rank</td><td>$pid</td><td>$count</td><td>$cmd</td><td><span class='status $status'>$status_text</span></td></tr>"
fi
done
else
add_to_report "<tr><td colspan='5'><span class='status status-warning'><i class='fas fa-exclamation-triangle'></i> lsof命令未安装,无法获取进程句柄信息</span></td></tr>"
fi
add_to_report "</table>"
add_to_report "</div>"
add_to_report "</div>"
# 4. 系统性能深度检测
echo "进行系统性能检测..."
add_to_report "<div id='Performance' class='tab-content'>"
add_to_report "<div class='section'>"
add_to_report "<h2><i class='fas fa-tachometer-alt'></i> 性能分析</h2>"
# 4.1 CPU性能分析
add_to_report "<h3>CPU性能分析</h3>"
cpu_model=$(grep -m1 'model name' /proc/cpuinfo 2>/dev/null | cut -d: -f2 | sed -e 's/^ *//' || echo "未知")
add_to_report "<table>"
add_to_report "<tr><th>项目</th><th>值</th><th>状态</th></tr>"
add_to_report "<tr><td>CPU型号</td><td>$cpu_model</td><td><span class='status status-info'>已识别</span></td></tr>"
add_to_report "<tr><td>CPU核心数</td><td>$cpu_cores</td><td><span class='status status-info'>已配置</span></td></tr>"
if command -v vmstat &> /dev/null; then
cpu_usage=$(vmstat 1 2 2>/dev/null | tail -n 1 | awk '{printf "%.2f", 100-$15}')
add_to_report "<tr><td>CPU使用率</td><td>$cpu_usage%</td><td>"
# 比较逻辑:检查CPU使用率是否大于等于80%
if (( $(echo "$cpu_usage >= 80" | bc -l 2>/dev/null) )); then
add_to_report "<span class='status status-danger'><i class='fas fa-exclamation-circle'></i> 过高</span>"
elif (( $(echo "$cpu_usage >= 60" | bc -l 2>/dev/null) )); then
add_to_report "<span class='status status-warning'><i class='fas fa-info-circle'></i> 中等</span>"
else
add_to_report "<span class='status status-success'><i class='fas fa-check-circle'></i> 正常</span>"
fi
add_to_report "</td></tr>"
add_to_report "<tr><td colspan='3'><div class='progress-bar'><div class='progress"
if (( $(echo "$cpu_usage >= 80" | bc -l 2>/dev/null) )); then
add_to_report " progress-danger' style='width: $cpu_usage%'></div></div></td></tr>"
elif (( $(echo "$cpu_usage >= 60" | bc -l 2>/dev/null) )); then
add_to_report " progress-warning' style='width: $cpu_usage%'></div></div></td></tr>"
else
add_to_report " progress-success' style='width: $cpu_usage%'></div></div></td></tr>"
fi
else
add_to_report "<tr><td>CPU平均使用率</td><td colspan='2'><span class='status status-warning'><i class='fas fa-exclamation-triangle'></i> sysstat未安装</span></td></tr>"
fi
add_to_report "</table>"
add_to_report "<h4>CPU占用TOP5进程</h4>"
add_to_report "<table>"
add_to_report "<tr><th>CPU%</th><th>PID</th><th>用户</th><th>命令</th><th>状态</th></tr>"
ps -eo %cpu,pid,user,comm --sort=-%cpu 2>/dev/null | head -6 | awk 'NR>1 {
status = "status-success"
status_text = "正常"
if ($1 > 20) {
status = "status-danger"
status_text = "过高"
} else if ($1 > 10) {
status = "status-warning"
status_text = "偏大"
}
printf "<tr><td>%.2f%%</td><td>%d</td><td>%s</td><td>%s</td><td><span class=\"status %s\">%s</span></td></tr>\n", $1, $2, $3, $4, status, status_text
}' >> $REPORT_FILE
add_to_report "</table>"
# 4.2 内存性能分析
add_to_report "<h3>内存性能分析</h3>"
mem_info=$(free -h 2>/dev/null || echo "未知")
if [ "$mem_info" != "未知" ]; then
mem_total=$(free -h | grep Mem | awk '{print $2}')
mem_used=$(free -h | grep Mem | awk '{print $3}')
mem_free=$(free -h | grep Mem | awk '{print $4}')
mem_available=$(free -h | grep Mem | awk '{print $7}')
mem_used_percent=$(free | grep Mem | awk '{printf "%.2f", $3/$2*100}')
else
mem_total="未知"
mem_used="未知"
mem_free="未知"
mem_available="未知"
mem_used_percent="未知"
fi
add_to_report "<table>"
add_to_report "<tr><th>项目</th><th>值</th><th>状态</th></tr>"
add_to_report "<tr><td>总内存</td><td>$mem_total</td><td><span class='status status-info'>已识别</span></td></tr>"
add_to_report "<tr><td>已使用</td><td>$mem_used ($mem_used_percent%)</td><td>"
if [ "$mem_used_percent" != "未知" ]; then
if (( $(echo "$mem_used_percent > 80" | bc -l 2>/dev/null) )); then
add_to_report "<span class='status status-danger'><i class='fas fa-exclamation-circle'></i> 过高</span>"
elif (( $(echo "$mem_used_percent > 60" | bc -l 2>/dev/null) )); then
add_to_report "<span class='status status-warning'><i class='fas fa-info-circle'></i> 中等</span>"
else
add_to_report "<span class='status status-success'><i class='fas fa-check-circle'></i> 正常</span>"
fi
else
add_to_report "<span class='status status-info'>未知</span>"
fi
add_to_report "</td></tr>"
add_to_report "<tr><td>空闲内存</td><td>$mem_free</td><td><span class='status status-info'>可用</span></td></tr>"
add_to_report "<tr><td>可用内存</td><td>$mem_available</td><td><span class='status status-info'>可分配</span></td></tr>"
if [ "$mem_used_percent" != "未知" ]; then
add_to_report "<tr><td colspan='3'><div class='progress-bar'><div class='progress"
if (( $(echo "$mem_used_percent > 80" | bc -l 2>/dev/null) )); then
add_to_report " progress-danger' style='width: $mem_used_percent%'></div></div></td></tr>"
elif (( $(echo "$mem_used_percent > 60" | bc -l 2>/dev/null) )); then
add_to_report " progress-warning' style='width: $mem_used_percent%'></div></div></td></tr>"
else
add_to_report " progress-success' style='width: $mem_used_percent%'></div></div></td></tr>"
fi
fi
add_to_report "</table>"
add_to_report "<h4>内存占用TOP5进程</h4>"
add_to_report "<table>"
add_to_report "<tr><th>内存%</th><th>内存大小</th><th>PID</th><th>用户</th><th>命令</th><th>状态</th></tr>"
ps -eo %mem,rss,pid,user,comm --sort=-%mem 2>/dev/null | head -6 | awk 'NR>1 {
status = "status-success"
status_text = "正常"
if ($1 > 10) {
status = "status-danger"
status_text = "过高"
} else if ($1 > 5) {
status = "status-warning"
status_text = "偏大"
}
printf "<tr><td>%.2f%%</td><td>%sK</td><td>%d</td><td>%s</td><td>%s</td><td><span class=\"status %s\">%s</span></td></tr>\n", $1, $2, $3, $4, $5, status, status_text
}' >> $REPORT_FILE
add_to_report "</table>"
# 4.3 磁盘性能分析
add_to_report "<h3>磁盘性能分析</h3>"
add_to_report "<h4>文件系统使用率</h4>"
add_to_report "<table>"
add_to_report "<tr><th>文件系统</th><th>大小</th><th>已用</th><th>可用</th><th>使用%</th><th>挂载点</th><th>状态</th></tr>"
df -h 2>/dev/null | grep -vE 'tmpfs|loop|udev' | awk 'NR>1 {print $0}' | while read line; do
fs=$(echo $line | awk '{print $1}')
size=$(echo $line | awk '{print $2}')
used=$(echo $line | awk '{print $3}')
avail=$(echo $line | awk '{print $4}')
usage=$(echo $line | awk '{print $5}')
mount=$(echo $line | awk '{print $6}')
usage_val=$(echo $usage | sed 's/%//')
if [ "$usage_val" -gt 80 ] 2>/dev/null; then
status="status-danger"
status_text="危险"
elif [ "$usage_val" -gt 60 ] 2>/dev/null; then
status="status-warning"
status_text="警告"
else
status="status-success"
status_text="正常"
fi
add_to_report "<tr><td>$fs</td><td>$size</td><td>$used</td><td>$avail</td><td>$usage</td><td>$mount</td><td><span class='status $status'>$status_text</span></td></tr>"
done
add_to_report "</table>"
add_to_report "<h4>磁盘I/O性能(1秒采样)</h4>"
if command -v iostat &> /dev/null; then
add_to_report "<pre>"
iostat -x 1 1 2>/dev/null | tail -n +4 >> $REPORT_FILE
add_to_report "</pre>"
else
add_to_report "<p><span class='status status-warning'><i class='fas fa-exclamation-triangle'></i> iostat命令未安装,无法获取磁盘I/O信息</span></p>"
fi
add_to_report "</div>"
add_to_report "</div>"
# 5. 服务与系统更新检查
echo "检查服务状态与系统更新..."
add_to_report "<div id='Services' class='tab-content'>"
add_to_report "<div class='section'>"
add_to_report "<h2><i class='fas fa-cogs'></i> 服务状态与系统更新</h2>"
# 5.1 关键服务状态
add_to_report "<h3>关键服务状态检查</h3>"
critical_services=(
"sshd" # SSH服务
"firewalld" # 防火墙服务
"crond" # 定时任务服务
"rsyslog" # 日志服务
"docker" # Docker服务(如有)
"nginx" # Nginx服务(如有)
"mysql" # MySQL服务(如有)
"redis" # Redis服务(如有)
)
add_to_report "<table>"
add_to_report "<tr><th>服务</th><th>状态</th><th>说明</th></tr>"
for service in "${critical_services[@]}"; do
if systemctl is-active --quiet $service 2>/dev/null; then
add_to_report "<tr><td>$service</td><td><span class='status status-success'><i class='fas fa-check-circle'></i> 正常运行</span></td><td>服务正在运行中</td></tr>"
else
if systemctl list-unit-files --type=service 2>/dev/null | grep -q "$service"; then
add_to_report "<tr><td>$service</td><td><span class='status status-warning'><i class='fas fa-exclamation-triangle'></i> 已安装但未运行</span></td><td>服务已安装但未启动</td></tr>"
else
add_to_report "<tr><td>$service</td><td><span class='status status-info'>未安装</span></td><td>服务未安装在系统中</td></tr>"
fi
fi
done
add_to_report "</table>"
# 5.2 系统更新检查
add_to_report "<h3>系统更新检查</h3>"
if command -v apt &> /dev/null; then
updates=$(apt list --upgradable 2>/dev/null | wc -l)
updates=$((updates-1)) # 减去标题行
security_updates=$(apt list --upgradable 2>/dev/null | grep -i security | wc -l)
add_to_report "<p>可用系统更新: <strong>$updates</strong> 个 (其中安全更新: <strong>$security_updates</strong> 个)</p>"
if [ "$updates" -gt 0 ]; then
add_to_report "<p><span class='status status-warning'><i class='fas fa-exclamation-triangle'></i> 系统有可用更新,建议及时更新</span></p>"
else
add_to_report "<p><span class='status status-success'><i class='fas fa-check-circle'></i> 系统已是最新状态</span></p>"
fi
elif command -v yum &> /dev/null; then
updates=$(yum check-update 2>/dev/null | grep -v "已加载插件" | wc -l)
security_updates=$(yum check-update --security 2>/dev/null | wc -l)
add_to_report "<p>可用系统更新: <strong>$updates</strong> 个 (其中安全更新: <strong>$security_updates</strong> 个)</p>"
if [ "$updates" -gt 0 ]; then
add_to_report "<p><span class='status status-warning'><i class='fas fa-exclamation-triangle'></i> 系统有可用更新,建议及时更新</span></p>"
else
add_to_report "<p><span class='status status-success'><i class='fas fa-check-circle'></i> 系统已是最新状态</span></p>"
fi
else
add_to_report "<p><span class='status status-info'><i class='fas fa-info-circle'></i> 无法检测可用更新(不支持apt/yum包管理器)</span></p>"
fi
add_to_report "</div>"
add_to_report "</div>"
# 6. 日志与定时任务检查
echo "检查日志与定时任务..."
add_to_report "<div id='Logs' class='tab-content'>"
add_to_report "<div class='section'>"
add_to_report "<h2><i class='fas fa-clipboard-list'></i> 日志与定时任务检查</h2>"
# 6.1 错误日志检查
add_to_report "<h3>系统错误日志检查</h3>"
log_files=("/var/log/messages" "/var/log/syslog")
error_found=0
for log_file in "${log_files[@]}"; do
if [ -f "$log_file" ]; then
error_logs=$(grep -iE "error|fail|critical|alert|emergency" "$log_file" 2>/dev/null | grep -v "CRON" | tail -5)
if [ -n "$error_logs" ]; then
error_found=1
add_to_report "<div class='highlight-box'><i class='fas fa-exclamation-triangle'></i> $log_file 中发现错误日志记录:</div>"
add_to_report "<pre>$error_logs</pre>"
fi
fi
done
if [ $error_found -eq 0 ]; then
add_to_report "<p><span class='status status-success'><i class='fas fa-check-circle'></i> 未发现明显错误日志</span></p>"
fi
# 6.2 登录失败检查
add_to_report "<h3>登录失败记录检查</h3>"
auth_files=("/var/log/secure" "/var/log/auth.log")
login_failures=0
for auth_file in "${auth_files[@]}"; do
if [ -f "$auth_file" ]; then
failed_logins=$(grep "Failed password" "$auth_file" 2>/dev/null | tail -5)
if [ -n "$failed_logins" ]; then
login_failures=1
add_to_report "<div class='highlight-box'><i class='fas fa-exclamation-triangle'></i> $auth_file 中发现登录失败记录:</div>"
add_to_report "<pre>$failed_logins</pre>"
fi
fi
done
if [ $login_failures -eq 0 ]; then
add_to_report "<p><span class='status status-success'><i class='fas fa-check-circle'></i> 未发现登录失败记录</span></p>"
fi
# 6.3 定时任务检查
add_to_report "<h3>定时任务安全检查</h3>"
add_to_report "<pre style='background:#2d3a4b;color:#e2e8f0;'>"
add_to_report "# 系统定时任务:"
cat /etc/crontab 2>/dev/null | grep -v '^#' | grep -v '^$' >> $REPORT_FILE
add_to_report ""
add_to_report "# 用户定时任务:"
for user in $(cut -f1 -d: /etc/passwd); do
user_cron=$(crontab -l -u $user 2>/dev/null | grep -v '^#' | grep -v '^$')
if [ -n "$user_cron" ]; then
add_to_report "# $user 用户的定时任务:"
echo "$user_cron" | sed "s/^/ /" >> $REPORT_FILE
fi
done
add_to_report "</pre>"
suspicious_crons=$(grep -r -E 'wget|curl|bash -i|nc |netcat' /etc/cron* 2>/dev/null | grep -v -E '#|/usr/bin/')
if [ -n "$suspicious_crons" ]; then
add_to_report "<div class='highlight-box'><i class='fas fa-exclamation-triangle'></i> 发现可能存在风险的定时任务:</div>"
add_to_report "<pre>$suspicious_crons</pre>"
else
add_to_report "<p><span class='status status-success'><i class='fas fa-check-circle'></i> 未发现明显风险的系统级定时任务</span></p>"
fi
add_to_report "</div>"
add_to_report "</div>"
# 7. 网络状态检查
echo "检查网络状态..."
add_to_report "<div id='Network' class='tab-content'>"
add_to_report "<div class='section'>"
add_to_report "<h2><i class='fas fa-network-wired'></i> 网络状态检查</h2>"
# 7.1 网络接口信息
add_to_report "<h3>网络接口信息</h3>"
add_to_report "<pre>"
ip addr show 2>/dev/null | grep -E "^([0-9]+):|inet " | grep -v "127.0.0.1" | head -10 >> $REPORT_FILE
add_to_report "</pre>"
# 7.2 网络连接状态
add_to_report "<h3>网络连接状态</h3>"
add_to_report "<table>"
add_to_report "<tr><th>状态</th><th>连接数</th><th>说明</th></tr>"
if command -v netstat &> /dev/null; then
netstat -ant 2>/dev/null | awk '/^tcp/ {++S[$NF]} END {for(a in S) print "<tr><td>" a "</td><td>" S[a] "</td><td>TCP连接状态</td></tr>"}' >> $REPORT_FILE
else
add_to_report "<tr><td colspan='3'><span class='status status-warning'><i class='fas fa-exclamation-triangle'></i> netstat命令未安装,无法获取网络连接信息</span></td></tr>"
fi
add_to_report "</table>"
# 7.3 监听端口检查
add_to_report "<h3>监听端口检查</h3>"
add_to_report "<table>"
add_to_report "<tr><th>协议</th><th>端口</th><th>程序</th><th>状态</th></tr>"
if command -v ss &> /dev/null; then
ss -tuln 2>/dev/null | awk 'NR>1 {print $1,$5,$7}' | while read proto port program; do
port_num=$(echo $port | awk -F: '{print $NF}')
add_to_report "<tr><td>$proto</td><td>$port_num</td><td>$program</td><td><span class='status status-info'>监听中</span></td></tr>"
done
else
add_to_report "<tr><td colspan='4'><span class='status status-warning'><i class='fas fa-exclamation-triangle'></i> ss命令不可用,无法获取端口信息</span></td></tr>"
fi
add_to_report "</table>"
add_to_report "</div>"
add_to_report "</div>"
# 巡检总结
add_to_report "<div class='summary'>"
add_to_report "<h2><i class='fas fa-tasks'></i> 巡检总结</h2>"
add_to_report "<p>检查完成时间: $(date +"%Y-%m-%d %H:%M:%S")</p>"
add_to_report "<h3>重点关注项:</h3>"
add_to_report "<ul>"
if [ "$usage_rate" != "未知" ] && (( $(echo "$usage_rate > 80" | bc -l 2>/dev/null) )); then
add_to_report "<li><span class='status status-danger'><i class='fas fa-exclamation-circle'></i> 系统句柄使用率过高: $usage_rate%</span></li>";
fi
if [ "$cpu_usage" != "未知" ] && (( $(echo "$cpu_usage > 80" | bc -l 2>/dev/null) )); then
add_to_report "<li><span class='status status-danger'><i class='fas fa-exclamation-circle'></i> CPU使用率过高: $cpu_usage%</span></li>";
fi
if [ "$mem_used_percent" != "未知" ] && (( $(echo "$mem_used_percent > 80" | bc -l 2>/dev/null) )); then
add_to_report "<li><span class='status status-danger'><i class='fas fa-exclamation-circle'></i> 内存使用率过高: $mem_used_percent%</span></li>";
fi
if [ -n "$empty_passwords" ] || [ -n "$privileged_users" ]; then
add_to_report "<li><span class='status status-danger'><i class='fas fa-exclamation-circle'></i> 用户安全配置存在问题</span></li>";
fi
add_to_report "</ul>"
add_to_report "<h3>建议措施:</h3>"
add_to_report "<ol>"
add_to_report "<li>定期检查系统更新并及时安装安全补丁</li>"
add_to_report "<li>监控系统资源使用情况,确保有足够空闲资源</li>"
add_to_report "<li>检查并优化高资源占用进程</li>"
add_to_report "<li>定期检查系统日志,及时发现并处理异常</li>"
add_to_report "<li>加强系统安全配置,遵循最小权限原则</li>"
add_to_report "</ol>"
add_to_report "</div>"
# 添加JavaScript标签页功能
add_to_report "<script>
function openTab(evt, tabName) {
var i, tabcontent, tablinks;
tabcontent = document.getElementsByClassName('tab-content');
for (i = 0; i < tabcontent.length; i++) {
tabcontent[i].style.display = 'none';
}
tablinks = document.getElementsByClassName('tab-btn');
for (i = 0; i < tablinks.length; i++) {
tablinks[i].className = tablinks[i].className.replace(' active', '');
}
document.getElementById(tabName).style.display = 'block';
evt.currentTarget.className += ' active';
// 添加历史记录
history.pushState(null, null, '#' + tabName);
}
// 检查URL哈希并打开相应标签
window.addEventListener('load', function() {
var hash = window.location.hash.substring(1);
if (hash) {
document.getElementById('defaultOpen').click();
var tab = document.getElementById(hash);
if (tab) {
tab.style.display = 'block';
document.querySelector('[onclick=\"openTab(event, \\'' + hash + '\\')\"]').className += ' active';
}
} else {
document.getElementById('defaultOpen').click();
}
});
// 添加平滑滚动效果
document.querySelectorAll('a[href^=\"#\"]').forEach(anchor => {
anchor.addEventListener('click', function (e) {
e.preventDefault();
document.querySelector(this.getAttribute('href')).scrollIntoView({
behavior: 'smooth'
});
});
});
</script>"
# 完成HTML报告
add_to_report "</div></body></html>"
echo "===== 操作系统综合巡检完成 ====="
echo "HTML巡检报告已保存至: $REPORT_FILE"
echo "请使用浏览器打开查看详细报告"
chmod +x generate_server_inspection_report.sh
chmod 700 generate_server_inspection_report.sh
或者简洁一些的
#!/bin/bash
# 定义输出HTML文件的路径和名称
OUTPUT_HTML="/data/server_inspection_report_$(date +%Y%m%d_%H%M%S).html"
SERVER_NAME=$(hostname)
INSPECTION_DATE=$(date "+%Y-%m-%d %H:%M:%S")
# 开始生成HTML内容
cat > $OUTPUT_HTML << EOF
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>Linux服务器巡检报告 - $SERVER_NAME</title>
<style>
body {
font-family: 'Arial', sans-serif;
margin: 40px;
background-color: #f5f5f5;
color: #333;
}
.container {
background-color: #fff;
padding: 30px;
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}
h1 {
color: #2c3e50;
border-bottom: 2px solid #3498db;
padding-bottom: 10px;
}
h2 {
color: #34495e;
margin-top: 25px;
background-color: #f8f9fa;
padding: 10px;
border-left: 4px solid #3498db;
}
.section {
margin-bottom: 30px;
}
pre {
background-color: #edf2f7;
padding: 15px;
border-radius: 5px;
overflow-x: auto;
border: 1px solid #ddd;
}
.ok {
color: green;
font-weight: bold;
}
.warning {
color: orange;
font-weight: bold;
}
.critical {
color: red;
font-weight: bold;
}
.summary-item {
margin: 5px 0;
}
</style>
</head>
<body>
<div class="container">
<h1>Linux服务器巡检报告</h1>
<p><strong>服务器主机名:</strong> $SERVER_NAME</p>
<p><strong>巡检时间:</strong> $INSPECTION_DATE</p>
<hr>
<div class="section">
<h2>1. 系统概览</h2>
<pre>$(uptime)</pre>
<pre>$(uname -a)</pre>
</div>
<div class="section">
<h2>2. CPU使用情况</h2>
<pre>$(top -bn1 | head -10)</pre>
</div>
<div class="section">
<h2>3. 内存使用情况</h2>
<pre>$(free -h)</pre>
</div>
<div class="section">
<h2>4. 磁盘使用情况</h2>
<pre>$(df -h)</pre>
</div>
<div class="section">
<h2>5. 磁盘Inode使用情况</h2>
<pre>$(df -i)</pre>
</div>
<div class="section">
<h2>6. 最近登录用户</h2>
<pre>$(last -n 10)</pre>
</div>
<div class="section">
<h2>7. 网络连接监听状态</h2>
<pre>$(ss -tuln)</pre>
</div>
<div class="section">
<h2>8. 内核消息(最近10条)</h2>
<pre>$(dmesg | tail -10)</pre>
</div>
<div class="section">
<h2>9. 关键进程状态检查</h2>
<pre>$(ps aux | head -10)
# 您可以在这里添加特定的进程检查,例如:
# $(systemctl status sshd --no-pager -l)
# $(ps aux | grep -E '(nginx|mysql|docker)' | grep -v grep)
</pre>
</div>
</div>
</body>
</html>
EOF
# 完成提示
echo "巡检报告已生成: $OUTPUT_HTML"
创建脚本:将上面的内容复制到一个新文件中,例如 vim generate_server_inspection_report.sh。
授权脚本:运行 chmod +x generate_server_inspection_report.sh。
执行脚本:运行 ./generate_server_inspection_report.sh。
查看报告:脚本执行后,会输出生成的HTML文件路径(例如 /dqata/server_inspection_report_20230922_123456.html)。您可以用浏览器直接打开这个文件,或者用 scp 命令将其下载到本地查看。
更多推荐


所有评论(0)