Simplex Server Docker Installation Guide (SMP / XFTP)

Introduction

Hello, today I am bringing you an updated (JUNE 01, 2024) guide on how to install Simplex SMP and XFTP servers using docker compose. This guide assumes you already have docker and docker compose installed – and also moves XFTP off default port of 443 due to reverse proxy conflicts.

Prepare Environment

  1. Create directories for persistent Docker configuration:
    mkdir -p $HOME/simplex/{xftp,smp}/{config,logs} && mkdir -p $HOME/simplex/xftp/files

  2. Add Services to Docker Compose

version: '3.7' #this version is obsolete, change me

networks:
  tor: 
  simplex:

services:
  simplex-smp-server:
    image: simplexchat/smp-server:latest
    container_name:  simplex-smp
    restart: unless-stopped
    user: "1000:1000" #user uid - change if necessary
    ports:
      - "5223:5223" #this will expose port 5223 to internet
    volumes:
      - ./simplex/smp/config:/etc/opt/simplex:Z
      - ./simplex/smp/logs:/var/opt/simplex:Z
    environment:
      - ADDR=${SIMPLEX_ADDR}
#     - PASS=${SIMPLEX_PASSWORD} #for non public servers
    networks:
      - simplex
      - tor
    security_opt:
      - no-new-privileges:true
    cap_drop:
      - ALL

  simplex-xftp-server:
    image: simplexchat/xftp-server:latest
    container_name:  simplex-xftp
    user: "1000:1000" #user uid - change if necessary
    ports:
      - "5233:443" #port mapping to expose xftp to internet on port 5233
    restart: unless-stopped
    volumes:
      - ./simplex/xftp/config:/etc/opt/simplex-xftp:Z
      - ./simplex/xftp/logs:/var/opt/simplex-xftp:Z
      - ./simplex/xftp/files:/srv/xftp:X
    environment:
      - ADDR=${XFTP_ADDR}
      - QUOTA=150gb #change to set your own quota
    networks:
      - simplex
      - tor
    security_opt:
      - no-new-privileges:true
    cap_drop:
      - ALL

  tor:
    image: osminogin/tor-simple
    container_name: tor
    volumes:
      - ./tor-data:/var/lib/tor
      - ./tor-data/torrc:/etc/tor
    networks:
      - tor

  watchtower:
    image: containrrr/watchtower
    container_name: watchtower
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
    command: --interval 14400
  1. Add to or create following to docker .env file
SIMPLEX_ADDR=      #If using FDQN, make sure to set DNS record
SIMPLEX_PASSWORD=
XFTP_ADDR=         #If using FDQN, make sure to set DNS record
  1. Create Tor Directories
    sudo mkdir -p $HOME/tor-data/torrc && sudo mkdir -p $HOME/tor-data/{simplex-xftp,simplex-smp}

  2. Set Tor Directory Permissions
    sudo chmod 700 $HOME/tor-data/simplex-xftp && sudo chmod 700 $HOME/tor-data/simplex-smp && sudo chown 100:65533 $HOME/tor-data/simplex-xftp && sudo chown 100:65533 $HOME/tor-data/simplex-smp

  3. Add Firewall Rules
    a. sudo ufw allow 5223/tcp
    b. sudo ufw allow 5233/tcp
    c. sudo ufw reload

Installation

  1. Pull the images and run the services
    a. docker compose up -d

  2. Check logs for errors, proceed if none
    a. docker logs simplex-smp
    b. docker logs simplex-xftp
    c. docker logs tor

  3. In log output, save server addresses starting with smp:// and xftp://

  4. Make any necessary changes to smp-server.ini and file-server.ini

  5. Add the following to torrc
    a. sudo nano $HOME/tor-data/torrc/torrc

 SOCKSPort 0
 HiddenServiceNonAnonymousMode 1
 HiddenServiceSingleHopMode 1
 HiddenServiceDir /var/lib/tor/simplex-smp
 HiddenServicePort 5223 simplex-smp:5223
 HiddenServiceDir /var/lib/tor/simplex-xftp
 HiddenServicePort 5233 simplex-xftp:443
  1. Restart Tor and List Onion Hostnames
    a. docker logs tor
    b. docker container restart tor
    c. sudo cat $HOME/tor-data/simplex-smp/hostname
    d. sudo cat $HOME/tor-data/simplex-xftp/hostname

  2. Copy/Paste Simplex private keys offline (keepass) and securely delete
    a. cat $HOME/simplex/smp/config/ca.key
    b. shred -u $HOME/simplex/smp/config/ca.key
    c. cat $HOME/simplex/xftp/config/ca.key
    d. shred -u $HOME/simplex/xftp/config/ca.key

  3. Double Check Services
    a. docker logs simplex-smp
    b. docker logs simplex-xftp
    c. docker logs tor
    d. netstat -tulpn

Client Configuration and Validation

In all example below we will be using hack liberty servers as legitimate reference. The ports and the server order must be in a particular order shown below. However, we must first validate each server works indepedently, both clearnet and onion.

SMP Server Validation

  1. In Simplex Client, navigate to Network & ServersSMP servers
  2. Replace the values below with your respective server and onion hostname
  3. Clearnet Only Test (Should result in Green Check)
    a. smp://esPsfRFGZd2TRyKijJDorCMo3Ld-QD8Cq8ASx8qrY_Q=@simplex.hackliberty.org
  4. Onion Only Test (Tor/Orbot running and Simplex Tor SOCKS proxy (9050)
    a. smp://esPsfRFGZd2TRyKijJDorCMo3Ld-QD8Cq8ASx8qrY_Q=@gstc5w42xawazcr4txrcyhitmkhiyu2vkkwy2xhwovbhlapzrccjeyad.onion
  5. If both servers result in passing test, combine into single server entry as seen below.
    a. smp://esPsfRFGZd2TRyKijJDorCMo3Ld-QD8Cq8ASx8qrY_Q=@simplex.hackliberty.org,gstc5w42xawazcr4txrcyhitmkhiyu2vkkwy2xhwovbhlapzrccjeyad.onion

XFTP Server Validation

  1. In Simplex Client, navigate to Network & ServersXFTP servers
  2. Replace the values below with your respective server and onion hostname
  3. Clearnet Only Test (Note the port number!!)
    a. xftp://DfK0yVcc9P5NgfaRR4retNWDDTKFa9g_NqF11maM87Q=@xftp.hackliberty.org:5233
  4. Onion Only Test (Tor/Orbot running and Simplex Tor SOCKS proxy (9050) NOTE THE PORT NUMBER!!
    a. smp://esPsfRFGZd2TRyKijJDorCMo3Ld-QD8Cq8ASx8qrY_Q=@kf25i7slt6skypu47j5kzl4s4nlt3aw3baiocanygf6gprrrbft4dyqd.onion:5233
  5. If both servers result in passing test, combine into single server entry as seen below (IMPORTANT: FOLLOW SYNTAX EXACTLY WITH PORT ONLY AT END).
    a. xftp://DfK0yVcc9P5NgfaRR4retNWDDTKFa9g_NqF11maM87Q=@xftp.hackliberty.org,kf25i7slt6skypu47j5kzl4s4nlt3aw3baiocanygf6gprrrbft4dyqd.onion:5233
    (If this causes either clearnet only or onion only issues, let me know)

Client Configuration

With your new servers added, you may now either delete the default simplex servers or uncheck use for new connections. To test the server, create a new invite or room using the server and invite others to it.

Conclusion

You should now have smp and xftp simplex servers up and running using docker compose. If you found this guide helpful, feel free to share, leave a comment below, or a send a donation to hackliberty.org.

SOCKS port for SMP PROXY

SMP-server versions starting from v5.8.0-beta.0 can be configured to PROXY smp servers available exclusively through Tor network to be accessible to the clients that do not use Tor. Run the following commands as root user.

  1. Edit docker-compose file and create new instance of Tor that we will call tor-proxy
  tor-proxy:
    image: osminogin/tor-simple
    container_name: tor-proxy
    volumes:
      - ./tor-proxy:/var/lib/tor
      - ./tor-proxy/torrc:/etc/tor
    networks:
      - tor
  1. create tor-proxy folders
    a. sudo mkdir -p tor-proxy/torrc && sudo chown -R 100:65533 tor-proxy/ && sudo chmod -R 700 tor-proxy/

  2. create torrc
    Do not use 0.0.0.0 unless your configuration requires it. For the purpose of this specific configuration, it is acceptable because docker container will only be accessible over tor docker network
    a. sudo echo "SocksPort 0.0.0.0:9050" > tor-proxy/torrc/torrc

  3. launch tor-proxy and check logs
    a. sudo docker compose up -d
    b. sudo docker logs tor-proxy

For docker configuration:

[..]

[notice] Read configuration file "/etc/tor/torrc"
[warn] You specified a public address '0.0.0.0:9050' for SocksPort. Other people on the Internet might find your computer and use it as an open proxy. Please dont allow this unless you have a good reason.
[notice] Opening Socks listener on 0.0.0.0:9050
[notice] Opened Socks listener connection (ready) on 0.0.0.0:9050

[..]

For localhost configuration:

[..]

[notice] Read configuration file "/etc/tor/torrc"
[notice] Opening Socks listener on 127.0.0.1:9050
[notice] Opened Socks listener connection (ready) on 127.0.0.1:9050

[..]
  1. add proxy section to smp-server.ini
[PROXY]
socks_proxy: tor-proxy:9050
  1. restart smp-server and check logs
    a. sudo docker container restart simplex-smp

Server information page

SMP-server versions starting from v5.8.0 can be configured to serve Web page with server information that can include admin info, server info, provider info, etc. Run the following commands as root user.

My server uses swag for reverse proxy so these instructions will be based around that

  1. Create folder to store webserver static files and assign correct permissions:
    a. sudo mkdir -p swag/www/simplex.hackliberty.org
    b. sudo chown 1000:1000 swag/www/simplex.hackliberty.org

  2. Add the following to your smp-server configuration (please modify fields in [INFORMATION] section to include relevant information):

[WEB]
static_path: /var/www/smp-server-web

[INFORMATION]
# AGPLv3 license requires that you make any source code modifications
# available to the end users of the server.
# LICENSE: https://github.com/simplex-chat/simplexmq/blob/stable/LICENSE
# Include correct source code URI in case the server source code is modified in any way.
# If any other information fields are present, source code property also MUST be present.

source_code: https://github.com/simplex-chat/simplexmq

# Declaring all below information is optional, any of these fields can be omitted.

# Server usage conditions and amendments.
# It is recommended to use standard conditions with any amendments in a separate document.
usage_conditions: https://git.hackliberty.org/hackliberty.org/hackliberty.org-legal/src/branch/main/code-of-conduct.md
# condition_amendments: link

# Server location and operator.
server_country: IS
operator: Hack Liberty
#operator_country:
website: https://hackliberty.org

# Administrative contacts.
#admin_simplex: SimpleX address
admin_email: contact@hackliberty.org
# admin_pgp:
admin_pgp_fingerprint: D8DD21D155D6558DEE1DA77C43CA3EEA51FC49A0

# Contacts for complaints and feedback.
# complaints_simplex: SimpleX address
complaints_email: abuse@hackliberty.org
# complaints_pgp:
complaints_pgp_fingerprint: 7A15CABC37A977A40B5B0E43A7072A16B4306703

# Hosting provider.
hosting: 1984.Hosting
hosting_country: IS

  1. Add persistent volume for simplex to serve static web files in swag directory

./swag/www/simplex.hackliberty.org:/var/www/smp-server-web:Z

  simplex-smp-server:
    image: simplexchat/smp-server:latest
    container_name:  simplex-smp
    restart: unless-stopped
    user: "1000:1000"
    ports:
      - "5223:5223"
    volumes:
      - ./simplex/smp/config:/etc/opt/simplex:Z
      - ./simplex/smp/logs:/var/opt/simplex:Z
      - ./swag/www/simplex.hackliberty.org:/var/www/smp-server-web:Z
    environment:
      - ADDR=${SIMPLEX_ADDR}
#     - PASS=${SIMPLEX_PASSWORD}
    networks:
      - simplex
      - tor
    security_opt:
      - no-new-privileges:true
    cap_drop:
      - ALL

  1. restart simplex-smp, check logs, and check for static web page
    a. sudo docker compose up -d
    b. sudo docker logs simplex-smp

apps/smp-server/web/Static.hs:48] Generated static site contents at "/var/www/smp-server-web"

ls swag/www/simplex.hackliberty.org/
contact  index.html  invitation  media
  1. create nginx site at /swag/nginx/site-confs
    a. nano swag/nginx/site-confs/simplex.conf
    What you see below is a hardened nginx conf which you will need to modify to suit your needs… probably by removing the include .confs
server {  
    listen 443 ssl http2;
    listen [::]:443 ssl http2;

    server_name simplex.*;

    include /config/nginx/ssl.conf;

    location / {
        include /config/nginx/proxy.conf;
        include /config/nginx/resolver.conf;
        include /config/nginx/security-headers.conf;
        add_header Content-Security-Policy "default-src 'none'; connect-src 'self'; font-src * https: data:; img-src * https: data:; manifest-src * https: data:; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; frame-ancestors 'none'; block-all-mixed-content; base-uri 'none'";        
        root /config/www/simplex.hackliberty.org;        
    }
}
  1. add subdomain to swag environment variables
    a. nano .env
SWAG_URL=hackliberty.org
SWAG_SUBDOMAINS=simplex #example only
  1. rebuild swag, reissue ssl certs (automatic), check website
    a. sudo docker compose up -d
    b. sudo docker logs swag -f

You should now have server info page!

Note:

I need to figure out why PGP fingerprint not displaying… will work on that later

BONUS POINTS: Server Information Page over Tor

  1. Edit simplex.conf is swag/nginx/site-confs and add onion listener
server {  
    listen 443 ssl http2;
    listen [::]:443 ssl http2;

    server_name simplex.*;

    include /config/nginx/ssl.conf;

    location / {
        include /config/nginx/proxy.conf;
        include /config/nginx/resolver.conf;
        include /config/nginx/security-headers.conf;
        add_header Content-Security-Policy "default-src 'none'; connect-src 'self'; font-src * https: data:; img-src * https: data:; manifest-src * https: data:; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; frame-ancestors 'none'; block-all-mixed-content; base-uri 'none'";        
        add_header Onion-Location http://gstc5w42xawazcr4txrcyhitmkhiyu2vkkwy2xhwovbhlapzrccjeyad.onion$request_uri;  
        root /config/www/simplex.hackliberty.org;        
    }
}

server {
    listen 9988;
    server_name gstc5w42xawazcr4txrcyhitmkhiyu2vkkwy2xhwovbhlapzrccjeyad.onion;
    location ~ ^/.*$ {
        root /config/www/simplex.hackliberty.org;
        include /config/nginx/gzip.conf;
        include /config/nginx/security-headers.conf;
        add_header Content-Security-Policy "default-src 'none'; connect-src 'self'; font-src * https: data:; img-src * https: data:; manifest-src * https: data:; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; frame-ancestors 'none'; block-all-mixed-content; base-uri 'none'";
  }
}

  1. edit entry in torrc
 HiddenServiceDir /var/lib/tor/simplex.hackliberty.org
 HiddenServicePort 5223 simplex-smp:5223
 HiddenServicePort 80 swag:9988
  1. restart tor and check logs for errors
    a. sudo docker container restart tor
    b. sudo docker container logs tor
    [notice] Bootstrapped 100% (done): Done

  2. restart swag and check logs for errors
    a. sudo docker container restart swag
    b. sudo docker container logs swag
    Server ready

  3. browse to simplex page and verify onion redirect and working onion link!!