Linux网络监控实战:用netlink实时捕获网卡状态与IP变动(附完整C代码)
Linux网络监控实战用netlink实时捕获网卡状态与IP变动附完整C代码你是否曾遇到过这样的场景服务器上的某个关键服务突然失联排查半天才发现是网卡意外down掉了或者一个动态IP环境下的容器其地址变更后依赖它的其他服务却毫不知情导致一连串的调用失败。在分布式系统和云原生架构大行其道的今天对网络状态的实时感知能力已经从“锦上添花”变成了“雪中送炭”的刚需。传统的轮询方式比如周期性执行ifconfig或ip addr show不仅效率低下、延迟高还会给系统带来不必要的开销。对于追求极致性能和实时响应的系统开发者或运维工程师而言我们需要一种更优雅、更高效的解决方案——直接与内核对话。这就是netlink的用武之地。它并非一个新鲜事物但却是Linux内核与用户空间进程进行双向通信的“瑞士军刀”尤其是在网络子系统领域。通过netlink套接字我们可以像订阅一份实时新闻简报一样让内核在网卡状态up/down、IP地址增删等网络事件发生的瞬间主动通知我们的监控程序。这种方式是事件驱动的零延迟零额外开销在无事件时。本文将带你深入实战从理解netlink机制的原理开始一步步构建一个健壮、实用的网络监控工具并附上可直接编译运行的完整C代码。无论你是正在开发一个需要网络自愈能力的中间件还是想深入理解Linux内核的事件通知机制这篇文章都将为你提供一条清晰的路径。1. 理解Netlink内核与用户空间的通信桥梁在深入代码之前我们有必要先厘清netlink到底是什么以及它为何能胜任实时网络监控的任务。简单来说netlink是一种基于套接字socket的进程间通信IPC机制但它专用于内核与用户空间进程之间的数据交换。你可以把它想象成一条在内核和你的应用程序之间铺设的专用数据总线。与传统的ioctl系统调用相比netlink的优势是压倒性的。ioctl是“输入/输出控制”的缩写它通过一个文件描述符和一系列命令字来操作设备或内核对象但其设计是混乱且不可扩展的每个驱动都可以定义自己的命令缺乏统一的消息格式。而netlink则提供了一种标准化、可扩展、异步、全双工的通信模型。Netlink的核心特征包括面向消息数据以自描述的消息struct nlmsghdr形式传递每个消息都包含长度、类型、序列号等元数据便于解析和扩展。多播支持这是实现事件订阅的关键。内核可以将消息发送到特定的“多播组”任何订阅了该组的用户空间套接字都能收到消息完美契合“一对多”的事件通知场景。协议族化Netlink本身是一个套接字协议族PF_NETLINK其下又细分了多个子协议用于不同的子系统。例如NETLINK_ROUTE用于网络路由、链路、地址等信息的管理与通知本文重点。NETLINK_KOBJECT_UEVENT用于内核设备热插拔事件udev的基础。NETLINK_SOCK_DIAG用于监控套接字状态。对于网络监控我们使用NETLINK_ROUTE协议。当创建一个NETLINK_ROUTE类型的netlink套接字并绑定到特定的多播组如RTMGRP_LINK对应链路事件RTMGRP_IPV4_IFADDR对应IPv4地址事件后内核就会在相应事件发生时自动将消息推送给我们。提示你可以通过man 7 netlink和man 7 rtnetlink命令在Linux系统上查看详细的官方手册其中包含了所有的消息类型和数据结构定义。为了更直观地理解netlink在Linux网络栈中的位置及其工作流程我们可以将其与传统轮询方式进行对比特性维度Netlink (事件驱动)传统轮询 (如周期性执行ip命令)响应延迟毫秒级近乎实时。事件发生即触发。取决于轮询间隔通常为秒级存在显著延迟。系统开销极低。仅在事件发生时产生CPU和内存开销。高。无论是否有变化固定间隔都会消耗CPU进行查询和解析。实现复杂度中高。需要理解netlink消息格式和内核数据结构。低。只需调用命令行工具并解析其文本输出。信息丰富度高。能获取到原始的、结构化的内核数据信息全面。中低。依赖于命令行工具的输出格式可能丢失细节。适用场景对实时性要求高的监控、自动化运维、网络管理后台。简单的脚本检查、对实时性不敏感的场景。显然在构建生产级别的监控工具时netlink是更专业的选择。它让我们从被动的“询问者”转变为主动的“倾听者”整个系统的效率和优雅度都得到了提升。2. 实战准备解析核心数据结构与消息流现在让我们把目光投向代码层面。要读懂和编写netlink程序必须掌握几个核心的数据结构它们是构成netlink消息的“砖瓦”。首先是Netlink消息头struct nlmsghdr。每一个netlink消息都以它开头定义了消息的框架。#include linux/netlink.h struct nlmsghdr { __u32 nlmsg_len; /* 整个消息的长度包括头部 */ __u16 nlmsg_type; /* 消息内容类型 */ __u16 nlmsg_flags; /* 标志位 */ __u32 nlmsg_seq; /* 序列号 */ __u32 nlmsg_pid; /* 发送端口ID */ };对于监控程序我们最关心的是nlmsg_type。来自内核的事件通知通常是RTM_NEWLINK链路新建或更新、RTM_DELLINK链路删除、RTM_NEWADDR地址添加、RTM_DELADDR地址删除等。nlmsg_flags中常见的NLM_F_MULTI标志表示这是一个多部分消息中的一片。紧随消息头之后的是具体的协议数据。对于NETLINK_ROUTE协议当nlmsg_type是RTM_NEWLINK或RTM_DELLINK时数据部分是一个struct ifinfomsg它描述了网络接口的通用信息当nlmsg_type是RTM_NEWADDR或RTM_DELADDR时数据部分是一个struct ifaddrmsg它描述了网络地址的信息。#include linux/if_link.h // 实际包含ifinfomsg的定义 #include linux/if_addr.h // 实际包含ifaddrmsg的定义 struct ifinfomsg { unsigned char ifi_family; /* 地址族AF_UNSPEC表示不关心 */ unsigned short ifi_type; /* 设备类型如ARPHRD_ETHER */ int ifi_index; /* 接口索引唯一标识 */ unsigned int ifi_flags; /* 接口标志如IFF_UP, IFF_RUNNING */ unsigned int ifi_change; /* 变化的掩码 */ }; struct ifaddrmsg { unsigned char ifa_family; /* 地址族如AF_INET */ unsigned char ifa_prefixlen; /* 前缀长度即子网掩码 */ unsigned char ifa_flags; /* 地址标志 */ unsigned char ifa_scope; /* 地址作用域 */ int ifa_index; /* 关联的接口索引 */ };在这些固定长度的结构体之后是可变长度的属性Attribute列表。这是netlink设计非常精妙的地方它通过“类型-长度-值”TLV的格式来携带可变或可选的数据。属性由struct rtattr描述struct rtattr { unsigned short rta_len; /* 属性总长度包含本头 */ unsigned short rta_type; /* 属性类型 */ /* 紧接着是属性值数据 */ };例如在ifinfomsg后面可能会跟着IFLA_IFNAME类型的属性其值就是接口的名字如eth0。在ifaddrmsg后面可能会跟着IFA_LOCAL类型的属性其值就是本机的IPv4地址。消息的接收和解析是一个循环过程。内核可能一次返回多个消息通过NLM_F_MULTI标志也可能一个消息被分成多个部分接收需要处理NLMSG_DONE。我们的程序需要在一个大缓冲区中使用NLMSG_OK和NLMSG_NEXT宏来安全地遍历每一个完整的netlink消息。理解了这些数据结构就像拿到了地图接下来我们就可以开始搭建监控程序的主体框架了。3. 构建监控程序从套接字到事件循环让我们从main函数开始一步步搭建程序的骨架。这个程序的核心生命周期是创建套接字 - 绑定到感兴趣的事件组 - 进入循环等待并处理内核事件。第一步创建Netlink套接字。这和我们创建普通的UDP/TCP套接字非常相似。int sock; struct sockaddr_nl addr; // 创建NETLINK_ROUTE协议的原始套接字 if ((sock socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE)) -1) { perror(socket); exit(EXIT_FAILURE); } // 初始化本地地址结构 memset(addr, 0, sizeof(addr)); addr.nl_family AF_NETLINK; // nl_pid通常设置为0内核会自动分配或者可以设置为getpid() addr.nl_pid 0; // 关键订阅我们感兴趣的多播组 // RTMGRP_LINK: 链路网卡状态变化 // RTMGRP_IPV4_IFADDR: IPv4地址变化 addr.nl_groups RTMGRP_LINK | RTMGRP_IPV4_IFADDR; // 绑定套接字 if (bind(sock, (struct sockaddr *)addr, sizeof(addr)) -1) { perror(bind); close(sock); exit(EXIT_FAILURE); }这里有几个关键点SOCK_RAW表示我们处理的是原始的netlink消息需要自己解析消息头。nl_groups的绑定是订阅机制的核心。你可以按位或组合多个组来监听多种事件。例如增加RTMGRP_IPV6_IFADDR就可以同时监听IPv6地址变化。绑定后所有发生在这些组内的内核事件都会自动发送到我们的套接字缓冲区。第二步设置信号处理实现优雅退出。一个常驻的监控程序应该能够响应SIGINTCtrlC等信号清理资源后退出。#include signal.h volatile sig_atomic_t running 1; void signal_handler(int sig) { running 0; // 将运行标志置零使主循环退出 } int main() { ... signal(SIGINT, signal_handler); signal(SIGTERM, signal_handler); ... }第三步主事件循环。在这个循环中我们使用recv系统调用阻塞等待内核发来的数据。char buf[8192]; // 缓冲区建议设置得大一些以容纳可能的大消息 struct nlmsghdr *nlh; int len; while (running) { // 阻塞式接收数据 len recv(sock, buf, sizeof(buf), 0); if (len 0) { // 如果被信号中断recv会返回-1并设置errno为EINTR if (errno EINTR) { continue; } perror(recv); break; } else if (len 0) { // netlink套接字不会返回EOF如果收到0说明有问题 fprintf(stderr, Unexpected EOF on netlink socket\n); break; } // 开始解析缓冲区中的数据 for (nlh (struct nlmsghdr *)buf; NLMSG_OK(nlh, len); nlh NLMSG_NEXT(nlh, len)) { // 如果收到结束标记说明一个多部分消息结束了 if (nlh-nlmsg_type NLMSG_DONE) { break; } // 处理我们关心的消息类型 switch (nlh-nlmsg_type) { case RTM_NEWLINK: case RTM_DELLINK: handle_link_event(nlh); break; case RTM_NEWADDR: case RTM_DELADDR: handle_addr_event(nlh); break; case NLMSG_ERROR: // 处理错误消息 handle_error(nlh); break; default: // 忽略其他不关心的消息类型 break; } } } close(sock); // 退出循环后关闭套接字 return 0;这个循环结构清晰、健壮。它妥善处理了信号中断、网络错误并能正确解析可能包含多个消息的数据包。框架搭好了接下来就是填充最核心的部分handle_link_event和handle_addr_event这两个事件处理器。4. 核心解析处理链路与地址事件事件处理函数是程序的“大脑”它们负责从原始的netlink消息中提取出对我们有意义的、人类可读的信息。我们先来看如何处理网卡链路事件。解析链路事件 (RTM_NEWLINK/RTM_DELLINK)RTM_NEWLINK消息既可能在新网卡加入时触发也可能在现有网卡状态如up/down发生变化时触发。我们需要解析ifinfomsg和其后的属性列表。void handle_link_event(struct nlmsghdr *nlh) { struct ifinfomsg *ifi; struct rtattr *rta; int rta_len; char ifname[IF_NAMESIZE] {0}; // 获取ifinfomsg结构体指针 ifi (struct ifinfomsg *)NLMSG_DATA(nlh); // 跳过回环接口我们通常不关心lo if (ifi-ifi_flags IFF_LOOPBACK) { return; } // 获取属性列表的起始位置和长度 rta (struct rtattr *)((char *)ifi NLMSG_ALIGN(sizeof(*ifi))); rta_len NLMSG_PAYLOAD(nlh, sizeof(*ifi)); // 遍历属性列表 while (RTA_OK(rta, rta_len)) { if (rta-rta_type IFLA_IFNAME) { // 找到接口名属性 strncpy(ifname, (char *)RTA_DATA(rta), sizeof(ifname) - 1); break; } rta RTA_NEXT(rta, rta_len); } if (ifname[0] \0) { // 如果没有IFLA_IFNAME属性尝试通过索引获取名字备选方案 if_indextoname(ifi-ifi_index, ifname); } // 判断接口状态 const char *state NULL; // IFF_RUNNING 通常比 IFF_UP 更能反映物理链路状态 if (ifi-ifi_flags IFF_RUNNING) { state UP (链路就绪); } else if (ifi-ifi_flags IFF_UP) { state UP (管理性开启但链路可能未就绪); } else { state DOWN; } // 判断是新增、删除还是更新 const char *event_type; if (nlh-nlmsg_type RTM_DELLINK) { event_type 接口删除; } else { // 对于NEWLINK可以通过ifi-ifi_change和标志位判断具体发生了什么变化 event_type 接口状态变化; } printf([%s] 接口: %s (索引: %d), 事件: %s, 状态: %s\n, timestamp(), ifname, ifi-ifi_index, event_type, state); }注意IFF_UP是管理状态通过ip link set eth0 up设置而IFF_RUNNING是物理链路状态网线已连接、无线已关联。一个接口可以IFF_UP但!IFF_RUNNING比如网线被拔掉。在判断网络连通性时IFF_RUNNING通常更可靠。解析地址事件 (RTM_NEWADDR/RTM_DELADDR)地址事件的处理逻辑类似但数据结构换成了ifaddrmsg我们关心的属性是IFA_LOCAL本地IPv4地址或IFA_ADDRESS。void handle_addr_event(struct nlmsghdr *nlh) { struct ifaddrmsg *ifa; struct rtattr *rta; int rta_len; char ifname[IF_NAMESIZE] {0}; char addr_str[INET_ADDRSTRLEN] {0}; ifa (struct ifaddrmsg *)NLMSG_DATA(nlh); // 只处理IPv4地址如果需要IPv6请检查 ifa-ifa_family AF_INET6 if (ifa-ifa_family ! AF_INET) { return; } // 根据接口索引获取接口名 if_indextoname(ifa-ifa_index, ifname); rta (struct rtattr *)IFA_RTA(ifa); rta_len IFA_PAYLOAD(nlh); while (rta_len 0 RTA_OK(rta, rta_len)) { // 寻找本地IPv4地址属性 if (rta-rta_type IFA_LOCAL) { struct in_addr *addr (struct in_addr *)RTA_DATA(rta); inet_ntop(AF_INET, addr, addr_str, sizeof(addr_str)); break; } rta RTA_NEXT(rta, rta_len); } if (addr_str[0] ! \0) { const char *event_type (nlh-nlmsg_type RTM_NEWADDR) ? 添加 : 删除; printf([%s] 接口: %s, IPv4地址: %s/%d, 事件: %s\n, timestamp(), ifname, addr_str, ifa-ifa_prefixlen, event_type); } }将这两个解析函数嵌入到上一节的事件循环中一个功能完整的netlink网络监控工具就初具雏形了。它现在可以安静地运行在后台一旦有网卡插拔、启用禁用、或者IP地址变更它都会第一时间在终端上打印出清晰的事件日志。5. 进阶优化与生产环境考量一个能在实验室跑通的demo距离一个能在生产环境稳定运行的工具还有一段路要走。我们需要考虑更多边界情况和性能问题。错误处理与消息验证内核可能返回NLMSG_ERROR类型的消息。一个健壮的程序必须处理它。void handle_error(struct nlmsghdr *nlh) { struct nlmsgerr *err (struct nlmsgerr *)NLMSG_DATA(nlh); // err-error 是负的错误码-errno if (err-error ! 0) { fprintf(stderr, Netlink error: %s (code: %d)\n, strerror(-err-error), err-error); } }缓冲区管理与大消息处理我们使用了固定大小的缓冲区如8KB。虽然绝大多数netlink消息都很小但理论上可能存在更大的消息。更稳健的做法是如果recv返回的len等于我们传入的缓冲区大小说明消息可能被截断。此时应该扩大缓冲区重新接收或者至少记录一个警告。#define BUFFER_INIT_SIZE 8192 #define BUFFER_MAX_SIZE 65536 char *buf malloc(BUFFER_INIT_SIZE); size_t buf_size BUFFER_INIT_SIZE; while (running) { len recv(sock, buf, buf_size, MSG_PEEK | MSG_TRUNC); if (len buf_size) { // 消息比缓冲区大需要扩容 size_t new_size len; char *new_buf realloc(buf, new_size); if (!new_buf) { perror(realloc buffer); break; } buf new_buf; buf_size new_size; // 重新接收不使用PEEK标志 len recv(sock, buf, buf_size, 0); } else { // 正常接收 len recv(sock, buf, buf_size, 0); } // ... 后续解析逻辑 }性能与扩展性多路复用如果你的程序除了监听netlink还需要处理其他I/O如HTTP请求、Unix Socket命令可以考虑使用epoll或libevent等多路复用机制将netlink套接字加入监控集合。消息队列与异步处理在主事件循环中解析和打印日志如果是同步的可能会阻塞新事件的接收。对于高性能场景可以将接收到的原始消息放入一个队列由单独的消费者线程进行处理和记录。过滤与聚合你可能只关心特定网卡如eth0或docker0的事件或者想对频繁的地址变化如DHCP租约更新进行去抖聚合。这可以在解析函数中通过检查ifname或添加简单的计时逻辑来实现。集成与日志在生产环境中直接printf到标准输出是不够的。你应该将事件记录到系统日志如通过syslog接口或者写入结构化的日志文件如JSON格式方便后续被ELK、Prometheus等监控系统采集和分析。#include syslog.h openlog(netlink-monitor, LOG_PID | LOG_CONS, LOG_USER); syslog(LOG_INFO, 接口 %s 状态变为 %s, ifname, state); closelog();编译与运行最后提供一个简单的Makefile和编译说明能让你的工具更容易被他人使用。CCgcc CFLAGS-Wall -Wextra -O2 TARGETnetlink_monitor SRCnetlink_monitor.c all: $(TARGET) $(TARGET): $(SRC) $(CC) $(CFLAGS) -o $ $ clean: rm -f $(TARGET) .PHONY: all clean编译命令make运行命令需要root权限因为需要创建NETLINK_ROUTE套接字sudo ./netlink_monitor你可以尝试在另一个终端执行sudo ip link set eth0 down或sudo ip addr add 192.168.1.100/24 dev eth0观察监控程序的实时输出。这种即时反馈正是netlink机制强大之处的直观体现。通过这个完整的实战项目你不仅获得了一个有用的工具更重要的是掌握了与Linux内核网络子系统深度交互的一种核心方法。

相关新闻

毫米波雷达开发避坑指南:FMCW三角波参数配置的5个常见错误(附车流量检测案例)

毫米波雷达开发避坑指南:FMCW三角波参数配置的5个常见错误(附车流量检测案例)

毫米波雷达开发避坑指南:FMCW三角波参数配置的5个常见错误(附车流量检测案例) 在工业级毫米波雷达的开发过程中,参数配置往往被视为一项基础工作,但其细微的偏差却足以让整个系统失效。许多开发者,尤其是从…

2026/5/17 7:09:57 阅读更多 →
解锁沉浸式体验:UE4/UE5 VR开发的全流程实践指南

解锁沉浸式体验:UE4/UE5 VR开发的全流程实践指南

解锁沉浸式体验:UE4/UE5 VR开发的全流程实践指南 【免费下载链接】VRExpansionPlugin A UE4 VR framework 项目地址: https://gitcode.com/gh_mirrors/vr/VRExpansionPlugin 价值定位:为什么选择VRExpansionPlugin构建VR应用? 在VR开…

2026/7/4 9:43:44 阅读更多 →
PyFA:舰船配置的革新者

PyFA:舰船配置的革新者

PyFA:舰船配置的革新者 【免费下载链接】Pyfa Python fitting assistant, cross-platform fitting tool for EVE Online 项目地址: https://gitcode.com/gh_mirrors/py/Pyfa 你是否曾在EVE Online中面对数十种装备选择而感到无所适从?是否为了找到…

2026/5/17 7:09:55 阅读更多 →

最新新闻

AI 压测数据回放:让模型读报告之前先校准口径

AI 压测数据回放:让模型读报告之前先校准口径

AI 压测数据回放:让模型读报告之前先校准口径 一、压测报告不能直接丢给模型 AI 可以帮助分析压测结果,但前提是输入数据口径清楚。很多压测报告里混着预热阶段、限流阶段、错误重试、下游故障和业务噪声。如果直接让模型总结,很容易得到一段…

2026/7/5 1:22:14 阅读更多 →
AI工具链选型:GitHub Copilot与Cursor、Codeium企业开发场景实测对比

AI工具链选型:GitHub Copilot与Cursor、Codeium企业开发场景实测对比

AI工具链选型:GitHub Copilot与Cursor、Codeium企业开发场景实测对比 一、评测体系设计与方法论 AI编码助手已成为开发效率的关键杠杆。本次评测聚焦三项主流工具的实际表现。从四个维度建立可复现的量化评测框架。 %%{init: {theme: base}}%% radartitle AI编码助手…

2026/7/5 1:20:14 阅读更多 →
PyTorch 数据加载瓶颈:GPU 空等时先看 DataLoader

PyTorch 数据加载瓶颈:GPU 空等时先看 DataLoader

PyTorch 数据加载瓶颈:GPU 空等时先看 DataLoader 一、训练慢不一定是模型慢 PyTorch 训练时,很多人看到速度慢就先改模型、调 batch size、换显卡。但如果 GPU 利用率忽高忽低,可能瓶颈根本不在模型,而在数据加载。图片解码、文本…

2026/7/5 1:20:14 阅读更多 →
群晖DSM 7.2.2视频管理终极解决方案:免费恢复Video Station完整功能

群晖DSM 7.2.2视频管理终极解决方案:免费恢复Video Station完整功能

群晖DSM 7.2.2视频管理终极解决方案:免费恢复Video Station完整功能 【免费下载链接】Video_Station_for_DSM_722 Script to install Video Station in DSM 7.2.2 and DSM 7.3 项目地址: https://gitcode.com/gh_mirrors/vi/Video_Station_for_DSM_722 你是否…

2026/7/5 1:20:14 阅读更多 →
云原生可观测性:构建全链路监控体系

云原生可观测性:构建全链路监控体系

引言在微服务架构和容器化部署成为主流的当下,系统的复杂性呈指数级增长。一个请求可能跨越数十个服务实例,传统的日志查看和单点监控已无法满足故障排查的需求。云原生可观测性(Observability)应运而生,它通过Metrics…

2026/7/5 1:18:13 阅读更多 →
工训赛智能小车 PCB 自制指南:从 BTN7971B 四路驱动到主控布局的 5 个要点

工训赛智能小车 PCB 自制指南:从 BTN7971B 四路驱动到主控布局的 5 个要点

工训赛智能小车PCB设计实战:从四路驱动到主控布局的进阶指南在工程训练综合能力竞赛的智能物流搬运赛项中,一辆性能卓越的小车往往始于精良的PCB设计。当现成模块难以满足定制化需求时,自主设计PCB不仅能显著降低成本,更能实现整车…

2026/7/5 1:18:13 阅读更多 →

日新闻

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容 【免费下载链接】BiliTools A cross-platform bilibili toolbox. 跨平台哔哩哔哩工具箱,支持下载视频、番剧等等各类资源 项目地址: https://gitcode.com/GitHub_Trending/bilit/BiliTools …

2026/7/5 0:03:34 阅读更多 →
威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型的陌生现状在忙碌疲惫的一天里,参与了关于混合后量子密码学的讨论,应付端点攻击找茬的人,还参与留言板讨论后,发现“威胁模型”对多数人仍是陌生概念,且多被当作时髦用语。有趣的相关画作有一幅由 Embyr 创作的…

2026/7/5 0:03:34 阅读更多 →
渗透测试入门指南:从零基础到实战环境搭建

渗透测试入门指南:从零基础到实战环境搭建

1. 从“看热闹”到“入门”:我理解的渗透测试到底是什么?每次看到新闻里说某个大公司的数据被“黑”了,或者某个网站被攻击导致服务瘫痪,你是不是和我一样,心里会冒出两个念头:一是“这黑客真厉害”&#x…

2026/7/5 0:07:38 阅读更多 →

周新闻

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容 【免费下载链接】BiliTools A cross-platform bilibili toolbox. 跨平台哔哩哔哩工具箱,支持下载视频、番剧等等各类资源 项目地址: https://gitcode.com/GitHub_Trending/bilit/BiliTools …

2026/7/5 0:03:34 阅读更多 →
威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型的陌生现状在忙碌疲惫的一天里,参与了关于混合后量子密码学的讨论,应付端点攻击找茬的人,还参与留言板讨论后,发现“威胁模型”对多数人仍是陌生概念,且多被当作时髦用语。有趣的相关画作有一幅由 Embyr 创作的…

2026/7/5 0:03:34 阅读更多 →
渗透测试入门指南:从零基础到实战环境搭建

渗透测试入门指南:从零基础到实战环境搭建

1. 从“看热闹”到“入门”:我理解的渗透测试到底是什么?每次看到新闻里说某个大公司的数据被“黑”了,或者某个网站被攻击导致服务瘫痪,你是不是和我一样,心里会冒出两个念头:一是“这黑客真厉害”&#x…

2026/7/5 0:07:38 阅读更多 →

月新闻