<!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>
网络安全监控中心
星空2025-08-29 11:02
相关推荐
FreeBuf_5 小时前
Kea DHCP高危漏洞CVE-2025-40779:单个数据包即可导致服务器崩溃bdgtd8817814 小时前
动态修补C扩展模块的函数指针有哪些风险?安全的修补方案是什么?深耕云原生14 小时前
Kubernetes 深入浅出系列 | 容器剖析之容器安全bkspiderx14 小时前
安全扫描:目标主机支持RSA密钥交换问题FreeBuf_14 小时前
Chrome高危零日漏洞PoC公开,已被用于野外攻击测试专家17 小时前
ARINC 825板卡的应用奶油话梅糖21 小时前
深入解析交换机端口安全:Sticky MAC的工作原理与应用实践TGC达成共识1 天前
解锁处暑健康生活jokr_1 天前
C++ STL 顶层设计与安全:迭代器、失效与线程安全