ecuguru has asked for the wisdom of the Perl Monks concerning the following question:

I've written a small perl program to execute a series of Root level commands, and give me the result. It works great when I run it from a terminal, but I tried moving it into my cgi-bin to talk to it from a web page, and I keep getting null responses from the execution commands.

So I call it with things like:
my $result = &SU("/bin/echo","hi");

And when I run from console, I get the result, but when I run from apache, I get null and no system errors.

IS this because apache isn't a sudoer? OR something along those lines, where I can't actually execute a sudo while running as the apache user?

Anyone got any enlightenment on how I can make this work?
#!/usr/bin/perl -w use strict; print CGI::header(); my $result = &SU("/bin/echo","hi"); print $result; exit; sub SU(){ my $app = $_[0]; my $args = $_[1]; $su = Sudo->new( { sudo => '/usr/bin/sudo', username => "root", password => "password", program => $app, program_args => $args } ); $result = $su->sudo_run(); if (exists($result->{error})) { print "Error is $result"; } else { if ($result->{stdout}eq""){ warn(); print "Null response"; } return ($result->{stdout}); } }

Replies are listed 'Best First'.
Re: Executing Sudo Console via Web
by ELISHEVA (Prior) on May 21, 2009 at 08:17 UTC

    A lot depends on how your server is configured. Are you using mod_suexec? If so, what have you set the CGI user to for your virtual host? Is that user given rights in the sudoers file? If not, what rights have you given the server user (e.g. apache) in the sudoers group? Without mod_suexec all scripts run with the rights of the server-wide CGI user (i.e. the user directive in your apache configuration file)

    Do you have FollowSymLinks turned on? What is the <Directory> directive set to for /usr/bin, /usr/sbin? On a secure server you will probably have told Apache not to access those directories at all and following symbolic links is probably turned off as well.

    In general, exercising sensitive root level commands through a web interface is a really bad idea security wise. To implement it you would have to violate a key security principle: give services only the rights they need to run and no more. Most of the changes you would have to make would also make your server in general wide open to attack. For example, adding apache to sudoers with ALL rights would essentially let anyone who hacked into your server account also be able to root your entire machine. Knowing the password for the apache user would be enough to run any script for which the apache user had sudoer rights.

    And if you've hard coded the password in the script (your code looks like you have) or turned off the password requirement in the sudoer's file because prompting for it got in the way of your CGI script, you'll have even more problems. Even if you were using mod_suexec anyone with rights to install and run CGI scripts for that particular virtual host would share your root privileges with you!

    Even if it is a pain, you are still better off doing your root level administration via an ssh connection rather than the web interface. You have much more control over who gets what rights that way.

    If you really must do web based root level administration, you would be better off

    • Creating a special virtual host for the purpose
    • Installing and configuring mod_suexec if you haven't already
    • Assigning a special CGI user for the virtual host. - Do not use yourself as this user. You probably have more rights than you want this virtual host to have.
    • Making sure this user is defined without a login shell and is used only to run scripts for this virtual host. There are people out there who operate bots that scan the internet for IP addresses with open ports and hit servers with brute force password attacks. Disabling the login account reduces the risk that one of these will work.
    • Setting file permissions on the virtual hosts document root and below so that only that CGI user can read and write files to the virtual host.
    • Giving that CGI user the most limited permissions possible in the sudoers file. And DO NOT TURN OFF password permissions.
    • Prompting for the password in real time. NEVER HARD CODE a password with root privileges in a script!
    • Allowing access to the virtual host only through https (passwords entered via http are sent clear text to the server opening you up to a man in the middle attack)
    • Limiting human users who have access to the virtual host to the smallest possible set of users. Consider using mod_pam to handle user authorization. This would allow you to closely align the OS's user account permissions with the sudo-enabled virtual host. It would also give you more authentication options than the standard Apache user authorization system
    • Turning off symbolic links. If symbolic links are on someone can get access to a prohibited file merely by depositing a file in an accessible directory and linking to the prohibited directory. Instead copy the root level commands you need to a privileged directory that is only accessible by this special CGI user. You'll also have to find any libraries they use and copy them to a special directory as well.

    But again, I still think this is a really bad idea. Use ssh, preferrably on an account with PPK only access.

    Best, beth

    Update: added comments about mod_pam

Re: Executing Sudo Console via Web
by tilly (Archbishop) on May 21, 2009 at 06:01 UTC
    I don't see where you use Sudo. If that is not your problem then I would suggest that you print out (getpwuid($<))[0] and see who Apache runs as, then go to the sudoers group to see whether that user has the permissions you want.