Discussion:
Apache 2.2 & Perl CGI::Simple running under separate uid's: SCGI? FCGI? PSGI?
(too old to reply)
Ivan Shmakov
2013-02-15 20:45:47 UTC
Permalink
Is there an easy way to run Perl CGI::Simple-based code
interfacing Apache 2.2, under a separate UID? (Apart of suexec,
that is, which, depending on the circumstances, may or may not
constitute "an easy way.") I'd like to make the code
"persistent" as well, but it's not a hard requirement for now.

I've been thinking of using mod_scgi on the Apache's side and
SCGI on Perl's, but I don't seem much work done on either in the
last five years or so.

AIUI, the SCGI specification allows the server to pass pretty
much the same information to the "CGI" code as does CGI proper,
thus, perhaps, it'd be possible for CGI::Simple (upon which my
existing code is based) to support it with little change. Also,
it may make sense to check if Apache's mod_scgi can be adapted
to allow for a Unix domain socket (AF_UNIX) to be used (instead
of AF_INET6 or AF_INET.)

The FCGI Perl module and mod_fcgi look like a bit more promising
a couple, as they seem to support AF_UNIX sockets "out of box."
Are there any issues likely to arise with them?

Finally, should I consider a PSGI implementation (Plack?) along
with Apache for my purpose? Should I use, say,
Plack::Handler::FCGI, for instance?

TIA.

PS. It's possible that I'll consider switching from Apache to Lighttpd
later, so I wonder if there could be any "CGI-like" interfaces
implemented for both of these HTTP servers?
--
FSF associate member #7257
Ben Morrow
2013-02-15 23:15:01 UTC
Permalink
[f'ups set to clpmisc]
Post by Ivan Shmakov
Is there an easy way to run Perl CGI::Simple-based code
interfacing Apache 2.2, under a separate UID? (Apart of suexec,
that is, which, depending on the circumstances, may or may not
constitute "an easy way.") I'd like to make the code
"persistent" as well, but it's not a hard requirement for now.
I've been thinking of using mod_scgi on the Apache's side and
SCGI on Perl's, but I don't seem much work done on either in the
last five years or so.
Are you considering changing the code which calls CGI::Simple, or are
you trying to avoid that?
Post by Ivan Shmakov
AIUI, the SCGI specification allows the server to pass pretty
much the same information to the "CGI" code as does CGI proper,
thus, perhaps, it'd be possible for CGI::Simple (upon which my
existing code is based) to support it with little change. Also,
it may make sense to check if Apache's mod_scgi can be adapted
to allow for a Unix domain socket (AF_UNIX) to be used (instead
of AF_INET6 or AF_INET.)
I have no experience with SCGI.
Post by Ivan Shmakov
The FCGI Perl module and mod_fcgi look like a bit more promising
a couple, as they seem to support AF_UNIX sockets "out of box."
Are there any issues likely to arise with them?
IME FastCGI with FCGI.pm is extremely reliable. I use it either via
Plack or via Catalyst (which uses Plack these days).
Post by Ivan Shmakov
Finally, should I consider a PSGI implementation (Plack?) along
with Apache for my purpose? Should I use, say,
Plack::Handler::FCGI, for instance?
That would be my recommendation. With modules like Plack::App::CGIBin
and CGI::PSGI or CGI::Emulate::PSGI you can probably avoid even having
to change your existing code, or at least migrate it to Plack later. If
your app is small you can migrate it to using Plack::Request directly;
if it's any size that isn't recommended, you're encouraged to use
another layer on top of Plack.
Post by Ivan Shmakov
PS. It's possible that I'll consider switching from Apache to Lighttpd
later, so I wonder if there could be any "CGI-like" interfaces
implemented for both of these HTTP servers?
Both Lighty and nginx (which you should consider as an alternative to
lighty) have good FastCGI support. They also both have good HTTP proxy
support, which is quite a common way to run persistent web apps these
days; basically you use HTTP as the app-to-server protocol as well as
the server-to-client protocol. The principal advantage of PSGI is that
you can switch to a different server protocol without any fuss.

Ben
Ivan Shmakov
2013-02-22 12:53:52 UTC
Permalink
Post by Ben Morrow
[f'ups set to clpmisc]
[Disregarded, and dropped news:comp.lang.perl.misc from
Followup-To:, as my questions below are little related to Perl.]
Post by Ben Morrow
Is there an easy way to run Perl CGI::Simple-based code interfacing
Apache 2.2, under a separate UID? (Apart of suexec, that is, which,
depending on the circumstances, may or may not constitute "an easy
way.")
To clarify: my issue with Apache's mod_suexec is that (as of
2.2) I cannot use configure SuexecUserGroup within, say, a
<Directory /> block. Which means that I have to introduce a
<VirtualHost /> whenever I want to run a new Web application
under a new UID.
Post by Ben Morrow
I'd like to make the code "persistent" as well, but it's not a hard
requirement for now.
[...]
Post by Ben Morrow
Are you considering changing the code which calls CGI::Simple, or are
you trying to avoid that?
FWIW, wrapping a CGI::Simple code into a FCGI loop doesn't seem
like a big deal. Like (untested):

## Was:

my $o
= \*STDOUT;
my $q
= CGI::Simple->new ()
or die ();
## ...
## FIXME: and what about the encoding?
$o->print ($q->header ("-type" => "application/xhtml+xml",
@more_headers));
binmode ($o);
$xml->setEncoding ("utf-8");
$xml->toFH ($o, 0);


## Becomes:

my $sock
= FCGI::OpenSocket ($sock_fn, 7);
die ()
if ($sock < 0);
my $o
= \*STDOUT;
binmode ($o);
my $rq
= FCGI::Request (\*STDIN, $o, \*STDERR, \%ENV, $sock)
or die ();
## NB: a never-ending loop?
while ($rq->Accept () >= 0) {
my $q
= CGI::Simple->new ()
or die ();
## ...
## FIXME: and what about the encoding?
$o->print ($q->header ("-type" => "application/xhtml+xml",
@more_headers));
$xml->setEncoding ("utf-8");
$xml->toFH ($o, 0);
$rq->Finish ();
}

Obviously, any "early exit" locations should be tweaked as well,
and the state cleaned up. (Most of the state should be GC'ed by
the Perl system itself, however, should it be associated with
"my" variables.)

[...]
Post by Ben Morrow
The FCGI Perl module and mod_fcgi look like a bit more promising a
couple, as they seem to support AF_UNIX sockets "out of box." Are
there any issues likely to arise with them?
IME FastCGI with FCGI.pm is extremely reliable.
ACK, thanks!
Post by Ben Morrow
I use it either via Plack or via Catalyst (which uses Plack these
days).
I believe that the only proper way to utilize a separate UID for
a Web application is to start it separately from the HTTP server
(say, with its own script run during the system's boot up), with
the server communicating the application via a Unix socket.

Then, either the starting script, a helper, or the Web
application itself is responsible for dropping the root
privileges. (Just as in the case of the HTTP server itself.)

The use of Unix sockets allows for the Unix filesystem access
control to be utilized, thus ensuring that the HTTP server
passes the (potentially sensitive) information contained within
the HTTP request to the designated application. (It is much
harder to maintain this level of security with TCP/IP sockets.)

Unfortunately, AIUI, the mod_fcgid (as available for Apache 2.2)
insists on starting the Fast CGI code by itself, thus requiring
a set-UID wrapper to switch the UID.

OTOH, mod_proxy_fcgi, while requiring for the Fast CGI code to
be started separately, insists on using TCP/IP sockets.

Thus, as it seems, I'm having no luck with Apache either way.

Lighttpd, however, can be configured in such a way. Consider,
e. g.:

--cut: http://redmine.lighttpd.net/projects/lighttpd/wiki/Docs_ModFastCGI --
fastcgi.server = ( ".php" =>
(( "socket" => "/tmp/php-fastcgi.socket",
"bin-path" => "/usr/local/bin/php"
))
)
--cut: http://redmine.lighttpd.net/projects/lighttpd/wiki/Docs_ModFastCGI --

(though, obviously, "bin-path" is an extra here.)

Unfortunately, I'm somewhat concerned with the (possible) lack
of features in Lighttpd that I may wish to utilize, one of them
being the Kerberos authentication support, yet to appear in its
stable version.

[...]
Post by Ben Morrow
PS. It's possible that I'll consider switching from Apache to
Lighttpd later, so I wonder if there could be any "CGI-like"
interfaces implemented for both of these HTTP servers?
Both Lighty and nginx (which you should consider as an alternative to
lighty)
Perhaps, though at the first glance, Lighttpd looked a bit
easier to configure. (Why, my ~/.lighttpd/lighttpd.conf, which
I used to gain some familiarity with the server, and its CGI
features, is only 27 lines long, sans the blank lines and
comments. IIRC, my ~/.nginx/nginx.conf was a few times larger.)
Post by Ben Morrow
have good FastCGI support. They also both have good HTTP proxy
support, which is quite a common way to run persistent web apps these
days; basically you use HTTP as the app-to-server protocol as well as
the server-to-client protocol.
There seem to be a couple of drawbacks in using HTTP for server
to application communication. Namely:

* I know of no standard way to pass the authentication
credentials (either HTTP "plain" or Kerberos), or X.509
certificate down such a proxy chain;

* as long as Apache is concerned, I expect it to require the use
of TCP/IP sockets for such communication (while using Unix
ones would arguably be more secure.)

Unless these issues are in fact easy to resolve, I wouldn't
really consider HTTP as a substitute for (whatever) CGI.

[...]
--
FSF associate member #7257
Ben Morrow
2013-02-22 17:00:56 UTC
Permalink
Post by Ivan Shmakov
Post by Ben Morrow
[f'ups set to clpmisc]
[Disregarded, and dropped news:comp.lang.perl.misc from
Followup-To:, as my questions below are little related to Perl.]
[since I only read clpmisc I won't see any replies]

<snip>
Post by Ivan Shmakov
Post by Ben Morrow
Are you considering changing the code which calls CGI::Simple, or are
you trying to avoid that?
FWIW, wrapping a CGI::Simple code into a FCGI loop doesn't seem
OK. For some people, in some situations, it would be.

<snip>
Post by Ivan Shmakov
I believe that the only proper way to utilize a separate UID for
a Web application is to start it separately from the HTTP server
(say, with its own script run during the system's boot up), with
the server communicating the application via a Unix socket.
Then, either the starting script, a helper, or the Web
application itself is responsible for dropping the root
privileges. (Just as in the case of the HTTP server itself.)
The use of Unix sockets allows for the Unix filesystem access
control to be utilized, thus ensuring that the HTTP server
passes the (potentially sensitive) information contained within
the HTTP request to the designated application. (It is much
harder to maintain this level of security with TCP/IP sockets.)
I agree with all of this.
Post by Ivan Shmakov
Unfortunately, AIUI, the mod_fcgid (as available for Apache 2.2)
insists on starting the Fast CGI code by itself, thus requiring
a set-UID wrapper to switch the UID.
OTOH, mod_proxy_fcgi, while requiring for the Fast CGI code to
be started separately, insists on using TCP/IP sockets.
The (Perl) Catalyst documentation recommends mod_fastcgi (no 'd'), which
has a FastCgiExternalServer directive for handling this. The module is
3rd-party, available from http://www.fastcgi.com (or, presumably, your
favourite distro).

Ben
Ivan Shmakov
2013-02-22 18:33:59 UTC
Permalink
[...]
Post by Ben Morrow
Post by Ivan Shmakov
[Disregarded, and dropped news:comp.lang.perl.misc from
Followup-To:, as my questions below are little related to Perl.]
[since I only read clpmisc I won't see any replies]
In a better Usenet, one'd simply "subscribe" to the thread
itself...

[...]
Post by Ben Morrow
Post by Ivan Shmakov
Unfortunately, AIUI, the mod_fcgid (as available for Apache 2.2)
insists on starting the Fast CGI code by itself, thus requiring a
set-UID wrapper to switch the UID.
OTOH, mod_proxy_fcgi, while requiring for the Fast CGI code to be
started separately, insists on using TCP/IP sockets.
The (Perl) Catalyst documentation recommends mod_fastcgi (no 'd'),
which has a FastCgiExternalServer directive for handling this.
Indeed, I was sure I've seen something like this while searching
the Web. Thanks!
Post by Ben Morrow
The module is 3rd-party, available from http://www.fastcgi.com (or,
presumably, your favourite distro).
... Alas, it isn't free software (even if it is available free
of charge), which makes enough a difference for me.

I guess I'd have to patch mod_fastcgid instead.
--
FSF associate member #7257
George Mpouras
2013-02-16 11:29:23 UTC
Permalink
out of topic but have you look the dander ?
http://perldancer.org
Loading...