服务器运维(三十三)日志分析ssh日志工具—东方仙盟

攻击类型

核心代码

东方仙盟 SSH/secure 日志分析工具使用说明

一、SSH/secure 日志分析的核心价值(聚焦危险快速定位)

SSH 作为服务器远程管理的核心入口,其日志(secure 日志)记录了所有登录尝试、认证行为和异常连接,对其进行专业分析,是秒级定位 SSH 攻击风险、筑牢服务器第一道安全防线的核心手段,具体价值体现在:

1. 秒级锁定攻击源,精准拦截恶意 IP

  • 按攻击次数排序展示恶意 IP:无需逐行翻阅日志,直接定位 "攻击次数 Top20" 的恶意 IP,快速识别高频密码爆破、无效用户尝试的源头;
  • 风险等级自动标记:根据攻击次数划分 "高危 / 中危 / 低危"IP(≥20 次攻击 = 高危),1 分钟内确定需要立即封禁的核心危险 IP,避免攻击持续渗透。

2. 精准识别攻击类型,针对性防御

  • 自动分类攻击行为:清晰区分 "root 密码尝试、普通密码爆破、无效用户侦察、协议错误攻击" 等类型,精准判断攻击者意图;
  • 攻击风险分级:✅ 高危(root 密码尝试、密码爆破):立即加固密码策略、开启登录限制;✅ 中危(无效用户尝试):预判攻击者侦察行为,提前隐藏敏感账户;✅ 低危(异常连接关闭):识别扫描行为,优化防火墙规则。

3. 量化攻击态势,掌握安全现状

  • 多维度统计攻击数据:总攻击次数、密码爆破次数、攻击 IP 数量等核心指标一目了然,快速判断服务器是否正遭受大规模 SSH 攻击;
  • 可视化攻击分布:通过 "攻击 IP 排行 + 攻击类型分析" 双视图,掌握攻击规模(如 "100 次攻击来自 20 个 IP,80% 为密码爆破"),制定精准防御策略。

4. 提前发现入侵前兆,避免服务器沦陷

  • 识别 "侦察 - 爆破 - 入侵" 全链路行为:从 "无效用户尝试"(侦察)到 "密码爆破"(攻击),提前阻断攻击链路,避免攻击者破解密码后入侵;
  • 发现异常协议请求:识别 "kex 协议错误、无效协议标识" 等非标准 SSH 请求,防范利用 SSH 协议漏洞的新型攻击。

二、网页版 SSH 日志分析工具的核心优势(零安装,危险定位快人一步)

传统的 SSH 日志分析需要登录服务器、使用grep/awk等命令行工具筛选攻击行为,且难以快速关联 IP 与攻击类型,而本网页版工具彻底解决这些痛点,核心优势聚焦 "快速定位危险":

1. 零安装成本,随时随地排查 SSH 风险

  • 无需在服务器 / 本地安装任何软件、插件,打开浏览器即可使用,跨 Windows/Mac/Linux/ 移动端全兼容;
  • 无需在服务器部署分析工具,避免因安装第三方软件引入新的安全漏洞,同时不占用 SSH 服务资源。

2. 智能解析,危险信息结构化呈现

  • 自动提取核心安全信息:从杂乱的 secure 日志中,精准解析出 "攻击 IP、攻击类型、攻击次数、风险等级",无需人工整理字段;
  • 一键生成分析报告:点击 "开始分析日志",自动完成攻击统计、IP 排序、风险标记,无需编写任何筛选命令。

3. 操作极简,非专业人员也能定位危险

  • 无需掌握 Linux 命令或 SSH 安全知识,3 步完成危险排查:
    1. 复制服务器 SSH/secure 日志内容(默认路径/var/log/secure/var/log/auth.log);
    2. 粘贴到工具文本框,点击 "开始分析日志";
    3. 查看攻击 IP 排行和类型分析,直接定位需要封禁的 IP、需要加固的防御点。

4. 数据本地解析,安全无泄露

  • 日志仅在本地浏览器解析,不上传至任何服务器,保障 SSH 日志中的 IP、账户等敏感信息不泄露;
  • 分析结果实时展示,支持清空重置,避免敏感数据留存。

三、SSH 日志分析定位危险的典型场景

  1. 场景 1:服务器疑似被 SSH 攻击 现象:服务器登录缓慢,怀疑有密码爆破行为,传统方式需逐行查/var/log/secure;工具使用:解析日志后,立即看到 "183.xxx.xxx.xxx 攻击 30 次(高危),均为 root 密码尝试",5 分钟内封禁该 IP 并开启 SSH 密钥登录,攻击立即终止。

  2. 场景 2:提前识别攻击前兆现象:日志中有少量 "Invalid user" 记录,不确定是否有风险;工具使用:解析后发现 "10 个 IP 在 1 小时内尝试了 50 次无效用户登录",判断为批量侦察行为,立即隐藏非必要账户、开启登录失败锁定,避免后续密码爆破。

  3. 场景 3:优化 SSH 防御策略现象:已封禁部分 IP,但攻击仍持续,无法确定防御漏洞;工具使用:解析日志后发现 "80% 攻击为密码爆破,且集中在 22 端口",立即修改 SSH 默认端口、开启双因素认证,攻击次数骤降 90%。

四、适配人群

  • 运维人员:快速定位 SSH 攻击源,秒级封禁恶意 IP,提升服务器安全防护效率;
  • 服务器管理员:无需专业安全知识,一键掌握 SSH 攻击态势,制定防御策略;
  • 小型团队 / 个人站长:无专业安全运维资源时,低成本实现 SSH 安全监控,避免服务器被入侵;
  • 安全人员:快速量化 SSH 攻击数据,为安全审计、应急响应提供精准依据。

完整代码

复制代码
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>东方仙盟服务器日志分析工具之ssh日志分析secure日志</title>
    <style>
        /* 科技修仙风格样式 */
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
            font-family: "Microsoft Yahei", monospace;
        }
        
        body {
            background: linear-gradient(135deg, #0a0a1a, #1a1a3a);
            color: #00ff9d;
            min-height: 100vh;
            padding: 20px;
            background-image: 
                radial-gradient(circle at 10% 20%, rgba(0, 255, 157, 0.1) 0%, transparent 20%),
                radial-gradient(circle at 90% 80%, rgba(0, 157, 255, 0.1) 0%, transparent 20%);
        }
        
        .container {
            max-width: 1400px;
            margin: 0 auto;
            background: rgba(10, 10, 30, 0.8);
            border: 1px solid #00ff9d;
            border-radius: 8px;
            padding: 30px;
            box-shadow: 0 0 20px rgba(0, 255, 157, 0.2);
        }
        
        .header {
            text-align: center;
            margin-bottom: 30px;
            border-bottom: 2px solid #00cc88;
            padding-bottom: 20px;
        }
        
        h1 {
            font-size: 2.5rem;
            text-shadow: 0 0 10px #00ff9d;
            margin-bottom: 10px;
            color: #00ffcc;
        }
        
        .subtitle {
            color: #00cc99;
            font-style: italic;
        }
        
        .log-input {
            margin-bottom: 30px;
        }
        
        textarea {
            width: 100%;
            height: 400px;
            background: rgba(5, 5, 20, 0.9);
            border: 1px solid #00cc88;
            color: #00ff9d;
            padding: 15px;
            font-size: 14px;
            resize: vertical;
            border-radius: 4px;
            margin-bottom: 15px;
            outline: none;
            transition: all 0.3s;
        }
        
        textarea:focus {
            box-shadow: 0 0 10px rgba(0, 255, 157, 0.5);
            border-color: #00ff9d;
        }
        
        button {
            background: linear-gradient(to right, #009966, #00cc88);
            color: #0a0a1a;
            border: none;
            padding: 12px 30px;
            font-size: 16px;
            font-weight: bold;
            border-radius: 4px;
            cursor: pointer;
            transition: all 0.3s;
            margin-right: 10px;
        }
        
        button:hover {
            background: linear-gradient(to right, #00cc88, #00ff9d);
            box-shadow: 0 0 10px rgba(0, 255, 157, 0.5);
            transform: translateY(-2px);
        }
        
        .results {
            display: flex;
            flex-direction: column;
            gap: 20px;
            margin-top: 30px;
        }
        
        .stat-card {
            background: rgba(15, 15, 40, 0.8);
            border: 1px solid #009966;
            border-radius: 6px;
            padding: 20px;
            box-shadow: 0 4px 8px rgba(0, 0, 0, 0.3);
            width: 100%;
        }
        
        .stat-card h2 {
            color: #00ffcc;
            margin-bottom: 15px;
            padding-bottom: 10px;
            border-bottom: 1px solid #00cc88;
        }
        
        .total-attacks-card {
            text-align: center;
        }
        
        .total-attacks {
            font-size: 3rem;
            font-weight: bold;
            color: #ff6600;
            margin: 10px 0;
        }
        
        table {
            width: 100%;
            border-collapse: collapse;
            margin-top: 15px;
        }
        
        th, td {
            padding: 12px 15px;
            text-align: left;
            border-bottom: 1px solid #006644;
        }
        
        th {
            background: rgba(0, 153, 102, 0.2);
            color: #00ffcc;
            font-size: 16px;
        }
        
        tr:hover {
            background: rgba(0, 153, 102, 0.1);
        }
        
        .attack-type {
            color: #ff9900;
            font-weight: bold;
        }
        
        .count-column {
            text-align: center;
            color: #ff6600;
            font-weight: bold;
        }
        
        .ip-column {
            width: 18%;
        }
        
        .attack-desc-column {
            width: 82%;
        }
        
        .clear-btn {
            background: linear-gradient(to right, #993300, #cc3300);
        }
        
        .clear-btn:hover {
            background: linear-gradient(to right, #cc3300, #ff3300);
        }
        
        .attack-severity {
            display: inline-block;
            padding: 2px 8px;
            border-radius: 4px;
            font-size: 12px;
            font-weight: bold;
            margin-right: 8px;
        }
        
        .severity-high {
            background: #ff4444;
            color: #000;
        }
        
        .severity-medium {
            background: #ffaa00;
            color: #000;
        }
        
        .severity-low {
            background: #00cc66;
            color: #000;
        }
        
        .client-type {
            display: inline-block;
            padding: 2px 8px;
            border-radius: 4px;
            font-size: 12px;
            font-weight: bold;
        }
        
        .client-malicious {
            background: #ff4444;
            color: #000;
        }
        
        .client-suspicious {
            background: #ffaa00;
            color: #000;
        }
        
        .client-normal {
            background: #00cc66;
            color: #000;
        }
        
        .attack-summary {
            display: flex;
            flex-wrap: wrap;
            gap: 20px;
            margin-top: 20px;
        }
        
        .summary-item {
            flex: 1;
            min-width: 200px;
            background: rgba(20, 20, 50, 0.8);
            border: 1px solid #00cc88;
            border-radius: 6px;
            padding: 15px;
            text-align: center;
        }
        
        .summary-value {
            font-size: 2rem;
            font-weight: bold;
            color: #00ff9d;
            margin: 10px 0;
        }
        
        .summary-label {
            color: #00cc99;
            font-size: 14px;
        }
        
        @media (max-width: 768px) {
            h1 {
                font-size: 1.8rem;
            }
            
            .total-attacks {
                font-size: 2rem;
            }
            
            th, td {
                padding: 8px 10px;
                font-size: 14px;
            }
            
            .ip-column {
                width: 25%;
            }
            
            .attack-desc-column {
                width: 75%;
            }
            
            .summary-item {
                flex: 100%;
            }
        }
    </style>
</head>
<body>
    <div class="container">
        <div class="header">
            <h1>东方仙盟服务器日志分析工具之ssh日志分析secure日志</h1>
            <p class="subtitle">科技修仙 · 洞察SSH攻击玄机</p>
        </div>
        
        <div class="log-input">
            <h2 style="margin-bottom: 10px;">请输入SSH/secure日志内容</h2>
            <textarea id="logInput" placeholder="请粘贴SSH/secure日志内容,每行一条日志..."></textarea>
            <button id="analyzeBtn"> 开始分析日志</button>
            <button id="clearBtn" class="clear-btn">清空内容</button>
        </div>
        
        <div id="results" class="results" style="display: none;">
            <!-- 总攻击统计 -->
            <div class="stat-card total-attacks-card">
                <h2> 攻击总览</h2>
                <div class="total-attacks" id="totalAttacks">0</div>
                <p>总计检测到的攻击/异常尝试次数</p>
                
                <div class="attack-summary">
                    <div class="summary-item">
                        <div class="summary-label">密码爆破尝试</div>
                        <div class="summary-value" id="passwordAttackCount">0</div>
                    </div>
                    <div class="summary-item">
                        <div class="summary-label">无效用户尝试</div>
                        <div class="summary-value" id="invalidUserCount">0</div>
                    </div>
                    <div class="summary-item">
                        <div class="summary-label">异常连接尝试</div>
                        <div class="summary-value" id="abnormalConnCount">0</div>
                    </div>
                    <div class="summary-item">
                        <div class="summary-label">攻击IP数量</div>
                        <div class="summary-value" id="attackIpCount">0</div>
                    </div>
                </div>
            </div>
            
            <!-- 攻击IP排行 -->
            <div class="stat-card">
                <h2> 攻击IP排行榜</h2>
                <table id="ipRankingTable">
                    <thead>
                        <tr>
                            <th class="ip-column">攻击IP</th>
                            <th>攻击类型</th>
                            <th class="count-column">攻击次数</th>
                            <th>风险等级</th>
                        </tr>
                    </thead>
                    <tbody id="ipRankingBody">
                        <!-- 动态填充内容 -->
                    </tbody>
                </table>
            </div>
            
            <!-- 攻击类型分析 -->
            <div class="stat-card">
                <h2>攻击类型分析</h2>
                <table id="attackTypeTable">
                    <thead>
                        <tr>
                            <th class="attack-type">攻击类型</th>
                            <th>描述</th>
                            <th class="count-column">出现次数</th>
                            <th>风险等级</th>
                        </tr>
                    </thead>
                    <tbody id="attackTypeBody">
                        <!-- 动态填充内容 -->
                    </tbody>
                </table>
            </div>
        </div>
    </div>

    <script>
        // DOM元素
        const logInput = document.getElementById('logInput');
        const analyzeBtn = document.getElementById('analyzeBtn');
        const clearBtn = document.getElementById('clearBtn');
        const results = document.getElementById('results');
        
        // 统计数据
        let stats = {
            totalAttacks: 0,
            passwordAttackCount: 0,
            invalidUserCount: 0,
            abnormalConnCount: 0,
            attackIps: {},
            attackTypes: {}
        };
        
        // IP风险等级判断
        function getIpRiskLevel(count) {
            if (count >= 20) return { class: 'severity-high', text: '高危' };
            if (count >= 10) return { class: 'severity-medium', text: '中危' };
            return { class: 'severity-low', text: '低危' };
        }
        
        // 攻击类型风险等级
        function getAttackRiskLevel(type) {
            const highRiskTypes = ['密码爆破', 'root密码尝试'];
            const mediumRiskTypes = ['无效用户尝试', '协议错误'];
            
            if (highRiskTypes.includes(type)) return { class: 'severity-high', text: '高危' };
            if (mediumRiskTypes.includes(type)) return { class: 'severity-medium', text: '中危' };
            return { class: 'severity-low', text: '低危' };
        }
        
        // 分析日志
        function analyzeLogs() {
            // 重置统计数据
            stats = {
                totalAttacks: 0,
                passwordAttackCount: 0,
                invalidUserCount: 0,
                abnormalConnCount: 0,
                attackIps: {},
                attackTypes: {}
            };
            
            const logLines = logInput.value.trim().split('\n');
            
            // 遍历每一行日志
            logLines.forEach(line => {
                if (!line.trim()) return;
                
                // 提取IP地址
                const ipMatch = line.match(/\b(?:\d{1,3}\.){3}\d{1,3}\b/);
                const ip = ipMatch ? ipMatch[0] : '未知IP';
                
                // 分类攻击类型
                if (line.includes('Failed password') || line.includes('authentication failure')) {
                    // 密码爆破攻击
                    stats.passwordAttackCount++;
                    stats.totalAttacks++;
                    
                    // 记录IP攻击次数
                    stats.attackIps[ip] = (stats.attackIps[ip] || 0) + 1;
                    
                    // 记录攻击类型
                    const attackType = line.includes('root') ? 'root密码尝试' : '密码爆破';
                    stats.attackTypes[attackType] = (stats.attackTypes[attackType] || 0) + 1;
                    
                } else if (line.includes('Invalid user')) {
                    // 无效用户尝试
                    stats.invalidUserCount++;
                    stats.totalAttacks++;
                    
                    stats.attackIps[ip] = (stats.attackIps[ip] || 0) + 1;
                    stats.attackTypes['无效用户尝试'] = (stats.attackTypes['无效用户尝试'] || 0) + 1;
                    
                } else if (line.includes('kex_exchange_identification') || 
                           line.includes('kex protocol error') ||
                           line.includes('invalid protocol identifier') ||
                           line.includes('Protocol major versions differ')) {
                    // 异常连接/协议错误
                    stats.abnormalConnCount++;
                    stats.totalAttacks++;
                    
                    stats.attackIps[ip] = (stats.attackIps[ip] || 0) + 1;
                    stats.attackTypes['协议错误'] = (stats.attackTypes['协议错误'] || 0) + 1;
                    
                } else if (line.includes('Connection closed by') && line.includes('[preauth]') ||
                           line.includes('Connection reset by') ||
                           line.includes('Broken pipe')) {
                    // 可疑连接关闭
                    stats.abnormalConnCount++;
                    stats.totalAttacks++;
                    
                    stats.attackIps[ip] = (stats.attackIps[ip] || 0) + 1;
                    stats.attackTypes['异常连接关闭'] = (stats.attackTypes['异常连接关闭'] || 0) + 1;
                }
            });
            
            // 显示分析结果
            displayResults();
        }
        
        // 显示分析结果
        function displayResults() {
            // 更新总统计
            document.getElementById('totalAttacks').textContent = stats.totalAttacks;
            document.getElementById('passwordAttackCount').textContent = stats.passwordAttackCount;
            document.getElementById('invalidUserCount').textContent = stats.invalidUserCount;
            document.getElementById('abnormalConnCount').textContent = stats.abnormalConnCount;
            document.getElementById('attackIpCount').textContent = Object.keys(stats.attackIps).length;
            
            // 清空表格内容
            document.getElementById('ipRankingBody').innerHTML = '';
            document.getElementById('attackTypeBody').innerHTML = '';
            
            // 排序攻击IP
            const sortedIps = Object.entries(stats.attackIps)
                .sort((a, b) => b[1] - a[1])
                .slice(0, 20); // 只显示前20个
            
            // 填充IP排行榜
            sortedIps.forEach(([ip, count]) => {
                const risk = getIpRiskLevel(count);
                const row = document.createElement('tr');
                row.innerHTML = `
                    <td class="ip-column">${ip}</td>
                    <td>暴力破解/异常连接</td>
                    <td class="count-column">${count}</td>
                    <td><span class="attack-severity ${risk.class}">${risk.text}</span></td>
                `;
                document.getElementById('ipRankingBody').appendChild(row);
            });
            
            // 填充攻击类型表格
            Object.entries(stats.attackTypes).forEach(([type, count]) => {
                const risk = getAttackRiskLevel(type);
                const row = document.createElement('tr');
                row.innerHTML = `
                    <td class="attack-type">${type}</td>
                    <td>${getAttackDescription(type)}</td>
                    <td class="count-column">${count}</td>
                    <td><span class="attack-severity ${risk.class}">${risk.text}</span></td>
                `;
                document.getElementById('attackTypeBody').appendChild(row);
            });
            
            // 显示结果区域
            results.style.display = 'flex';
        }
        
        // 获取攻击类型描述
        function getAttackDescription(type) {
            const descriptions = {
                'root密码尝试': '攻击者尝试使用root账户进行密码爆破,高危风险',
                '密码爆破': '攻击者尝试破解用户密码,中高危风险',
                '无效用户尝试': '攻击者尝试使用不存在的用户名登录,侦察行为',
                '协议错误': '异常的SSH协议请求,可能是扫描或恶意工具',
                '异常连接关闭': '连接在认证前异常关闭,通常是扫描行为'
            };
            return descriptions[type] || '未知攻击类型';
        }
        
        // 清空内容
        function clearContent() {
            logInput.value = '';
            results.style.display = 'none';
        }
        
        // 事件监听
        analyzeBtn.addEventListener('click', analyzeLogs);
        clearBtn.addEventListener('click', clearContent);
        
        // 支持按Enter键分析
        logInput.addEventListener('keypress', function(e) {
            if (e.key === 'Enter' && e.ctrlKey) {
                analyzeLogs();
            }
        });
    </script>
</body>
</html>

总结

  1. SSH/secure 日志分析的核心价值是秒级定位攻击 IP、识别攻击类型、分级防御风险,筑牢服务器远程管理安全防线;
  2. 网页版工具零安装、零服务器风险,智能解析日志并结构化呈现危险信息,1 分钟锁定核心攻击源;
  3. 操作仅需 "复制 - 粘贴 - 解析" 三步,非专业人员也能快速定位 SSH 危险,大幅降低服务器被入侵的风险。

该工具以 "科技修仙" 轻量化设计,将复杂的 SSH 日志分析简化为 "一键解析、危险秒现",让 SSH 安全防护从 "被动应对" 变为 "主动防御",真正实现 "洞察 SSH 攻击玄机,秒级锁定安全危险"。

阿雪技术观

在科技发展浪潮中,我们不妨积极投身技术共享。不满足于做受益者,更要主动担当贡献者。无论是分享代码、撰写技术博客,还是参与开源项目维护改进,每一个微小举动都可能蕴含推动技术进步的巨大能量。东方仙盟是汇聚力量的天地,我们携手在此探索硅基生命,为科技进步添砖加瓦。

Hey folks, in this wild tech - driven world, why not dive headfirst into the whole tech - sharing scene? Don't just be the one reaping all the benefits; step up and be a contributor too. Whether you're tossing out your code snippets, hammering out some tech blogs, or getting your hands dirty with maintaining and sprucing up open - source projects, every little thing you do might just end up being a massive force that pushes tech forward. And guess what? The Eastern FairyAlliance is this awesome place where we all come together. We're gonna team up

相关推荐
梦想很大很大14 小时前
拒绝“盲猜式”调优:在 Go Gin 项目中落地 OpenTelemetry 链路追踪
运维·后端·go
Sinclair15 小时前
内网服务器离线安装 Nginx+PHP+MySQL 的方法
运维
叶落阁主15 小时前
Tailscale 完全指南:从入门到私有 DERP 部署
运维·安全·远程工作
茶杯梦轩1 天前
从零起步学习RabbitMQ || 第二章:RabbitMQ 深入理解概念 Producer、Consumer、Exchange、Queue 与企业实战案例
服务器·后端·消息队列
甲鱼9292 天前
MySQL 实战手记:日志管理与主从复制搭建全指南
运维
YuMiao3 天前
gstatic连接问题导致Google Gemini / Studio页面乱码或图标缺失问题
服务器·网络协议
碳基沙盒4 天前
OpenClaw 多 Agent 配置实战指南
运维
Sinclair6 天前
简单几步,安卓手机秒变服务器,安装 CMS 程序
android·服务器
Rockbean7 天前
用40行代码搭建自己的无服务器OCR
服务器·python·deepseek
蝎子莱莱爱打怪7 天前
Centos7中一键安装K8s集群以及Rancher安装记录
运维·后端·kubernetes