2022-11-29 snac on the fediverse

Going to have a light dinner and watch some more of *The Pacific*.

I installed snac, a simple, minimalistic ActivityPub instance, written in C. I hate C, but it’s small, it uses JSON files (like Epicyon), and it seems to work. I think I finally figured out what kept GoToSocial from working. But instead of going back, I’m going to wait and see how much I like this one as a fallback. I’m @alex.

snac

Epicyon

GoToSocial

@alex

Sadly, the instance was always online whenever I was logged in as root – and shut down whenever I logged off. So whenever I went to investigate, it was online. 🤦

I created a snac user without a login, and manually created a directory for it, checked out the sources, built it, installed it, initialized it, and created my first user.

useradd --system snac
mkdir /home/snac
cd /home/snac
git clone https://codeberg.org/grunfink/snac2.git
cd snac2
make
make install
snac init snac-data
snac adduser snac-data alex
chown snac.snac /home/snac
chown snac.snac /home/snac/snac-data

I created the file “/home/snac/snac.service” with the following:

[Unit]
Description=Snac

[Service]
Type=simple
Restart=always
RestartSec=5
ExecStart=/usr/local/bin/snac httpd /home/snac/snac-data
User=snac
MemoryMax=50M
MemoryHigh=40M

[Install]
WantedBy=multi-user.target

This is what I use for systemd. If you have some good ideas to add, let me know. Securing these services is a problem.

cp /home/snac/snac/snac.service /etc/systemd/system/
systemctl enable snac.service
systemctl daemon-reload
systemctl start

My virtual host for Apache also has some redirects and different CSP headings so I want to enable image loading over https:

<VirtualHost *:443>
    ServerAdmin alex@alexschroeder.ch
    ServerName social.alexschroeder.ch
    ProxyPass / http://localhost:4025/
    SSLEngine on
    # allow loading of images from the main site
    Header set Content-Security-Policy "default-src 'self'; base-uri 'none'; img-src https:; worker-src 'none'; frame-src 'none'; form-action 'self'; frame-ancestors 'none'; object-src 'none'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'"
    RewriteEngine On
    RewriteRule ^/@([a-z]+)$ /$1 [redirect,last]
    RewriteRule ^/users/([a-z]+)$ /$1 [redirect,last]
</VirtualHost>

​#Mastodon ​#Fediverse ​#snac

Comments

(Please contact me if you want to remove your comment.)

If it doesn’t have lots of dependencies (could it even be linked static?), I guess other than running this on a container (I know! but as an “architect” once said on a high stakes meeting “containers provide containment”), you could use the good old chroot.

– jjm 2022-11-30 07:47 UTC

jjm

---

Yeah, I’m sure this can be configured using systemd.

That all said, systemd of course does offer you a way to chroot() specific daemons and manage them like any other with the usual tools. This is supported via the RootDirectory= option in systemd service files. – systemd for Administrators, Part VI

systemd for Administrators, Part VI

Maybe this is the way to go.

Or this?

With the switches ReadOnlyDirectories= and InaccessibleDirectories= you may setup a file system namespace jail for your service. Initially, it will be identical to your host OS’ file system namespace. By listing directories in these directives you may then mark certain directories or mount points of the host OS as read-only or even completely inaccessible to the daemon.

Some more thinking is required, unfortunately.

– Alex 2022-11-30 08:36 UTC

---

I think the only dependencies are libssl and libcurl4-openssl. I will try a static compile and see how that turns out.

– Frotz 2022-11-30 15:03 UTC

---

If I want to allow alex to be able to post from the command line:

usermod -a -G snac alex
chmod g+w /home/snac/snac-data/queue
chmod g+w /home/snac/snac-data/timeline

– Alex 2022-12-03 22:56 UTC

---

If you upgrade to 2.13, make sure to look at the pull request that fixes that segfault.

– Alex 2022-12-04 09:39 UTC

---

Thinking about the features I think I’d like to add:

I hope that these aren’t too hard.

A lot harder:

– Alex 2022-12-04 09:40 UTC

---

Alternatives for small instances:

GoToSocial

Epicyon

microblog.pub

Honk

@nelson has more:

@nelson

I asked on Mastodon about servers and got some suggestions. Here they are. – ActivityPub servers

ActivityPub servers

– Alex 2022-12-05 18:04 UTC

---

The Mastodon client API is a lot of work, sadly. My guess that either there is more command line use, or use `curl`.

Mastodon client API

As for command-line use, the problem is that you need permissions to write to the various directories, as the user that runs `snac`. Not a problem on a single-user instance, of course. One solution, as illustrated in a previous comment, is to give group write permissions (`g+w`) to all the directories `snac` uses and to add my account to the `snac` group. But now the user can mess with the data files.

`curl` works. I just tested this:

curl --user "nick:*secret*" \
     --form content="Testing from curl!" \
     https://example.org/nick/admin/note

An alternative would be a command line client `snac-cli` that handles the `curl` call. Perhaps it reads username, password and URL from `~/.config/snac/snac-cli-config`. Then we don’t need to fiddle with permissions.

Example:

#!/usr/bin/env perl
use Modern::Perl;
use Mojo::JSON qw(decode_json);;
use File::Slurper qw(read_binary);
use Mojo::UserAgent;
my $file = "$ENV{HOME}/.config/snac-cli/config.json";
my $conf;
$conf = decode_json read_binary $file if -f $file;
if (not $conf->{username}) { print "Username: "; $conf->{username} = <STDIN> }
if (not $conf->{password}) { print "Password: "; $conf->{password} = <STDIN> }
if (not $conf->{url})      { print "URL: "; $conf->{url} = <STDIN> }
$conf->{url} =~ s/\/$//; # strip trailing slash
my $url = Mojo::URL->new("$conf->{url}/$conf->{username}/admin/note")
    ->userinfo("$conf->{username}:$conf->{password}");
say $url;
say "Content to post, end with Ctrl D:";
undef $/;
my $content = <STDIN>;
my $ua  = Mojo::UserAgent->new;
my $res = $ua->post($url => form => { content => $content})->result;
say "Posted." if $res->code == 303;

I just tested this:

echo "Also trying to post from a little command-line tool." | snac-cli

The problem is that we don’t have OAuth2 and thus the password you provide in the config file or elsewhere is the “real” password. Perhaps we should read the credentials from `~/.authinfo.gpg` or something like that, if it exists.

– Alex 2022-12-06 07:04 UTC

---

There’s also the problem that `snac` doesn’t download any media. That is, all the images and avatars are always loaded from remotes. Which is nice, less storage, right? And we’re not really “bandwidth stealing” as they called it in the old days, because this is how other people want us to use their images and videos. But in a way it’s a weird privacy issue, now. Anybody monitoring their web-server logs for a one-person instance can now figure out when I’m looking at their social media posts, no? Or alternatively: the people manning the corporate firewalls with their automated filters and their snooping machine learning watchdogs might similarly start wondering what the heck is going on.

Sadly, caching all that media takes resources, and cache expiration and fallback code all add extra pain. I don’t see an easy way out.

Perhaps this: Only load these resources on demand.

– Alex 2022-12-06 11:01 UTC

---

Perhaps what I like best about snac is that there appears to be no size limit. I guess the ActivityPub protocol itself also has no size limit. After all, why limit text size when you allow the attachment of images and videos that are many megabytes in size. I guess it starts to feel a lot more like a blog. That makes me think of how one could use it. No comments on the front-page: it’s a blog. Threads on the front-page: looks like a forum. With comments and posts sorted by date on front-page, without sorting: looks like Twitter or Mastodon. I don’t look how other ActivityPub servers serve their front pages.

Perhaps it would be an interesting investigation to have a switch somewhere, or a separate feed, to display the posts in different ways.

I’ve been using snac for a little but, following a handful of people, and now I decided to follow a larger chunk of people (but still far away from my my octodon.social which account follows over 500 people). I think it showing its limitations.

Threading is confusing because whole threads move up and if they’re longer than a handful of posts I have to read them again to find what’s new. If you follow people that have long threads, maybe not even toot storms but just long threads that they keep posting to … imagine this thread returning, again and again, to the top of your page. Longer than ever.

If strangers reply to the thread, same thing.

A supporter of threads would say: “This is great! I’m never lost.”

By comparison, the Mastodon threading is easier on my brain: by default is is invisible. Posts stand on their own. If I want to know what this is a reply to, I can click on the post and see all the ancestors above (the chain of posts that lead to the post I’m looking at) and all the descendants below (all the posts that resulted in response). And if I want to know more about the other branches parallel to the one I’m looking at (which I can’t see right now), I can always click on an ancestor (usually the oldest one). That shows all the branches starting from the top. And if I scroll down and feel confused by replies, wondering who is answering to whom, I can always click on a post and repeat the process.

In a way, Mastodon has three views and allows me to interactively change between them:

Perhaps it would make sense to add a traditional threaded view for context. But as it is implemented in snac, I now realize that threaded views need a lot more UI to be useful. Like my old USENET and mail readers: highlighting new posts, jumping to new posts without losing my position in the thread, it has to be quick, and perhaps it doesn’t scale to 20 or thirty levels of replies.

Mastodon strikes a good balance, I think.

And finally: once you have boosted or liked a post, I don’t see a way to take that back. And we already talked about the lack of edit. 😆

– Alex 2022-12-12 20:01 UTC

---

The longer I use snac, on the side, the more I think that perhaps it’s better suited for people with small networks: if you follow less than 100 people, perhaps? Perhaps best if you follow 20 active posters?

– Alex 2022-12-19 13:00 UTC