OpenBSD 6.6: switching back from httpd to nginx

I really like the idea of httpd being secure and lightweight and all, but I also need flexibily, especially from my webserver. Couple of things I was missing in httpd are:

  • configuring multiple files as index: index "index.html index.php index.htm"
  • block access to certain locations based on IP
  • using custom error pages
  • dynamic vhosts (although I still have to figure out how to do those with https)

I read man pages, asked questions online, used google (as it turns out openbsd httpd is a really shitty search-query when you don’t just want to install wordpress….). I even looked at the code, but my C knowledge is rusty, I know where to make the needed changes in the code, but don’t know quite how to do it. And while I love to learn, that will take some time and quite frankly I don’t have that right now, so…. Let’s go back to nginx!

OEMP!

$ doas pkg_add nginx
$ doas mkdir /etc/nginx/sites-available
$ doas mkdir /etc/nginx/sites-enabled

For now I just wanted my sites back online; I tweaked /etc/nginx/nginx.conf so it uses sites-available and sites-enabled directories:

# /etc/nginx/nginx.conf:
worker_processes  1;

worker_rlimit_nofile 1024;
events {
    worker_connections  800;
}

http {
    include       mime.types;
    default_type  application/octet-stream;
    index         index.html index.php index.htm;

    keepalive_timeout  65;
    server_tokens off;
    disable_symlinks off;

    include sites-enabled/*;
}

Simple and effective main nginx.conf that came with the install with all outcommented lines deleted. After that I created /etc/nginx/php-fpm.conf that can be included in every site-config that needs it:

# /etc/nginx/php-fpm.conf
# pass the PHP scripts to FastCGI server listening on unix socket
#
location ~ \.php$ {
   try_files      $uri $uri/ =404;
   fastcgi_pass   unix:run/php-fpm.sock;
   fastcgi_index  index.php;
   fastcgi_param  SCRIPT_FILENAME $document_root$fastcgi_script_name;
   include        fastcgi_params;
}

So now for a simple site that allows for dynamic vhosting using only http:

# /etc/nginx/sites-available/dynamic.vhosts
server {
	listen 80 default_server;
	listen [::]:80 default_server;

	index index.php index.html index.htm index.nginx-debian.html;

	set $basepath "/vhosts";
	set $domain $host;

	if ($domain ~ "^(.[^.]*)\.(.[^.]*)$") {
		set $rootpath "$1.$2/www/";
		set $servername $domain;
	}

	if ($domain ~ "^(.[^.]*)\.(.[^.]*)\.(.[^.]*)$") {
	        set $rootpath "$2.$3/$1/";
                set $servername $domain;
	}

	server_name $servername;
	root $basepath/$rootpath;

	location / {
		# First attempt to serve request as file, then
		# as directory, then fall back to displaying a 404.
		try_files $uri $uri/ =404;
	}

	include php-fpm.conf;
}

Enable this site:

$ doas ln -sf /etc/nginx/sites-available/dynamic.vhosts /etc/nginx/sites-enabled/dynamic.vhosts

With all the configfiles in place it is time to switch:

$ doas rcctl stop httpd
$ doas rcctl disable httpd
$ doas rcctl enable nginx
$ doas rcctl start nginx

Of course this is not yet final, I’ll have to setup nginx to respond to the acme-challenges that I have in my cron, I still have to setup https too, but at least my sites are back online no matter whether they have an index.html or an index.php.