# Setting up a Fedi-server Snac for the Yggdrasil Network | DevZone
# Setting up a Fedi-server Snac for the Yggdrasil Network
15 min. reading
May 11
[
2
](https://devzone.org.ua/votes/show/post/40059)
· 52 ·
[
1
](#comments)
·
Shortly after my [thoughts on p2p](https://devzone.org.ua/post/hrabli-p2p), I decided to try setting up my own experimental instance of [Fediverse](https://uk.wikipedia.org/wiki/%D0%A4%D0%B5%D0%B4%D0%B8%D0%B2%D0%B5%D1%80%D1%81). Moreover, to do this using the means of the overlay network [Yggdrasil](https://devzone.org.ua/post/yggdrasil-mereza-z-detsentralizovanym-routynhom), since I do not plan to buy a dedicated IP or VPS for this toy; instead, I will host from a modem, a single-board computer, or even from a PC when I am online, with a dynamic address behind NAT.
I am writing this note primarily for myself, and also, it may be useful for those who, like me, are just starting their experiments in the field of administering their own Fediverse node and are interested in alternative networks, in the context of Linux.
## What is Snac
[Snac](https://codeberg.org/grunfink/snac2) is a minimalistic, JS-less, written in C alternative to the [Mastodon](https://joinmastodon.org/uk) server, which also does not require installing PostgreSQL; instead, it stores all profile data in JSON files. Recently, [IPv6 support was added](https://codeberg.org/grunfink/snac2/pulls/256) to this server, and therefore, it will work with the Yggdrasil range `0200::/7` as well.
Since Yggdrasil allows generating an unlimited number of static IPs for free (based on the private key [Ed25519](https://en.wikipedia.org/wiki/EdDSA#Ed25519)), there is no usual need for DNS here. Although, you can optionally attach [Alfis](https://devzone.org.ua/post/alfis-dns-reyestratsiia-domenu-v-blokcheyn), but personally, I do not use it (including due to the still unresolved issue [#364](https://github.com/Revertron/Alfis/issues/364)), so I also do not want to impose it within the ActivityPub protocol—it will simply be the format `username@IPv6`, which I do not need to update or mine later.
## Installation
1.
I do not know the exact list of packages for Debian, since my system is not new and already has previously installed packages. As indicated in the [README](https://codeberg.org/grunfink/snac2#building-and-installation), I only installed libssl-dev and libcurl4-openssl-dev (for Fedora, it should be approximately the same with the suffix *-devel).
2.
Next, create a separate system user to isolate from potential vulnerabilities:
```
useradd -m snac
```
1. Change the environment to bash in the /etc/passwd file for convenience.
2. Log in via su snac and go to this user's home directory: cd
3. Download the latest source code: git clone https://codeberg.org/grunfink/snac2.git
4. Go to the working directory cd snac2
5. Compile make && sudo make install and install with appropriate permissions.
6. Initialize the server storage: snac init /home/snac/storage
7. And add our first user to it snac adduser /home/snac/storage
8. Then continue from root by executing the command exit
## Configuration
I already have an installed and configured Yggdrasil node; if anyone is interested in the installation process, use the [previous publication](https://devzone.org.ua/post/yggdrasil-mereza-z-detsentralizovanym-routynhom) or the [official documentation](https://yggdrasil-network.github.io/documentation.html).
### Yggdrasil Subnet Address
You can skip this step and use the main address `2*`, if ports `80` or `8001` are not occupied. But note that within the ActivityPub protocol API, the Snac server will provide your host address to other nodes, and they will cache it as part of the ID, and since the host address is stored locally in files, not in a DB, it will be difficult to replace it later. Therefore, it is better to allocate a separate one, especially if it is production:
1. yggdrasilctl getself - find out your IP, including the IPv6 subnet output
2. ifconfig lo inet6 add IP - instead of IP, specify an arbitrary address for the received range, for example 3xx:xxxx:xxxx:xxxx::fed/64, where fed is a kind of wordplay within the "dictionary" of IPv6 (0-9A-F).
* note that ifconfig routing data is not saved after system reboot; for this, you need to add the corresponding entry (command from point 2), for example to /etc/netplan/01-ygglo.yaml, /etc/network/interfaces, or directly to systemd yggdrasil.service (section ExecStartPost=) - depending on the operating system.
### Nginx Proxy
My server already has the [Nginx](https://nginx.org/) web server installed, which occupies port `80`; I do not want to change anything yet, and I also do not want to have public Snac addresses with its standard port `8001`. Therefore, since I already have a dedicated subnet address, I will simply proxy the API to port `80` through a new virtual host, partially using the [original configuration example](https://codeberg.org/grunfink/snac2/src/branch/master/examples/nginx-alpine-ssl/default.conf):
```
# /etc/nginx/sites-available/default
server {
listen [3xx:xxxx:xxxx:xxxx::fed]:80;
server_name 3xx:xxxx:xxxx:xxxx::fed;
location @proxy {
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_redirect off;
proxy_connect_timeout 90;
proxy_send_timeout 90;
proxy_read_timeout 90;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Proxy "";
proxy_pass_header Server;
proxy_buffering on;
tcp_nodelay on;
proxy_pass http://[3xx:xxxx:xxxx:xxxx::fed]:8001;
proxy_set_header Host $http_host;
}
location /.well-known/webfinger {
try_files $uri @proxy;
}
location /.well-known/nodeinfo {
try_files $uri @proxy;
}
location / {
try_files $uri @proxy;
}
location /fedi/ {
try_files $uri @proxy;
}
}
```
* systemctl reload nginx - apply changes
* perhaps, you will want to create a separate configuration file for Nginx, instead of default - I have one for all hosts.
* optionally, using Nginx, you can close separate locations by IP
As you can see, in the example above, port `443` is not specified, and there are no SSL certificates. This is done intentionally, since Yggdrasil already has a secure channel, and I do not want to create an extra layer here.
Since Yggdrasil client connections also have a static address, I decided to restrict access to the administrative API (admin of all accounts + `oauth`) by IP. How effective this is and whether I forgot about other addresses - I do not know, but I will add my example of a regular expression for `location`:
```
location ~ /([^\/]+/admin|oauth) {
allow ADMIN_IP;
deny all;
try_files $uri @proxy;
}
```
### Snac Configuration
Edit the file `/home/snac/storage/server.json` previously generated by the `snac init` command:
```
{
"host": "[3xx:xxxx:xxxx:xxxx::fed]",
"prefix": "",
"address": "3xx:xxxx:xxxx:xxxx::fed",
"port": 8001,
"layout": 2.7,
"dbglevel": 0,
"queue_retry_minutes": 2,
"queue_retry_max": 10,
"queue_timeout": 6,
"queue_timeout_2": 8,
"cssurls": [
""
],
"def_timeline_entries": 50,
"max_timeline_entries": 50,
"timeline_purge_days": 120,
"local_purge_days": 0,
"min_account_age": 0,
"admin_email": "",
"admin_account": "",
"title": "",
"short_description": "",
"short_description_raw": false,
"protocol": "http",
"fastcgi": false
}
```
* note that in my example, the protocol is changed to http
### iptables Accesses
The configuration in the examples does not provide for access to the node from the Internet network, so I opened the port only for Yggdrasil, so that other nodes within this network could interact with each other on events like following (both nodes must be online for the transaction):
```
ufw allow from 0200::/7 to any port 80
```
* if you do not use Nginx, or the server has a standard or other port, just specify the actual one instead of 80, for example 8001
* if you limit traffic by the range 0200::/7, also pay attention to the note about private mode, which is described below
### systemd Configuration
There is a ready [official configuration example](https://codeberg.org/grunfink/snac2/src/branch/master/examples/snac.service), but I supplemented it a bit:
```
# /etc/systemd/system/snac.service
[Unit]
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=snac
Group=snac
ExecStart=/usr/local/bin/snac httpd /home/snac/storage
StandardOutput=file:/home/snac/debug.log
StandardError=file:/home/snac/error.log
[Install]
WantedBy=multi-user.target
```
* systemctl daemon-reload - update systemd configuration
* systemctl enable snac - autostart on system startup
* systemctl start snac - launch
* systemctl status snac - check status
### Backup
Since the Snac database is stored in file format, it is quite simple to backup the profile by only one location.
I do this using `rsync` for different time intervals with the following `crontab -e` command:
```
@daily /usr/bin/rsync -av --delete /home/snac/storage /path/to/snac/daily
@weekly /usr/bin/rsync -av --delete /home/snac/storage /path/to/snac/weekly
@monthly /usr/bin/rsync -av --delete /home/snac/storage /path/to/snac/monthly
```
## Usage
After launching Snac with the command `snac httpd /home/snac/storage` or through the `systemd` service, you can try opening `http://[3xx:xxxx:xxxx:xxxx::fed]` in the browser.
### Testing Interaction (API)
To check interaction with another Yggdrasil node, repeat the same actions for it and do a test following or correspondence between users via Web UI or a connected external client application.
### Browser Tuning
If you are using Yggdrasil sites in Firefox for the first time, you may need to optimize the handling of "raw" IPv6 addresses in `about:config`:
* browser.fixup.fallback-to-https : false - disable redirect http -> https
* browser.fixup.alternate.enabled : false
