With the events that the private messaging app Signal has been blocked in Iran, Signal has come up with an “proxy” solution akin to Tor’s Bridges, and have given instructions on how to do it.
For people who prefer FreeBSD over Linux like myself, we obviously can’t run Docker, which is what Signal’s instructions focus on.
Fortunately, the Docker image is just a fancy wrapper around nginx, and the configs can be ported to any OS. Here, I’ll show you how to set up a Signal Proxy on FreeBSD.
Prerequisites
You will need a FreeBSD server that is not running anything on Port 80 or 443. If you don’t run FreeBSD, you can substitute the commands with ones specific to your OS or Linux distro.
You can also substitute acme.sh
with another ACME-compatible Let’s Encrypt
client, or use another CA. I used acme.sh
with ZeroSSL, but won’t describe
the latter here for simplicity’s sake.
Steps
First, you’ll need to install acme.sh
and nginx
:
pkg install acme.sh nginx
Then, you’ll need to get an SSL certificate:
acme.sh --register-account -m neel@neelc.org --server zerossl
acme.sh --issue --standalone -d DOMAIN
Replace DOMAIN
with the hostname you want to use.
Next, use the following config for /usr/local/etc/nginx/nginx.conf
:
load_module /usr/local/libexec/nginx/ngx_stream_module.so;
user www;
events {}
stream {
map $ssl_preread_server_name $name {
textsecure-service.whispersystems.org signal-service;
storage.signal.org storage-service;
cdn.signal.org signal-cdn;
cdn2.signal.org signal-cdn2;
api.directory.signal.org directory;
contentproxy.signal.org content-proxy;
uptime.signal.org uptime;
api.backup.signal.org backup;
sfu.voip.signal.org sfu;
updates.signal.org updates;
updates2.signal.org updates2;
default deny;
}
upstream relay {
server localhost:4433;
}
upstream signal-service {
server textsecure-service.whispersystems.org:443;
}
upstream storage-service {
server storage.signal.org:443;
}
upstream signal-cdn {
server cdn.signal.org:443;
}
upstream signal-cdn2 {
server cdn2.signal.org:443;
}
upstream directory {
server api.directory.signal.org:443;
}
upstream content-proxy {
server contentproxy.signal.org:443;
}
upstream backup {
server api.backup.signal.org:443;
}
upstream sfu {
server sfu.voip.signal.org:443;
}
upstream updates {
server updates.signal.org:443;
}
upstream updates2 {
server updates2.signal.org:443;
}
upstream deny {
server 127.0.0.1:9;
}
server {
listen 443 ssl;
proxy_pass relay;
access_log off;
error_log /dev/null;
ssl_certificate /root/.acme.sh/DOMAIN/fullchain.cer;
ssl_certificate_key /root/.acme.sh/DOMAIN/DOMAIN.key;
}
server {
listen 4433;
proxy_pass $name;
ssl_preread on;
error_log /dev/null;
access_log off;
}
}
Again replace DOMAIN
with the domain your Signal proxy is on.
After you have set the nginx
config, enable it via sysrc:
sysrc nginx_enable=YES
And start it:
service nginx start
You should have a fully-functioning Signal proxy.
Share the proxy
While the official Signal instructions are very Docker-centric for the tech part, it does have other useful information on sharing the proxy securely. This means I won’t duplicate the information here.
Here’s the subsection on Signal’s website on sharing the proxy.