These tutorials are written by Freedom Lab members in their free time. If you find them helpful, please consider supporting our work.

TutorialsSelf-Hosted SimpleX SMP Server

Self-Hosted SimpleX SMP Server

Self-hosting Privacy Linux

Run your own SimpleX SMP server for private, decentralized messaging.

This guide covers installing a SimpleX SMP (Simple Messaging Protocol) server on a Debian/Ubuntu VPS with Tor support.

Prerequisites

Secure SSH Access

After logging in, update your system:

sudo apt update && sudo apt upgrade -y

Edit the SSH configuration:

sudo vim /etc/ssh/sshd_config

Change the following settings (uncomment if needed):

Port 22222
PasswordAuthentication no
UsePAM no

Restart SSH:

sudo systemctl restart sshd

Setup Firewall

sudo apt install ufw -y
sudo ufw allow 22222/tcp
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw allow 5223/tcp
sudo ufw enable

Install Dependencies

sudo apt install -y gpg curl

Install SimpleX SMP Server

Download and run the SimpleX installation script:

curl -o- https://raw.githubusercontent.com/simplex-chat/simplexmq/stable/install.sh | bash

When prompted, select option 1 to install the SMP server.

Initialize the Server

Initialize the SMP server with your domain (replace smp.example.com with your domain):

sudo su smp -c 'smp-server init --yes \
    --store-log \
    --no-password \
    --control-port \
    --socks-proxy \
    --source-code \
    --fqdn=smp.example.com'

Save the output — it contains your server's fingerprint.

Install Tor

Install prerequisites:

sudo apt install -y apt-transport-https gnupg wget

Add the Tor Project repository. Create /etc/apt/sources.list.d/tor.sources:

CODENAME="$(lsb_release -c | awk '{print $2}')"

sudo tee /etc/apt/sources.list.d/tor.sources <<EOF
Types: deb deb-src
URIs: https://deb.torproject.org/torproject.org/
Suites: ${CODENAME}
Components: main
Signed-By: /usr/share/keyrings/deb.torproject.org-keyring.gpg
EOF

Add the GPG key:

wget -qO- https://deb.torproject.org/torproject.org/A3C4F0F979CAA22CDBA8F512EE8CBC9E886DDD89.asc | gpg --dearmor | sudo tee /usr/share/keyrings/deb.torproject.org-keyring.gpg >/dev/null

Install Tor:

sudo apt update && sudo apt install -y tor deb.torproject.org-keyring

Configure Tor

Create the hidden service directory:

sudo tor-instance-create tor2
sudo mkdir -p /var/lib/tor/simplex-smp/
sudo chown debian-tor:debian-tor /var/lib/tor/simplex-smp/
sudo chmod 700 /var/lib/tor/simplex-smp/

Edit /etc/tor/torrc and add at the bottom:

# Enable log
Log notice file /var/log/tor/notices.log

# Enable single hop routing (reduces latency, acceptable since onion address is public)
SOCKSPort 0
HiddenServiceNonAnonymousMode 1
HiddenServiceSingleHopMode 1

# SMP server hidden service
HiddenServiceDir /var/lib/tor/simplex-smp/
HiddenServicePort 5223 localhost:5223
HiddenServicePort 443 localhost:443

Edit /etc/tor/instances/tor2/torrc and replace the contents with:

# Log tor to systemd daemon
Log notice syslog

# Listen to local 9050 port for socks proxy
SocksPort 9050

Enable and start Tor:

sudo systemctl enable tor
sudo systemctl start tor
sudo systemctl restart tor
sudo systemctl enable --now tor@tor2

Install Caddy

Install Caddy for TLS certificates:

sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https curl

curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg

curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.list

sudo apt update && sudo apt install -y caddy

Configure Caddy

Edit /etc/caddy/Caddyfile and replace the contents with (use your domain):

http://smp.example.com {
    redir https://smp.example.com{uri} permanent
}

smp.example.com:8443 {
    tls {
        key_type rsa4096
    }
}

Setup Certificate Script

Create the certificate script:

sudo vim /usr/local/bin/simplex-servers-certs

Add the following (replace smp.example.com with your domain):

#!/usr/bin/env sh
set -eu

user='smp'
group="$user"

domain='smp.example.com'
folder_in="/var/lib/caddy/.local/share/caddy/certificates/acme-v02.api.letsencrypt.org-directory/${domain}"
folder_out='/etc/opt/simplex'
key_name='web.key'
cert_name='web.crt'

# Copy certificate from Caddy directory to smp-server directory
cp "${folder_in}/${domain}.crt" "${folder_out}/${cert_name}"
chown "$user":"$group" "${folder_out}/${cert_name}"

# Copy certificate key from Caddy directory to smp-server directory
cp "${folder_in}/${domain}.key" "${folder_out}/${key_name}"
chown "$user":"$group" "${folder_out}/${key_name}"

Make it executable:

sudo chmod +x /usr/local/bin/simplex-servers-certs

Setup Certificate Renewal

Add a cron job for automatic certificate renewal:

sudo crontab -e

Add at the bottom:

# Every week on Sunday at 00:20
20 0 * * 0 /usr/local/bin/simplex-servers-certs

Start Caddy and Generate Certificate

Enable Caddy and wait for the certificate to be generated:

sudo systemctl enable --now caddy

Wait a few minutes for Caddy to obtain the certificate, then run:

sudo systemctl restart caddy
sudo /usr/local/bin/simplex-servers-certs

If the certificate script fails, wait a few more minutes and try again. Caddy needs time to obtain the certificate from Let's Encrypt.

Start the SMP Server

sudo systemctl enable --now smp-server.service

Get Your Server Address

Run this to display your server addresses:

smp="$(journalctl --output cat -q _SYSTEMD_INVOCATION_ID="$(systemctl show -p InvocationID --value smp-server)" | grep -m1 'Server address:' | awk '{print $NF}' | sed 's/:443.*//')"
tor="$(cat /var/lib/tor/simplex-smp/hostname)"

echo "Clearweb: ${smp}"
echo "Tor: ${smp%@*}@${tor}"

You'll get two addresses:

Configure SimpleX Client

In the SimpleX app:

  1. Go to Settings → Network & Servers
  2. Go to Your Servers → Add server → Enter Server manually
  3. Enter your server address (clearweb or Tor)
  4. Check Use for new connections
  5. Save

To use only your server:

  1. Disable the default Flux servers
  2. In SimpleX servers, keep Use Servers on (needed for files if you don't have XFTP)
  3. Uncheck To Receive and For Private Routing under "Use for messages"

Your conversations will now show "receiving via" your server address.