Search code examples
javaunixiptables

How can I execute this command the correct way within a java servlet


I'm probably wrong on the syntax with this one, or I simply have no clue how I can execute this command.

        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();
        }

They are 2 commands to insert an iptables rule when someone succesfully logs in on my tomcat(localhost) server which runs on a Raspberry pi. On my mac it returns an exception error, when I try to log on succesfully on my phone, it won't give me internet access(when I check the iptables on the pi there is nothing inserted).


Solution

  • There are several issues with your code. The ProcessBuilder constructor takes a list of arguments as following:

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

    see ProcessBuilder Javadoc. In your case, sudo is the command and the rest are the arguments. If you have at least Java 7 then you can forward the output of the command by using the inheritIO method.

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

    Check this for a detailed discussion.

    Secondly, you must provide the full path to the executable (i.e. /usr/bin/sudo instead of sudo) otherwise it won't be able to find it.

    A quick fix to your code should look like this:

    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);
    

    Similar question here.

    Hope it helps.