Restart Service from Cgi Script

Restart a Unix service via a CGI script

I'd say grant your User restarting rights for tinyproxy:

add this line via visudo:

youruser ALL = NOPASSWD: /sbin/service tinyproxy start, /sbin/service tinyproxy stop, /sbin/service tinyproxy restart

and then your user should be able to execute this:

sudo /sbin/service tinyproxy restart

How to start/stop services using Perl CGI script

I suggest displaying the output from the stop command. I strongly suspect that you will see an error indicating that you do not have permission to stop the service.

A correctly configured web server process will be owned by a user that has almost no permissions on the system. This is a security feature. CGI programs on your web server can be run by anyone who can access the web server. For that reason, the web server user is usually configured to only run a very limited set of programs.

Starting and stopping your web server is something that you will usually need root permissions for. Your web server process will not have root permissions (for, hopefully, obvious reasons). But it's entirely possible that every user on the system (including the web server user) will have permissions to get the status of the web server process. This is why your httpd status command works, while the httpd stop command doesn't.

You could give the web server user temporary permission to start or stop services, using sudo or something like that. But you would need to do it very carefully - perhaps requiring a password on the web page (and transmitting that password securely over https).

But it's probably a better idea to reconsider this approach completely.

Can I also point that it's a bad idea to use backticks to run external commands that you don't want to collect the output from. In cases like that, it will be more efficient to use the system() function.

I also note, that you are loading the CGI module, but not using any of its functionality. You even manually create your Content-Type header, ignoring the module's header() function.

And here's my traditional admonition that writing new CGI programs in 2017 is a terrible idea. Please read CGI::Alternatives and consider a PSGI-based approach instead.

Start background process/daemon from CGI script

Don't fork - run batch separately

This double-forking approach is some kind of hack, which to me is indication it shouldn't be done :). For CGI anyway. Under the general principle that if something is too hard to accomplish, you are probably approaching it the wrong way.

Luckily you give the background info on what you need - a CGI call to initiate some processing that happens independently and to return back to the caller. Well sure - there are unix commands that do just that - schedule command to run at specific time (at) or whenever CPU is free (batch). So do this instead:

import os

os.system("batch <<< '/home/some_user/do_the_due.py'")
# or if you don't want to wait for system idle,
# os.system("at now <<< '/home/some_user/do_the_due.py'")

print 'Content-type: text/html\n'
print 'Done!'

And there you have it. Keep in mind that if there is some output to stdout/stderr, that will be mailed to the user (which is good for debugging but otherwise script probably should keep quiet).

PS. i just remembered that Windows also has version of at, so with minor modification of the invocation you can have that work under apache on windows too (vs fork trick that won't work on windows).

PPS. make sure the process running CGI is not excluded in /etc/at.deny from scheduling batch jobs

How do I programatically restart a system service(not apache) from apache in linux?

Like Skip said, but don't run the CGI as root. Instead, have the CGI call sudo. You can give your web server permission to run /etc/init.d/tomcat restart only in the sudoers file.

I've actually done this at work; the relevant part of the CGI looks like this:

#!/usr/bin/perl
use CGI;
use IPC::Run3;
my $CGI = new CGI;

my $output;
if (defined $CGI->param('go') && 'restart' eq $CGI->param('go')) {
run3 [ qw(sudo /etc/init.d/tomcat5.5 restart) ], \undef, \$output, \$output;
}

print <<EOF
Content-type: text/html

Blah, blah, blah, HTML form, displays $output at some point.
EOF

Here is an example line from /etc/sudoers (use visudo to edit, of course):

ALL     ALL=(root) NOPASSWD: /etc/init.d/tomcat5.5 restart

That allows everyone to restart tomcat. You could limit it to Apache only if you'd like.

Apache2.4 is finally running python script... but why?


  1. The event Multi-Processing Module (MPM) is designed to allow more
    requests to be served simultaneously by passing off some processing
    work to supporting threads, freeing up the main threads to work on new
    requests.
    http://httpd.apache.org/docs/2.2/mod/event.html

  2. This Multi-Processing Module (MPM) implements a non-threaded,
    pre-forking web server. Each server process may answer incoming
    requests, and a parent process manages the size of the server pool. It
    is appropriate for sites that need to avoid threading for
    compatibility with non-thread-safe libraries. It is also the best MPM
    for isolating each request, so that a problem with a single request
    will not affect any other.
    http://httpd.apache.org/docs/current/mod/prefork.html

5)

a2enmod is a script that enables the specified module within
the apache2 configuration.
http://manpages.ubuntu.com/manpages/lucid/man8/a2enmod.8.html

The name a2enmod stands for apache2 enable module.

For some reason the first two lines of the script.py are absolutely
necessary.

The first one tells apache how to execute your cgi script. After all, there are other server side languages, like php, perl, ruby, etc. How is apache supposed to know which server side language you are using?

The second line outputs an HTTP header, which is the simplest header you can use. The headers are required to be output before the body of the request--that's the way the http protocol works.

sudo chmod +x /usr/lib/cgi-bin/script.py 

why do I need this? how come it is not executable by default?

A file cannot be executed unless an administrator has given permission to do so. That is for security reasons.

If there is a more obvious/better/correct way to run a python script
using Apache24, I would really love to learn it.

Most of the commands you listed are to setup the apache configuration. You shouldn't have to run those commands every time you execute a cgi script. Once apache is configured, all you should have to do is start apache, then request a web page.

P.S. Some people recommend adding:

AddHandler cgi-script .py .cgi 

to /etc/apache2/conf-enabled/serve-cgi-bin.conf if you encounter a
problem when running a script on Apache. But for some reason it
doesn't make any difference in my case. Why?

See here:

AddHandler handler-name extension [extension]

Files having the name extension will be served by the specified
handler-name. This mapping is added to any already in force,
overriding any mappings that already exist for the same extension. For
example, to activate CGI scripts with the file extension .cgi, you
might use:

AddHandler cgi-script .cgi

Once that has been put into your httpd.conf file, any file containing
the .cgi extension will be treated as a CGI program.
http://httpd.apache.org/docs/2.2/mod/mod_mime.html#addhandler

So it appears that when you add the AddHandler line it is overriding a configuration setting somewhere that does the same thing.

Response to comment:

ScriptInterpreterSource Directive

This directive is used to control how Apache httpd finds the
interpreter used to run CGI scripts. The default setting is Script.
This causes Apache httpd to use the interpreter pointed to by the
shebang line (first line, starting with #!) in the script
http://httpd.apache.org/docs/current/mod/core.html

On the same page, there is this directive:

CGIMapExtension Directive

This directive is used to control how Apache httpd finds the
interpreter used to run CGI scripts. For example, setting
CGIMapExtension sys:\foo.nlm .foo will cause all CGI script files with
a .foo extension to be passed to the FOO interpreter.

How to restart Perl script running under mod_fcgid when changed?

The right way to do it is a little bit subtle. I would recommend looking at Plack::Loader::Restarter for how to do it, or better yet adapting you app to run on Plack and then just launching it with plackup's -r option to load the restarter automatically. Adapting your app might be easier than you expect, possibly as easy as changing

use CGI::Fast;
while (my $cgi = CGI::Fast->new) {
processRequest($cgi);
}

to

use CGI::Emulate::PSGI;
use CGI;

my $app = CGI::Emulate::PSGI->handler(sub {
my $cgi = CGI->new;
processRequest($cgi);
});

(writing a proper native PSGI app is even nicer, but this version saves you from rewriting most of your app).



Related Topics



Leave a reply



Submit