Install snac on OpenBSD (without relayd)
Author and for comments: @antics@mastodon.nu
Last update: - CC0 1.0 Universal
Snac is a simple, minimalistic ActivityPub instance and runs as a daemon (proxied by a TLS-enabled real httpd server) and provides the basic services for a Fediverse / ActivityPub instance (sharing messages and stuff from/to other systems like Mastodon, Pleroma, Friendica, etc.).Read more about and download snac here: https://codeberg.org/grunfink/snac2
This guide guides the steps to install snac on OpenBSD in a chroot'd environment for extra security Apparently I have no idea how to chroot when running the service with rcctl start snac. If anyone knows how to do it, or if it is even necessary, please send me a comment @antics@mastodon.nu and without the need to setup relayd.
Contents
- Web server with tls encryption: httpd and acme-client
- Configure httpd.conf to work with snac (FastCGI)
- Install and run snac in a chroot environment
- Only run snac with the daemon user _snac
- Download and install snac
- Setup the chroot environment
- Run snac in chroot /var/snac
- Enable and start the snac daemon service
httpd
Copy the httpd.conf example config:
cp /etc/examples/httpd.conf /etc/httpd.conf
Edit /etc/httpd.conf and add an optional alias in the tls server section and an optional root to serve your documents and files.It is worth noting that httpd by default runs in chroot /var/www. So the root folder /htdocs/example.com to serve static content from would be in /var/www/htdocs/example.com.
server "example.com" {
listen on * tls port 443
alias "www.example.com"
root "/htdocs/example.com"
...
Test the httpd.conf configuration and start the httpd server:
httpd -dvn
rcctl enable httpd
rcctl start httpd
acme-client
If all went (ok) with httpd you continue and copy the acme-client.conf example config:
cp /etc/examples/acme-client.conf /etc/acme-client.conf
Append your domain to /etc/acme-client.conf:
domain example.com {
alternative names { www.example.com }
domain key "/etc/ssl/private/example.com.key"
domain certificate "/etc/ssl/example.com.crt"
domain full chain certificate "/etc/ssl/example.com.fullchain.pem"
sign with letsencrypt
}
Create directories:
mkdir -p -m 700 /etc/ssl/private
mkdir -p -m 755 /var/www/acme
Run acme-client to create your keys:
acme-client -v example.com
If all went well you should now have your certificates in /etc/ssl. The certificates needs to be renewed every 72 days. Add the following script to /etc/daily.local to automatically check for renewal:
acme-client example.com
if [ $? -eq 0 ]
then
rcctl reload httpd
fi
Add an index.html file to /var/www/htdocs/example.com/ and visit example.com in your browser to test if your server are serving request correctly.
We have now set up a basic httpd server with tls encryption.
The following configuration locations are from the snac(8) man page. Add them to the end of the tls server section in /etc/httpd.conf:
...
#
# snac access points
#
location "/fedi/*" {
fastcgi socket tcp "127.0.0.1" 8001
}
location "/.well-known/webfinger" {
fastcgi socket tcp "127.0.0.1" 8001
}
location "/oauth/*" {
fastcgi socket tcp "127.0.0.1" 8001
}
location "/api/v1/*" {
fastcgi socket tcp "127.0.0.1" 8001
}
location "/api/v2/*" {
fastcgi socket tcp "127.0.0.1" 8001
}
location "/.well-known/nodeinfo" {
fastcgi socket tcp "127.0.0.1" 8001
}
location "/.well-known/host-meta" {
fastcgi socket tcp "127.0.0.1" 8001
}
...
Test the configuration and then reload httpd if all is (ok). Also, start the slowcgi service,
httpd -dvn
rcctl reload httpd
rcctl slowcgi enable
rcctl slowcgi start
Under OpenBSD, snac makes use of the enhanced security functions unveil(2) and pledge(2). However, I'm not a good programmer and would in all certainty not recognize a security hole or backdoor in its code. Also, snac is not popular enough to being audited by security folks. So, we cannot trust snac and need some precautions.
Only run snac with the daemon user _snac
Create user _snac with home directory /var/snac:
useradd -g =uid -c "Snac daemon user." -L daemon -s /sbin/nologin -d /var/snac _snac
Download and install snac
Install git. Git also installs curl which is the only dependency for snac. Then clone snac to $HOME/src and build and install snac:
pkg_add git
mkdir $HOME/src
cd $HOME/src
git clone https://codeberg.org/grunfink/snac2.git
cd snac2
make
make install
Setup the chroot environment
Or am I wrong? According to this presentation, chroot is not a security feature. But then if that is the case, why would httpd run in chroot /var/www?
The point of this part is to make snac run as user _snac in chroot /var/snac. That means basically, where the user _snac is concerned, the root filesystem / is based in /var/snac. My rationale for that is the fact that we cannot trust sources from outside of the OpenBSD ecosystem and especially from sources that are not well audited.Even with well audited sources theres backdoors like the recent xc attack.
Move the snac binary to /var/snac/bin
We will later create a script in place of /usr/local/bin/snac that change user and chroots every time we run the snac binary.
mkdir -p /var/snac/bin
mv /usr/local/bin/snac /var/snac/bin
Check which libraries snac is linked with:
ldd /var/snac/bin/snac
... Name
... /var/snac/bin/snac
... /usr/local/lib/libcurl.so.26.24
... /usr/lib/libcrypto.so.52.0
... /usr/lib/libpthread.so.27.1
... /usr/lib/libc.so.97.1
... /usr/local/lib/libnghttp3.so.2.0
... /usr/local/lib/libngtcp2_crypto_quictls.so.0.0
... /usr/local/lib/libngtcp2.so.3.0
... /usr/lib/libssl.so.55.0
... /usr/local/lib/libnghttp2.so.0.21
... /usr/lib/libz.so.7.0
... /usr/libexec/ld.so
Now, create the same directory structre in /var/snac like so:
mkdir -p /var/snac/usr/local/lib
mkdir -p /var/snac/usr/lib
mkdir -p /var/snac/usr/libexec
And then copy the 11 library files to the corresponding directory in /var/snac
cp /usr/local/lib/libcurl.so.26.2 /var/snac/usr/local/lib
...
cp /usr/libexec/ld.so /var/snac/usr/libexec
Lastly, copy the /var/ld.so.hints file to the chroot environment so that ld.so can find the linked files.
mkdir /var/snac/var/run
cp /var/run/ld.so.hints /var/snac/var/run/ld.so.hints
Optional: if for some reason the shared libraries in /usr/local/lib isn't found in /var/run/ld.so.hints (run ldconfig -r for a list) you can rescan the directories (ldconfig -R /usr/local/lib) and then copy the file as above.
Run snac in chroot /var/snac
First make sure that /var/snac is owned by _snac
chown -R _snac:_snac /var/snac
Execute the snac binary:
chroot -u _snac /var/snac/ /bin/snac
snac 2.51 - A simple, minimalistic ActivityPub instance
Copyright (c) 2022 - 2024 grunfink et al. / MIT license
Commands:
init [{basedir}] Initializes the data storage
...
Everything ok! Create a startup script in /usr/local/bin/snac containing the following:
#!/bin/sh
chroot -u _snac /var/snac snac $1 $2
Lets create your instance. The following command will create and populate a data directory for your instance in /var/snac/snac-data.Optionally you could also name it to be more domain specific, i.e. example.com, instead of snac-data. When asked for a prefix: enter /fedi.
snac init snac-data
Now edit /var/snac/snac-data/server.json and set fastcgi to true:
...
"fastcgi": true,
...
Test run the snac httpd daemon!
snac httpd snac-data
23:19:17 warning: shm object error (No such file or directory)
23:19:17 httpd (FastCGI) start 127.0.0.1:8001 snac/2.51
23:19:17 available (rlimit) fds: 128 (cur) / 1024 (max)
23:19:17 using 4 threads
23:19:17 background thread started
Success! Read the docs and add a new user:
snac adduser snac-data
Attention! This startup script will not start snac in a chrooted environment. I have yet to figure out how to do that. See here, here and here. However the following script works fine.
Create the rc.d startup script for snac in /etc/rc.d/snac with the following contents:
#!/bin/ksh
daemon_args="httpd snac-data"
daemon_logger="daemon.info"
daemon_execdir="/var/snac"
daemon_user="_snac"
daemon="bin/snac ${daemon_args}"
. /etc/rc.d/rc.subr
pexp="${daemon}.*"
rc_reload=NO
rc_bg=YES
rc_cmd $1
Enable and start the service:
rcctl enable snac
rcctl start snac
You should now have a running instance of snac on your OpenBSD box.