Guide: Setup a Signal Proxy to Help People in Oppressive Regimes Communicate Privately
An announcement published today on the official Signal blog is encouraging users to setup an open source Signal TLS proxy in order to help people in Iran, and possibly other countries in the not too distant future as the app has suddenly exploded in popularity as of late, continue to be able to access and use the end-to-end encrypted messaging app even as their governments block access to it. The Signal blog post puts the focus on Iran as they just recently blocked Signal, but I would not at all be surprised if nations such as China and Russia followed in their footsteps very soon. These proxies could end up being useful to millions worldwide.
If you have have set up a VPS before, and you have a spare domain lying around or an active one you don't mind creating a subdomain for, you can easily help out this decentralised community effort by running Signal's TLS proxy.
The instructions on Signal's site are very easy to follow if you are familiar with all this stuff already. So if you know how to spin up a VPS, point a domain at it, and install an automated Docker image just read the Signal post.
This post is a mini-guide for noobs with more specific instructions on each step. If you know your way around a computer but are a bit fuzzy on setting up a VPS, you are the target audience for this post.
Important note: Eventually the Iranian government, and other oppressive governments who may block Signal in the future, are likely to block the domain of your proxy. If this is a concern to you just pick up a cheap domain exclusively for the proxy. The IP of the server you use would be blocked too but this shouldn't matter as we will be using a separate VPS.
If you want your existing domain to stay accessible in countries with oppressive regimes, it is highly advised to set this up on a a new or unused domain.
Thankfully, this is a very lightweight application that will run on even a very cheap VPS. And a domain can be purchased for a couple quid a year depending on the TLD.
I will assume a certain level of technical expertise if you've gotten this far and are still interested. The steps are super simple for anyone with basic computer knowledge. First off, this is an excellent guide on how to perform the initial setup of a VPS. I will base my post here on Digital Ocean because they make it very quick and easy to set a VPS up and have a lot of good documentation.
Please note some steps outlined in the linked guide above are specific to Digital Ocean “droplets”. For instance if you instead use AWS EC2 to host a proxy, you don't need to manually setup a non-root user and disable SSH access to root, as this is already done in the default install. Other than that however, everything else is the same if you install Ubuntu 20.04.
So the basic prerequisites are:
- Own a domain. Be able to point that domain or a subdomain of it to a VPS. If you don't mind the domain getting blocked by authoritarian regimes, you can use a subdomain of one you already have. If you want to keep your site open to users in such countries, buy any cheap domain or use a spare one as a throwaway instead.
- The automated setup is designed to be put on a dedicated server, so unless you want to do some type of manual setup, just nab a cheap VPS. This can literally be the lowest spec provided. Digital Ocean is easy to get going with a $5 a month VPS and is fully compatible with the server setup guide linked in the above paragraph, which this guide is also loosely based on with some extra steps. (Full disclosure: this is a referral link, if you use it you get $100 in credit to use over two months. I get $25 credit which will go directly towards the cost of hosting Aspie Chattr, my Mastodon instance for people on the autism spectrum. If you haven't used DO before, this would be a great way to try it out. Plus your proxy will run for free for two months.)
- SSH keys or the ability to run
ssh-keygenand basic knowledge of how SSH works. The steps are explained by DO and this post if you need to setup SSH keys.
- Basic knowledge of setting up a Linux server, which in this case mostly requires copy/pasting a few commands.
This guide is assuming you are setting up a brand new cheap VPS instance on a fresh domain. Remember the automated Docker setup provided is designed to be used on a dedicated server regardless of the domain.
So let's get started.
Creating a “droplet” and setting it up for key based SSH authentication
Assuming you're using Digital Ocean, because getting it setup requires fewer steps than EC2, once you have an account you want to create a “droplet.” By default Ubuntu 20.04 LTS is selected. Keep this selected.
Under “choose a plan” select “basic” and go for the cheapest one, which is $5 a month.
You do not need to add “block storage.” The 25GB SSD included with the droplet will be more than enough.
Select whichever datacentre region you want.
I highly recommend adding an SSH key for authentication to avoid the server getting hijacked for malicious purposes. When you hit “new key” a tutorial on the side tells you how to do it.
There is a more extensive guide to key based SSH authentication here. But as we're setting up a new VPS and DO automates adding the key, simply running
ssh-keygen on your computer and pasting your public key into the box on their website when creating the droplet should be all you need to do.
If you already have an SSH key you can make it show up in the terminal, just run
cat ~/.ssh/id_rsa.pub and paste the result into the “new key” box on DO.
If you are using a Mac or pretty much any Linux distro, the tools required come with your OS so just open the Terminal and follow those instructions. If you are using Windows 10, you can follow the guide by first installing OpenSSH as an “extra feature.” Here is a detailed tutorial.
Now back to creating the droplet.
It'll ask for a hostname for the droplet. This is also the name it'll have in the control panel. Make it something descriptive and simple like “Signal TLS proxy.”
Now hit the button to create the droplet and wait roughly 30 seconds while it's all installed and ready to go.
When this is done, click on it. Copy the public IP (not the private IP) and, assuming you've set up an SSH key, you can just run “ssh root@[public IP address]” in your terminal and as it's your first time connecting you will get a message like:
The authenticity of host '[public IP]' can't be established.
This is nothing to worry about, it just means your computer doesn't know about the server yet. Type “yes” and it'll begin logging in via SSH. It may ask you to enter the password for your SSH key or may not, depending on your local setup.
Now you're in!
Securing the new VPS, creating a user with sudo privileges, disabling root login via SSH
Firstly turn the firewall on:
ufw allow http
ufw allow https
ufw allow ssh
If it warns it may disrupt your SSH session just type “y” and hit enter. As long as you remember to allow SSH you won't even need to reconnect. Now your firewall is setup.
Then make sure everything is updated:
apt update && apt upgrade
Let it download and install the updates. Since this is going through a datacentre it should be very quick.
Final setup step is to create a non-root user with sudo access then disable root login via SSH.
Create a user:
I'm using “proxy” as the username in this guide but you can make it whatever you want.
It'll ask for a password, make sure it's secure but that you'll remember it. You won't need it to login by SSH but you will need it when you use sudo to run things with admin privileges.
You can just hit enter leaving the other fields blank.
Then just give your new user sudo rights:
usermod -aG sudo proxy
Now to make sure you can SSH into that new user, assuming you set an SSH key at setup, use this to copy that SSH key to your new user:
rsync --archive --chown=proxy:proxy ~/.ssh /home/proxy
Now before the last step in the setup just make sure you can successfully SSH into your new account, so type:
To log out of the current SSH session, then run the same SSH command you did to login originally, but replace “root” with the username you picked, again I'm using “proxy” as an example:
ssh proxy@[public IP]
Assuming that worked, you can safely disable root login by SSH. To do this, run:
sudo nano /etc/ssh/sshd_config
Note you need
sudo for this as you're editing a system configuration file from a normal user. This means you'll be prompted for the password you made for that account to get temporary root (admin) privileges. So just type that in and the config should come up.
Scroll down a little until you see the line that says:
Change “yes” to “no” then hit control + O then enter to save, then control + X to quit.
Finally, reboot the server to ensure all updates and changes are applied:
This will of course disconnect your SSH session. It should only take around 30 seconds for the server to reboot. So after that you can SSH in again using the username you made.
Setting up your domain or subdomain to point to your VPS
Now it's secured, the VPS is ready to be setup for the proxy, but first you need a domain name pointing to it. The exact interface will differ depending on where you got the domain and what DNS service you're using, but typically, unless you changed anything yourself, the domain registrar will provide your DNS service.
So go to your DNS settings on the site you got your domain (I personally use Gandi, but Digital Ocean also sell domains and you hopefully have that $100 free credit!)
You want to create an A record. This can point to the “apex” domain (your main one, i.e. example.com) or a subdomain (i.e. proxy.example.com, or something that looks less obvious like media.example.com). Either way, for the IP paste in the same public IP address you've been using to SSH into the server. You should also have a “TTL” option. Set this to the minimum (usually 300) to make the DNS update spread through the internet (propagate) as quickly as possible.
Now go back to the SSH session and let's get the proxy setup while the DNS update is propagating. It's important you have the domain already pointing to your VPS so that the installer for the proxy can generate a TLS (SSL) certificate for it, otherwise it can't work.
So now, as per Signal's install instructions, we first install Docker:
sudo apt update && sudo apt install docker docker-compose git
Once that's done, you grab the repo from GitHub:
git clone https://github.com/signalapp/Signal-TLS-Proxy.git
Change your working directory to the new folder it's created:
Now we run the script to generate the TLS certificates. Remember you must have the domain already pointing at your server before you do this. It'll ask for the domain you're using:
Once it's done it should automate TLS setup and tell you:
After running 'docker-compose up --detach' you can share your proxy as: https://signal.tube/#[your domain]
So now we run just that:
sudo docker-compose up --detach
This bit may take some time as it builds the Docker image, which is a container with everything needed to run the proxy packaged up and virtualised.
Aaaand... that's it! Done!
As the output previously told you, you can now share your proxy by using the signal.tube domain like so:
I set mine up as I was writing this blog post so you can use it at:
If you are or know someone in a country censoring Signal, feel free to use or share that link or replace the domain after
# with your own.
As long as the user has Signal installed on their phone they can tap the link and it will connect them through the proxy automatically. At the time of writing this functionality is limited to the beta build of Signal for Android but they're rolling it out quickly. You can easily sign up for the Signal beta programme via the Play Store. Search for “Signal” in the Play Store, go on the app's page, scroll down and there should be an option to become a beta tester. Now check for updates.
Signal's post recommends sharing proxies on your social media platform of choice using the hashtag
#IRanASignalProxy – you can also tell people to DM you so it doesn't get picked up quickly by the censors.
You've now helped people in oppressive regimes access private communication with friends and family :)