24 KiB
Contents
Introduction
The fediverse is a set of federated servers, typically using a communication protocol called ActivityPub which was devised by the social working group within the World Wide Web Consortium (W3C). At present it is mostly used for microblogging, although ActivityPub is sufficiently general that it can also be used for a variety of other purposes.
The word fediverse (federated universe) appears to have originated around 2012 as the first identi.ca website was ending and the pump.io project was beginning. The ActivityPub protocol was initially called ActivityPump, due to the influence which pump.io had upon its creation. Fediverse servers are typically referred to as "instances".
Servers such as Mastodon are well known, but these are aimed at large scale deployments on powerful hardware running within data centers, making use of content distribution networks (CDN) and due to their large number of dependencies requiring someone with a high level of systems administration skill to maintain. Epicyon is designed for the opposite situation where it is only intended to have a single user or a small number of users (less than ten) running from your home location or on a modest VPS and where maintenance is extremely trivial such that it's possible to keep an instance running for long durations with minimal intervention.
Epicyon is part of the "small web" category of internet software, in that it is intended to scale via federation rather than to scale vertically via resource intensive and expensive hardware. Think many small communicating nodes rather than a small number of large servers. Also, in spite of the prevailing great obsession with scale, not everything needs to. You can federate with a small number of servers for a particular purpose - such as running a club or hackspace - and that's ok.
It is hardly possible to visit many sites on the web without your browser loading and running a large amount of javascript. Epicyon takes a minimalist approach where its web interface only uses HTML and CSS. You can disable javascript, or use a browser which doesn't have javascript capability, and the user experience is unchanged. Lack of javascript also rules out a large area of potential attack surface.
Epicyon also includes some lightweight organizing features, such as calendar, events and sharing economy features.
Installation
Prerequisites
You will need python version 3.7 or later.
On a Debian based system:
sudo apt install -y tor python3-socks imagemagick python3-setuptools python3-cryptography python3-dateutil python3-idna python3-requests python3-flake8 python3-django-timezone-field python3-pyqrcode python3-png python3-bandit libimage-exiftool-perl certbot nginx wget
Source code
The following instructions install Epicyon to the /opt directory. It's not essential that it be installed there, and it could be in any other preferred directory.
Clone the repo, or if you downloaded the tarball then extract it into the /opt directory.
cd /opt
git clone https://gitlab.com/bashrc2/epicyon
Set permissions
Create a user for the server to run as:
sudo su
adduser --system --home=/opt/epicyon --group epicyon
chown -R epicyon:epicyon /opt/epicyon
News mirrors
The content for RSS feed links can be downloaded and mirrored, so that even if the original sources go offline the content remains readable. Link the RSS/newswire mirrors with.
mkdir /var/www/YOUR_DOMAIN
mkdir -p /opt/epicyon/accounts/newsmirror
ln -s /opt/epicyon/accounts/newsmirror /var/www/YOUR_DOMAIN/newsmirror
Create daemon
Typically the server will run from a systemd daemon. It can be set up as follows:
nano /etc/systemd/system/epicyon.service
Paste the following:
[Unit]
Description=epicyon
After=syslog.target
After=network.target
[Service]
Type=simple
User=epicyon
Group=epicyon
WorkingDirectory=/opt/epicyon
ExecStart=/usr/bin/python3 /opt/epicyon/epicyon.py --port 443 --proxy 7156 --domain YOUR_DOMAIN --registration open --debug --log_login_failures
Environment=USER=epicyon
Environment=PYTHONUNBUFFERED=true
Restart=always
StandardError=syslog
CPUQuota=80%
ProtectHome=true
ProtectKernelTunables=true
ProtectKernelModules=true
ProtectControlGroups=true
ProtectKernelLogs=true
ProtectHostname=true
ProtectClock=true
ProtectProc=invisible
ProcSubset=pid
PrivateTmp=true
PrivateUsers=true
PrivateDevices=true
PrivateIPC=true
MemoryDenyWriteExecute=true
NoNewPrivileges=true
LockPersonality=true
RestrictRealtime=true
RestrictSUIDSGID=true
RestrictNamespaces=true
SystemCallArchitectures=native
[Install]
WantedBy=multi-user.target
Activate the daemon:
systemctl enable epicyon
systemctl start epicyon
Web server setup
Create a web server configuration.
nano /etc/nginx/sites-available/YOUR_DOMAIN
And paste the following:
server {
listen 80;
listen [::]:80;
server_name YOUR_DOMAIN;
access_log /dev/null;
error_log /dev/null;
client_max_body_size 31m;
client_body_buffer_size 128k;
limit_conn conn_limit_per_ip 10;
limit_req zone=req_limit_per_ip burst=10 nodelay;
index index.html;
rewrite ^ https://$server_name$request_uri? permanent;
}
server {
listen 443 ssl;
server_name YOUR_DOMAIN;
gzip on;
gzip_disable "msie6";
gzip_vary on;
gzip_proxied any;
gzip_min_length 1024;
gzip_comp_level 6;
gzip_buffers 16 8k;
gzip_http_version 1.1;
gzip_types text/plain text/css text/vcard text/vcard+xml application/json application/ld+json application/javascript text/xml application/xml application/rdf+xml application/xml+rss text/javascript;
ssl_stapling off;
ssl_stapling_verify off;
ssl on;
ssl_certificate /etc/letsencrypt/live/YOUR_DOMAIN/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/YOUR_DOMAIN/privkey.pem;
#ssl_dhparam /etc/ssl/certs/YOUR_DOMAIN.dhparam;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!MEDIUM:!LOW:!aNULL:!NULL:!SHA;
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
ssl_session_tickets off;
add_header Content-Security-Policy "default-src https:; script-src https: 'unsafe-inline'; style-src https: 'unsafe-inline'";
add_header X-Frame-Options DENY;
add_header X-Content-Type-Options nosniff;
add_header X-XSS-Protection "1; mode=block";
add_header X-Download-Options noopen;
add_header X-Permitted-Cross-Domain-Policies none;
add_header Strict-Transport-Security "max-age=15768000; includeSubDomains; preload" always;
access_log /dev/null;
error_log /dev/null;
index index.html;
location /newsmirror {
root /var/www/YOUR_DOMAIN;
try_files $uri =404;
}
keepalive_timeout 70;
sendfile on;
location / {
proxy_http_version 1.1;
client_max_body_size 31M;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forward-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forward-Proto http;
proxy_set_header X-Nginx-Proxy true;
proxy_temp_file_write_size 64k;
proxy_connect_timeout 10080s;
proxy_send_timeout 10080;
proxy_read_timeout 10080;
proxy_buffer_size 64k;
proxy_buffers 16 32k;
proxy_busy_buffers_size 64k;
proxy_redirect off;
proxy_request_buffering off;
proxy_buffering off;
proxy_pass http://localhost:7156;
tcp_nodelay on;
}
}
Enable the site:
ln -s /etc/nginx/sites-available/YOUR_DOMAIN /etc/nginx/sites-enabled/
On your internet router
Forward port 443 from your internet router to your server. If you have dynamic DNS make sure its configured.
Obtain a TLS certificate
systemctl stop nginx
certbot certonly -n --server https://acme-v02.api.letsencrypt.org/directory --standalone -d YOUR_DOMAIN --renew-by-default --agree-tos --email YOUR_EMAIL
systemctl start nginx
Restart the web server
systemctl restart nginx
If you need to use fail2ban then failed login attempts can be found in accounts/loginfailures.log.
If you are using the Caddy web server then see caddy.example.conf.
Now you can navigate to your domain and register an account. The first account becomes the administrator.
Installing on Onion or i2p domains
If you don't have access to the clearnet, or prefer to avoid it, then it's possible to run an Epicyon instance easily from your laptop. There are scripts within the deploy directory which can be used to install an instance on a Debian or Arch/Parabola operating system. With some modification of package names they could be also used with other distros.
Please be aware that such installations will not federate with ordinary fediverse instances on the clearnet, unless those instances have been specially modified to do so. But onion instances will federate with other onion instances and i2p instances with other i2p instances.
Upgrading
Unlike some other instance types, Epicyon is really easy to upgrade. It only requires a git pull to obtain the changes from the upstream repo, then set permissions and restart the daemon.
cd /opt/epicyon
git pull
chown -R epicyon:epicyon *
systemctl restart epicyon
Registering accounts
You will notice that within the systemd daemon the registration option is set to open. In a browser if you navigate to the URL of your instance then you should see a Register button. The first account to register becomes the administrator.
To avoid spam signups, or overloading the system, there is a maximum number of accounts for the instance which by default is set to 10.
Logging in
In a browser if you navigate to the URL of your instance and enter the username and password that you previously registered. The first time that you log in it will show a series of introduction screens which prompt you to add a profile picture, name and bio description.
Account Profiles
Initial setup
When you first register an account on the instance the first thing that you may want to do is to add more profile details and change your preferences. From the main timeline screen select the top banner to kove to your profile and then select the edit button, which usually looks like a pen and is adjacent to the logout icon.
Basic details
Describe yourself
Add an appropriate description of youself, which doesn't resemble the type of thing which would appear on a spam account. When other fediverse users are judging a follow request from you they will want to know that you are a real person and not a spammer or troll.
Other fediverse accounts
If you have any other fediverse accounts on different instances then you might want to add URLs for those. You can set the languages which you can read, as two letter abbreviations. This helps to avoid having posts from other people within your timeline which you can't read.
Expiring posts
You can set your posts to expire after a number of days. If this value is zero then the instance will keep your posts indefinitely.
Quitting Twitter
If you are coming to the fediverse as an exile from Twitter then you may want to select the option to remove any Twitter posts from your timeline. Sometimes people want to make a clean break from Twitter and have no further involvement with it.
Alternative contact details
You can set additional contact details, such as email, XMPP and Matrix addresses. So if people want to contact you for private end-to-end secure chat then they can do so. The fediverse was never designed for end-to-end security - it is primarily for public communications - and so it's better to leave secure private chat to the apps which are specialized for that purpose.
Filtering and blocking
If you want to block particular fediverse accounts or instances then you can enter those in the blocked account section. There should be one account per line.
Geolocation spoofing
Within the filtering and blocking section you can also set a city which will be used for geolocation spoofing. When you post a photo, instead of removing all metadata spoofed metadata will be added in order to consistently fool the machine learning systems behind web crawlers or scrapers, and create a confirmation bias effect where the surveillance systems become increasingly confident in an erroneous conclusion. Setting a city somewhere near to your time zone is preferable, so that it matches your typical pattern of daily posting activity without giving away your real location.
Roles
If you are the administrator then within your profile settings you can also specify roles for other accounts on the instance. A small instance is like a ship with the roles being crew positions, and all members of the crew need to work together to keep the ship afloat. The current roles are:
Moderator
Is allowed to remove posts and deal with moderation reports.
Editor
Editors can change the links in the left column and the RSS feeds within the right newswire column.
Artist
Artists can change the colors and style of the web interface, using the theme designer.
Counselor
A counselor is someone tasked with resolving disputes between users of the instance. They are permitted to send DMs to any user account on the instance. Obviously, this type of power can be abused and so the administrator should choose counselors with care.
Devop
Devops are permitted to perform some routine administration functions, such as monitoring instance performance graphs.
Following
On the main timeline screen at the top right of the centre column there is a search icon which looks like a magnifying glass. By convention within the fediverse the search function is also the way to look up and follow other people. Enter the handle (@name@domain) or URL of the profile page for the person that you want to follow and select search. If the account is found then its details will appear and you can choose to follow or not.
Once you are following someone then selecting their profile picture and then the unfollow button will remove the follow.
Creating posts
To make a new post from the main timeline screen select the new post icon at the top right of the centre column.
Post scopes
Posts can have different scopes which provide some amount of privacy, or particular functions. To change the scope select the current one and a dropdown list will appear.
Public
Is visible to anyone in the fediverse. May also be visible outside of the fediverse to anyone with an appropriate link.
Blog
Used to create a blog post. Blog posts are typically longer than other types of post, and are also publicly visible to anyone on the web.
Unlisted
Similar to a public post, but will not appear as a recent post within your profile. Unlisted posts can add a little more privacy to a conversation in that it will not be immediately obvious to casual observers. Often in practice this is all that's needed to avoid trolls or unwanted attention.
Followers
A followers only post will only be visible to people who are following you. They will not be visible to people who are not your followers, or to other observers on the web.
A subtlety of this type of post is that people have different followers, so if you send to your followers and they send a reply to their followers then your post or references to it may end up with people who are not your followers.
DM
Direct messages are only send to specific people, designated by their fediverse handles (@name@domain).
Reminder
A reminder is a direct message to yourself at some time in the future. It will appear on your calendar.
Report
A report is a type of post which is sent to moderators on your instance, to alert them about some problem. It is not sent to any other instance.
Shares
A shared item post describes a physical object or service which may be shared by people on your instance. Shared items may also be visible to people on specific named instances if that has been set up by the administrator.
Wanted
A wanted item is a physical object or service which you want. These posts will be visible to other people on your instance and also to people on specific named instances if that has been set up by the administrator.
Attachments
Attachments can use a variety of formats.
- Images: jpg, jpeg, gif, webp, avif, svg, ico, jxl, png
- Audio: mp3, ogg, flac, opus
- Video: mp4, webm, ogv
Attachments should be as small as possible in terms of file size. Videos should be no more than 20 seconds in length. Epicyon is not suitable for hosting lengthy or high resolution videos, although podcasts might be feasible.
Events
You can specify a date, time and location for the post. If a date is set then the post will appear as an event on the calendar of recipients. This makes it easy for people to organize events without needing to explicitly manage calendars.
Maps
The location field on a post can be a description, but it can also be a map geolocation. To add a geolocation go to openstreetmap.org, find your location and copy and paste the URL into the location field of your new post.
Selecting the location header will open the last known geolocation, so if your current location is near this makes it quicker to find.
The Timeline
Layout
On a desktop system the main timeline screen has a multi-column layout. The main content containing posts is in the centre. To the left is a column containing useful web links. To the right is the newswire containing links from RSS feeds.
At the top right of the centre column there are a few icons, for show/hide, calendar, search and creating a new post.
Different timelines are listed at the top - inbox, DM, replies, outbox, etc - and more can be shown by selecting the show/hide icon.
Navigation
As a general principle of navigation selecting the top banner always takes you back to the previous screen, or if you are on the main timeline screen then it will alternate with your profile.
At the bottom of the timeline there will usually be an arrow icon to go to the next page, and a list of page numbers. You can also move between pages using key shortcuts ALT+SHIFT+> and ALT+SHIFT+<. Key shortcuts exist for most navigation events, and you can customise them by selecting the key shortcuts link at the bottom of the left column.
Side columns
The links within the side columns are global to the instance, and only users having the editor role can change them. Since the number of accounts on the instance is expected to be small these links provide a common point of reference.
Links
Web links within the left column are intended to be generally useful or of interest to the users of the instance. They are similar to a blogroll. If you have the editor role there is an edit button at the top of the left column which can be used to add or remove links. Headers can also be added to group links into logical sections. For example:
* Search
Code search https://beta.sayhello.so
Wiby https://wiby.me/
* Links
16colors https://16colo.rs
Dotshareit http://dotshare.it
Newswire
The right column is the newswire column. It contains a list of links generated from RSS/Atom feeds.
If you have the editor role then an edit icon will appear at the top of the right column, and the edit screen then allows you to add or remove feeds. Feeds can be either moderated or not. Moderated feed items must be approved by a moderator before then can appear in the newswire column and be visible to other users on the instance. To indicate that a feed should be moderated prefix its URL with a star * character.
Newswire items can also be mirrored. This means that instead of newswire items being links back to the original source article a copy will be made of the article locally on your server. Mirroring can be useful if the site of the RSS/Atom feed is unreliable or likely to go offline (such as solar powered systems only online during daylight hours). When deciding whether to mirror a feed you will also want to consider the copyright status of the content being mirrored, and whether legal problems could arise. To indicate that a feed should be mirrored prefix its URL with an exclamation mark ! character.
Filters and warnings
On this screen you can also set filtered words and dogwhistle content warnings for the instance. Filtered words should be on separate lines, and dogwhistle words can be added in the format:
dogwhistleword -> content warning to be added
dogwhistle phrase -> content warning to be added
DogwhistleWordPrefix* -> content warning to be added
*DogwhistleWordEnding -> content warning to be added
Newswire tagging rules
As news arrives via RSS or Atom feeds it can be processed to add or remove hashtags, in accordance to some rules which you can define.
On the newswire edit screen, available to accounts having the moderator role, you can define the news processing rules. There is one rule per line.
Syntax: if [conditions] then [action]
Logical Operators: not, and, or, xor, from, contains
A simple example is:
if moderated and not #oxfordimc then block
For moderated feeds this will only allow items through if they have the #oxfordimc hashtag.
If you want to add hashtags an example is:
if contains "garden" or contains "lawn" then add #gardening
So if incoming news contains the word "garden" either in its title or description then it will automatically be assigned the hashtag #gardening. You can also add hashtags based upon other hashtags.
if #garden or #lawn then add #gardening
You can also remove hashtags.
if #garden or #lawn then remove #gardening
Which will remove #gardening if it exists as a hashtag within the news post.
You can add tags based upon the RSS link, such as:
if from "mycatsite.com" then add #cats
Calendar
Moderation
Instance level moderation
Moderator screen
Account level moderation
Emergencies
The fediverse is typically calmer than the centralized social networks, but there can be times when disputes break out and tempers become heated. In the worst cases this can lead to administrator burnout and instances shutting down.
If you are the administrator and you are in a situation where you or the users on your instance are getting a lot of targeted harassement then you can put the instance into broch mode, which is a type of temporary allowlist which lasts for between one and two weeks. This prevents previously unknown instances from sending posts to your timelines, so adversaries can't create a lot of temporary instances for the purpose of attacking yours.
A general observation is that it is difficult to maintain collective outrage at a high level for more than a week, so trolling campaigns tend to not last much longer than that. Broch mode allows you to ride out the storm, while retaining normal communications with friendly instances.
To enable broch mode the administrator should edit their profile, go to the instance settings and select the option. Once enabled it will turn itself off automatically after 7-14 days. The somewhat uncertain deactivation time prevents an adversary from knowing when to begin a new flooding attempt, and after a couple of weeks they will be losing the motivation to continue.