OpenBSD httpd FastCGI
httpd is the OpenBSD built-in Webserver. It has support for FastCGI which is a protocol that allows Web servers to execute external programs through a FastCGI Server. In OpenBSD, the FastCGI Server is called slowcgi and also is in the default installation. So it is possible to build a dynamic website or API without installing additional packages.
First, we create a simple httpd.conf:
# /etc/httpd.conf
server "default" {
listen on * port 80
location "/cgi-bin/*" {
fastcgi
root "/"
}
}
Next, we check the config, enable and start httpd:
rcctl configtest httpd
rcctl enable
rcctl start httpd
Because we need a FastCGI Server, we also enable and start slowcgi:
rcctl enable slowcgi
rcctl start slowcgi
Shell Example
# /var/www/cgi-bin/shell.cgi
#!/bin/sh
echo "Content-Type: text/html";
echo "";
echo "<html>";
echo "<head>";
echo "<title>Test :)</title>";
echo "</head>";
echo "<body>";
echo "<h1>Test :)</h1>";
echo "</body>";
echo "</html>";
After creating the Script, we need to change the user and group to www because httpd and slowcgi run with that user. We also need to make the script executeable for the user. 500
means read and execute for the User only.
chown www:www /var/www/cgi-bin/shell.cgi
chmod 500 /var/www/cgi-bin/shell.cgi
Because httpd and slowcgi are chrooted to /var/www, they cannot access the whole filesystem. That they can execute the script they need /bin/sh
so we need to copy it to /var/www.
cp /bin/sh /var/www/bin/
Now you can open your browser and go to http://[IP]/cgi-bin/shell.cgi
to see the Page.
Perl example
You can do a lot with a Shell Script but for bigger things, it is nicer to have a more complete programming language like Perl.
# /var/www/cgi-bin/perl.cgi
#!/usr/bin/perl
print "Content-Type: text/html\n\n";
print "<html>\n";
print "<head>\n";
print "<title>Test :)</title>\n";
print "</head>\n";
print "<body>\n";
print "<h1>Test :)</h1>\n";
print "</body>\n";
print "</html>\n";
Again we need to set the User/Group and the Execute bit like in the Shell example.
chown www:www /var/www/cgi-bin/perl.cgi
chmod 500 /var/www/cgi-bin/perl.cgi
But the interpreter is not as easy as in the Shell example above. Perl needs a lot more.
which perl
ldd /usr/bin/perl
mkdir /var/www/usr
mkdir /var/www/usr/bin
mkdir /var/www/usr/lib
mkdir /var/www/usr/libexec
cp /usr/bin/perl /var/www/usr/bin/perl
cp /usr/lib/libperl.so.23.0 /var/www/usr/lib/libperl.so.23.0
cp /usr/lib/libm.so.10.1 /var/www/usr/lib/libm.so.10.1
cp /usr/lib/libc.so.99.0 /var/www/usr/lib/libc.so.99.0
cp /usr/libexec/ld.so /var/www/usr/libexec/ld.so
Now you can open your browser and go to http://[IP]/cgi-bin/perl.cgi
to see the Page.
When I learn things like that, I am always very impressed by how much is possible with the default OpenBSD installation.
04 August 2024 - Philipp Keschl