LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   *BSD (https://www.linuxquestions.org/questions/%2Absd-17/)
-   -   moinmoin wiki with OpenBSD httpd(8) (https://www.linuxquestions.org/questions/%2Absd-17/moinmoin-wiki-with-openbsd-httpd-8-a-4175607276/)

Turbocapitalist 06-04-2017 08:17 AM

moinmoin wiki with OpenBSD httpd(8)
 
What I'd like to do is add an instance of the moinmoin wiki in the least invasive way possible to a tiny system I have running OpenBSD snapshots. Looking at the boatload of dependencies, my guess is that there is no way to keep httpd(8) chrooted and still run the wiki.I'm happy with my current setup(s) running chrooted httpd(8) on OpenBSD's snapshots and would like to minimize changes.

I'd prefer not to have to redo everything else under nginx.

How feasible is it to try running moinmoin under httpd(8) if I turn of the chroot?

jggimi 06-04-2017 10:13 AM

You can't "turn off" the chroot in httpd(8). I've never attempted to run it with the chroot set to /, but I suppose one could attempt it.

While I don't know anything about moinmoin, if it uses FastCGI for webserver communication you should still be able to run the webserver without altering the default chroot, either by having a socket linked within the chroot, or using a loopback interface.

Turbocapitalist 06-05-2017 08:28 AM

Quote:

Originally Posted by jggimi (Post 5718919)
While I don't know anything about moinmoin, if it uses FastCGI for webserver communication you should still be able to run the webserver without altering the default chroot, either by having a socket linked within the chroot, or using a loopback interface.

FastCGI seems to be the way to go after reading a bit. It's not as well documented for moinmoin, though. I have some catch-up to do, so this may take a while. I'll post back either once I get stuck or make some progress.

jggimi 06-05-2017 11:41 AM

Using FastCGI simplifies webserver deployment, because the webserver only manages presentation, the application can reside elsewhere. All of my web applications use it, but they're PHP rather than Python, so I may not be much help with provisioning requirements. Also, the majority use nginx due to a need for client certs.

Turbocapitalist 06-06-2017 05:25 AM

Yes it looks like FastCGI simplifies things. httpd(8) uses a socket within the chroot for that. I am pursuing that approach but I'm new to using sockets. Does the FastCGI-using script then just run as a daemon watching the designated socket via an API?

Along the way, the examples I run across for moinmoin all use TCP instead of sockets. I don't see a way for the process and the the web server to authenticate to each other. So, if I read things correctly, it looks like a compromised process could just search around for and take over all the internal FastCGI connections.

jggimi 06-06-2017 05:45 AM

A Unix-domain TCP socket is nothing more than a local (in system) TCP connection that uses a filesystem as the administrative communication tool between processes. It usually has lower overhead than using a loopback address.

I understand that httpd(8) can also listen for TCP connections via the network stack with ":<port number>" as the socket path, such as:
Code:

fastcgi socket ":9991"

jggimi 06-06-2017 06:10 AM

I'd seen that ":<port number>" configuration on the web, though it is not currently documented in the httpd.conf(5) man page. However, the port number is parsed and the socket(2) type switched from AF_UNIX to AF_INET in src/usr.sbin/httpd/server_fcgi.c.

Turbocapitalist 06-06-2017 08:44 AM

Ok. I think I see now how FastCGI works. Or at least I see one way. If I have it set in httpd.conf(5)

Code:

server "default" {
        listen on $ext_addr port 80

        location "/cgi-bin/foo.pl" {
                fastcgi socket "/run/sockets/foo.sock"
        }

}

The the script foo.pl doesn't actually have to exist in the cgi-bin directory. It does have to be running and listening to the socket created, however:

Code:

#!/usr/bin/perl -T 

use strict;       
use warnings;     
use English qw( -no_match_vars );     

use FCGI;         

my $privilege_separated_user = qq(www);
my $sock = qq(/var/www/run/sockets/foo.sock);                                 

my $counter = 0;   

my ( undef, undef, $privilege_separated_uid, $privilege_separated_gid )       
        = getpwnam( $privilege_separated_user )                               
        or die ( "$privilege_separated_user not in passwd file\n" );           

my $socket  = FCGI::OpenSocket($sock, 5);                                     

chown( $privilege_separated_uid, $privilege_separated_gid, $sock )             
        or die("Could not chown '$sock' : $!\n");                             

my $request = FCGI::Request(\*STDIN, \*STDOUT, \*STDERR, \%ENV, $socket);     

$EGID = "$privilege_separated_gid $privilege_separated_gid";                   
$EUID = $privilege_separated_uid;     

while($request->Accept() >= 0) {       
        print qq(Content-type: text/plain\n\n);                               
        print qq(Hello, world\n);     
        $counter++;
        print qq(Counter = $counter\n);
        print qq(U=$EUID; G=$EGID\n);                                         
}                 

exit ( 0 );

The above must be launched as root, it's a sloppy demo.

Regular POSIX permissions apply to the directory and socket. The web server process must be able to read and write the socket, obviously.

Code:

doas ./foo.pl
Also, it does not clean up and remove the socket after exiting.

jggimi 06-06-2017 08:59 AM

If memory serves, the location provisions the use of the socket with matching URIs. So for my PHP applications, all I need is location "*.php" to direct these through the FastCGI socket. And for PHP, the php-fpm package also runs chrooted by default.

---

(Should you discover you need to "disable" the httpd chroot, /etc/examples/httpd.conf shows an example of the chroot set to "/". So my guess above should work if needed.)

Turbocapitalist 06-06-2017 11:37 PM

Quote:

Originally Posted by jggimi (Post 5719645)
So for my PHP applications, all I need is location "*.php" to direct these through the FastCGI socket.

How are the PHP scripts launched in your case?

And if the scripts are all working via a single socket, how do they work out which one the data is for?

jggimi 06-07-2017 05:58 AM

The PHP scripts are launched through php-fpm, the FastCGI Process Manager ("fpm") for PHP.

[Browser with a .php URI] -> [webserver] -> [php-fpm] - > [PHP application]

Turbocapitalist 07-15-2017 04:47 AM

Ok, after figuring this out (kind of), having time to forget, and then re-figuring it out, I'm going to call it done. Moinmoin is rather undocummented if one actually examines what's out there. One has to read a lot of python code to make any headway. But as far as the OpenBSD-specific parts, I think the following three items do it:

From /etc/httpd.conf, it is necessary to specify which socket FastCGI should use for that wiki:

Code:

        location match "/wiki*" {
                ...
                fastcgi socket "/run/sockets/moinmoin.sock"
                ...
        }

That socket is obviously inside httpd's chroot.

Then in the dozens of changes to the wiki source code, one has to specify the same socket to use in moin.fcgi:

Code:

...
# WSGIServer(application).run()
WSGIServer(application,bindAddress="/var/www/run/sockets/moinmoin.sock").run()
...

Of course it has to be in a directory where the account Moinmoin is using can write. Then once that socket is created, it has to be readable and writable by the HTTP daemon. That can be done after the fact by chgrp and chmod

Code:

chgrp www  /var/www/run/sockets/moinmoin.sock ;
chmod g+rw /var/www/run/sockets/moinmoin.sock ;

But it would be better for me to find a way to do it from within the python script at the moment of creation.


All times are GMT -5. The time now is 10:12 PM.