服务器运维(三十三)日志分析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

相关推荐
梦雨羊2 小时前
搭建服务器进行测试
linux·运维·服务器
青主创享阁2 小时前
玄晶引擎2.7.6技术拆解+实战略落地:春节前自动化运营能力升级全解析
运维·自动化
FLS1682 小时前
华为S5700交换机SSH/Telnet/Web登录完整配置流程(V200R005C00SPC500)
运维·网络·华为·ssh
MyFreeIT2 小时前
OpenSSL
linux·运维·服务器
MarkHD3 小时前
自动化桌面整理脚本——用GUI自动化终结混乱(Day 19-20)
运维·自动化
funnycoffee1233 小时前
华为,华三交换机开启snmp的命令
服务器·华为·华为snmp·华三snmp
AD钙奶-lalala3 小时前
Error starting ApplicationContext. To display the condition evaluation···
linux·运维·服务器
市安3 小时前
基于Debain构建Ngxin镜像
运维·nginx·docker·云原生·容器·debian·镜像
未来之窗软件服务3 小时前
平台对接(2)美团/抖音/饿了么/有赞/微信/京东券核销服务商模式—东方仙盟
大数据·运维·微信·平台对接·仙盟创梦ide·东方仙盟·东方仙盟sdk