How to Create Anonymous Email Aliases with SimpleLogin

A photograph of a laptop on top of a couch.

SimpleLogin is a lightweight and easy-to-use aliases server that allows you to create permanent and anonymous email identities without creating new mailboxes. This article will show you how to install a SimpleLogin server on Ubuntu and create anonymous email aliases to use online.

Preparing the System

Assumption: This article assumes that you are installing SimpleLogin on a VPS with at least 2GB of RAM. It also assumes that you have an active domain name for it from a DNS registrar.

To start, import the Docker project’s signing key to your machine:

curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg

Create a repository file for the Docker project:

sudo nano /etc/apt/sources.list.d/docker.list

Write the following line of code inside the repository file:

deb [arch=amd64 signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu jammy stable

Refresh your machine’s repositories by running the following command:

sudo apt update && sudo apt upgrade

Installing the Dependencies for SimpleLogin

Install both Docker and SimpleLogin’s dependencies to your system:

sudo apt install docker-ce docker-ce-cli containerd.io docker-compose-plugin docker-buildx-plugin nginx dnsutils postfix postfix-pgsql

Select Internet Site when the Postfix install wizard asks for your mail server configuration type.

A terminal showing the "Internet Site" option on the Postfix installer.

Press Enter to confirm the default “System mail name” value.

A terminal showing the default system name value for the server.

Make sure that the “core” snap package is running on your machine:

sudo snap install core

Install the certbot snap package from the Electronic Frontier Foundation (EFF):

sudo snap install certbot --classic

Ensure that your system’s firewall is not blocking any of the ports for SimpleLogin:

sudo ufw allow 25,80,443/tcp

Preparing the DNS Records

Go to your domain registrar and create a new “A” record pointing to your machine’s IPv4 address. Set the hostname value to a subdomain that you want for your SimpleLogin instance.

A screenshot of an example A record for SimpleLogin.

Add an “MX” record for your root domain with a target hostname set to your SimpleLogin subdomain.

A screenshot of an example MX record for SimpleLogin.

Create a “TXT” record for your root domain and set its value to the following:

v=spf1 mx ~all
A screenshot of an example TXT record for SPF.

Create a different “TXT” record for the subdomain “_dmarc”, then set its value to the following:

v=DMARC1; p=quarantine; adkim=r; aspf=r
A screenshot of a TXT record for DMARC.

Open a terminal session, then generate a DKIM keypair using OpenSSL:

openssl genrsa -out dkim.key -traditional 1024
openssl rsa -in dkim.key -pubout -out dkim.pub.key

Run the following command then copy its result to your system clipboard. This is a sed script that the developers use to extract the DKIM public key from its keyfile:

sed "s/-----BEGIN PUBLIC KEY-----/v=DKIM1; k=rsa; p=/" $(pwd)/dkim.pub.key | sed "s/-----END PUBLIC KEY-----//" | tr -d '\n' | sed -e '$a\'

Create a “TXT” record for the subdomain “dkim._domainkey”, then set the output of the previous command as its value.

A screenshot of a TXT record for DKIM.

Good to know: learn more about DNS and name servers by using dig in Linux.

Creating the Postgres Database

Aside from using special DNS records, SimpleLogin also takes advantage of PostgresDB to manage email aliases. To set this up, first create the subdirectories for the SimpleLogin Docker container:

mkdir -p ~/sl/{pgp,db,upload}

Start a virtual network using Docker on your server:

sudo docker network create -d bridge \
    --subnet=10.0.0.0/24 \
    --gateway=10.0.0.1 \
    sl-network

Paste the following command to a new terminal session:

sudo docker run -d \
    --name sl-db \
    -e POSTGRES_PASSWORD=YOUR-RANDOM-PASSWORD-HERE \
    -e POSTGRES_USER=postgres \
    -e POSTGRES_DB=simplelogin \
    -p 127.0.0.1:5432:5432 \
    -v $(pwd)/sl/db:/var/lib/postgresql/data \
    --restart always \
    --network="sl-network" \
    postgres:12.1

Change the value for the “POSTGRES_PASSWORD” variable with a long and random string of text.

A terminal highlighting the random Postgres password for the SimpleLogin instance.

Note: You can generate this random string by running: cat /dev/urandom | tr -dc 'A-Za-z0-9' | fold -w 32 | head -n 1.

Run the modified Docker command to start your database.

Configuring Postfix for SimpleLogin

Start by deleting the default configuration file for Postfix, then create a blank file with the same name using your favorite text editor:

sudo rm /etc/postfix/main.cf && sudo nano /etc/postfix/main.cf

Paste the following block of code inside your new config file. This is a Postfix template from the developers’ repository that I modified to highlight the parts where you will add your server’s domain name:

smtpd_banner = $myhostname ESMTP $mail_name (Ubuntu)
biff = no
append_dot_mydomain = no
readme_directory = no
compatibility_level = 2
smtpd_tls_cert_file=/etc/ssl/certs/ssl-cert-snakeoil.pem
smtpd_tls_key_file=/etc/ssl/private/ssl-cert-snakeoil.key
smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache
smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache
smtp_tls_security_level = may
smtpd_tls_security_level = may
alias_maps = hash:/etc/aliases
mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128 10.0.0.0/24
 
mydestination =
myhostname = SUBDOMAIN.YOUR-ROOT.DOMAIN
mydomain = YOUR-ROOT.DOMAIN
myorigin = YOUR-ROOT.DOMAIN
 
relay_domains = pgsql:/etc/postfix/pgsql-relay-domains.cf
transport_maps = pgsql:/etc/postfix/pgsql-transport-maps.cf
 
smtpd_delay_reject = yes
smtpd_helo_required = yes
smtpd_helo_restrictions =
    permit_mynetworks,
    reject_non_fqdn_helo_hostname,
    reject_invalid_helo_hostname,
    permit
smtpd_sender_restrictions =
    permit_mynetworks,
    reject_non_fqdn_sender,
    reject_unknown_sender_domain,
    permit
smtpd_recipient_restrictions =
   reject_unauth_pipelining,
   reject_non_fqdn_recipient,
   reject_unknown_recipient_domain,
   permit_mynetworks,
   reject_unauth_destination,
   reject_rbl_client zen.spamhaus.org=127.0.0.[2..11],
   reject_rbl_client bl.spamcop.net=127.0.0.2,
   permit

Change the value of “myhostname” with the address of your web app, then update the value of both “mydomain” and “myorigin” to your root domain.

A terminal highlighting the hostname and domain block for the Postfix config file.

Linking Postgres with Postfix

Create a new “pgsql-relay-domains.cf” file under “/etc/postfix.” This will serve as the link between Postfix and Postgres:

sudo nano /etc/postfix/pgsql-relay-domains.cf

Paste the following block of code inside your new config file:

hosts = localhost
user = postgres
password = DATABASE-PASSWORD
dbname = simplelogin
 
query = SELECT domain FROM custom_domain WHERE domain='%s' AND verified=true
    UNION SELECT domain FROM public_domain WHERE domain='%s'
    UNION SELECT '%s' WHERE '%s' = 'mydomain.com' LIMIT 1;

Replace “DATABASE-PASSWORD” with your Postgres password.

A terminal highlighting the Postgres password in the Postfix relay config file.

Create a new “pgsql-transport-maps.cf” under the same directory:

sudo nano /etc/postfix/pgsql-transport-maps.cf

Paste the following block of code inside your new config file:

hosts = localhost
user = postgres
password = DATABASE-PASSWORD
dbname = simplelogin
 
query = SELECT 'smtp:127.0.0.1:20381' FROM custom_domain WHERE domain = '%s' AND verified=true
    UNION SELECT 'smtp:127.0.0.1:20381' FROM public_domain WHERE domain = '%s'
    UNION SELECT 'smtp:127.0.0.1:20381' WHERE '%s' = 'mydomain.com' LIMIT 1;

Just like with the previous config, replace “DATABASE-PASSWORD” with your Postgres password.

A terminal showing the Postgres password in the Postfix transport map config file.

Installing SimpleLogin

Navigate to the home directory of your user, then create the environment file for SimpleLogin.

cd && nano ./simplelogin.env

Write the following block of code inside your new environment file:

URL=https://SUBDOMAIN.YOUR-ROOT.DOMAIN
EMAIL_DOMAIN=YOUR-ROOT.DOMAIN
SUPPORT_EMAIL=support@YOUR-ROOT.DOMAIN
EMAIL_SERVERS_WITH_PRIORITY=[(10, "SUBDOMAIN.YOUR-ROOT.DOMAIN.")]
DB_URI=postgresql://postgres:DATABASE-PASSWORD@sl-db:5432/simplelogin
FLASK_SECRET=ADD-A-NEW-RANDOM-STRING-HERE
 
DISABLE_ALIAS_SUFFIX=1
DKIM_PRIVATE_KEY_PATH=/dkim.key
GNUPGHOME=/sl/pgp
LOCAL_FILE_UPLOAD=1
POSTFIX_SERVER=10.0.0.1

Replace every instance of “SUBDOMAIN.YOUR-ROOT.DOMAIN” with your SimpleLogin URL.

A terminal highlighting the sections of the config file that needs to include the server's subdomain.

Change the value of “YOUR-ROOT.DOMAIN” to your root domain.

A terminal highlighting the sections of the environment file that only needs the server's root domain.

Replace the “DATABASE-PASSWORD” variable with your Postgres password.

A terminal highlighting the section of the environment file that needs the Postgres password.

Generate a new random string and set that as the value “FLASK_SECRET”

A terminal highlighting the section of the environment file that requires a new random string.

Running the SimpleLogin Docker Containers

With that setup and ready, you can now fetch and run the SimpleLogin Docker container. To start, import the Postgres database to your SimpleLogin install:

sudo docker run --rm \
    --name sl-migration \
    -v $(pwd)/sl:/sl \
    -v $(pwd)/sl/upload:/code/static/upload \
    -v $(pwd)/dkim.key:/dkim.key \
    -v $(pwd)/dkim.pub.key:/dkim.pub.key \
    -v $(pwd)/simplelogin.env:/code/.env \
    --network="sl-network" \
    simplelogin/app:4.6.5-beta alembic upgrade head

Run the Docker container for SimpleLogin’s initialization script:

sudo docker run --rm \
    --name sl-init \
    -v $(pwd)/sl:/sl \
    -v $(pwd)/simplelogin.env:/code/.env \
    -v $(pwd)/dkim.key:/dkim.key \
    -v $(pwd)/dkim.pub.key:/dkim.pub.key \
    --network="sl-network" \
    simplelogin/app:4.6.5-beta python init_app.py

Start the Docker container that manages the app’s front-end interface:

sudo docker run -d \
    --name sl-app \
    -v $(pwd)/sl:/sl \
    -v $(pwd)/sl/upload:/code/static/upload \
    -v $(pwd)/simplelogin.env:/code/.env \
    -v $(pwd)/dkim.key:/dkim.key \
    -v $(pwd)/dkim.pub.key:/dkim.pub.key \
    -p 127.0.0.1:7777:7777 \
    --restart always \
    --network="sl-network" \
    simplelogin/app:4.6.5-beta

Run the container that handles the email backend for SimpleLogin:

sudo docker run -d \
    --name sl-email \
    -v $(pwd)/sl:/sl \
    -v $(pwd)/sl/upload:/code/static/upload \
    -v $(pwd)/simplelogin.env:/code/.env \
    -v $(pwd)/dkim.key:/dkim.key \
    -v $(pwd)/dkim.pub.key:/dkim.pub.key \
    -p 127.0.0.1:20381:20381 \
    --restart always \
    --network="sl-network" \
    simplelogin/app:4.6.5-beta python email_handler.py

Lastly, start the container that manages routine tasks for the SimpleLogin system:

sudo docker run -d \
    --name sl-job-runner \
    -v $(pwd)/sl:/sl \
    -v $(pwd)/sl/upload:/code/static/upload \
    -v $(pwd)/simplelogin.env:/code/.env \
    -v $(pwd)/dkim.key:/dkim.key \
    -v $(pwd)/dkim.pub.key:/dkim.pub.key \
    --restart always \
    --network="sl-network" \
    simplelogin/app:4.6.5-beta python job_runner.py

FYI: Docker is more than just a way to deploy SimpleLogin. Learn how you can quickly host your own WordPress site using Docker.

Creating an SSL Reverse Proxy with Nginx

At this point, SimpleLogin is now running on the server at port 7777. To access it, you need to pass its outgoing connection through an SSL reverse proxy.

Create the site file for your SimpleLogin instance:

sudo nano /etc/nginx/sites-available/simplelogin

Paste the following block of code inside your site file:

server {
 
        server_name SUBDOMAIN.YOUR-ROOT.DOMAIN;
 
        location / {
                proxy_pass http://127.0.0.1:7777;
                proxy_http_version 1.1;
                proxy_set_header Upgrade $http_upgrade;
                proxy_set_header Connection "upgrade";
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header Host $host;
        }
}

Create a symbolic link for your site file in “/etc/nginx/sites-enabled/”:

sudo ln -s /etc/nginx/sites-available/simplelogin /etc/nginx/sites-enabled/

Apply your new settings by restarting the Nginx daemon:

sudo systemctl restart nginx

Register your SimpleLogin instance to the EFF by running the following command:

sudo certbot register --agree-tos -m YOUR@EMAIL.ADDRESS

Request a new SSL certificate for your reverse proxy:

sudo certbot --nginx -d SUBDOMAIN.YOUR-ROOT.DOMAIN

Open your Postfix config file using your favorite text editor:

sudo nano /etc/postfix/main.cf

Scroll down to the “smtpd_tls_cert_file” and “smtpd_tls_key_file” variables and replace them with the following lines of code:

smtpd_tls_cert_file=/etc/letsencrypt/live/SUBDOMAIN.YOUR-ROOT.DOMAIN/fullchain.pem
smtpd_tls_key_file=/etc/letsencrypt/live/SUBDOMAIN.YOUR-ROOT.DOMAIN/privkey.pem

Test if your SimpleLogin instance is running properly by opening your subdomain on a browser and creating a new account.

A screenshot of a working SimpleLogin web dashboard.

Creating Email Aliases With SimpleLogin

Go back to your server’s terminal session, then open the app’s database:

docker exec -it sl-db psql -U postgres simplelogin

Run the following to enable the Premium status for your primary account:

UPDATE users SET lifetime = TRUE;
exit
A screenshot of the SimpleLogin dashboard running on Premium mode.

Doing this will ensure that your account won’t have any limits to the amount of aliases that you can make for your email.

To create your first email alias, click the New Custom Alias button on the web app’s dashboard.

A screenshot of the SimpleLogin dashboard highlighting the "New Custom Alias" button.

Note: you can also create an alias with a random name by clicking the Random Alias button.

Provide a memorable name for your new email alias, then click Create.

A screenshot highlighting the "Create" button for the new email alias.

Check if your new email alias is working properly by sending a message to it from a different email address.

A screenshot showing an example message to an email alias.

Sending Emails from a SimpleLogin Alias

Aside from receiving mail from an alias, SimpleLogin also supports sending messages through them. To achieve that, the app creates a “reverse alias” for the destination address to which you can send your email.

To do this, click the Contacts button on the alias that you want to send an email from. In my case, I want to send from my “hello-maketecheasier@myvpsserver.top” address.

A screenshot highlighting the "Contacts" button for creating reverse-alias addresses.

Provide the email address of your recipient, then click Create reverse-alias.

Click the Copy reverse-alias button on your new contact, then paste it to the recipient field of your email client. Sending a message to this custom address will allow SimpleLogin to mask your real email with your alias to your recipient.

A screenshot showing a message being sent to a reverse alias.

Self-hosting your own email aliases server using SimpleLogin is just one of the steps of reclaiming your digital privacy. Take control of your entire digital communications chain by hosting your own email server using Mail-in-a-Box.

Image credit: Lukas Blazek via Unsplash and SimpleLogin Github. All alterations and screenshots by Ramces Red.

Subscribe to our newsletter!

Our latest tutorials delivered straight to your inbox

Ramces Red
Ramces Red - Staff Writer

Ramces is a technology writer that lived with computers all his life. A prolific reader and a student of Anthropology, he is an eccentric character that writes articles about Linux and anything *nix.