增加frpc配置文件处理
This commit is contained in:
@@ -1,10 +1,12 @@
|
|||||||
package com.tongran.agent.client.core.config;
|
package com.tongran.agent.client.core.config;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
@ConfigurationProperties(prefix = "spring.application")
|
@ConfigurationProperties(prefix = "spring.application")
|
||||||
|
@Data
|
||||||
public class ApplicationProperties {
|
public class ApplicationProperties {
|
||||||
|
|
||||||
private String name;
|
private String name;
|
||||||
@@ -13,54 +15,5 @@ public class ApplicationProperties {
|
|||||||
private String scriptPath;
|
private String scriptPath;
|
||||||
private String tmpPath;
|
private String tmpPath;
|
||||||
private String tempPath;
|
private String tempPath;
|
||||||
|
private String frpPath;
|
||||||
|
|
||||||
// Getter 和 Setter 方法
|
|
||||||
public String getName() {
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setName(String name) {
|
|
||||||
this.name = name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getVersion() {
|
|
||||||
return version;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setVersion(String version) {
|
|
||||||
this.version = version;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getConfPath() {
|
|
||||||
return confPath;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setConfPath(String confPath) {
|
|
||||||
this.confPath = confPath;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getScriptPath() {
|
|
||||||
return scriptPath;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setScriptPath(String scriptPath) {
|
|
||||||
this.scriptPath = scriptPath;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getTmpPath() {
|
|
||||||
return tmpPath;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setTmpPath(String tmpPath) {
|
|
||||||
this.tmpPath = tmpPath;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getTempPath() {
|
|
||||||
return tempPath;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setTempPath(String tempPath) {
|
|
||||||
this.tempPath = tempPath;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -67,6 +67,8 @@ public enum MsgEnum {
|
|||||||
|
|
||||||
Agent版本更新应答("AGENT_VERSION_UPDATE_RSP"),
|
Agent版本更新应答("AGENT_VERSION_UPDATE_RSP"),
|
||||||
|
|
||||||
|
修改frp配置文件应答("UPDATE_FRP_RSP"),
|
||||||
|
|
||||||
多网IP探测上报("NETWORK_DETECT");
|
多网IP探测上报("NETWORK_DETECT");
|
||||||
|
|
||||||
private String value;
|
private String value;
|
||||||
|
|||||||
@@ -0,0 +1,15 @@
|
|||||||
|
package com.tongran.agent.client.core.eo;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class FrpMsgEO {
|
||||||
|
/** 远程端口 */
|
||||||
|
private Integer remotePort;
|
||||||
|
|
||||||
|
/** 服务器端口 */
|
||||||
|
private String serverPort;
|
||||||
|
|
||||||
|
/** 服务器地址 */
|
||||||
|
private String serverAddr;
|
||||||
|
}
|
||||||
@@ -9,6 +9,7 @@ import com.tongran.agent.client.core.config.GlobalConfig;
|
|||||||
import com.tongran.agent.client.core.enums.MsgEnum;
|
import com.tongran.agent.client.core.enums.MsgEnum;
|
||||||
import com.tongran.agent.client.core.eo.AgentVersionUpdateEO;
|
import com.tongran.agent.client.core.eo.AgentVersionUpdateEO;
|
||||||
import com.tongran.agent.client.core.eo.CollectEO;
|
import com.tongran.agent.client.core.eo.CollectEO;
|
||||||
|
import com.tongran.agent.client.core.eo.FrpMsgEO;
|
||||||
import com.tongran.agent.client.core.eo.ScriptPolicyEO;
|
import com.tongran.agent.client.core.eo.ScriptPolicyEO;
|
||||||
import com.tongran.agent.client.core.session.SessionManager;
|
import com.tongran.agent.client.core.session.SessionManager;
|
||||||
import com.tongran.agent.client.netty.MultiTargetNettyClient;
|
import com.tongran.agent.client.netty.MultiTargetNettyClient;
|
||||||
@@ -29,6 +30,7 @@ import org.springframework.stereotype.Service;
|
|||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
|
import java.net.ServerSocket;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.nio.file.*;
|
import java.nio.file.*;
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
@@ -862,9 +864,205 @@ public class AgentServiceImpl implements AgentService {
|
|||||||
// 添加防火墙策略
|
// 添加防火墙策略
|
||||||
addFirewall(netName);
|
addFirewall(netName);
|
||||||
}
|
}
|
||||||
|
if(jsonObject.containsKey("frpMsg")){
|
||||||
|
String frpMsg = jsonObject.getString("frpMsg");
|
||||||
|
FrpMsgEO frpMsgEO = JSON.parseObject(frpMsg, FrpMsgEO.class);
|
||||||
|
String serverAddr = frpMsgEO.getServerAddr();
|
||||||
|
String serverPort = frpMsgEO.getServerPort();
|
||||||
|
Integer remotePort = frpMsgEO.getRemotePort();
|
||||||
|
long timestamp = System.currentTimeMillis();
|
||||||
|
timestamp = Math.round(timestamp / 1000.0);
|
||||||
|
// 先检查端口是否被占用
|
||||||
|
if (remotePort != null && isPortInUse(remotePort)) {
|
||||||
|
AssertLog.info("端口{}被占用", remotePort);
|
||||||
|
JSONObject json = new JSONObject();
|
||||||
|
json.put("resCode",2);
|
||||||
|
json.put("remotePort",remotePort);
|
||||||
|
json.put("resMsg", "端口"+remotePort+"被占用");
|
||||||
|
json.put("timestamp",timestamp);
|
||||||
|
// 判定客户端与服务端是否连接
|
||||||
|
if (Objects.nonNull(sessionManager.getSessionById(GlobalConfig.CLIENT_ID))) {
|
||||||
|
Message message = Message.builder().clientId(GlobalConfig.CLIENT_ID).dataType(MsgEnum.修改frp配置文件应答.getValue())
|
||||||
|
.data(json.toString()).build();
|
||||||
|
sessionManager.writeAndFlush(sessionManager.getSessionById(GlobalConfig.CLIENT_ID).getChannel(), message);
|
||||||
|
AssertLog.info("发送FRP配置文件更新应答={}",JSON.toJSONString(message));
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
// 端口未被占用,修改frpc.toml配置文件
|
||||||
|
updateFrpcConfig(serverAddr, serverPort, remotePort);
|
||||||
|
// 启动frpc服务
|
||||||
|
restartFrpc(properties.getFrpPath());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
/** 启动frpc服务 */
|
||||||
|
private void restartFrpc(String frpPath) {
|
||||||
|
long timestamp = System.currentTimeMillis() / 1000;
|
||||||
|
JSONObject json = new JSONObject();
|
||||||
|
int resCode = 1;
|
||||||
|
String resMsg = "frpc.toml修改成功";
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 停止进程
|
||||||
|
Runtime.getRuntime().exec("pkill -f frpc").waitFor();
|
||||||
|
Thread.sleep(1000);
|
||||||
|
|
||||||
|
// 启动进程
|
||||||
|
String[] cmd = {frpPath + "/frpc", "-c", frpPath + "/frpc.toml"};
|
||||||
|
new ProcessBuilder(cmd)
|
||||||
|
.directory(new File(frpPath))
|
||||||
|
.redirectErrorStream(true)
|
||||||
|
.start();
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
resCode = 0;
|
||||||
|
resMsg = "操作失败: " + e.getMessage();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 基本响应
|
||||||
|
json.put("resCode", resCode);
|
||||||
|
json.put("resMsg", resMsg);
|
||||||
|
json.put("timestamp", timestamp);
|
||||||
|
json.put("isRunning", isFrpcRunning()?"1":"0");
|
||||||
|
|
||||||
|
// 从配置文件获取所有配置
|
||||||
|
Map<String, String> config = readFrpcConfig(frpPath + "/frpc.toml");
|
||||||
|
|
||||||
|
json.put("serverAddr", config.getOrDefault("serverAddr", ""));
|
||||||
|
json.put("serverPort", config.getOrDefault("serverPort", ""));
|
||||||
|
json.put("remotePort", config.getOrDefault("remotePort", ""));
|
||||||
|
json.put("name", config.getOrDefault("name", ""));
|
||||||
|
json.put("type", config.getOrDefault("type", ""));
|
||||||
|
json.put("localIP", config.getOrDefault("localIP", ""));
|
||||||
|
json.put("localPort", config.getOrDefault("localPort", ""));
|
||||||
|
|
||||||
|
if (Objects.nonNull(sessionManager.getSessionById(GlobalConfig.CLIENT_ID))) {
|
||||||
|
Message message = Message.builder()
|
||||||
|
.clientId(GlobalConfig.CLIENT_ID)
|
||||||
|
.dataType(MsgEnum.修改frp配置文件应答.getValue())
|
||||||
|
.data(json.toString())
|
||||||
|
.build();
|
||||||
|
sessionManager.writeAndFlush(sessionManager.getSessionById(GlobalConfig.CLIENT_ID).getChannel(), message);
|
||||||
|
AssertLog.info("发送FRP配置文件更新应答={}", JSON.toJSONString(message));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 从frpc.toml配置文件读取配置
|
||||||
|
*/
|
||||||
|
private Map<String, String> readFrpcConfig(String configPath) {
|
||||||
|
Map<String, String> config = new HashMap<>();
|
||||||
|
|
||||||
|
try {
|
||||||
|
File configFile = new File(configPath);
|
||||||
|
if (!configFile.exists()) {
|
||||||
|
return config;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<String> lines = Files.readAllLines(configFile.toPath());
|
||||||
|
for (String line : lines) {
|
||||||
|
String trimmed = line.trim();
|
||||||
|
if (trimmed.isEmpty() || trimmed.startsWith("#")) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (trimmed.contains("=")) {
|
||||||
|
String[] parts = trimmed.split("=", 2);
|
||||||
|
if (parts.length == 2) {
|
||||||
|
String key = parts[0].trim();
|
||||||
|
String value = parts[1].trim();
|
||||||
|
|
||||||
|
// 去除引号
|
||||||
|
if (value.startsWith("\"") && value.endsWith("\"")) {
|
||||||
|
value = value.substring(1, value.length() - 1);
|
||||||
|
} else if (value.startsWith("'") && value.endsWith("'")) {
|
||||||
|
value = value.substring(1, value.length() - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 去除尾部注释
|
||||||
|
int commentIndex = value.indexOf("#");
|
||||||
|
if (commentIndex != -1) {
|
||||||
|
value = value.substring(0, commentIndex).trim();
|
||||||
|
}
|
||||||
|
|
||||||
|
config.put(key, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
AssertLog.warn("读取配置文件失败: {}", e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
return config;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 检查frpc进程是否在运行
|
||||||
|
*/
|
||||||
|
private boolean isFrpcRunning() {
|
||||||
|
try {
|
||||||
|
Process process = Runtime.getRuntime().exec(new String[]{"ps", "-ef"});
|
||||||
|
String output = new String(process.getInputStream().readAllBytes());
|
||||||
|
return output.contains("frpc") && output.contains("-c");
|
||||||
|
} catch (IOException e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 修改frpc.toml配置文件
|
||||||
|
*/
|
||||||
|
private void updateFrpcConfig(String serverAddr, String serverPort, Integer remotePort) {
|
||||||
|
try {
|
||||||
|
// 配置文件路径
|
||||||
|
String configFile = properties.getFrpPath() + File.separator + "frpc.toml";
|
||||||
|
File file = new File(configFile);
|
||||||
|
|
||||||
|
// 如果文件不存在,创建默认配置
|
||||||
|
if (!file.exists()) {
|
||||||
|
AssertLog.info("FRP配置文件不存在");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 读取现有配置文件
|
||||||
|
List<String> lines = Files.readAllLines(file.toPath(), StandardCharsets.UTF_8);
|
||||||
|
List<String> newLines = new ArrayList<>();
|
||||||
|
|
||||||
|
for (String line : lines) {
|
||||||
|
// 替换serverAddr
|
||||||
|
if (line.trim().startsWith("serverAddr =")) {
|
||||||
|
newLines.add("serverAddr = \"" + serverAddr + "\"");
|
||||||
|
}
|
||||||
|
// 替换serverPort
|
||||||
|
else if (line.trim().startsWith("serverPort =")) {
|
||||||
|
newLines.add("serverPort = " + serverPort);
|
||||||
|
}
|
||||||
|
// 替换remotePort
|
||||||
|
else if (remotePort != null && line.trim().startsWith("remotePort =")) {
|
||||||
|
newLines.add("remotePort = " + remotePort);
|
||||||
|
}
|
||||||
|
// 保持其他行不变
|
||||||
|
else {
|
||||||
|
newLines.add(line);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 写入配置文件
|
||||||
|
Files.write(file.toPath(), newLines, StandardCharsets.UTF_8);
|
||||||
|
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException("修改frpc配置失败: " + e.getMessage(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 检查端口是否被占用
|
||||||
|
*/
|
||||||
|
private boolean isPortInUse(int port) {
|
||||||
|
try (ServerSocket serverSocket = new ServerSocket(port)) {
|
||||||
|
return false; // 端口可用
|
||||||
|
} catch (IOException e) {
|
||||||
|
return true; // 端口已被占用或其他异常
|
||||||
|
}
|
||||||
|
}
|
||||||
@Override
|
@Override
|
||||||
public void checkTrAgent() {
|
public void checkTrAgent() {
|
||||||
String CRON_FILE_PATH = properties.getScriptPath()+"/tr_live.cron";
|
String CRON_FILE_PATH = properties.getScriptPath()+"/tr_live.cron";
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
server:
|
server:
|
||||||
port: 7011
|
port: -1
|
||||||
servlet:
|
servlet:
|
||||||
context-path: /tr-agent-client
|
context-path: /tr-agent-client
|
||||||
|
|
||||||
@@ -16,8 +16,8 @@ logging:
|
|||||||
|
|
||||||
netty:
|
netty:
|
||||||
server:
|
server:
|
||||||
host: 127.0.0.1
|
host: 120.211.95.173
|
||||||
port: 6620
|
port: 56620
|
||||||
client:
|
client:
|
||||||
client-id: client-001
|
client-id: client-001
|
||||||
reconnect-interval: 5
|
reconnect-interval: 5
|
||||||
|
|||||||
@@ -6,11 +6,12 @@ spring:
|
|||||||
matching-strategy: ant_path_matcher
|
matching-strategy: ant_path_matcher
|
||||||
application:
|
application:
|
||||||
name: tr-agent-client
|
name: tr-agent-client
|
||||||
version: 1.1
|
version: 1.1.7
|
||||||
conf-path: /usr/local/tongran/conf
|
conf-path: /usr/local/tongran/conf
|
||||||
script-path: /usr/local/tongran/sbin
|
script-path: /usr/local/tongran/sbin
|
||||||
tmp-path: /usr/local/tongran/tmp
|
tmp-path: /usr/local/tongran/tmp
|
||||||
temp-path: /usr/local/tongran/temp
|
temp-path: /usr/local/tongran/temp
|
||||||
|
frp-path: /usr/local/tongran/frp
|
||||||
web:
|
web:
|
||||||
resources:
|
resources:
|
||||||
static-locations: classpath*:/META-INF/resources/
|
static-locations: classpath*:/META-INF/resources/
|
||||||
|
|||||||
Reference in New Issue
Block a user