java调用linux-shell命令执行iptables规格
业务场景
应用系统部署在广东主机上且服务端口为9999,此时需要北京主机需要访问广东主机的9999端口的服务,因为网络策略原因北京主机与广东主机之间无法直接访问,但北京主机与上海主机网络互通,上海与广东之间网络互通。所以从上海主机进行中转,以达到北京主机与广东主机网络打通的目的。
即 192.168.121.55 (北京主机)访问 192.168.121.56:8888端口 (上海),并通过iptables将请求转发到192.168.121.57:9999 (广东)端口
示例:
北京主机:192.168.121.55 (请求发起主机)
上海主机:192.168.121.56 (转发实现主机,转发操作在该主机上进行操作)
广东主机:192.168.121.57 (应答主机,应用系统部署所在主机)
在**上海主机**进行以下命令:
添加转发规则到iptables规则表中
iptables -t nat -A PREROUTING -p tcp --dport 8888 -j DNAT --to-destination 192.168.121.57:9999
为转发请求指明请求来源,将请求B主机3307端口转发至C主机3306端口
iptables -t nat -A POSTROUTING -p tcp -d 192.168.121.57 --dport 9999 -j SNAT --to-source 192.168.121.56
验证:在北京主机上执行:telnet 192.168.121.56:8888 端口,能通说明配置成功;
通过java代码实现, 别磨叽 直接上干货。
controller
package xxx.controller;
import com.alibaba.fastjson.JSONObject;
import com.httphelper.util.TestTables;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@Slf4j
@RestController
public class SouthBusinessController {
@GetMapping("/test")
public String test() {
log.warn("cccccccccccccccccccccccccc");
return "ssssssssssssssss";
}
@GetMapping("/getPrerouting")
public List<String> getPrerouting() throws Exception {
log.warn("getPrerouting");
List<String> strings = TestTables.executeCommand("iptables -t nat -L PREROUTING -n --line");
return strings;
}
/**
* 请求示例
*
* {
* "preCommand":"iptables -t nat -A PREROUTING -p tcp --dport 8888 -j DNAT --to-destination 192.168.121.57:9999",
* "postCommand":"iptables -t nat -A POSTROUTING -p tcp -d 192.168.121.57 --dport 9999 -j SNAT --to-source 192.168.121.56"
* }
*
* @param param
* @return
* @throws Exception
*/
@PostMapping("/addRoute")
public String addRoute(@RequestBody JSONObject param) throws Exception {
log.warn("addRoute ,param:{}", param);
String preCommand = param.getString("preCommand");
log.warn("添加前置commandPre:{} ", preCommand);
TestTables.executeCommand(preCommand);
String postCommand = param.getString("postCommand");
log.warn("添加后置commandpost:{} ", postCommand);
TestTables.executeCommand(postCommand);
return "success";
}
@PostMapping("/delRoute")
public String delRoute(@RequestBody JSONObject param) throws Exception {
log.warn("delRoute , param:{}", param);
String command = param.getString("command");
TestTables.executeCommand(command);
return "success";
}
@GetMapping("/getPostrouting")
public List<String> getPostrouting() throws Exception {
log.warn("getPostrouting");
List<String> strings = TestTables.executeCommand("iptables -t nat -L POSTROUTING -n --line");
return strings;
}
}
工具类
package com.httphelper.util;
import lombok.extern.slf4j.Slf4j;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
@Slf4j
public class TestTables {
public static List<String> executeCommand(String command) throws Exception {
List<String> strings = new ArrayList<>();
BufferedReader reader = null;
try {
// 创建ProcessBuilder对象,并设置要执行的命令和参数
ProcessBuilder pb = new ProcessBuilder("/bin/bash", "-c", command );
// 启动进程,并获得一个Process对象
Process process = pb.start();
// 获取进程的标准输出流,并通过BufferedReader读取输出
reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line;
while ((line = reader.readLine()) != null) {
// log.warn("执行结果:{}", line);
strings.add(line);
}
// 等待进程执行完毕
int exitCode = process.waitFor();
log.warn("Exit code:{}", exitCode);
}catch (Exception e){
log.error("执行异常",e);
}finally {
reader.close();
}
return strings;
}
}