1. Introduction
The following list contains all tutorials in the AEREEnet tutorial series:
- [Users, Tutorial] Igl, W (2025). AEREEnet: Using a low-cost, light-weight, scalable, anonymous, secure social network – A Short Tutorial for IRC Users. https://biosphere.wilmarigl.de/en/?p=4776
- [Admins, Short tutorial] Igl, W. (2025). AEREEnet: Creating a low-cost, light-weight, scalable, anonymous, secure social network – A Short Tutorial for Admins. https://biosphere.wilmarigl.de/en/?p=4654
- [Admins, Complete Tutorial] Igl, W. (2025). AEREEnet: Creating a low-cost, light-weight, scalable, anonymous, secure social network – A Complete Tutorial for Admins. https://biosphere.wilmarigl.de/en/?p=4559
1. 1 Overview
1.1.1 Technical
Here, I provide a detailed and complete tutorial on how to install a low-cost, light-weight, scalable, open-source, cross-platform, anonymous, secure, self-hosted social network based on Internet Relay Chat (IRC) technology [1] using DOCKER containers [2]. The current software stack provides a low-cost solution to build a social network with anonymity for clients and servers (via the Tor network [3]) and security (ie, encryption) for the client-server connection (via Transport Layer Security (TLS) [4] or via Tor hidden services). In addition, security (ie, encryption) for the end-to-end (client-to-client) connection [5] can be applied with an appropriate IRC client (see section 5).
IRC Server (Demo):
- Clearnet (Use Standard Browser!): https://aeree.net
- Darknet (Use Tor Browser!): http://yi5dvnkqev4gsbcy6wdaa4udhlqhsvcnq3nylxnjfratnlhpu7bz7aid.onion
The overall framework of running a social network as docker containers as a hidden service in the Tor network is generic, which means that the web client (TheLounge) [6] and IRC server (ERGO) [6] components can be replaced by other open-source components, for which a Docker container is available. For example, the MOVIM [8] web client and the PROSODY [10] XMPP server may be used for for XMPP-based social networking [10].
1.1.2 Political
The current wave of fascism across many societies and the oppression of free speech by right-wing governments [11, 12], requires new ways to protect free speech of common people [70].
Corporate, centralized social networks are corrupted by capitalist interests and can be more easily controlled politically [13, 14]. In addition, although some messengers provide end-to-end encryption (eg, WhatsApp, Facebook Messenger) this feature may not be activated by default and meta data (eg, who contacted whom?) may still be available. Moreover, the account maybe linked to a personal identifier (eg, phone number), so therefore, such services are at best secure (encrypted) but not anonymous [70].
Non-corporate, decentralized (“federated”) social networks (eg, Mastodon [15]/ActivityPub [16], Bluesky [17]/ATproto [18]) support free communication, but are resource-intensive (eg, text, audio, image, video data) and, therefore, more expensive to maintain privately, ie by running a server [19]. They also usually do not offer full anonymity (ie, IP visible) and only secure client-server connection, ie no end-to-end encryption.
Non-profit, privacy-focused social networks, eg Signal, Telegram, have high security and anonymity standards, however, they (eg, Signal, Telegram) still uses personal identifiers, like phone numbers, which may make them non-anonymous. In addition, these centralized networks may be blocked in certain regions and the leadership of these organisation may be pressured to lower security standards or shutdown the service.
Therefore, a combination of a classic, open-source, light-weight, scalable social network and modern anonymization and encryption services (Tor, TLS) is proposed to contribute to protecting civil liberties against government oppression. Historically, IRC has played an important role for social communication and is still considered a hallmark of the anarchic spirit of the early internet [20, 21, 22].
Rare technologies (eg, Linux, IRC) are less exposed governmental control than mainstream technologies (eg, MS Windows, Whatsapp), therefore, “obscurity” is considered a strength, not a weakness, in this context. At the end, also governments have limited resources (ie, time, money, talent). The more decentralized social networks are, the harder it is for corporations and governments to control them. At the end governments and corporations need citizens to have access to the internet to control the society by manufacturing consent.
1.2 Features
1. The social network is installed as DOCKER containers because it can be applied on various operating systems for which the used software may otherwise not be available as installable packages. Therefore, this approach is generically applicable to any device which are able to run DOCKER containers. [2]
2. The social network may be installed on a device within a home network (LAN/WLAN). Here, a QNAP Network Attached Storage (ie, NAS TS-653A with QTS 5.x) was used [23]. Using one’s own (idling) device may save costs and gives more control over the network since no third-party cloud provider is needed. Low cost solutions may use (pre-used) Raspberry Pi (3B+ or higher recommended) mini-computers [24] for about 50EUR to 100EUR purchase price, (pre-used) smart phones, or network-attached storages. However, the approach can also be used with a remote virtual private server (VPS) at a cloud provider.
3. The social network is made available as a hidden service in the Tor network [3], which hides the IP address and location of the server. If chat users also use a Tor Browser to connect via the Tor network, the user and the server will be in principle anonymous, ie non-identifiable and not able to be located. In addition, the client-server connections will be encrypted. Other applications can be used to access hidden services in the Tor network via the Tor Browser as proxy [25].
4. The social network is based on the text-based, channel-based Internet Relay Chat (IRC) technology [1, 20]. IRC has minimal resource requirements because it supports only text communication and does not automatically store messages. Other, modern technologies may offer additional functionality, but would require a multiple of resources (eg, XMPP [10, 71, 72, 73]) by supporting image and videos in posts and conferencing, which may drive costs, and is not a desired feature here.
For example, a small server (eg 2 virtual CPUs, 2 GB Memory, 150Mbit/sec bandwidth) will be able to serve several thousands of users who are chatting simultaneously (text-only) on hundreds of channels using IRC technology. Such a small server is safely estimated to be able to handle about 15,000 simultaneous IRC users using external IRC clients [26]. These features make this technology easily accessible to civil political (“grassroots”) movements with little budget, especially in the Global South.
If so, larger files (text, image, videos) can be shared by additional websites to keep the workload for the IRC server (ie, compute, memory, storage) at a minimum:
- Clearnet:
- text: pastebin.com [57]
- images: pasteboard.co [58]
- text and images: justpaste.it [59]
- all file types: filebin.net [60]
- Darknet:
- all file types: onionshare.org [61]
1.3 Components and Steps
The following steps are ordered by increasing functionality and complexity. A minimal social network can easily implemented by following steps #1 (domain), #2 (router) and #3.1 (ERGO, eg using a self-signed TLS certificate, instead of an external CA-signed TLS certificate).
Steps:
- Configure Clearnet Domain (optional: required for Clearnet address)
Note: Registering a Clearnet domain will allow TLS encryption and a memorable, identifiable domain name. - Configure Router (required)
Note: Open specific ports for port forwarding will allow incoming traffic. - Install and Run Docker containers
- ERGO IRC server (required)
Note: The IRC server will handle chat messages, but requires a client to use it. - TheLounge Web Client (optional)
Note: TheLounge is an IRC web client with a user-friendly web interface with limited functionality, eg no end-to-end encryption. - Tor Server (optional)
Note: The Tor relay server makes the IRC network available as a hidden service, thereby, hiding the IP address and location of the server. - Caddy Web Server (optional)
Note: Caddy will handle secure (TLS) connections to the TheLounge web client and auto-renew TLS certificates via Let’s encrypt/ZeroSSL as certificate authorities (clearnet addresses only).
- ERGO IRC server (required)
Notes:
- No separate bouncer (eg ZNC) [27] was used. The ERGO IRC server was configured to automatically keep a limited channel history to provide context of ongoing discussions for newjoiners. A bouncer, which is a proxy server which is permanently logged into the IRC demon and stores the messages in a channel, was, therefore, not required.
- No separate IRC services (eg ANOPE) [28] were used. The ERGO IRC server includes already important IRC services, eg nickserv for user registration and chanserv for channel registration.
- No separate SMTP server (eg POSTFIX) [62] was used. The ERGO IRC server includes capability to send emails for user verification or password recovery (not enabled for security purposes).
- No separate Bots (eg, EGGDROP [29]) were used. However, such bots may be useful to defend against trolls, hackers, and botnets. If so, the used of a modern IRC bot, such as LIMNORIA [30]) is recommended (see inspircd anti-spam tutorial [31]).
- The relevant lines in the configuration files, which have been modified relative to the default configuration, are annotated with the line “# — EDIT BELOW –” to be easier to identify.
1.4 Data flow
The non-trivial data flow using port forwarding via the Tor network is as follows:
1.4.1 Clearnet
Incoming Data (to Server):
Client (Browser) → CADDY Container (Port 443, https) → THELOUNGE Container (Port 9000) → ERGO Container (Port 6697)
Outgoing Data Flow (from Server):
ERGO Container (Port 6697) → THELOUNGE Container (Port 9000) → CADDY Container (Port 443, https) → Client (Browser)
Note: The client-server connection is encrypted via Transport Layers Security (TLS, https) via port 443 (see lock symbol left of web address in browser).
1.4.2 Darknet
Incoming Data (to Server):
Client (TOR Browser, Port 9150) → TOR Network (Port 9001/9030) → TOR Container (Port 9050) → CADDY Container (Port 80) → THELOUNGE Container (Port 9000) → ERGO Container (Port 6697)
Outgoing Data Flow (from Server):
ERGO Container (Port 6697) → THELOUNGE Container (Port 9000) → CADDY Container (Port 80) → TOR Container (Port 9050) → TOR Network (Port 9001/9030) → Client (TOR Browser, Port 9150)
Note:
- The client-server connection is encrypted via the Tor network, although standard port 80 is used (see lock symbol left of web address in TOR browser).
- The connection between THELOUNGE web client and the ERGO IRC server, which run as Docker containers in the same Docker network on the same server, is implemented via a network path within the Docker network, for all addresses used for the IRC server. This means, also when a user connects to the THELOUNGE web client at its darknet (ie, .onion) address and THELOUNGE connects to the ERGO IRC server at its clearnet (ie, https://aeree.net) address, the traffic between THELOUNGE web client and ERGO IRC server will not be sent via the clearnet, but within the docker network on the same server (ie, neither via the clearnet nor the darknet).
2. Register Domain
- Check the public IP address of your private network in your router. The administration web interface of the router is usually available at 192.168.0.1. The login and password for the admin account are usually on a sticker on your router. Alternatively, use web services [74].
- Example: The router Wifi Hub C2 [32] by Swedish Tele2 [33] shows the public internet address in the following menu:
192.168.0.1 > Home > Internet > WAN Status > IPv4 > Public IP - Register a domain and domain provider, eg namecheap.com [34], and point the domain to the public IP address by creating a “Type A” record.
- An internet provider assign your IP address dynamically, ie it may change, which may break the connection between your domain name and your host, on which your IRC network is running. From my personal experience, the public IP remained stable over many weeks, and the change of the public IP was not an issue with my provider. However, if so, there are the following solutions:
- To rent a Dynamic Domain Name Server (DDNS) and configure your device to regularly update the DNS entries with your current IP (QNAP ) [35, used here].
- To configure a Dynamic DDNS with the Caddy server [36].
- Ask your internet service provider to give you a static IP address [33].
- Manually update the DNS entry at your domain name provider, if the public IP address changes.
3. Configure Router
The router requires the configuration of rules for “Port Forwarding” mapping incoming (!) traffic (external/WAN -> internal/LAN):
- mapping external port 80 to internal port 80 for default web traffic and Tor-encrypted web traffic
- mapping external port 443 to internal port 443 for TLS-encrypted, secure web traffic
- mapping external port 6697 to internal port 6697 for TLS-encrypted, secure IRC traffic (Port 6667 for plaintext was not enabled)
- mapping external port 9050 to internal port 9050 for Tor-encrypted traffic
No ports need to be opened for outgoing traffic, eg Port 9150, which is used when using the Tor Browser as a proxy for tor-encrypted outgoing traffic, also the server-response is routed back to the client using the same connection initiated by the client via port 9150, so port 9150 does not need to be opened for incoming traffic initiated by external clients.
Here, an example of the configuration for the WIFI HUB C2 router for the Swedish provider TELE2.
Menu for WIFI HUB C2: 192.168.0.1 > Enter “admin” and the password (see router sticker) > Access Control > Port Forwarding:
Figure 1: Port Forwarding on Router
Note: External Host “*” means any external client is allowed to connect, ie no restrictions on IP range.
Trouble shooting:
- If the configuration does not work you may also check and enable the following services for the specific ports (80, 443, 6667, 6697, 9000, 9050, 9150):
- UPnP (IGd), which allows temporarily opening ports for which traffic was requested by specific apps, eg games.
- Port Triggering, which allows temporarily opening ports for which traffic was requested by specific apps, eg games.
- Firewall
- Note: The router may need restarting to update the port configuration.
- You can check whether your port is open using web services [37]. If a port is reported is closed, this can be caused the issues in the router configuration, but also by a software issue, ie that the service is not listening on the correct port.
- You may need to get support from your Internet Provider for your specific router model (Say: “SHIBBOLEET!” ;-)) [75].
4. Quick Installation
The following steps allow the quick installation of the overall software stack by cloning the config files from a GIT code repository. A tutorial specfically describing the installation and de-installation using the included installation scripts is available here:
Igl, W. (2025). AEREEnet: Creating a low-cost, light-weight, scalable, anonymous, secure social network – A Short Tutorial. https://biosphere.wilmarigl.de/en/?p=4654
Note:
- Using QNAP/QTS/Container Station, the “dockerusr” needs have admin privileges (ie, in sudo group).
- However, for security purposes the “dockerusr” should not have permission to connect via secure shell (ssh). Use another user account with admin and ssh privileges, whose username you keep secret, to connect to your server and then switch to the “dockerusr” as described below.
Warning! For demonstration purposes and simplicity the same server is configured for the clearnet and the darknet in this tutorial using the “hybridnet” installation script (see below). Therefore, the darknet server can be identified via the clearnet web address and IP and, therefore, is not anonymous. A completely hidden server in the Tor network should NOT be made available in the clearnet, ie should NOT have a domain address assigned and the expression aeree.net:443{…} should be removed from the Caddyfile of the webserver (see below). Therefore, for maximum anonymity and security the “Darknet” server installation script is the primary recommendation.
1. Connect to server
LOCAL> ssh adminusr@192.168.0.24
2. Switch to standard (non-admin) user:
SERVER> sudo -i -u dockerusr
3. Clone code repository with Docker container configuration into ~/docker/
SERVER> cd ~; git clone https://wiliglpm@bitbucket.org/wiliglpm/aereenet.git
5. Run install script
# “Darknet” server Installation [Primary Recommendation]
SERVER>bash ~/aereenet/11_AEREENET_DARKNET_INSTALL.sh | tee ~/11_AEREENET_DARKNET_INSTALL_$(date '+%Y%m%d_%H%M%S').log
# “Clearnet” Server Installation [Secondary Recommendation]
SERVER>bash ./aereenet/21_AEREENET_CLEARNET_INSTALL.sh | tee ~/21_AEREENET_CLEARNET_INSTALL_$(date '+%Y%m%d_%H%M%S').log
# “Hybridnet” Server Installation [Demo only]
SERVER>bash ./aereenet/31_AEREENET_HYBRIDNET_INSTALL.sh | tee ~/31_AEREENET_HYBRIDNET_INSTALL_$(date '+%Y%m%d_%H%M%S').log
5. Run DOCKER containers
Important! The following steps will be automatically performed by the installation scripts. The main configurations of the “Hybridnet” installation script are described here for educational purposes. Please see installation script “~/aereenet/31_AEREENET_HYBRIDNET_INSTALL.sh” in the Git code repository for full details.
The planned IRC network includes the following software components:
- CADDY (a reverse proxy to forward traffic)
- ERGO (an IRC demon including IRC services, ie nickserv, chanserv)
- THELOUNGE (a web client for an IRC server)
- TOR (a relay server making the IRC network available as a hidden service)
Notes:
- These apps/containers will exchange information via specific ports, which requires creating a virtual network in DOCKER and adding the containers to the network when starting them. Since Docker containers get a specific internal IP address and a network on their own, port forwarding with localhost:port or 127.0.0.1:port, which you find in many tutorials for host-level (non-docker) installations of similar software stacks, will NOT work.
- To install DOCKER images and run DOCKER containers, one can use terminal commands or define configurations files (compose.yaml). Configuration files of complex configurations are easier to format and understand.
5.1 Preparations
Notes:
- General advice on how to install non-standard packages on a QNAP NAS (with QTS 5.x) is available here [69].
- A DOCKER installation is required on your host (eg, QNAP NAS). On a QNAP NAS, “Container Station” needs to be installed via the App Center. (Note: It seems the Container Station is fine for running containers, but for building containers it does not support the current “buildx” environment, only legacy environment.)
- I recommend installing a simple editor, such as “nano” (as .qpkg package file) [38], on the QNAP NAS, because the default editor “vim” is unnecessarily difficult to use for writing simple config files. If you get the error (“Error opening terminal: xterm-256color.”) after entering “nano” in the terminal, execute “export TERM=xterm” in the terminal. To make the change permanent, add the command to the .profile (see [69]).
- I recommend installing “tmux” (as .qpkg package file) [39] as a terminal multiplexer on the QNAP NAS, which is more user friendly than the preinstalled “screen” tool. It allows creating permanent terminal sessions after disconnecting from the server and reattaching to these sessions after reconnecting.
- I recommend installing “git” (as QGit_*.qpkg file) [66] as version control system on the QNAP NAS, to clone and version control the overall Docker container configurations.
- For additional security, one can create a different non-admin user (eg, dockeruser) to run the docker containers.
- If you use the “–volume” flag to bind-mount a file or directory that does not yet exist on the Docker host, Docker automatically creates the directory on the host for you. It’s always created as a directory, therefore, mounting specific configuration files need to be saved in the target path on the host before mounting [40].
- To avoid permission issues between host permissions (eg, dockerusr, id 100*), container permissions using the default docker user (eg, root, id 1000) or custom docker users (eg, tor, id 100), 1) a named volume is created in the container and 2) the contents in the hosted folder are mapped to a container volume. Then, then the contents are copied from the container volume to the named volume and permissions, which automatically sets the permissions from the default container user. If custom container users (ie, non-root, id is not 1000), the permissions of the named volume can be changed manually to avoid conflicts with permissions of host (eg git) and container (eg tor).
Useful DOCKER commands:
# DOCKER CONTAINER SERVER> docker container list # lists all containers including container names SERVER> docker inspect <container_name> # shows details of a container SERVER> docker restart <containername> # restarts container and reloads configuration SERVER> docker compose -f /path/to/compose.yaml down SERVER> docker compose -f /path/to/compose.yaml up --detach --force-recreate # restarts container and reloads ALL configuration SERVER> docker stop <containername> # stops the running container SERVER> docker rm <container_name> # removes the stopped container, required before starting container with same name SERVER> docker container logs <container_name> # short: docker logs <container_name> # show logs of container started in detached mode SERVER> docker cp <containerId>:/file/path/within/container /host/path/target # copy files from container to host, eg to edit default config files SERVER> docker exec -it <containerid> /bin/sh # start an interactive shell in (!) the container SERVER> docker exec -w /etc/caddy caddy caddy reload # -w <workingdirectory> <container_name> <flags> # reload Caddy container SERVER> docker exec -w /etc/caddy caddy caddy fmt --overwrite # auto-formats Caddyfile # DOCKER VOLUMES SERVER> docker run --rm -v nvol_tor_conf:/etc/tor/ -v ~/docker/tor/tor_conf/torrc.conf:/torrc.conf busybox cp /torrc.conf /etc/tor/torrc SERVER> docker volume list SERVER> docker volume inspect <volume_name> SERVER> docker volume prune SERVER> docker volume remove --force # DOCKER NETWORKS SERVER> docker network create <network_name> # create network for containers SERVER> docker network list # list networks for containers SERVER> docker network connect <network_nam> <container_name> # connect container to a specific network of containers
SERVER> docker network inspect <network_name> # show containers connected with network of containers SERVER> docker network prune # remove networks, which are not used by any containers anymore SERVER> docker network remove --force
Use your CLIENT (eg, laptop) to connect to your SERVER (eg, QNAP NAS):
CLIENT> ssh dockerusr@192.168.0.24 -p 22 # Intranet LAN IP and default port for ssh connection
Note:
- For a reproducible, production system, specific docker images, which are referenced by there version numbers, should be used. The downloaded “latest” image will change over time.
- QNAP/QTS 5.x only allows users with admin privileges to connect via ssh to the NAS, however, dockeruser should not have ssh privileges for security purposes. Therefore, one has to connect with a user account in the admin group with ssh privileges to the NAS and then switch to the “dockerusr” account with the following command:
LOCAL> ssh adminusr@192.168.0.24
SERVER> sudo -i -u dockerusr
Important! Create a DOCKER network which all Docker containers will be connected with:
SERVER> docker network create aeree_net
5.2 Run CADDY
The documentation of the docker container is recommended for further instructions [41]. The basic approach to configure CADDY web server as a reverse proxy is described elsewhere [42] (very useful!).
Create the following CADDY configuration folders:
SERVER> mkdir -P ~/aereenet/caddy
SERVER> mkdir -P ~/aereenet/caddy/caddy_data/ # permanent data storage
SERVER> mkdir -P ~/aereenet/caddy/caddy_conf/ # permanent config storage
SERVER> cd ~/aereenet/caddy/
Edit main Docker configuration file (“compose.yaml”):
SERVER> nano ~/aereenet/caddy/compose.yaml # Docker configuration file
Configure DOCKER container for Caddy (~/aereenet/caddy/compose.yaml):
services:
caddy:
image: caddy:latest
container_name: caddy
volumes:
- nvol_caddy_file:/etc/caddy/
- nvol_caddy_conf:/config/
- nvol_caddy_data:/data/
networks:
- aeree_net
ports:
- "80:80"
- "443:443"
- "443:443/udp"
restart: unless-stopped
volumes:
nvol_caddy_file:
name: nvol_caddy_file
external: true
nvol_caddy_conf:
name: nvol_caddy_conf
external: true
nvol_caddy_data:
name: nvol_caddy_data
external: true
networks:
aeree_net:
name: aeree_net
external: true
Run Docker container for Caddy:
SERVER> docker compose -f ~/aereenet/caddy/compose.yaml up --detach --force-recreate
SERVER> docker logs caddy # check whether container is working
Edit main Caddy configuration file (“Caddyfile”):
SERVER> nano ~/aereenet/caddy/Caddyfile # main Caddy configuration file
Contents of the Caddy configuration file (~/aereenet/caddy/Caddyfile, “Hybridnet” version):
# Reverse Proxy for Clearnet traffic
# Uncomment config below, if you want to use a clearnet address.
# Warning! Assigning a Clearnet address makes the Darknet address non-anonymous!
https://aeree.net:443 {
tls {
issuer acme {
email burneremail.i6z8l@passinbox.com
dir https://acme.zerossl.com/v2/DV90
#dir https://acme-v02.api.letsencrypt.org/directory
}
}
reverse_proxy thelounge:9000
}
# Reverse proxy for Darknet traffic
http://*.onion:80 {
reverse_proxy thelounge:9000
}
Note:
- Caddy is very strict with formatting, esp. indentation (ie 4 spaces per indentation level).
- As certificate authority ZeroSSL was preferred over Let’s encrypt, because ZeroSSL does not have any rate limitations [68], which was convenient during development and testing. The selection of certificate authority also affects the path to the TLS certificates, which are used by the ERGO chat server (cf ircd.yaml).
- A TLS certificate by certifying authority for the “clearnet” domain address aeree.net, will be automatically generated, thereby, enabling client-server encryption via TLS (https).
- Certifying authorities usually do not issue TLS certificates for .onion addresses. Therefore, for “Darknet” addresses a self-signed certificate is used to enable TLS-encryption for the client-server connection (in addition to Tor encryption). However, browsers usually flag self-signed certificates as “unsecure”/”invalid”/”untrusted”, which will may unnecessarily alarm non-expert users, since the client-server connection for hidden services in the Tor network is already encrypted.
Reload CADDY Configuration:
SERVER> docker restart caddy # alternative: docker exec -w /etc/caddy caddy caddy reload
Notes: If there is warning that the Caddyfile is not formatted correctly, run this command first, then reload:
SERVER> docker exec -w /etc/caddy caddy caddy fmt --overwrite
Notes: Restarting a Docker container may lead to losing the connection to the aeree_net docker network and you may have to re-connect the container to the docker network (see Useful Docker Commands above).
5.3 Run IRCD
5.3.1 Run ERGO IRC server [RECOMMENDED]
The documentation of the docker container is recommended for further instructions [43, 44]. Use the docker image from Github as detailed below, not from Docker Hub, whose docker images are outdated! Don’t mix up with “ergo” cryptocurrency images! Tutorials on basic and advanced use of IRC are available elsewhere [63, 64, 65].
Create the following configuration folders:
SERVER> mkdir -P ~/aereenet/ergo/ircd/
SERVER> cd ~/aereenet/ergo/
Edit main Docker configuration file (“~/aereenet/ergo/compose.yaml”):
SERVER> nano ~/aereenet/ergo/compose.yaml
Configure DOCKER container for ERGO (~/aereenet/ergo/compose.yaml):
services:
ircd:
image: ghcr.io/ergochat/ergo:stable
container_name: ircd
volumes:
- nvol_ircd_conf:/ircd/
- nvol_caddy_data:/ircd/certs/
networks:
- aeree_net
ports:
- "6667:6667"
- "6697:6697"
init: true
restart: unless-stopped
volumes:
nvol_ircd_conf:
name: nvol_ircd_conf
external: true
nvol_caddy_data:
name: nvol_caddy_data
external: true
networks:
aeree_net:
name: aeree_net
external: true
Notes:
- Automatically generated TLS certificates are imported from Caddy webserver via named volume “nvol_caddy_data”.
- The named volumes are created before the start of the ircd container in the installation script.
Run Docker container for ERGO:
SERVER> docker compose up --detach --force-recreate
SERVER> docker logs ircd # check whether container is working
Edit main Docker configuration file (~/aereenet/ergo/ergo_conf/ircd.yaml):
SERVER> nano ~/aereenet/ergo/ergo_conf/ircd.yaml
Edit main ERGO configuration file with the following minimal revisions:
# network configuration
network:
# name of the network
# -- EDIT BELOW --
name: AEREENET
#...
# server configuration
server:
# server name
# -- EDIT BELOW --
name: aeree.net
#...
# -- EDIT BELOW --
# ":6667":
# ...
# The standard SSL/TLS port for IRC is 6697. This will listen on all interfaces:
":6697":
# this is a standard TLS configuration with a single certificate;
# see the manual for instructions on how to configure SNI
# -- EDIT BELOW --
tls:
# ZeroSSL Paths
cert: /ircd/certs/caddy/certificates/acme.zerossl.com-v2-dv90/aeree.net/aeree.net.crt
key: /ircd/certs/caddy/certificates/acme.zerossl.com-v2-dv90/aeree.net/aeree.net.key
# ...
# allow at most this many connections at once (0 for no limit):
# -- EDIT BELOW --
max-connections: 0
#...
# connection throttling (limit how many connection attempts are allowed at once):
throttle-duration: 10m
# set to 0 to disable throttling:
# -- EDIT BELOW --
max-connections-per-duration: 0
# operators can be authenticated either by password (with the /OPER command),
# or by certificate fingerprint, or both. if a password hash is set, then a
# password is required to oper up (e.g., /OPER dan mypassword). to generate
# the hash, use `ergo genpasswd`.
# -- EDIT BELOW --
password: "$2a$04$9mq/CA88hEUN3H.OgT.JtO/T80vYfuYG41UY4y2ClJYrlSebNJWcy"
Notes:
- Automatically generated TLS certificates by Caddy server are imported to the ERGO server via mapping the folder with the TLS certificates.
- Since ERGO is running in a docker container, to generate a new encrypted password (hash) for Operators (eg, “admin”) use:
SERVER> docker exec -it ircd /bin/sh -c "/ircd-bin/ergo genpasswd"
Warning! Store all passwords safely, eg in a password manager. Passwords cannot be recovered via email!
Reload ERGO Configuration:
SERVER> docker restart ircd # alternative: docker compose down; docker compose up --detach --force-recreate
5.3.2 Run INSPIRCD IRC server [ALTERNATIVE]
The documentation of the docker container is recommended for further instructions [77].
Create the following configuration folders:
SERVER> mkdir -P ~/aereenet/inspircd/inspircd_conf/
SERVER> cd ~/aereenet/inspircd/
Edit main Docker configuration file (“~/aereenet/inspircd/compose.yaml”):
services:
ircd:
image: inspircd/inspircd-docker
container_name: ircd
volumes:
- nvol_ircd_conf:/inspircd/conf/
- nvol_caddy_data:/inspircd/conf/certs/
networks:
- aeree_net
ports:
- "6667:6667"
- "6697:6697"
restart: always
environment:
INSP_NET_SUFFIX: '.aeree.net'
INSP_NET_NAME: 'AEREENET'
INSP_ADMIN_NAME: 'AEREENET Admin'
INSP_ADMIN_NICK: 'admin'
INSP_ADMIN_EMAIL: 'burneremail.i6z8l@passinbox.com'
INSP_OPER_SSLONLY: 'yes'
INSP_OPER_NAME: 'admin'
INSP_OPER_HASH: 'sha256'
INSP_OPER_PASSWORD_HASH: '8f6ee6d4b95ad40d32c8fdeabae85dbcc9c8a08636e6b9c1db5a7c33525163f6'
volumes:
nvol_ircd_conf:
name: nvol_ircd_conf
external: true
nvol_caddy_data:
name: nvol_caddy_data
external: true
networks:
aeree_net:
name: aeree_net
external: true
Notes:
- Automatically generated TLS certificates are imported from Caddy webserver via named volume “nvol_caddy_data”.
- The named volumes are created before the start of the ircd container in the installation script.
- To generate a new password hash for INSP_OPER_PASSWORD_HASH:
IRCServerWindow>/mkpasswd sha256 mynewpassword
Run Docker container for INSPIRCD:
SERVER> docker compose -f ~/aereenet/inspircd/compose.yaml up --detach --force-recreate
SERVER> docker logs ircd # check whether container is working
Edit main INSPIRCD configuration files (~/aereenet/inspircd/inspircd_conf/inspircd.conf and ./modules.conf):
SERVER> nano ~/aereenet/inspircd/inspircd_conf/inspircd.conf
SERVER> nano ~/aereenet/inspircd/inspircd_conf/modules.conf
Edit main INSPIRCD configuration file (“inspircd.conf”) as follows to use the TLS certificates automatically generated by Caddy and activate channel history as default setting for all channels:
# -- EDIT BELOW --
<sslprofile name="Clients"
provider="gnutls"
cafile=""
certfile="/inspircd/conf/certs/caddy/certificates/acme.zerossl.com-v2-dv90/aeree.net/aeree.net.crt"
crlfile=""
dhfile=""
hash="sha256"
keyfile="/inspircd/conf/certs/caddy/certificates/acme.zerossl.com-v2-dv90/aeree.net/aeree.net.key"
mindhbits="1024"
outrecsize="2048"
priority="NORMAL"
requestclientcert="yes"
strictpriority="no">
#...
# -- EDIT BELOW --
defaultmodes="notH 50:24h"
Edit main INSPIRCD configuration file (“modules.conf”) as follows to enable “cloaking”, ie hiding user IP addresses from each other:
# -- EDIT BELOW --
<module name="md5">
#...
# -- EDIT BELOW --
<cloak mode="full"
key="DERfqvJnjEEpamAKEEqZRMUHuznbdWzneDgXFrbNrrLcaghkvjvXrzcmFodrMpBK"
prefix="aer-"
ignorecase="no">
#...
# -- EDIT BELOW --
<autojoin channel="#aer-meetngreet">
Note: A more comprehensive tutorial how to configure a inspircd server is available elsewhere [78].
Reload INSPIRCD Configuration:
SERVER> docker restart ircd # alternative: docker compose down; docker compose up --detach --force-recreate
5.4 Run THELOUNGE
The documentation of the docker container is recommended for further instructions [45].
Create the following THELOUNGE configuration folders:
SERVER> mkdir -P ~/aereenet/thelounge/
SERVER> cd ~/aereenet/thelounge/
Edit main Docker configuration file (“~/aereenet/thelounge/compose.yaml”):
SERVER> nano ~/areenet/thelounge/compose.yaml
Configure DOCKER container for THELOUNGE (“~/areenet/thelounge/compose.yaml”):
services:
thelounge:
image: thelounge/thelounge:latest
container_name: thelounge
volumes:
- nvol_thelounge_data:/var/opt/thelounge/
- nvol_ircd_conf:/ircd/
- nvol_caddy_data:/caddy_data/
networks:
- aeree_net
ports:
- "9000:9000"
environment:
- NODE_EXTRA_CA_CERTS=/usr/local/share/ca-certificates/ergo_selfsigned_fullchain.crt
# - NODE_EXTRA_CA_CERTS=/etc/ssl/certs/ca-certificates.crt
restart: always
volumes:
nvol_thelounge_data:
name: nvol_thelounge_data
external: true
nvol_ircd_conf:
name: nvol_ircd_conf
external: true
nvol_caddy_data:
name: nvol_caddy_data
external: true
networks:
aeree_net:
name: aeree_net
external: true
Run Docker container for TheLounge:
SERVER> docker compose -f ~/aereenet/thelounge/compose.yaml up --detach --force-recreate
SERVER> docker logs thelounge # check whether container is working
Edit the main THELOUNGE configuration file (“config.js”):
SERVER> nano ~/aereenet/thelounge/config.js
Configure the main THELOUNGE configuration file (“config.js”) as follows:
// ## Server settings
// ### `public`
//...
// -- EDIT BELOW --
public: true,
// ...
// ## Default network
// ### `defaults`
// ...
// -- EDIT BELOW --
defaults: {
name: "AEREENET",
host: "aeree.net",
port: 6697,
password: "",
tls: true,
rejectUnauthorized: false,
nick: "eaglet%%",
username: "tinyeagle",
realname: "Tiny Eagle",
join: "#aer-meetngreet",
leaveMessage: "Peace out!",
},
// ### `lockNetwork`
// ...
// This value is set to `false` by default.
// -- EDIT BELOW --
lockNetwork: true,
Note: Do NOT use the internal “web server” by THELOUNGE (“config.js”: https: {enable: false, …}), which does not work reliably.
Reload THELOUNGE Configuration:
SERVER> docker restart thelounge #alternative: docker exec -w /var/opt/thelounge thelounge reload
5.5 Run TOR
The documentation of the docker container is recommended for further instructions [46, 47]. Best practices for security in the Tor network are discussed here [48, 49, 67].
Configuring the THELOUNGE web client as hidden service via the TOR network using a .onion address, will hide the IP address and, hence, the location of the server and encrypt the client-server connections.
Note:
- Check install logs for warnings whether TOR version is still up-to-date, alternatively check when docker image was uploaded.
Create the following TOR configuration folders:
SERVER> mkdir -p ~/aereenet/tor/tor_conf/; mkdir -p ~/aereenet/tor/tor_data/
SERVER> cd ~/aereenet/tor/
Edit the Docker configuration file (~/aereenet/tor/compose.yaml):
SERVER> nano ~/aereenet/tor/compose.yaml
Configure DOCKER container for TOR (~/aereenet/tor/compose.yaml):
services:
tor:
image: wiligl/tor-default
user: 100:100
container_name: tor
volumes:
- nvol_tor_conf:/etc/tor/
- nvol_tor_data:/var/lib/tor/
networks:
- aeree_net
ports:
- "127.0.0.1:9050:9050"
restart: always
volumes:
nvol_tor_conf:
name: nvol_tor_conf
external: true
nvol_tor_data:
name: nvol_tor_data
external: true
networks:
aeree_net:
name: aeree_net
external: true
Run Docker container for TOR:
SERVER> docker compose -f ~/aereenet/tor/compose.yaml up --detach --force-recreate
SERVER> docker logs tor
Check if Tor works from inside the Tor container:
SERVER/TorContainer> docker exec -it tor /bin/sh
SERVER/TorContainer> curl --socks5 localhost:9050 https://check.torproject.org/api/ip # OUTPUT: {"IsTor":true,"IP":"45.138.16.239"}
Check if Tor works from outside the Tor container on Server (ie, QNAP NAS):
SERVER> curl -i -s -S -f --socks5 localhost:9050 --socks5-hostname localhost:9050 https://check.torproject.org/api/ip
Get .onion address:
SERVER> docker exec -it tor /bin/sh -c "cat /var/lib/tor/aereenet/hostname"
yi5dvnkqev4gsbcy6wdaa4udhlqhsvcnq3nylxnjfratnlhpu7bz7aid.onion
Edit Tor configuration file:
SERVER> nano ~/docker/tor/tor_conf/torrc.conf
Configure main TOR configuration file as follows (## comments provided for context):
## Tor opens a SOCKS proxy on port 9050 by default -- even if you don't
## configure one below. Set "SOCKSPort 0" if you plan to run Tor only
## as a relay, and not make any local application connections yourself.
#SOCKSPort 9050 # Default: Bind to localhost:9050 for local connections.
#SOCKSPort 192.168.0.1:9100 # Bind to this address:port too.
# -- EDIT BELOW --
SOCKSPort 0.0.0.0:9050
# ...
############### This section is just for location-hidden services ###
## Once you have configured a hidden service, you can look at the
## contents of the file ".../hidden_service/hostname" for the address
## to tell people.
##
## HiddenServicePort x y:z says to redirect requests on port x to the
## address y:z.
# Hidden Services for Caddy/http (:80), IRC/Plain (:6667), IRC/TLS (:6697)
HiddenServiceDir /var/lib/tor/aereenet/
HiddenServicePort 80 caddy:80
HiddenServicePort 6697 ircd:6697
Notes:
- The Tor server is listening on port 80 (default port for web traffic) and forwards the traffic to the Caddy webserver (reverse proxy) at port 80.
- The Tor server is listening on port 6697 (default port for TLS-encrypted IRC traffic) and forwards the traffic to the IRC server at port 6697 (TLS encrypted).
Reload TOR Configuration:
SERVER> docker restart tor
6. Secure communication
Here, a conceptual discussion of secure communication is provided. A tutorial with examples how to configure various IRC clients for end-to-end encryption is available elsewhere [76].
6.1 Dual complementary network approach
I would like to propose a dual complementary network approach to secure communication, which combines a low-trust, high-safety and a high-trust, low-safety communication network. The reason is, that the principle of Anonymity protects users, but it conflicts with the principle of Secrecy. If one user cannot identify another user, he cannot be certain that the shared content will reach the intended user or somebody else. This means even if the content is encrypted, it may not be secret, for example, similarly to sending a sealed letter to the wrong John Smith in London.
Principles of a low-trust, high-safety network:
- Integrity: The used system should work as described and be protected against modification by unauthorized users (eg, malware, man-in-the-middle attacks).
- Anonymity: The user controls his/her identity by creating an anonymous identity without any directly of indirectly (linked) personally identifiable data.
- Secrecy: The content of the communication should be secret by using encryption technologies which protects the content from other unauthorized users.
- Usability: The user should sufficiently understand the network features to use it correctly (cf mental model alignment, system-user congruence).
Principles of a high-trust, low-safety network:
- Integrity: The used system should work as described and be protected against modification by unauthorized users (eg, malware, man-in-the-middle attacks).
- Identity: The user controls his/her identity by creating a permanent, verified identity.
- Secrecy: The content of the communication should be secret by using encryption technologies which protects the content from other unauthorized users.
- Usability: The user should sufficiently understand the network features to use it correctly (cf mental model alignment, system-user congruence).
This means that to communicate with a high-trust and high-safety, passwords (secret, key) for secure, encrypted communication in a low-trust, high-safety network need to be combined by exchanging the passwords (secret, key) in a high-trust, low-safety network. This implies the risk that meta-data about which users interacted in the high-trust, low-safety network (eg, connecting via WhatsApp based on personal phone numbers, exchanging a note with password in café) may still be recorded and potentially used against users.
6.2 Clearnet
If users communicate using the IRC network at https://aeree.net or irc://aeree.net/6697 (“clearnet”):
- the client-server connection is encrypted via TLS
- the end-to-end (client-to-client) connections can be encrypted with an appropriate IRC client, for example:
- Hexachat (GUI) using FiSH encryption [50, 51]
- Chatzilla (GUI) in the Thunderbird or Seamonkey suite using Off-the-record (OTR) encryption [52, 53, 54]
- Weechat (Terminal) using FiSH (fish.py) or OpenPGP (ircrypt.py) encryption [55, 51, 56].
Note: Without end-to-end encryption users have to trust the admin of the AEREE.NET server to treat their data private.
6.3 Darknet
If users communicate using the IRC network at the http://xxx.onion domain in the Tor network (“darknet”):
- the server are anonymous (ie, unknown domain, unknown IP, unknown Location)
- the clients (users) are anonymous (ie, unknown identity, unknown IP, unknown Location)
- the client-server connection is encrypted
- the end-to-end (client-to-client) connections can be encrypted with an appropriate IRC client, for example:
- Hexachat (GUI) using FiSH encryption [50, 51]
- Chatzilla (GUI) in the Thunderbird or Seamonkey suite using Off-the-record (OTR) encryption [52, 53, 54]
- Weechat (Terminal) using FiSH (fish.py) or OpenPGP (ircrypt.py) encryption [55, 51, 56].
Note: Without end-to-end encryption users have to trust the admin of a (random) TOR “rendezvous point” server in the Tor network, to treat their data private. This may provide additional protection against targeted attacks in comparison to encrypted “clearnet” client-server connections via TLS.
6.4 Warnings
- Since nicknames/usernames are not automatically permanent in an IRC network unless registered (with IRC services such as NickServ), the users should use another trusted communication channel (eg, in real life, phone, letter, …) to identify the other user as the trusted, intended communication partner. This means, exchange of shared secrets/keys/passwords for an encrypted communication, need to be exchanged in an operationally secure way, which makes sure that the person/nickname one is communicating with is actually the trusted person, you want to communicate with.
- There are also tricks like posting an external link in the IRC chat, and if users click it, the link is automatically opened in the clearnet (depending on the desktop configuration) maybe in the standard browser making the user leave the Tor network and becoming identifiable. Therefore, it is strongly recommended clicking only on links in the chat which are trusted and potentially comprising anonymity is acceptable (ie low risk).
- Fingerprinting may be used to create profile of a users based on multiple, available parameters, eg screen dimensions/resolution, keyboard layout, typical typos, etc and the fingerprints between anonymous and identifiable accounts can be correlated, effectively de-anonymizing/identifying the users. The Tor browser takes specific pre-cautions to protect users from fingerprinting.
- Social engineering techniques, ie stepwise building trust may be used, to elicit identifiable information (ie, first name, city, hobbies) from a user.
- Users are ultimately responsible for their own anonymity, security, integrity of their system, and having sufficient mental model (“understanding”) of the systems they are using. No system is completely secure. Strength of security vs the strength of the motive of attackers to breach one’s security needs to be balanced depending on the identity of the user (activist vs my grandma) and content (eg, entry codes for nuclear power plant vs yesterday’s grocery list).
- Nobody will stop users doing reckless things, like posting their real names or addresses on social networks.
7. Appendix: Notes to myself
I am summarizing some seemingly alternative approaches, which did not work or were inefficient because they required additional work, in short “Don’t!”.
7.1 QNAP/QTS: “Container Station”
- The various DOCKER containers are also available via the “Container Station” App of the QNAP QTS operating system. Existing containers can also be modified, eg by restricting the resource use (eg CPUs, memory) to avoid interfering with other NAS operations. However, the main issues is that a DOCKER network needs to be created and the various Docker services (caddy, irc, thelounge) need to be connected, which is not available in the Container Station (to my knowledge).
7.2 QNAP/QTS: Handling TLS/SSL certificates
- QNAP QTS operating system can also generate and renew TLS certificates (QNAP QTS > Control Panel > System > Security > SSL Certificate & Private Key). The certificate files can also be downloaded and copied into the config folders of various services. This is not optimal because this step needs to be manually repeated every 3 months. Certificates are only available for default domains (eg, myname.myqnapcloud.com), not custom domains.
- QNAP QTS operating system can also import manually created TLS certificates for custom domains (QNAP > Control Panel > System > Security > SSL Certificate & Private Key > Import). The fullchain.pem file and the privkey.pem file have to be appended in one file, eg combinedkeys.pem, and uploaded. Format:
—–BEGIN CERTIFICATE—–
(Contents of fullchain.pem)
—–END CERTIFICATE—–
—-BEGIN PRIVATE KEY—–
(Contents of privkey.pem)
—–END PRIVATE KEY——
This is not optimal because this step needs to be manually repeated every 3 months.
- A TLS certificate can be manually created on another system with the following command:
CLIENT> sudo certbot certonly --manual --domain aeree.net --preferred-challenges=dns --agree-tos
The certifcates can be found in the default folder ‘/etc/letsencrypt/archive/aree.net/’ of the client and copied to the server.
7.3 QNAP/QTS: Reverse Proxy
- QNAP QTS operating system includes a reverse proxy (QNAP QTS > Control Panel > Network & File Services > Network Access > Reverse Proxy). This requires creating a DNS TXT record for the domain on the website of your domain name provided with value of an ACME authentification key (eg, xPZyoMQvhKCzDNZAwM-3VmZEbc5PLJrmlxOGIVxIs30).
7.4 TheLounge: Internal Web Server
- Do NOT use the internal “web server” by THELOUNGE (“config.js”: https: {enable: false, …}) for TLS-encrypted, secure connections, since it does not work reliably.
7.5 ERGO: Selection of IRC server
The ERGO IRC server was preferred over InspIRCd IRC server, because it allowed to considerably reduce the complexity of the software stack and the tutorial:
- ERGO integrates IRC services and, thereby, does not need the installation of ANOPE software.
- ANOPE, which uses an integrated SQLite database as default for testing, requires an additional MySQL installation for production.
- ERGO integrates Bouncer services, which does not require the installation of the ZNC software. While InspIRCd also allows configuring the channel history, ERGO IRC has more functionality handling the channel history.
- ERGO integrates email services, which does not require the installation of an SMTP server.
- ERGO server is somewhat easier to configure.
References
[1] https://en.wikipedia.org/wiki/IRC
[2] https://en.wikipedia.org/wiki/Docker_(software)
[3] https://en.wikipedia.org/wiki/Tor_(network)
[4] https://en.wikipedia.org/wiki/Transport_Layer_Security
[5] https://en.wikipedia.org/wiki/End-to-end_encryption
[6] https://thelounge.chat
[7] https://ergo.chat
[8] https://movim.eu
[9] https://prosody.im
[10] https://en.wikipedia.org/wiki/XMPP
[11] https://thewire.in/world/the-right-wing-is-on-the-rise-globally
[12] https://foreignpolicy.com/2023/12/26/right-wing-populism-are-set-to-sweep-the-west-in-2024/
[13] McChesney, RW (1997). Corporate Media and the Threat to Democracy. Penguin Random House, https://www.penguinrandomhouse.com/books/213901/corporate-media-and-the-threat-to-democracy-by-robert-w-mcchesney/
[14] Olaniran, B., & Williams, I. (2020). Social Media Effects: Hijacking Democracy and Civility in Civic Engagement. Platforms, Protests, and the Challenge of Networked Democracy, 77–94. https://doi.org/10.1007/978-3-030-36525-7_5
[15] https://joinmastodon.org
[16] https://en.wikipedia.org/wiki/ActivityPub
[17] https://bsky.social/
[18] https://en.wikipedia.org/wiki/AT_Protocol
[19] https://justingarrison.com/blog/2023-04-24-mastodon-is-doomed/
[20] Söderberg, J., Maxigas (2022). Internet Relay Chat: A time machine that stood the test of time. In: Söderberg, J., Maxigas (Eds). Resistance to the Current – The Dialectics of Hacking. Cambridge, MA, USA: MIT Press.
[21] AnonOps (2024). OpNewblood Guide for IRC Chat Setup & Anonymity. https://newblood.anonops.com/index.html
[22] https://biosphere.wilmarigl.de/en/?p=3659
[23] https://www.qnap.com/en/product/ts-653a
[24] https://www.raspberrypi.com/products/raspberry-pi-3-model-b-plus/
[25] https://www.torproject.org/download/
[26] Prompt “Assume a server with 2GB of memory and a bandwidth of 150Mbit/second, which runs a minimal Linux operating System, such as Alpine Linux, an IRC server, eg ERGO chat, and an IRC web client, eg TheLounge. All connections use TLS encryption. Questions: 1) How much memory is available for handling Internet Relay Chat (IRC) traffic, if the web client is not used by any users? How many IRC users can simultaneously be active on such a server? 2) How much memory is available for handling Internet Relay Chat (IRC) traffic, if the web client is used by all users? How many IRC users can simultaneously be active on such a server?”, Retrieved 2025-01-28 from https://chatgpt.com.
[27] https://wiki.znc.in/ZNC
[28] https://www.anope.org
[29] https://www.eggheads.org/
[30] https://github.com/progval/Limnoria/
[31] https://docs.inspircd.org/tutorials/prevent-spam/
[32] https://www.tele2.se/bredband/utrustning/wifi-hub-c2
[33] https://www.tele2.se/kundservice/kontakt
[34] https://www.namecheap.com
[35] https://docs.qnap.com/operating-system/qvp/1.4/en-us/GUID-9EE2C9F0-1825-4A9A-84B7-4476DDA4CBE0.html
[36] https://caddyserver.com/docs/modules/dynamic_dns
[37] https://www.yougetsignal.com/tools/open-ports/
[38] https://www.myqnap.org/product/nano-cli/
[39] https://www.myqnap.org/product/tmux-cli/
[40] https://docs.docker.com/engine/storage/bind-mounts/
[41] https://hub.docker.com/_/caddy
[42] https://docs.vultr.com/how-to-install-caddy-using-docker-on-a-vultr-cloud-server
[43] https://github.com/ergochat/ergo/pkgs/container/ergo
[44] https://github.com/ergochat/ergo/blob/master/distrib/docker/README.md
[45] https://hub.docker.com/r/thelounge/thelounge/
[46] https://hub.docker.com/r/leplusorg/tor
[47] https://github.com/leplusorg/docker-tor
[48] https://riseup.net/en/security
[49] https://riseup.net/en/security/network-security/tor/onionservices-best-practices
[50] https://hexchat.github.io
[51] https://en.wikipedia.org/wiki/Fish_(cryptography)
[52] https://support.mozilla.org/en-US/kb/instant-messaging-and-chat
[53] https://www.seamonkey-project.org/doc/features
[54] https://en.wikipedia.org/wiki/Off-the-record_messaging
[55] https://weechat.org
[56] https://en.wikipedia.org/wiki/Pretty_Good_Privacy
[57] https://pastebin.com
[58] https://pasteboard.co
[59] https://justpaste.it
[60] https://filebin.net
[61] https://onionshare.org
[62] https://www.postfix.org
[63] https://opensource.com/life/16/6/irc-quickstart-guide
[64] https://biosphere.wilmarigl.de/en/?p=4209
[65] https://www.irchelp.org
[66] https://www.myqnap.org/?s=git
[67] https://support.torproject.org/faq/staying-anonymous/
[68] https://letsencrypt.org/docs/rate-limits/
[69] https://biosphere.wilmarigl.de/en/?p=4422
[70] https://www.wired.com/story/the-wired-guide-to-protecting-yourself-from-government-surveillance/
[71] https://biosphere.wilmarigl.de/en/?p=4705
[72] https://biosphere.wilmarigl.de/en/?p=4712
[73] https://biosphere.wilmarigl.de/en/?p=4722
[74] https://www.whatismyip.com
[75] https://xkcd.com/806/
[76] https://biosphere.wilmarigl.de/en/?p=4654
[77] https://hub.docker.com/r/inspircd/inspircd-docker
[78] https://biosphere.wilmarigl.de/en/?p=3659