Installing Nextcloud on OpenBSD
So today I went about tearing down my old NextCloud server and rebuilding it on an OpenBSD base. My previous server was based on FreeBSD 12.2.
The process was very different from FreeBSD and I wanted to document this down for future reference.
Software
Software versions used
- OpenBSD 7.0
- OpenBSD httpd
- Postgresql 13.4p0
- PHP 7.4.25
- Redis 6.2.6
- Nextcloud 12.2.2
Preparation
-
Prepare the OpenBSD server as normal, keeping in mind to give
/var
the largest partition you can give. OpenBSD’s HTTPd is chrooted to the/var/www
directory by default. -
Configure
/etc/pf.conf
to accept incoming http and https requests
webports = "{http, https}"
pass proto tcp from any to $ext_if port $webports
Postgres
- Install Postgres and configure a database
# pkg_add postgresql-server
# su - _postgresql
$ mkdir /var/postgresql/data
$ initdb -D /var/postgresql/data -U postgres -A scram-sha-256 -E UTF8 -W
$ exit
# rcctl enable postgresql
# rcctl start postgresql
# psql -U postgres
Password for user postgres:
postgres=# create database nextcloud;
postgres=# create user nextcloud with encrypted password 'topsecret';
postgres=# grant all privileges on database nextcloud to nextcloud;
postgres=# \q
PHP
- Install PHP and the various modules. Choose the 7.4 version each time. Enable the extensions by copying them into the
/etc/php-7.4/
directory. Link the PHP executables.
# pkg_add php php-pdo_pgsql php-bz2 php-curl php-gd php-intl php-gmp php-pcntl php-xml php-zip pecl74-imagick
# cd /etc/php-7.4.sample
# for i in *; do ln -sf ../php-7.4.sample/$i ../php-7.4/; done
# ln -sf /usr/local/bin/php-7.4 /usr/local/bin/php
# ln -sf /usr/local/bin/php-config-7.4 /usr/local/bin/php-config
# ln -sf /usr/local/bin/phpize-7.4 /usr/local/bin/phpize
- Edit
/etc/php-7.4.ini
. I left/etc/php-fpm.conf
at its defaults.
[PHP]
expose_php = Off
max_execution_time = 70
memory_limit = 512M
post_max_size = 512M
upload_max_filesize = 512M
[opcache]
opcache.enable=1
opcache.enable_cli=1
opcache.interned_strings_buffer=8
opcache.max_accelerated_files=10000
opcache.memory_consumption=512
opcache.save_comments=1
opcache.revalidate_freq=1
- Restart PHP-FPM
# rcctl enable php74_fpm
# rcctl start php74_fpm
Redis
- Install Redis as the memory cache server.
# pkg_add redis pecl74-redis
# rcctl enable redis
# rcctl start redis
- Redis will be configured as a UNIX socket in the chrooted
/var/www
directory
# mkdir /var/www/redis
# chown -R www:www /var/www/redis
# chmod 0775 /var/www/redis
# usermod -g www _redis
# cat /etc/redis/redis.conf
port 0
unixsocket /var/www/redis/redis.sock
unixsocketperm 770
logfile "redis.log"
HTTPd and acme-client
- Create the
/var/www/nextcloud
directory and populate it with the contents of the nextcloud zip file downloaded from NextCloud.
# ftp https://download.nextcloud.com/server/releases/nextcloud-22.2.2.zip
# cp /root/nextcloud-22.2.2.zip /var/www/
# cd /var/www/
# pkg_add unzip
# unzip ./nextcloud-22.2.2.zip
# chown -R www:www /var/www/nextcloud
- Configure httpd. Don’t restart it yet - this will be left after configuring
acme-client
.
prefork 4
ext_ip="X.X.X.X"
server "nextcloud.server.domain" {
listen on $ext_ip port 80
location "/.well-known/acme-challenge/*" {
root "/acme"
request strip 2
}
location * {
block return 302 "https://nextcloud.server.domain$REQUEST_URI"
}
}
server "nextcloud.server.domain" {
listen on $ext_ip tls port 443
root "/nextcloud"
directory index index.php
hsts {
preload
subdomains
max-age 15768000
}
tls {
certificate "/etc/ssl/nextcloud.server.domain.fullchain.pem"
key "/etc/ssl/private/nextcloud.server.domain.key"
}
# Set max upload size to 513M (in bytes)
connection max request body 537919488
connection max requests 1000
connection request timeout 3600
connection timeout 3600
location "/.well-known/acme-challenge/*" {
root "/acme"
request strip 2
}
# First deny access to the specified files
location "/.ht*" { block }
location "/.user*" { block }
location "/README" { block }
location "/data*" { block }
location "/config*" { block }
location "/lib*" { block }
location "/3rdparty*" { block }
location "/occ*" { block }
location "/console*" { block }
location "/*.php*" {
fastcgi socket "/run/php-fpm.sock"
}
location "/apps/*" {
pass
}
location "/core/*" {
pass
}
location "/.well-known/carddav" {
block return 301 "/remote.php/dav"
}
location "/.well-known/caldav" {
block return 301 "/remote.php/dav"
}
location "/.well-known/webfinger" {
block return 301 "/public.php?service=webfinger"
}
location "/.well-known/host-meta" {
block return 301 "/public.php?service=host-meta"
}
location "/.well-known/host-meta.json" {
block return 301 "/public.php?service=host-meta-json"
}
location match "/oc[ms]%-provider/*" {
directory index index.php
pass
}
}
- Configure our HTTPS certificates in
/etc/acme-client.conf
to be generated by acme-client
authority letsencrypt {
api url "https://acme-v02.api.letsencrypt.org/directory"
account key "/etc/acme/letsencrypt-privkey.pem"
}
authority letsencrypt-staging {
api url "https://acme-staging-v02.api.letsencrypt.org/directory"
account key "/etc/acme/letsencrypt-staging-privkey.pem"
}
domain nextcloud.server.domain {
domain key "/etc/ssl/private/nextcloud.server.domain.key"
domain full chain certificate "/etc/ssl/nextcloud.server.domain.fullchain.pem"
sign with letsencrypt
}
- Since httpd is chrooted, we need to ensure that hostnames are resolvable and certificates can be verified within the chroot.
# mkdir -p /var/www/etc/ssl
# install -m 444 -o root -g bin /etc/resolv.conf /var/www/etc
# install -m 444 -o root -g bin /etc/ssl/cert.pem /etc/ssl/openssl.cnf /var/www/etc/ssl/
# chown -R www:www /var/www/etc
- Run acme-client to generate the HTTPS certificates and restart httpd
# acme-client -v nextcloud.server.domain
# ocspcheck -N -o /etc/ssl/nextcloud.server.domain.ocsp.pem /etc/ssl/nextcloud.server.domain.pem
# rcctl restart php74_fpm
# rcctl restart httpd
Configuration
- Open a web browser and surf to your Nextcloud installation. Complete the installation.
NextCloud data : /nextcloud/data
Database type: PostgreSQL
Database user : nextcloud
Database password : topsecret
Database name : nextcloud
Datebase server : localhost:5432
- After completing the installation, edit
/var/www/nextcloud/config/config.php
to include the Redis memory cache
'filelocking.enabled' => true,
'memcache.local' => '\\OC\\Memcache\\Redis',
'memcache.locking' => '\\OC\\Memcache\\Redis',
'memcache.distributed' => '\\OC\\Memcache\\Redis',
'redis' =>
array (
'host' => '/redis/redis.sock',
'port' => 0,
'timeout' => 1.5,
),
- Add a cron job for Nextcloud and certificate renewal.
# crontab -u www -e
#*/5 * * * * /usr/local/bin/php-7.4 -f /var/www/nextcloud/cron.php
*/5 * * * * /usr/bin/ftp -Vo - https://nextcloud.server.domain/cron.php >/dev/null
0 0 * * * acme-client nextcloud.server.domain && rcctl reload httpd
0 * * * * ocspcheck -N -o /etc/ssl/nextcloud.server.domain.ocsp.pem /etc/ssl/nextcloud.server.domain.pem && rcctl reload httpd
Caveats of adding ocspcheck in your scripts from the manpage.
While ocspcheck could possibly be used in scripts to query responders for
server certificates seen on client connections, this is almost always a
bad idea. God kills a kitten every time you make an OCSP query from the
client side of a TLS connection.
Testing
- To test the cronjobs, you can issue either command.
# su -m www -c /usr/local/bin/php-7.4 -f /var/www/nextcloud/cron.php
# doas -u www /usr/bin/ftp -Vo - https://nextcloud.server.domain/cron.php
-
Go to Nextcloud Scan to do a security check on your server.
-
Under Settings -> Administration -> Overview, you can view any further security and setup warnings.
-
Now you should have a fully functional Nextcloud server on OpenBSD.