【问题标题】:How can I execute this command the correct way within a java servlet如何在 java servlet 中以正确的方式执行此命令
【发布时间】:2019-01-14 23:49:12
【问题描述】:

我可能在这个语法上错了,或者我根本不知道如何执行这个命令。

        String ipAddress = request.getRemoteAddr();

        System.out.println(ipAddress);

        String[] command = {"sudo iptables -t nat -I PREROUTING 1 -s "+ipAddress+" -p tcp -m tcp --dport 80 -j ACCEPT && sudo iptables -t nat -I PREROUTING 2 -s "+ipAddress+" -p tcp -m tcp --dport 443 -j ACCEPT"};
        ProcessBuilder probuilder = new ProcessBuilder(command);

        Process process = probuilder.start();

        //Read out dir output
        InputStream is = process.getInputStream();
        InputStreamReader isr = new InputStreamReader(is);
        BufferedReader br = new BufferedReader(isr);
        String line;
        System.out.printf("Output of running %s is:\n",
                Arrays.toString(command));
        while ((line = br.readLine()) != null) {
            System.out.println(line);
        }

        //Wait to get exit value
        try {
            int exitValue = process.waitFor();
            System.out.println("\n\nExit Value is " + exitValue);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

当有人成功登录我在 Raspberry pi 上运行的 tomcat(localhost) 服务器时,它们是插入 iptables 规则的 2 个命令。在我的 Mac 上它返回一个异常错误,当我尝试在我的手机上成功登录时,它不会让我访问互联网(当我检查 pi 上的 iptables 时没有插入任何内容)。

【问题讨论】:

    标签: java unix iptables


    【解决方案1】:

    您的代码存在几个问题。 ProcessBuilder 构造函数采用如下参数列表:

    Process p = new ProcessBuilder("myCommand", "myArg").start();
    

    ProcessBuilder Javadoc。在您的情况下,sudo 是命令,其余的是参数。如果您至少有 Java 7,那么您可以使用 inheritIO 方法转发命令的输出。

     ProcessBuilder probuilder = new ProcessBuilder().inheritIO().command("myCommand", "myArg");
    

    查看this 了解详细讨论。

    其次,您必须提供可执行文件的完整路径(即/usr/bin/sudo 而不是sudo),否则它将无法找到它。

    快速修复您的代码应如下所示:

    String[] command = { "/usr/bin/sudo iptables -t nat -I PREROUTING 1 -s " + ipAddress
            + " -p tcp -m tcp --dport 80 -j ACCEPT " };
    String[] commands = command[0].split(" ");
    ProcessBuilder probuilder = new ProcessBuilder(commands);
    

    类似问题here

    希望对你有帮助。

    【讨论】:

    • 非常感谢您的帮助,在我在 Intellij 上的 tomcat 日志中,我得到了它运行命令的响应。但是,在我的 pi 上没有任何反应。原因可能是 sudo 是一个命令,而 iptables 也是一个命令。 iptables 命令应该在我的 2 个重定向规则之上添加 1 个新规则。我还在我的 pi 中授予了我的 tomcat8 超级用户权限。但是,我会尝试检查是否真的将超级用户权限授予了 tomcat。
    • 我编辑了答案。您应该检查iptables 命令的输出和Java 进程的输出。另外,为方便起见,您可以使用iptables 命令创建一个脚本并从java 中执行该脚本。
    • 我试过这个,它给了我:“无法运行程序:”usr/bin/sudo”:错误 = 2,没有这样的文件或目录。我在我的 /usr/bin Pi和sudo列在那里。所以我真的不知道发生了什么。我也没有制作脚本的经验。我怎么能用脚本执行2个iptables命令?但至少现在我知道该命令正在尝试执行。
    • 确保没有多余的空格,否则拆分将无法正常工作。检查路径 - 您似乎错过了第一个斜线 /usr/bin/sudo
    • 它成功了,我将代码重建为非常简单的东西“ Runtime.getRuntime().exec("sudo iptables -t nat -I PREROUTING -s "+ipAddress+" -j ACCEPT"); "并授予 tomcat8 shell 访问权限,因此它可以执行命令。与执行代码相比,sudo 权限似乎更成问题。
    猜你喜欢
    • 2012-11-04
    • 2013-08-14
    • 2014-06-13
    • 2016-03-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-03
    • 1970-01-01
    相关资源
    最近更新 更多