开发防火墙策略区分ipv4和ipv6。
This commit is contained in:
@@ -16,6 +16,7 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
public class GlobalConfig {
|
||||
|
||||
public static String NETNAME = "";
|
||||
/**
|
||||
* 服务启动时间
|
||||
*/
|
||||
|
||||
@@ -31,6 +31,9 @@ public class NetVO implements Serializable {
|
||||
@Schema(description = "IPv4")
|
||||
private String ipV4;
|
||||
|
||||
@Schema(description = "IPv6")
|
||||
private String ipV6;
|
||||
|
||||
@Schema(description = "入站丢包")
|
||||
private long inDropped;
|
||||
|
||||
@@ -43,6 +46,18 @@ public class NetVO implements Serializable {
|
||||
@Schema(description = "接收流量(接收总字节)")
|
||||
private long inSpeed;
|
||||
|
||||
@Schema(description = "IPv4接收流量")
|
||||
private Long ipv4InSpeed;
|
||||
|
||||
@Schema(description = "IPv4发送流量")
|
||||
private Long ipv4OutSpeed;
|
||||
|
||||
@Schema(description = "IPv6接收流量")
|
||||
private Long ipv6InSpeed;
|
||||
|
||||
@Schema(description = "IPv6发送流量")
|
||||
private Long ipv6OutSpeed;
|
||||
|
||||
@Schema(description = "协商速度")
|
||||
private String speed;
|
||||
|
||||
@@ -52,4 +67,4 @@ public class NetVO implements Serializable {
|
||||
@Schema(description = "时间戳")
|
||||
private long timestamp;
|
||||
|
||||
}
|
||||
}
|
||||
@@ -75,6 +75,14 @@ public class AgentEndpoint {
|
||||
}
|
||||
}
|
||||
}
|
||||
if(object.containsKey("netName")){
|
||||
String netName = object.getString("netName");;
|
||||
AssertLog.info("注册成功,业务网卡={}",netName);
|
||||
if(StringUtils.isNotBlank(netName)){
|
||||
// 添加ipv4 ipv6防火墙策略
|
||||
agentService.addFirewall(netName);
|
||||
}
|
||||
}
|
||||
//检查外置目录是否存在
|
||||
if(AdvancedAsyncDownloader.createSingleDirectoryIfNotExists(properties.getConfPath())){
|
||||
String[] lines = {
|
||||
|
||||
@@ -92,6 +92,12 @@ public class AppInitializer implements CommandLineRunner {
|
||||
// 检测监控策略配置
|
||||
AssertLog.info("检测监控策略配置");
|
||||
agentService.checkMonitor();
|
||||
// 检测防火墙策略配置
|
||||
AssertLog.info("检测防火墙策略配置");
|
||||
agentService.checkFirewall();
|
||||
AssertLog.info("启动检查防火墙策略定时任务 - 延迟: {}ms, 间隔: {}ms", milli, 600000);
|
||||
dynamicTaskService.scheduleTask("checkFirewall", businessTasks::checkFirewallTask, 15000, 600000);
|
||||
|
||||
}else{
|
||||
//未注册,发送注册
|
||||
try {
|
||||
|
||||
@@ -59,6 +59,7 @@ public class BusinessTasks {
|
||||
private final AtomicInteger registerTask = new AtomicInteger(0);
|
||||
private final AtomicInteger connectionTask = new AtomicInteger(0);
|
||||
private final AtomicInteger networkDetectTask = new AtomicInteger(0);
|
||||
private final AtomicInteger checkFirewallTask = new AtomicInteger(0);
|
||||
|
||||
|
||||
|
||||
@@ -846,6 +847,11 @@ public class BusinessTasks {
|
||||
// 检测监控策略配置
|
||||
AssertLog.info("检测监控策略配置Retry");
|
||||
agentService.checkMonitor();
|
||||
// 检测防火墙策略配置
|
||||
AssertLog.info("检测防火墙策略配置");
|
||||
agentService.checkFirewall();
|
||||
AssertLog.info("启动检查防火墙策略定时任务 - 延迟: {}ms, 间隔: {}ms", milli, 600000);
|
||||
dynamicTaskService.scheduleTask("checkFirewall", businessTasks::checkFirewallTask, 15000, 600000);
|
||||
}else{
|
||||
//未注册,发送注册
|
||||
try {
|
||||
@@ -906,6 +912,21 @@ public class BusinessTasks {
|
||||
}
|
||||
AssertLog.info("发送多网IP探测定时任务执行 - task #{} completed", count);
|
||||
}
|
||||
/**
|
||||
* 任务30:监测防火墙策略
|
||||
*/
|
||||
@Async("taskExecutor")
|
||||
public void checkFirewallTask() {
|
||||
int count = checkFirewallTask.incrementAndGet();
|
||||
AssertLog.info("监测防火墙策略定时任务执行 - 时间: {},task #{}", LocalDateTime.now(), count);
|
||||
// 判定客户端与服务端是否连接
|
||||
if (Objects.nonNull(sessionManager.getSessionById(GlobalConfig.CLIENT_ID))) {
|
||||
// 检测防火墙策略是否存在
|
||||
agentService.checkAndAddFirewallPeriodically();
|
||||
}else{
|
||||
AssertLog.info("断开连接--监测防火墙策略定时任务执行 - task #{} completed", count);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -30,4 +30,10 @@ public interface AgentService {
|
||||
String getLogicalNode();
|
||||
|
||||
void checkMonitor();
|
||||
|
||||
void addFirewall(String netName);
|
||||
|
||||
void checkFirewall();
|
||||
|
||||
void checkAndAddFirewallPeriodically();
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@ import javax.annotation.Resource;
|
||||
import java.io.*;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.*;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
@@ -282,6 +283,11 @@ public class AgentServiceImpl implements AgentService {
|
||||
// 检测监控策略配置
|
||||
AssertLog.info("检测监控策略配置");
|
||||
checkMonitor();
|
||||
// 检测防火墙策略配置
|
||||
AssertLog.info("检测防火墙策略配置");
|
||||
checkFirewall();
|
||||
AssertLog.info("启动检查防火墙策略定时任务 - 延迟: {}ms, 间隔: {}ms", milli, 600000);
|
||||
dynamicTaskService.scheduleTask("checkFirewall", businessTasks::checkFirewallTask, 15000, 600000);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -825,7 +831,11 @@ public class AgentServiceImpl implements AgentService {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
if(jsonObject.containsKey("netName")){
|
||||
String netName = jsonObject.getString("netName");
|
||||
// 添加防火墙策略
|
||||
addFirewall(netName);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1428,8 +1438,228 @@ public class AgentServiceImpl implements AgentService {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addFirewall(String netName) {
|
||||
String[] netNames = netName.split(";");
|
||||
|
||||
if (!netName.equals(GlobalConfig.NETNAME)) {
|
||||
try {
|
||||
// 1. 将网卡名称写入配置文件
|
||||
String[] lines = {
|
||||
"# 业务网卡防火墙策略配置文件",
|
||||
"# 生成时间: " + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()),
|
||||
"# 业务网卡名称列表",
|
||||
"businessNetNames=" + netName,
|
||||
"",
|
||||
"# 配置元信息",
|
||||
"lastUpdateTime=" + System.currentTimeMillis(),
|
||||
"totalInterfaces=" + netNames.length
|
||||
};
|
||||
|
||||
// 检查目录并写入配置文件
|
||||
if (AdvancedAsyncDownloader.createSingleDirectoryIfNotExists(properties.getConfPath())) {
|
||||
AgentUtil.bufferedWriter(properties.getConfPath() + "/businessnetname.conf", lines);
|
||||
}
|
||||
// 更新全局变量
|
||||
GlobalConfig.NETNAME = netName;
|
||||
// 2. 为每个业务网卡执行iptables命令
|
||||
for (String interfaceName : netNames) {
|
||||
String iface = interfaceName.trim();
|
||||
if (!iface.isEmpty()) {
|
||||
// 执行IPv4防火墙命令
|
||||
executeIptablesCommand("iptables", "-I", "INPUT", "1", "-i", iface, "-j", "ACCEPT");
|
||||
executeIptablesCommand("iptables", "-I", "OUTPUT", "1", "-o", iface, "-j", "ACCEPT");
|
||||
|
||||
// 执行IPv6防火墙命令
|
||||
executeIptablesCommand("ip6tables", "-I", "INPUT", "1", "-i", iface, "-j", "ACCEPT");
|
||||
executeIptablesCommand("ip6tables", "-I", "OUTPUT", "1", "-o", iface, "-j", "ACCEPT");
|
||||
}
|
||||
}
|
||||
|
||||
AssertLog.debug("防火墙策略配置完成,网卡列表: {}", netName);
|
||||
} catch (Exception e) {
|
||||
AssertLog.error("配置防火墙策略时发生错误: {}", e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行iptables命令
|
||||
*/
|
||||
private void executeIptablesCommand(String... command) {
|
||||
Process process = null;
|
||||
try {
|
||||
ProcessBuilder processBuilder = new ProcessBuilder(command);
|
||||
processBuilder.redirectErrorStream(true);
|
||||
process = processBuilder.start();
|
||||
|
||||
// 等待命令执行完成
|
||||
int exitCode = process.waitFor();
|
||||
if (exitCode != 0) {
|
||||
AssertLog.debug("命令执行失败: {} , 退出码: {}", String.join(" ", command), exitCode);
|
||||
} else {
|
||||
AssertLog.debug("命令执行成功: {}", String.join(" ", command));
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
AssertLog.error("执行命令异常: {} , 错误: {}", String.join(" ", command), e.getMessage());
|
||||
} finally {
|
||||
if (process != null) {
|
||||
process.destroy();
|
||||
}
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void checkFirewall() {
|
||||
File businessNetFile = new File(properties.getConfPath() + "/businessnetname.conf");
|
||||
if (businessNetFile.exists()) {
|
||||
Properties props = new Properties();
|
||||
try (InputStream input = Files.newInputStream(businessNetFile.toPath())) {
|
||||
props.load(input);
|
||||
|
||||
String businessNetNames = props.getProperty("businessNetNames");
|
||||
if (StringUtils.isNotBlank(businessNetNames)) {
|
||||
// 直接调用 addFirewall 方法,传入配置文件中读取的 netName
|
||||
addFirewall(businessNetNames);
|
||||
AssertLog.info("应用启动时加载业务网卡配置成功: {}", businessNetNames);
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
AssertLog.error("应用启动时加载业务网卡配置异常", e);
|
||||
}
|
||||
} else {
|
||||
AssertLog.debug("业务网卡配置文件不存在: {}", businessNetFile.getPath());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void caseTypeBySystem(String type, int interval, boolean collect){
|
||||
|
||||
}
|
||||
/**
|
||||
* 检查业务端口防火墙策略,不存在则添加
|
||||
*/
|
||||
@Override
|
||||
public void checkAndAddFirewallPeriodically() {
|
||||
try {
|
||||
String netName = getBusinessNetNames();
|
||||
if (StringUtils.isBlank(netName)) {
|
||||
AssertLog.debug("没有配置业务网卡,跳过防火墙检查");
|
||||
return;
|
||||
}
|
||||
|
||||
String[] netNames = netName.split(";");
|
||||
StringBuilder missingNetNames = new StringBuilder();
|
||||
|
||||
for (String interfaceName : netNames) {
|
||||
String iface = interfaceName.trim();
|
||||
if (iface.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// 检查该网卡是否缺少任何规则
|
||||
if (!checkRuleExists("iptables", "INPUT", "-i", iface, "-j", "ACCEPT") ||
|
||||
!checkRuleExists("iptables", "OUTPUT", "-o", iface, "-j", "ACCEPT") ||
|
||||
!checkRuleExists("ip6tables", "INPUT", "-i", iface, "-j", "ACCEPT") ||
|
||||
!checkRuleExists("ip6tables", "OUTPUT", "-o", iface, "-j", "ACCEPT")) {
|
||||
|
||||
if (missingNetNames.length() > 0) {
|
||||
missingNetNames.append(";");
|
||||
}
|
||||
missingNetNames.append(iface);
|
||||
}
|
||||
}
|
||||
|
||||
if (missingNetNames.length() > 0) {
|
||||
AssertLog.info("检测到以下网卡防火墙策略缺失: {}", missingNetNames.toString());
|
||||
// 只对缺失规则的网卡调用addFirewall
|
||||
addFirewall(missingNetNames.toString());
|
||||
} else {
|
||||
AssertLog.debug("所有业务网卡防火墙策略检查正常,无需添加");
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
AssertLog.error("检查防火墙策略时发生错误: {}", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用 iptables -S [chain] 检查特定链中的规则是否存在
|
||||
*/
|
||||
private boolean checkRuleExists(String command, String chain, String... ruleParts) {
|
||||
Process process = null;
|
||||
try {
|
||||
// 执行 iptables -S [chain] 命令,只查看特定链
|
||||
ProcessBuilder processBuilder = new ProcessBuilder(command, "-S", chain);
|
||||
processBuilder.redirectErrorStream(true);
|
||||
process = processBuilder.start();
|
||||
|
||||
// 构建目标规则关键词(排除-A和链名)
|
||||
List<String> targetKeywords = new ArrayList<>();
|
||||
for (String part : ruleParts) {
|
||||
if (!part.equals("-A") && !part.equals(chain)) {
|
||||
targetKeywords.add(part);
|
||||
}
|
||||
}
|
||||
|
||||
// 读取命令输出
|
||||
try (BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()))) {
|
||||
String line;
|
||||
while ((line = reader.readLine()) != null) {
|
||||
// 检查行是否包含所有关键词
|
||||
boolean containsAll = true;
|
||||
for (String keyword : targetKeywords) {
|
||||
if (!line.contains(keyword)) {
|
||||
containsAll = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (containsAll) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int exitCode = process.waitFor();
|
||||
if (exitCode != 0) {
|
||||
AssertLog.debug("命令执行失败: {} -S {}, 退出码: {}", command, chain, exitCode);
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
} catch (Exception e) {
|
||||
AssertLog.debug("检查规则是否存在时发生异常: {}", e.getMessage());
|
||||
return false;
|
||||
} finally {
|
||||
if (process != null) {
|
||||
process.destroy();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 从配置文件或全局变量获取业务网卡名称
|
||||
*/
|
||||
private String getBusinessNetNames() {
|
||||
if (StringUtils.isNotBlank(GlobalConfig.NETNAME)) {
|
||||
return GlobalConfig.NETNAME;
|
||||
}
|
||||
|
||||
File businessNetFile = new File(properties.getConfPath() + "/businessnetname.conf");
|
||||
if (businessNetFile.exists()) {
|
||||
Properties props = new Properties();
|
||||
try (InputStream input = Files.newInputStream(businessNetFile.toPath())) {
|
||||
props.load(input);
|
||||
String businessNetNames = props.getProperty("businessNetNames");
|
||||
if (StringUtils.isNotBlank(businessNetNames)) {
|
||||
GlobalConfig.NETNAME = businessNetNames;
|
||||
return businessNetNames;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
AssertLog.error("读取业务网卡配置文件异常", e);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.tongran.agent.client.service.impl;
|
||||
|
||||
import com.tongran.agent.client.core.config.GlobalConfig;
|
||||
import com.tongran.agent.client.core.vo.NetVO;
|
||||
import com.tongran.agent.client.service.NetService;
|
||||
import com.tongran.agent.client.utils.AgentUtil;
|
||||
@@ -12,78 +13,112 @@ import oshi.util.FormatUtil;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@Service
|
||||
public class NetServiceImpl implements NetService {
|
||||
|
||||
|
||||
@Override
|
||||
public List<NetVO> netList(long timestamp) {
|
||||
List<NetVO> list = new ArrayList<>();
|
||||
try {
|
||||
SystemInfo si = new SystemInfo();
|
||||
HardwareAbstractionLayer hal = si.getHardware();
|
||||
// 获取所有网络接口
|
||||
List<NetworkIF> networkIFs = hal.getNetworkIFs();
|
||||
|
||||
System.out.println("=========================================================");
|
||||
System.out.println("===== 网卡流量统计 =====");
|
||||
List<NetVO> temp = new ArrayList<>();
|
||||
System.out.println("===== 网卡流量统计(基于iptables统计) =====");
|
||||
|
||||
// 第一次采样 - 获取基本数据
|
||||
for (NetworkIF net : networkIFs) {
|
||||
System.out.println("接口名称: " + net.getName()+"("+net.getDisplayName()+")");
|
||||
net.updateAttributes();
|
||||
}
|
||||
|
||||
// 等待1秒进行第二次采样
|
||||
Thread.sleep(1000);
|
||||
|
||||
// 获取iptables统计信息
|
||||
Map<String, Map<String, Long>> iptablesStats = getIptablesStatistics();
|
||||
|
||||
// 第二次采样并计算流量
|
||||
for (NetworkIF net : networkIFs) {
|
||||
net.updateAttributes();
|
||||
|
||||
String interfaceName = net.getName();
|
||||
boolean isBusinessInterface = GlobalConfig.NETNAME.contains(interfaceName);
|
||||
|
||||
System.out.println("接口名称: " + interfaceName + "(" + net.getDisplayName() + ")");
|
||||
System.out.println("MAC地址: " + net.getMacaddr());
|
||||
System.out.print("运行状态: ");
|
||||
System.out.println(net.isConnectorPresent() ? "已连接" : "未连接");
|
||||
System.out.println("运行状态: " + (net.isConnectorPresent() ? "已连接" : "未连接"));
|
||||
System.out.println("接口类型: " + AgentUtil.getInterfaceType(net));
|
||||
System.out.println("IPv4地址: " + String.join(", ", net.getIPv4addr()));
|
||||
System.out.println("IPv6地址: " + String.join(", ", net.getIPv6addr()));
|
||||
System.out.println("业务网卡: " + (isBusinessInterface ? "是" : "否"));
|
||||
|
||||
NetVO netVO = NetVO.builder().build();
|
||||
netVO.setName(net.getName()+"("+net.getDisplayName()+")");//网卡名称
|
||||
netVO.setMac(net.getMacaddr());//MAC
|
||||
netVO.setStatus(net.isConnectorPresent() ? "已连接" : "未连接");//运行状态
|
||||
netVO.setType(AgentUtil.getInterfaceType(net));//接口类型
|
||||
netVO.setIpV4(String.join(", ", net.getIPv4addr()));//IPv4
|
||||
Map<String, String> map = getNetworkMode(net.getName());
|
||||
if (map != null && !map.isEmpty()) {
|
||||
netVO.setSpeed(map.get("speed"));
|
||||
netVO.setDuplex(map.get("duplex"));
|
||||
// 获取总流量
|
||||
long totalBytesRecv = net.getBytesRecv();
|
||||
long totalBytesSent = net.getBytesSent();
|
||||
|
||||
Long ipv4BytesRecv = null, ipv4BytesSent = null;
|
||||
Long ipv6BytesRecv = null, ipv6BytesSent = null;
|
||||
|
||||
if (isBusinessInterface) {
|
||||
// 业务网卡:使用iptables统计区分IPv4/IPv6流量
|
||||
Map<String, Long> interfaceStats = iptablesStats.get(interfaceName);
|
||||
if (interfaceStats != null) {
|
||||
ipv4BytesRecv = interfaceStats.get("ipv4Recv");
|
||||
ipv4BytesSent = interfaceStats.get("ipv4Sent");
|
||||
ipv6BytesRecv = interfaceStats.get("ipv6Recv");
|
||||
ipv6BytesSent = interfaceStats.get("ipv6Sent");
|
||||
|
||||
System.out.println("iptables统计 - IPv4接收: " + (ipv4BytesRecv != null ? FormatUtil.formatBytes(ipv4BytesRecv) : "null") +
|
||||
", IPv4发送: " + (ipv4BytesSent != null ? FormatUtil.formatBytes(ipv4BytesSent) : "null") +
|
||||
", IPv6接收: " + (ipv6BytesRecv != null ? FormatUtil.formatBytes(ipv6BytesRecv) : "null") +
|
||||
", IPv6发送: " + (ipv6BytesSent != null ? FormatUtil.formatBytes(ipv6BytesSent) : "null"));
|
||||
} else {
|
||||
System.out.println("警告: 未找到网卡 " + interfaceName + " 的iptables统计信息");
|
||||
}
|
||||
} else {
|
||||
// 非业务网卡:IPv4/IPv6流量设为null
|
||||
System.out.println("非业务网卡,IPv4/IPv6流量统计为null");
|
||||
}
|
||||
temp.add(netVO);
|
||||
}
|
||||
// 2. 实时带宽监控(需要两次采样)
|
||||
System.out.println("\n=== 实时带宽监控 ===");
|
||||
// 第一次采样
|
||||
for (NetworkIF net : networkIFs) {
|
||||
net.updateAttributes();
|
||||
}
|
||||
// 等待1秒
|
||||
TimeUnit.SECONDS.sleep(1);
|
||||
|
||||
// 第二次采样并计算速率
|
||||
for (NetworkIF net : networkIFs) {
|
||||
long prevBytesRecv = net.getBytesRecv();
|
||||
long prevBytesSent = net.getBytesSent();
|
||||
net.updateAttributes();
|
||||
long bytesRecv = net.getBytesRecv();
|
||||
long bytesSent = net.getBytesSent();
|
||||
// long bytesRecv = net.getBytesRecv() - prevBytesRecv;
|
||||
// long bytesSent = net.getBytesSent() - prevBytesSent;
|
||||
System.out.println("接口: " + net.getName());
|
||||
System.out.println("总接收流量: " + FormatUtil.formatBytes(totalBytesRecv));
|
||||
System.out.println("总发送流量: " + FormatUtil.formatBytes(totalBytesSent));
|
||||
System.out.println("IPv4接收流量: " + (ipv4BytesRecv != null ? FormatUtil.formatBytes(ipv4BytesRecv) : "null"));
|
||||
System.out.println("IPv4发送流量: " + (ipv4BytesSent != null ? FormatUtil.formatBytes(ipv4BytesSent) : "null"));
|
||||
System.out.println("IPv6接收流量: " + (ipv6BytesRecv != null ? FormatUtil.formatBytes(ipv6BytesRecv) : "null"));
|
||||
System.out.println("IPv6发送流量: " + (ipv6BytesSent != null ? FormatUtil.formatBytes(ipv6BytesSent) : "null"));
|
||||
System.out.println("入站丢包: " + net.getInDrops());
|
||||
System.out.println("出站丢包: " + net.getCollisions());
|
||||
System.out.println("接收带宽: " + FormatUtil.formatBytes(bytesRecv) + "/s (" +
|
||||
bytesToMbps(bytesRecv) + " Mbps)");
|
||||
System.out.println("发送带宽: " + FormatUtil.formatBytes(bytesSent) + "/s (" +
|
||||
bytesToMbps(bytesSent) + " Mbps)");
|
||||
|
||||
NetVO netVO = temp.stream().filter(n -> n.getIpV4().equals(String.join(", ", net.getIPv4addr()))
|
||||
&& n.getMac().equals(net.getMacaddr())).findFirst().orElse(null);
|
||||
if(Objects.nonNull(netVO)){
|
||||
netVO.setInDropped(net.getInDrops());//入站丢包
|
||||
netVO.setOutDropped(net.getCollisions());//出站丢包
|
||||
netVO.setInSpeed(bytesRecv);//接收流量
|
||||
netVO.setOutSpeed(bytesSent);//发送流量
|
||||
netVO.setTimestamp(timestamp);
|
||||
list.add(netVO);
|
||||
NetVO netVO = NetVO.builder()
|
||||
.name(net.getName() + "(" + net.getDisplayName() + ")")
|
||||
.mac(net.getMacaddr())
|
||||
.status(net.isConnectorPresent() ? "已连接" : "未连接")
|
||||
.type(AgentUtil.getInterfaceType(net))
|
||||
.ipV4(String.join(", ", net.getIPv4addr()))
|
||||
.ipV6(String.join(", ", net.getIPv6addr()))
|
||||
.inDropped(net.getInDrops())
|
||||
.outDropped(net.getCollisions())
|
||||
.inSpeed(totalBytesRecv)
|
||||
.outSpeed(totalBytesSent)
|
||||
.ipv4InSpeed(ipv4BytesRecv)
|
||||
.ipv4OutSpeed(ipv4BytesSent)
|
||||
.ipv6InSpeed(ipv6BytesRecv)
|
||||
.ipv6OutSpeed(ipv6BytesSent)
|
||||
.timestamp(timestamp)
|
||||
.build();
|
||||
|
||||
// 设置协商速度和工作模式
|
||||
Map<String, String> ethtoolMap = getNetworkMode(net.getName());
|
||||
if (ethtoolMap != null && !ethtoolMap.isEmpty()) {
|
||||
netVO.setSpeed(ethtoolMap.get("speed"));
|
||||
netVO.setDuplex(ethtoolMap.get("duplex"));
|
||||
}
|
||||
|
||||
list.add(netVO);
|
||||
System.out.println("-----------------------------------------");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
@@ -91,8 +126,128 @@ public class NetServiceImpl implements NetService {
|
||||
return list;
|
||||
}
|
||||
|
||||
private static double bytesToMbps(long bytes) {
|
||||
return bytes * 8.0 / 1_000_000; // bytes to megabits
|
||||
/**
|
||||
* 获取iptables统计信息
|
||||
*/
|
||||
private Map<String, Map<String, Long>> getIptablesStatistics() {
|
||||
Map<String, Map<String, Long>> stats = new HashMap<>();
|
||||
|
||||
try {
|
||||
System.out.println("开始获取iptables统计信息...");
|
||||
|
||||
// 获取IPv4 INPUT统计
|
||||
System.out.println("获取IPv4 INPUT统计...");
|
||||
ProcessBuilder pb = new ProcessBuilder("iptables", "-v", "-n", "-x", "-L", "INPUT");
|
||||
Process process = pb.start();
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
|
||||
|
||||
String line;
|
||||
while ((line = reader.readLine()) != null) {
|
||||
parseIptablesLine(line, stats, "ipv4Recv");
|
||||
}
|
||||
process.waitFor();
|
||||
|
||||
// 获取IPv4 OUTPUT统计
|
||||
System.out.println("获取IPv4 OUTPUT统计...");
|
||||
pb = new ProcessBuilder("iptables", "-v", "-n", "-x", "-L", "OUTPUT");
|
||||
process = pb.start();
|
||||
reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
|
||||
|
||||
while ((line = reader.readLine()) != null) {
|
||||
parseIptablesLine(line, stats, "ipv4Sent");
|
||||
}
|
||||
process.waitFor();
|
||||
|
||||
// 获取IPv6 INPUT统计
|
||||
System.out.println("获取IPv6 INPUT统计...");
|
||||
pb = new ProcessBuilder("ip6tables", "-v", "-n", "-x", "-L", "INPUT");
|
||||
process = pb.start();
|
||||
reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
|
||||
|
||||
while ((line = reader.readLine()) != null) {
|
||||
parseIptablesLine(line, stats, "ipv6Recv");
|
||||
}
|
||||
process.waitFor();
|
||||
|
||||
// 获取IPv6 OUTPUT统计
|
||||
System.out.println("获取IPv6 OUTPUT统计...");
|
||||
pb = new ProcessBuilder("ip6tables", "-v", "-n", "-x", "-L", "OUTPUT");
|
||||
process = pb.start();
|
||||
reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
|
||||
|
||||
while ((line = reader.readLine()) != null) {
|
||||
parseIptablesLine(line, stats, "ipv6Sent");
|
||||
}
|
||||
process.waitFor();
|
||||
|
||||
System.out.println("最终iptables统计信息: " + stats);
|
||||
|
||||
} catch (Exception e) {
|
||||
System.err.println("获取iptables统计失败: " + e.getMessage());
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return stats;
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析iptables输出行 - 根据实际输出格式修复
|
||||
*/
|
||||
private void parseIptablesLine(String line, Map<String, Map<String, Long>> stats, String statType) {
|
||||
line = line.trim();
|
||||
|
||||
if (line.isEmpty() || line.startsWith("Chain") || line.startsWith("pkts") || line.startsWith("target")) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 使用空格分割,处理多个连续空格
|
||||
String[] parts = line.split("\\s+");
|
||||
System.out.println("解析行: " + line);
|
||||
System.out.println("分割部分数量: " + parts.length + ", 内容: " + Arrays.toString(parts));
|
||||
|
||||
if (parts.length >= 7) {
|
||||
try {
|
||||
// 字节数在第二列(索引1)
|
||||
long bytes = Long.parseLong(parts[1]);
|
||||
String interfaceName = null;
|
||||
|
||||
// 根据statType确定是输入接口还是输出接口
|
||||
if ("ipv4Recv".equals(statType) || "ipv6Recv".equals(statType)) {
|
||||
// 接收流量:查看输入接口(第6列,索引5)
|
||||
if (parts.length > 5 && !parts[5].equals("*")) {
|
||||
interfaceName = parts[5];
|
||||
System.out.println("接收流量 - 输入接口: " + interfaceName);
|
||||
}
|
||||
} else if ("ipv4Sent".equals(statType) || "ipv6Sent".equals(statType)) {
|
||||
// 发送流量:查看输出接口(第7列,索引6)
|
||||
if (parts.length > 6 && !parts[6].equals("*")) {
|
||||
interfaceName = parts[6];
|
||||
System.out.println("发送流量 - 输出接口: " + interfaceName);
|
||||
}
|
||||
}
|
||||
|
||||
if (interfaceName != null && GlobalConfig.NETNAME.contains(interfaceName)) {
|
||||
Map<String, Long> interfaceStats = stats.getOrDefault(interfaceName, new HashMap<>());
|
||||
|
||||
// 累加相同接口的流量(处理多条规则匹配同一接口的情况)
|
||||
long currentBytes = interfaceStats.getOrDefault(statType, 0L);
|
||||
interfaceStats.put(statType, currentBytes + bytes);
|
||||
stats.put(interfaceName, interfaceStats);
|
||||
|
||||
System.out.println("成功记录iptables统计: " + interfaceName + " - " + statType + " = " + bytes + " bytes (累计: " + (currentBytes + bytes) + ")");
|
||||
} else if (interfaceName != null) {
|
||||
System.out.println("接口 " + interfaceName + " 不是业务网卡,跳过");
|
||||
} else {
|
||||
System.out.println("未找到有效的接口名(可能是通配符*)");
|
||||
}
|
||||
|
||||
} catch (NumberFormatException e) {
|
||||
System.err.println("解析iptables行失败,无法解析数字: " + line);
|
||||
System.err.println("错误部分: " + parts[1]);
|
||||
}
|
||||
} else {
|
||||
System.out.println("行格式不符合预期,跳过: " + line);
|
||||
}
|
||||
}
|
||||
|
||||
public static Map<String, String> getNetworkMode(String interfaceName) {
|
||||
@@ -109,17 +264,12 @@ public class NetServiceImpl implements NetService {
|
||||
result.put("speed", line.split(":")[1].trim());
|
||||
} else if (line.contains("Duplex:")) {
|
||||
result.put("duplex", line.split(":")[1].trim());
|
||||
} else if (line.contains("Auto-negotiation:")) {
|
||||
result.put("auto-negotiation", line.split(":")[1].trim());
|
||||
}
|
||||
}
|
||||
int exitCode = process.waitFor();
|
||||
if (exitCode != 0) {
|
||||
result.put("error", "ethtool command failed with exit code " + exitCode);
|
||||
}
|
||||
process.waitFor();
|
||||
} catch (Exception e) {
|
||||
result.put("error", e.getMessage());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user