in reply to Re: Perl script needs root privilegies
in thread Perl script needs root privilegies

nobody: ALL=(ALL) NOPASSWD:/sbin/iptables

Eek! Now all of the CGI scripts, mod_perl code and everything else that runs anonymously under the web server, PLUS everything else that runs under user nobody on the system, including things like a font server, will be able to run this command!

The best approach in my opinion is to combine both:

  1. Script is setuid to a dedicated user that runs only that script, and
  2. That dedicated user is only allowed to run a couple of key commands via sudo.

But if I had to choose and use only one approach, I'd pick the OP's.

Now as to how to make the script setuid in the first place, that depends. If you have an operating system like Solaris that has secure setuid scripts, it will work directly. Otherwise you have the suidperl can of worms. As an alternative, the web server might make use of suExec and you may be able to get that to cause your script to run under the correct user ID.

In any case, don't forget to turn on taint checks if they're not turned on automatically for whatever invocation style you end up using (they are turned on automatically for true setuid scripts.

Replies are listed 'Best First'.
Re^3: Perl script needs root privilegies
by tirwhan (Abbot) on Dec 27, 2005 at 19:51 UTC

    You missed out my following statement "I'd prefer to write separate shell scripts which execute exactly the iptables command I want the user to be able to execute" :-). Which would you rather have, /sbin/iptables that is setuid and user-executable (which nobody advocated, for good reason) or my line in sudoers? Same thing goes for scripts you write yourself.


    A computer is a state machine. Threads are for people who can't program state machines. -- Alan Cox

      Which would you rather have, /sbin/iptables that is setuid and user-executable (which nobody advocated, for good reason) or my line in sudoers? Same thing goes for scripts you write yourself.

      Actually those two choices are quite similar (control access to iptables via file permissions or control access via sudoers). I would have neither. I must stress again that the line you suggested for inclusion in sudoers lets you run any iptables command you want (in other words: run iptables with any arguments you want) as long as you are user nobody. Since on the OP's system nobody is the web server account, lots of code runs as that user and will have access to run iptables. Indeed on mostly any system there's usually some piece of code that runs as user nobody that should not be trusted with iptables privileges.

      Obviously the goal is for unprivileged users to be able to cause iptables commands to be executed, but the goal is to only permit those iptables commands that the application specifically requires. Which iptables commands get executed is only under the indirect control of the user, according to what the CGI script will choose to honour. That's why the limited API between the client's user agent and the CGI needs to be the where the barrier between security domains is located (or equivalently, the CGI can call a backend that provides an API that is not more powerful than the one facing the user agent; some other monks suggested that).

      All of this of course assumes that the CGI actually limits what the end user can cause iptables to do. If the CGI script is the following code, then all bets are off!

      use CGI qw/standard/; system("iptables " . param("iptables_command"));