🍄Bookmarks Manager On Openbsd

I need a way to store all my links and find them quickly. There's Betula, it serves as a link aggregator with tags. I like Shiori more because it creates an offline copy, so I will eventually find the content after the website is gone.

I want to use as much default things as possible on OpenBSD, the whole setup is very similar to Setup Mycorrhiza on OpenBSD in that we will use relayd(8), httpd(8), acme-client(1), cron(8). But the Shiori application is not packaged for OpenBSD. Here I will describe all the things that are necessary to create a working service for OpenBSD. Please refer to the Setup Mycorrhiza on OpenBSD article which has all the missing pieces.

Building

Since Shiori is not packaged on OpenBSD, we need to compile it. Luckily for us Shiori is a Go application. We can compile it on the server or cross-compile it from a Linux machine which I will do in order to not pollute the server environment.

git clone https://github.com/go-shiori/shiori
cd shiori
env GOARCH=arm GOOS=openbsd go install

This gives a lot of errors of such kind:

package github.com/go-shiori/shiori
        imports github.com/go-shiori/shiori/internal/cmd
        imports github.com/go-shiori/shiori/internal/core
        imports github.com/go-shiori/shiori/internal/dependencies
        imports github.com/go-shiori/shiori/internal/database
        imports git.sr.ht/~emersion/go-sqlite3-fts5
        imports git.sr.ht/~emersion/go-sqlite3-fts5/internal: build constraints exclude all Go files in /h
ome/grfork/go/pkg/mod/git.sr.ht/~emersion/go-sqlite3-fts5@v0.0.0-20240124102820-f3a72e8b79b1/internal

This probably means that cross-compilation is not supported for this package, probably because of using cgo with sqlite. Let's try to do the same on the server:

doas pkg_add go
git clone https://github.com/go-shiori/shiori
cd shiori
go build
doas cp shiori /usr/local/bin/
doas chown root:bin /usr/local/bin/shiori

This successfully compiles a binary and copies it to a general directory for use.

rc service

Now let's create a service from that compiled binary. First add a corresponding user and create a directory for its files:

doas mkdir /var/shiori
doas useradd -c "Shiori User" -d /var/shiori -s /sbin/nologin -L daemon _shiori
doas chown _shiori:_shiori /var/shiori/

Then add a /etc/rc.d/shiori service file with this content:

#!/bin/ksh

daemon="/usr/local/bin/shiori"
daemon_flags="server --storage-directory /var/shiori \
        --address 127.0.0.1 --port 1738"
daemon_user="_shiori"
daemon_logger="daemon.info"

. /etc/rc.d/rc.subr

rc_bg=YES
rc_reload=NO

rc_cmd $1

and make it executable:

doas chmod +x /etc/rc.d/shiori

Now we can start it and make sure that it works:

doas rcctl start shiori
curl localhost:1738

If it works, let's also enable it on boot:

doas rcctl enable shiori

Expose to the internet

Now it is time to use the Setup Mycorrhiza on OpenBSD article in order to expose this service to the internet, right now it only runs locally.

The CSP rules are going to be different because Shiori uses both Vie.js and iframes to display its contents. CSP rules should be strict by default and only relaxed when we need it. So the following excerpt from the /etc/relayd.conf file shows both: how to keep different configurations of a header, and which CSP rules are necessary for Shiori to work.

http protocol https {
# ...

match request tag default
match request header "Host" value "links.greenfork.me" tag links.greenfork.me

match response tagged default header set "Content-Security-Policy" value \
        "default-src 'none'; script-src 'self'; style-src 'self'; \
	img-src 'self'; font-src 'self'; base-uri 'none'; \
	form-action 'self'; frame-ancestors 'none'"
match response tagged links.greenfork.me header set "Content-Security-Policy" value \
        "default-src 'none'; \
	script-src 'self' 'unsafe-inline' 'unsafe-eval'; \
        style-src 'self' 'unsafe-inline'; \
	img-src 'self' data:; font-src 'self'; \ base-uri 'self'; \
	form-action 'self'; frame-ancestors 'self'; connect-src 'self'; \
        frame-src 'self';"

# ...
}

Goodies

Shiori also has a browser extension, could be nice to use.