网络安全监控中心

发布于:2025-08-28 ⋅ 阅读:(16) ⋅ 点赞:(0)
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>网络安全监控中心</title>
    <script src="https://cdn.tailwindcss.com"></script>
    <link href="https://cdn.jsdelivr.net/npm/font-awesome@4.7.0/css/font-awesome.min.css" rel="stylesheet">
    <script src="https://cdn.jsdelivr.net/npm/echarts@5.4.3/dist/echarts.min.js"></script>

    <!-- 配置Tailwind自定义颜色和字体 -->
    <script>
        tailwind.config = {
            theme: {
                extend: {
                    colors: {
                        primary: '#165DFF',
                        secondary: '#0E2E8B',
                        accent: '#FF6B35',
                        danger: '#E63946',
                        darkBlue: '#0A2463',
                        lightBlue: '#3E92CC',
                        cardBlue: '#1A3A6B'
                    },
                    fontFamily: {
                        sans: ['Inter', 'system-ui', 'sans-serif'],
                    },
                }
            }
        }
    </script>

    <style type="text/tailwindcss">
        @layer utilities {
            .content-auto {
                content-visibility: auto;
            }
            .scrollbar-hide {
                -ms-overflow-style: none;
                scrollbar-width: none;
            }
            .scrollbar-hide::-webkit-scrollbar {
                display: none;
            }
            .text-shadow {
                text-shadow: 0 2px 4px rgba(0,0,0,0.1);
            }
            .bg-gradient-blue {
                background: linear-gradient(135deg, #0A2463 0%, #165DFF 100%);
            }
            .card-hover {
                transition: all 0.3s ease;
            }
            .card-hover:hover {
                transform: translateY(-3px);
                box-shadow: 0 10px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04);
            }
        }
    </style>
</head>
<body class="bg-gradient-to-br from-darkBlue to-primary min-h-screen text-gray-100 font-sans">
    <!-- 顶部导航栏 -->
    <header class="bg-darkBlue/80 backdrop-blur-md border-b border-primary/30 sticky top-0 z-50">
        <div class="container mx-auto px-4 py-3 flex items-center justify-between">
            <div class="flex items-center space-x-3">
                <i class="fa fa-shield text-2xl text-accent"></i>
                <h1 class="text-xl md:text-2xl font-bold text-shadow">网络安全监控中心</h1>
            </div>
            <div class="flex items-center space-x-4">
                <div class="hidden md:flex items-center space-x-2 text-sm">
                    <span class="text-gray-300">当前时间:</span>
                    <span id="current-time" class="font-medium"></span>
                </div>
                <button class="bg-primary/20 hover:bg-primary/40 transition-colors p-2 rounded-full">
                    <i class="fa fa-bell-o"></i>
                </button>
                <div class="h-8 w-8 rounded-full bg-accent flex items-center justify-center">
                    <span class="text-xs font-bold">AD</span>
                </div>
            </div>
        </div>
    </header>

    <!-- 主内容区 -->
    <main class="container mx-auto px-4 py-6">
        <!-- 标签页导航 -->
        <div class="mb-8 flex justify-center">
            <div class="inline-flex bg-secondary/30 p-1 rounded-lg">
                <button class="tab-button active px-6 py-2 rounded-md bg-primary font-medium transition-all" data-tab="threat">
                    威胁态势
                </button>
                <button class="tab-button px-6 py-2 rounded-md hover:bg-primary/50 font-medium transition-all" data-tab="compromise">
                    失陷态势
                </button>
                <button class="tab-button px-6 py-2 rounded-md hover:bg-primary/50 font-medium transition-all" data-tab="apt">
                    APT情报
                </button>
            </div>
        </div>

        <!-- 主要内容网格 -->
        <div class="grid grid-cols-1 lg:grid-cols-3 gap-6">
            <!-- 左侧攻击事件列表 -->
            <div class="lg:col-span-1">
                <div class="bg-cardBlue/60 backdrop-blur-sm rounded-xl shadow-lg overflow-hidden border border-primary/20">
                    <div class="p-4 border-b border-primary/20 flex justify-between items-center">
                        <h2 class="text-lg font-semibold">最近30日发生的网络攻击行为</h2>
                        <span class="text-xs bg-accent/20 text-accent px-2 py-1 rounded-full">实时更新</span>
                    </div>

                    <div class="flex border-b border-primary/20">
                        <div class="w-1/3 py-2 px-4 bg-danger/80 text-center font-medium text-sm">
                            攻击源地址
                        </div>
                        <div class="w-2/3 py-2 px-4 bg-primary text-center font-medium text-sm">
                            被攻击地址
                        </div>
                    </div>

                    <div class="max-h-[600px] overflow-y-auto scrollbar-hide">
                        <div id="attack-list" class="divide-y divide-primary/10">
                            <!-- 攻击事件项将通过JavaScript动态生成 -->
                        </div>
                    </div>
                </div>
            </div>

            <!-- 右侧世界地图 -->
            <div class="lg:col-span-2">
                <div class="bg-cardBlue/60 backdrop-blur-sm rounded-xl shadow-lg overflow-hidden border border-primary/20 h-full flex flex-col">
                    <div class="p-4 border-b border-primary/20">
                        <h2 class="text-lg font-semibold">全球网络攻击分布</h2>
                    </div>

                    <div class="flex-1 p-4 relative">
                        <div class="absolute top-4 right-4 bg-darkBlue/70 backdrop-blur-sm rounded-lg p-3 shadow-lg border border-primary/20 z-10">
                            <div class="flex items-center space-x-2 mb-2">
                                <div class="w-3 h-3 rounded-full bg-accent"></div>
                                <span class="text-sm">攻击路径</span>
                            </div>
                            <div class="flex items-center space-x-2 mb-2">
                                <div class="w-3 h-3 rounded-full bg-danger"></div>
                                <span class="text-sm">攻击源</span>
                            </div>
                            <div class="flex items-center space-x-2">
                                <div class="w-3 h-3 rounded-full bg-primary"></div>
                                <span class="text-sm">目标地址</span>
                            </div>
                        </div>

                        <div class="h-full relative">
                            <!-- 地图容器 -->
                            <div id="world-map" class="w-full h-full"></div>
                        </div>
                    </div>

                    <!-- 统计数据卡片 -->
                    <div class="grid grid-cols-2 md:grid-cols-4 gap-4 p-4 border-t border-primary/20">
                        <div class="bg-darkBlue/50 rounded-lg p-3 card-hover">
                            <div class="text-xs text-gray-300 mb-1">总攻击次数</div>
                            <div class="text-2xl font-bold text-white">2,847</div>
                            <div class="text-xs text-green-400 mt-1 flex items-center">
                                <i class="fa fa-arrow-up mr-1"></i> 12.5%
                            </div>
                        </div>
                        <div class="bg-darkBlue/50 rounded-lg p-3 card-hover">
                            <div class="text-xs text-gray-300 mb-1">攻击源IP</div>
                            <div class="text-2xl font-bold text-white">147</div>
                            <div class="text-xs text-green-400 mt-1 flex items-center">
                                <i class="fa fa-arrow-up mr-1"></i> 3.2%
                            </div>
                        </div>
                        <div class="bg-darkBlue/50 rounded-lg p-3 card-hover">
                            <div class="text-xs text-gray-300 mb-1">目标IP</div>
                            <div class="text-2xl font-bold text-white">892</div>
                            <div class="text-xs text-red-400 mt-1 flex items-center">
                                <i class="fa fa-arrow-down mr-1"></i> 2.1%
                            </div>
                        </div>
                        <div class="bg-darkBlue/50 rounded-lg p-3 card-hover">
                            <div class="text-xs text-gray-300 mb-1">高危攻击</div>
                            <div class="text-2xl font-bold text-white">346</div>
                            <div class="text-xs text-green-400 mt-1 flex items-center">
                                <i class="fa fa-arrow-up mr-1"></i> 8.7%
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </main>

    <script>
        // 实时时间更新
        function updateTime() {
            const now = new Date();
            const options = { year: 'numeric', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit', second: '2-digit' };
            document.getElementById('current-time').textContent = now.toLocaleString('zh-CN', options);
        }
        setInterval(updateTime, 1000);
        updateTime();

        // 标签页切换功能
        const tabButtons = document.querySelectorAll('.tab-button');
        tabButtons.forEach(button => {
            button.addEventListener('click', () => {
                // 移除所有活动状态
                tabButtons.forEach(btn => btn.classList.remove('active', 'bg-primary'));
                tabButtons.forEach(btn => btn.classList.add('hover:bg-primary/50'));

                // 添加当前活动状态
                button.classList.add('active', 'bg-primary');
                button.classList.remove('hover:bg-primary/50');

                // 这里可以添加不同标签页内容的切换逻辑
                const tabName = button.getAttribute('data-tab');
                console.log(`切换到${tabName}标签页`);
            });
        });

        // 攻击数据
        const attackData = [
            { source: "172.192.38.118", sourceCountry: "au", target: "121.***.**.69", targetCountry: "cn", severity: "high" },
            { source: "172.192.38.118", sourceCountry: "au", target: "121.***.**.75", targetCountry: "cn", severity: "high" },
            { source: "172.192.38.118", sourceCountry: "au", target: "121.***.**.76", targetCountry: "cn", severity: "medium" },
            { source: "172.192.38.118", sourceCountry: "au", target: "121.***.**.77", targetCountry: "cn", severity: "high" },
            { source: "172.192.38.118", sourceCountry: "au", target: "121.***.**.78", targetCountry: "cn", severity: "medium" },
            { source: "172.192.38.118", sourceCountry: "au", target: "121.***.**.79", targetCountry: "cn", severity: "low" },
            { source: "172.192.38.118", sourceCountry: "au", target: "121.***.**.80", targetCountry: "cn", severity: "medium" },
            { source: "172.192.38.118", sourceCountry: "au", target: "121.***.**.81", targetCountry: "cn", severity: "high" },
            { source: "172.192.38.118", sourceCountry: "au", target: "121.***.**.82", targetCountry: "cn", severity: "medium" },
            { source: "47.***.30.140", sourceCountry: "us", target: "218.***.**.102", targetCountry: "cn", severity: "high" },
            { source: "64.***.12.89", sourceCountry: "de", target: "117.***.**.56", targetCountry: "cn", severity: "low" },
            { source: "89.***.45.22", sourceCountry: "uk", target: "202.***.**.91", targetCountry: "cn", severity: "medium" },
            { source: "103.***.76.15", sourceCountry: "jp", target: "180.***.**.143", targetCountry: "cn", severity: "high" },
            { source: "212.***.33.77", sourceCountry: "fr", target: "58.***.**.207", targetCountry: "cn", severity: "medium" },
        ];

        // 生成攻击列表
        const attackList = document.getElementById('attack-list');
        attackData.forEach(attack => {
            const attackItem = document.createElement('div');
            attackItem.className = 'flex hover:bg-primary/10 transition-colors';

            // 攻击源地址列
            const sourceCol = document.createElement('div');
            sourceCol.className = 'w-1/3 p-3';
            sourceCol.innerHTML = `
                <div class="flex items-center">
                    <img src="https://flagcdn.com/w80/${attack.sourceCountry}.png" alt="${attack.sourceCountry}国旗" class="w-5 h-3 mr-2 rounded">
                    <span class="text-sm truncate">${attack.source}</span>
                </div>
            `;

            // 目标地址列
            const targetCol = document.createElement('div');
            targetCol.className = 'w-2/3 p-3 flex items-center justify-between';
            targetCol.innerHTML = `
                <div class="flex items-center">
                    <img src="https://flagcdn.com/w80/${attack.targetCountry}.png" alt="${attack.targetCountry}国旗" class="w-5 h-3 mr-2 rounded">
                    <span class="text-sm truncate">${attack.target}</span>
                </div>
                <span class="text-xs px-2 py-0.5 rounded-full ${
                    attack.severity === 'high' ? 'bg-danger/80' :
                    attack.severity === 'medium' ? 'bg-yellow-500/80' : 'bg-green-500/80'
                }">
                    ${attack.severity === 'high' ? '高危' :
                      attack.severity === 'medium' ? '中危' : '低危'}
                </span>
            `;

            attackItem.appendChild(sourceCol);
            attackItem.appendChild(targetCol);
            attackList.appendChild(attackItem);
        });

        // 国家经纬度数据
        const countryCoordinates = {
            'au': { name: '澳大利亚', lng: 133.7751, lat: -25.2744 },
            'cn': { name: '中国', lng: 104.1954, lat: 35.8617 },
            'us': { name: '美国', lng: -95.7129, lat: 37.0902 },
            'de': { name: '德国', lng: 10.4515, lat: 51.1657 },
            'uk': { name: '英国', lng: -3.4360, lat: 55.3781 },
            'jp': { name: '日本', lng: 138.2529, lat: 36.2048 },
            'fr': { name: '法国', lng: 2.2137, lat: 46.2276 }
        };

        // 初始化地图
        window.addEventListener('load', function() {
            // 创建地图实例
            const chartDom = document.getElementById('world-map');
            const myChart = echarts.init(chartDom);

            // 处理地图数据
            function getAttackPaths() {
                return attackData.map(attack => {
                    const source = countryCoordinates[attack.sourceCountry];
                    const target = countryCoordinates[attack.targetCountry];

                    return {
                        source: {
                            name: source.name,
                            value: [source.lng, source.lat]
                        },
                        target: {
                            name: target.name,
                            value: [target.lng, target.lat]
                        }
                    };
                });
            }

            function getUniqueSources() {
                const sources = {};
                attackData.forEach(attack => {
                    if (!sources[attack.sourceCountry]) {
                        const country = countryCoordinates[attack.sourceCountry];
                        sources[attack.sourceCountry] = {
                            name: country.name,
                            value: [country.lng, country.lat]
                        };
                    }
                });
                return Object.values(sources);
            }

            function getUniqueTargets() {
                const targets = {};
                attackData.forEach(attack => {
                    if (!targets[attack.targetCountry]) {
                        const country = countryCoordinates[attack.targetCountry];
                        targets[attack.targetCountry] = {
                            name: country.name,
                            value: [country.lng, country.lat]
                        };
                    }
                });
                return Object.values(targets);
            }

            // 注册世界地图
            fetch('https://cdn.jsdelivr.net/npm/echarts/map/json/world.json')
                .then(response => response.json())
                .then(worldJson => {
                    echarts.registerMap('world', worldJson);

                    // 设置地图配置
                    const option = {
                        backgroundColor: 'transparent',
                        tooltip: {
                            trigger: 'item',
                            formatter: function(params) {
                                return `${params.name}<br/>攻击次数: ${getAttackCount(params.name)}`;
                            }
                        },
                        geo: {
                            map: 'world',
                            roam: true, // 开启缩放和平移
                            label: {
                                show: false
                            },
                            itemStyle: {
                                areaColor: 'rgba(26, 58, 107, 0.6)',
                                borderColor: 'rgba(22, 93, 255, 0.3)',
                                borderWidth: 1
                            },
                            emphasis: {
                                itemStyle: {
                                    areaColor: 'rgba(22, 93, 255, 0.5)'
                                }
                            }
                        },
                        series: [
                            // 攻击路径
                            {
                                name: '攻击路径',
                                type: 'lines',
                                zlevel: 2,
                                effect: {
                                    show: true,
                                    period: 6,
                                    trailLength: 0.3,
                                    symbol: 'arrow',
                                    symbolSize: 6,
                                    color: '#FF6B35'
                                },
                                lineStyle: {
                                    width: 2,
                                    color: '#FF6B35',
                                    curveness: 0.2,
                                    opacity: 0.7
                                },
                                data: getAttackPaths()
                            },
                            // 攻击源点
                            {
                                name: '攻击源',
                                type: 'scatter',
                                coordinateSystem: 'geo',
                                zlevel: 3,
                                symbol: 'circle',
                                symbolSize: 10,
                                itemStyle: {
                                    color: '#E63946',
                                    shadowBlur: 10,
                                    shadowColor: '#E63946'
                                },
                                data: getUniqueSources()
                            },
                            // 目标点
                            {
                                name: '目标地址',
                                type: 'scatter',
                                coordinateSystem: 'geo',
                                zlevel: 3,
                                symbol: 'circle',
                                symbolSize: 10,
                                itemStyle: {
                                    color: '#165DFF',
                                    shadowBlur: 10,
                                    shadowColor: '#165DFF'
                                },
                                data: getUniqueTargets()
                            }
                        ]
                    };

                    // 计算每个国家的攻击次数
                    function getAttackCount(countryName) {
                        let count = 0;
                        attackData.forEach(attack => {
                            if (countryCoordinates[attack.sourceCountry]?.name === countryName ||
                                countryCoordinates[attack.targetCountry]?.name === countryName) {
                                count++;
                            }
                        });
                        return count;
                    }

                    // 设置配置并渲染地图
                    myChart.setOption(option);

                    // 窗口大小变化时调整地图大小
                    window.addEventListener('resize', function() {
                        myChart.resize();
                    });
                })
                .catch(error => {
                    console.error('地图加载失败:', error);
                    // 显示错误信息
                    const mapContainer = document.getElementById('world-map');
                    mapContainer.innerHTML = `
                        <div class="flex items-center justify-center h-full text-red-400">
                            <i class="fa fa-exclamation-triangle mr-2"></i>
                            地图加载失败,请检查网络连接
                        </div>
                    `;
                });
        });
    </script>
</body>
</html>