feat: ASW-64 新增 api acl 接口
This commit is contained in:
@@ -189,4 +189,61 @@ public class APIController {
|
|||||||
Integer timeout = T.MapUtil.getInt(requestBody, "timeout", 10);
|
Integer timeout = T.MapUtil.getInt(requestBody, "timeout", 10);
|
||||||
return R.ok().putData("result", adbUtil.execShellCommand(cmd, timeout));
|
return R.ok().putData("result", adbUtil.execShellCommand(cmd, timeout));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@GetMapping("/acl")
|
||||||
|
public R listAcl() {
|
||||||
|
return R.ok().putData("records", adbUtil.listAcl());
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/acl")
|
||||||
|
public R addAcl(@RequestBody Map<String, Object> requestBody) {
|
||||||
|
String ip = T.MapUtil.getStr(requestBody, "ip");
|
||||||
|
String port = T.MapUtil.getStr(requestBody, "port");
|
||||||
|
if (T.StrUtil.isAllEmpty(ip, port)) {
|
||||||
|
return R.error(RCode.BAD_REQUEST);
|
||||||
|
}
|
||||||
|
|
||||||
|
String protocol = T.MapUtil.getStr(requestBody, "protocol", "all");
|
||||||
|
if (!T.StrUtil.equalsAny(protocol, "tcp", "udp", "all")) {
|
||||||
|
return R.error(RCode.BAD_REQUEST);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ("all".equals(protocol) && T.StrUtil.isEmpty(ip)) {
|
||||||
|
return R.error(RCode.BAD_REQUEST);
|
||||||
|
}
|
||||||
|
|
||||||
|
adbUtil.addAcl(protocol, ip, port);
|
||||||
|
return R.ok().putData("records", adbUtil.listAcl());
|
||||||
|
}
|
||||||
|
|
||||||
|
@DeleteMapping("/acl")
|
||||||
|
public R deleteAcl(@RequestBody Map<String, Object> requestBody) {
|
||||||
|
String ip = T.MapUtil.getStr(requestBody, "ip");
|
||||||
|
String port = T.MapUtil.getStr(requestBody, "port");
|
||||||
|
if (T.StrUtil.isAllEmpty(ip, port)) {
|
||||||
|
return R.error(RCode.BAD_REQUEST);
|
||||||
|
}
|
||||||
|
|
||||||
|
String protocol = T.MapUtil.getStr(requestBody, "protocol", "all");
|
||||||
|
if (!T.StrUtil.equalsAny(protocol, "tcp", "udp", "all")) {
|
||||||
|
return R.error(RCode.BAD_REQUEST);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ("all".equals(protocol) && T.StrUtil.isEmpty(ip)) {
|
||||||
|
return R.error(RCode.BAD_REQUEST);
|
||||||
|
}
|
||||||
|
|
||||||
|
adbUtil.deleteAcl(protocol, ip, port);
|
||||||
|
return R.ok().putData("records", adbUtil.listAcl());
|
||||||
|
}
|
||||||
|
|
||||||
|
@DeleteMapping("/acl/flush")
|
||||||
|
public R flushAcl() {
|
||||||
|
AdbUtil.CommandResult result = adbUtil.flushAcl();
|
||||||
|
if (0 != result.exitCode()) {
|
||||||
|
return R.error(result.output());
|
||||||
|
}
|
||||||
|
return R.ok();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -136,6 +136,68 @@ public class AdbCommandBuilder {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public AdbCommandBuilder buildIptablesLnRulesCommand(String chainName) {
|
||||||
|
this.command.add("shell");
|
||||||
|
this.command.add("iptables");
|
||||||
|
this.command.add("-nL");
|
||||||
|
this.command.add(chainName);
|
||||||
|
this.command.add("--line-numbers");
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AdbCommandBuilder buildIptablesAddRuleCommand(String chainName, String protocol, String ip, String port) {
|
||||||
|
this.command.add("shell");
|
||||||
|
this.command.add("iptables");
|
||||||
|
this.command.add("-A");
|
||||||
|
this.command.add(chainName);
|
||||||
|
this.command.add("-p");
|
||||||
|
this.command.add(protocol);
|
||||||
|
|
||||||
|
if (T.StrUtil.isNotEmpty(ip)) {
|
||||||
|
this.command.add("-d");
|
||||||
|
this.command.add(ip);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (T.StrUtil.isNotEmpty(port) && !"all".equals(protocol)) {
|
||||||
|
this.command.add("--dport");
|
||||||
|
this.command.add(port);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.command.add("-j");
|
||||||
|
this.command.add("ACCEPT");
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AdbCommandBuilder buildIptablesDelRuleCommand(String chainName, String protocol, String ip, String port) {
|
||||||
|
this.command.add("shell");
|
||||||
|
this.command.add("iptables");
|
||||||
|
this.command.add("-D");
|
||||||
|
this.command.add(chainName);
|
||||||
|
this.command.add("-p");
|
||||||
|
this.command.add(protocol);
|
||||||
|
|
||||||
|
if (T.StrUtil.isNotEmpty(ip)) {
|
||||||
|
this.command.add("-d");
|
||||||
|
this.command.add(ip);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (T.StrUtil.isNotEmpty(port) && !"all".equals(protocol)) {
|
||||||
|
this.command.add("--dport");
|
||||||
|
this.command.add(port);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.command.add("-j");
|
||||||
|
this.command.add("ACCEPT");
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AdbCommandBuilder buildIptablesFlushRuleCommand(String chainName) {
|
||||||
|
this.command.add("shell");
|
||||||
|
this.command.add("iptables");
|
||||||
|
this.command.add("-F");
|
||||||
|
this.command.add(chainName);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
public List<String> build() {
|
public List<String> build() {
|
||||||
return this.command;
|
return this.command;
|
||||||
|
|||||||
@@ -120,6 +120,9 @@ public class AdbUtil {
|
|||||||
// 后台启动
|
// 后台启动
|
||||||
this.execShellCommand("shell am start-foreground-service -n net.christianbeier.droidvnc_ng/.MainService -a net.christianbeier.droidvnc_ng.ACTION_STOP --es net.christianbeier.droidvnc_ng.EXTRA_ACCESS_KEY d042e2b5d5f348588a4e1a243eb7a9a0");
|
this.execShellCommand("shell am start-foreground-service -n net.christianbeier.droidvnc_ng/.MainService -a net.christianbeier.droidvnc_ng.ACTION_STOP --es net.christianbeier.droidvnc_ng.EXTRA_ACCESS_KEY d042e2b5d5f348588a4e1a243eb7a9a0");
|
||||||
this.execShellCommand("shell am start-foreground-service -n net.christianbeier.droidvnc_ng/.MainService -a net.christianbeier.droidvnc_ng.ACTION_START --es net.christianbeier.droidvnc_ng.EXTRA_ACCESS_KEY d042e2b5d5f348588a4e1a243eb7a9a0");
|
this.execShellCommand("shell am start-foreground-service -n net.christianbeier.droidvnc_ng/.MainService -a net.christianbeier.droidvnc_ng.ACTION_START --es net.christianbeier.droidvnc_ng.EXTRA_ACCESS_KEY d042e2b5d5f348588a4e1a243eb7a9a0");
|
||||||
|
|
||||||
|
// 添加自定义链
|
||||||
|
this.addAswOutputChain();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -703,6 +706,111 @@ public class AdbUtil {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 1. 添加自定义链
|
||||||
|
* 2. 自定义链添加到 OUTPUT 链中
|
||||||
|
*/
|
||||||
|
private void addAswOutputChain() {
|
||||||
|
// name=ASW_OUTPUT
|
||||||
|
this.execShellCommand("shell iptables -N ASW_OUTPUT");
|
||||||
|
|
||||||
|
String outputChainResult = CommandExec.exec(AdbCommandBuilder.builder()
|
||||||
|
.serial(this.getSerial())
|
||||||
|
.buildShellCommand(String.format("shell \"iptables -L OUTPUT --line-numbers | grep ASW_OUTPUT\""))
|
||||||
|
.build());
|
||||||
|
log.info("[addAswOutputChain] [ASW_OUTPUT in OUTPUT Chain] [result: {}]", outputChainResult);
|
||||||
|
if (T.StrUtil.isEmpty(outputChainResult)) {
|
||||||
|
// ASW_OUTPUT 添加到 OUTPUT 链中
|
||||||
|
this.execShellCommand("shell iptables -A OUTPUT -j ASW_OUTPUT");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ASW_OUTPUT chain rules
|
||||||
|
* iptables -nL ASW_OUTPUT --line-numbers
|
||||||
|
*/
|
||||||
|
public List<Map> listAcl() {
|
||||||
|
String result = CommandExec.exec(AdbCommandBuilder.builder()
|
||||||
|
.serial(this.getSerial())
|
||||||
|
.buildIptablesLnRulesCommand("ASW_OUTPUT")
|
||||||
|
.build());
|
||||||
|
|
||||||
|
List<Map> chainList = T.ListUtil.list(true);
|
||||||
|
|
||||||
|
String[] lines = result.split("\\n");
|
||||||
|
for (String line : lines) {
|
||||||
|
String[] split = line.split("\\s+");
|
||||||
|
|
||||||
|
String chainIndex = T.StrUtil.trim(split[0]);
|
||||||
|
|
||||||
|
if (T.StrUtil.isNumeric(chainIndex)) {
|
||||||
|
String protocol = T.StrUtil.trim(split[2]);
|
||||||
|
Map<Object, Object> m = T.MapUtil.builder()
|
||||||
|
.put("num", Integer.valueOf(chainIndex))
|
||||||
|
.put("protocol", protocol)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
String destIp = T.StrUtil.trim(split[5]);
|
||||||
|
if (!T.StrUtil.equals("0.0.0.0/0", destIp)) {
|
||||||
|
m.put("ip", destIp);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (split.length == 8) {
|
||||||
|
String dpt = T.StrUtil.trim(split[7]);
|
||||||
|
dpt = dpt.replaceAll("dpt:", "");
|
||||||
|
if (T.StrUtil.isNumeric(chainIndex)) {
|
||||||
|
m.put("port", Integer.valueOf(dpt));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
chainList.add(m);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return chainList;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* add chain rule
|
||||||
|
* iptables -A ASW_OUTPUT -p prot -d ip --dport port -j ACCEPT
|
||||||
|
*/
|
||||||
|
public void addAcl(String protocol, String ip, String port) {
|
||||||
|
// add chain
|
||||||
|
this.addAswOutputChain();
|
||||||
|
|
||||||
|
// add chain ruls
|
||||||
|
String result = CommandExec.exec(AdbCommandBuilder.builder()
|
||||||
|
.serial(this.getSerial())
|
||||||
|
.buildIptablesAddRuleCommand("ASW_OUTPUT", protocol, ip, port)
|
||||||
|
.build());
|
||||||
|
log.info("[addAcl] [protocol: {}] [ip: {}] [port: {}] [result: {}]", protocol, ip, port, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* del chain rule
|
||||||
|
* iptables -D ASW_OUTPUT -p prot -d ip --dport port -j ACCEPT
|
||||||
|
*/
|
||||||
|
public void deleteAcl(String protocol, String ip, String port) {
|
||||||
|
// add chain ruls
|
||||||
|
String result = CommandExec.exec(AdbCommandBuilder.builder()
|
||||||
|
.serial(this.getSerial())
|
||||||
|
.buildIptablesDelRuleCommand("ASW_OUTPUT", protocol, ip, port)
|
||||||
|
.build());
|
||||||
|
log.info("[deleteAcl] [protocol: {}] [ip: {}] [port: {}] [result: {}]", protocol, ip, port, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* flushAcl
|
||||||
|
* iptables -F ASW_OUTPUT
|
||||||
|
*/
|
||||||
|
public CommandResult flushAcl() {
|
||||||
|
String result = CommandExec.exec(AdbCommandBuilder.builder()
|
||||||
|
.serial(this.getSerial())
|
||||||
|
.buildIptablesFlushRuleCommand("ASW_OUTPUT")
|
||||||
|
.build());
|
||||||
|
log.info("[flushAcl] [result: {}]", result);
|
||||||
|
return new CommandResult(T.StrUtil.isNotEmpty(result) ? 1 : 0, result);
|
||||||
|
}
|
||||||
|
|
||||||
private synchronized ExecutorService getThreadPool() {
|
private synchronized ExecutorService getThreadPool() {
|
||||||
if (threadPool == null) {
|
if (threadPool == null) {
|
||||||
threadPool = new ThreadPoolExecutor(
|
threadPool = new ThreadPoolExecutor(
|
||||||
|
|||||||
@@ -11,7 +11,9 @@ public class Constant {
|
|||||||
static {
|
static {
|
||||||
File tempPath = T.FileUtil.file(TEMP_PATH);
|
File tempPath = T.FileUtil.file(TEMP_PATH);
|
||||||
// 程序启动清空临时目录
|
// 程序启动清空临时目录
|
||||||
T.FileUtil.del(tempPath);
|
// T.FileUtil.del(tempPath);
|
||||||
T.FileUtil.mkdir(tempPath);
|
if (!T.FileUtil.exist(tempPath)) {
|
||||||
|
T.FileUtil.mkdir(tempPath);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user