From c3ef184c81ca0fdc1003035a1125617c7aacd791 Mon Sep 17 00:00:00 2001 From: Moxie Marlinspike Date: Thu, 28 Jan 2021 10:34:53 -0800 Subject: [PATCH] Big bang --- .gitignore | 1 + LICENSE | 22 ++++++++++ README.md | 10 +++++ data/nginx-relay/nginx.conf | 77 +++++++++++++++++++++++++++++++++ data/nginx-terminate/nginx.conf | 37 ++++++++++++++++ docker-compose.yml | 26 +++++++++++ init-certificate.sh | 43 ++++++++++++++++++ nginx-relay/Dockerfile | 22 ++++++++++ nginx-terminate/Dockerfile | 22 ++++++++++ 9 files changed, 260 insertions(+) create mode 100644 .gitignore create mode 100644 LICENSE create mode 100644 README.md create mode 100644 data/nginx-relay/nginx.conf create mode 100644 data/nginx-terminate/nginx.conf create mode 100644 docker-compose.yml create mode 100755 init-certificate.sh create mode 100644 nginx-relay/Dockerfile create mode 100644 nginx-terminate/Dockerfile diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..68f5d13 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/data/certbot diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..519d1a6 --- /dev/null +++ b/LICENSE @@ -0,0 +1,22 @@ +MIT License + +Copyright (c) 2018 Philipp Schmieder +Copyright (c) 2021 Signal + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..846240d --- /dev/null +++ b/README.md @@ -0,0 +1,10 @@ +# Signal TLS Proxy + +To run a Signal TLS proxy, you will need a host with a domain name that has ports 80 and 443 available. + +1. Install docker and docker-compose (`apt update && apt install docker docker-compose`) +1. Clone this repository +1. `./init-certificate.sh` +1. `docker-compose up --detach` + +Your proxy is now running! You can share this with the URL `https://signal.tube/#` diff --git a/data/nginx-relay/nginx.conf b/data/nginx-relay/nginx.conf new file mode 100644 index 0000000..c8fdc19 --- /dev/null +++ b/data/nginx-relay/nginx.conf @@ -0,0 +1,77 @@ + +user nginx; +worker_processes auto; + + +events { + worker_connections 1024; +} + +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 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 4433; + proxy_pass $name; + ssl_preread on; + error_log /dev/null; + access_log off; + } +} diff --git a/data/nginx-terminate/nginx.conf b/data/nginx-terminate/nginx.conf new file mode 100644 index 0000000..61f0e6a --- /dev/null +++ b/data/nginx-terminate/nginx.conf @@ -0,0 +1,37 @@ +user nginx; +worker_processes auto; + +events { + worker_connections 1024; +} + +http { + server { + listen 80; + + location /.well-known/acme-challenge/ { + root /var/www/certbot; + } + } +} + +stream { + + upstream relay { + server nginx-relay:4433; + } + + server { + listen 443 ssl; + proxy_pass relay; + + access_log off; + error_log /dev/null; + + ssl_certificate /etc/letsencrypt/active/fullchain.pem; + ssl_certificate_key /etc/letsencrypt/active/privkey.pem; + include /etc/letsencrypt/options-ssl-nginx.conf; + ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; + } + +} diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..a3b3635 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,26 @@ +version: '3' + +services: + nginx-terminate: + build: ./nginx-terminate/ + restart: unless-stopped + volumes: + - ./data/nginx-terminate:/etc/nginx/conf.d + - ./data/certbot/conf:/etc/letsencrypt + - ./data/certbot/www:/var/www/certbot + ports: + - "443:443" + command: "/bin/sh -c 'while :; do sleep 6h & wait $${!}; /opt/nginx/sbin/nginx -s reload; done & /opt/nginx/sbin/nginx -c /etc/nginx/conf.d/nginx.conf -g \"daemon off;\"'" + nginx-relay: + build: ./nginx-relay/ + restart: unless-stopped + volumes: + - ./data/nginx-relay:/etc/nginx/conf.d + command: "/bin/sh -c 'while :; do sleep 6h & wait $${!}; /opt/nginx/sbin/nginx -s reload; done & /opt/nginx/sbin/nginx -c /etc/nginx/conf.d/nginx.conf -g \"daemon off;\"'" + certbot: + image: certbot/certbot + restart: unless-stopped + volumes: + - ./data/certbot/conf:/etc/letsencrypt + - ./data/certbot/www:/var/www/certbot + entrypoint: "/bin/sh -c 'trap exit TERM; while :; do certbot renew; sleep 12h & wait $${!}; done;'" diff --git a/init-certificate.sh b/init-certificate.sh new file mode 100755 index 0000000..cfa81f1 --- /dev/null +++ b/init-certificate.sh @@ -0,0 +1,43 @@ +#!/bin/bash + +if ! [ -x "$(command -v docker-compose)" ]; then + echo 'Error: docker-compose is not installed.' >&2 + exit 1 +fi + +data_path="./data/certbot" + +read -p "Enter domain name (eg. www.example.com): " domains + +if [ -d "$data_path" ]; then + read -p "Existing data found. Continue and replace existing certificate? (y/N) " decision + if [ "$decision" != "Y" ] && [ "$decision" != "y" ]; then + exit + fi +fi + + +if [ ! -e "$data_path/conf/options-ssl-nginx.conf" ] || [ ! -e "$data_path/conf/ssl-dhparams.pem" ]; then + echo "### Downloading recommended TLS parameters ..." + mkdir -p "$data_path/conf" + curl -s https://raw.githubusercontent.com/certbot/certbot/master/certbot-nginx/certbot_nginx/_internal/tls_configs/options-ssl-nginx.conf > "$data_path/conf/options-ssl-nginx.conf" + curl -s https://raw.githubusercontent.com/certbot/certbot/master/certbot/certbot/ssl-dhparams.pem > "$data_path/conf/ssl-dhparams.pem" + echo +fi + +echo "### Requesting Let's Encrypt certificate for $domains ..." +#Join $domains to -d args +domain_args="" +for domain in "${domains[@]}"; do + domain_args="$domain_args -d $domain" +done + +docker-compose run -p 80:80 --rm --entrypoint "\ + sh -c \"certbot certonly --standalone \ + --register-unsafely-without-email \ + $domain_args \ + --agree-tos \ + --force-renewal && \ + ln -fs /etc/letsencrypt/live/$domains/ /etc/letsencrypt/active\"" certbot +echo +echo "After running 'docker-compose up --detach' you can share your proxy as: https://signal.tube/#$domains" diff --git a/nginx-relay/Dockerfile b/nginx-relay/Dockerfile new file mode 100644 index 0000000..d4ac07d --- /dev/null +++ b/nginx-relay/Dockerfile @@ -0,0 +1,22 @@ +FROM ubuntu:20.04 + +RUN apt-get update && apt-get -y upgrade && \ + apt-get install -y wget libpcre3-dev build-essential libssl-dev zlib1g-dev && \ + rm -rf /var/lib/apt/lists/* + +WORKDIR /opt + +RUN wget http://nginx.org/download/nginx-1.18.0.tar.gz && \ + tar -zxvf nginx-1.*.tar.gz && \ + cd nginx-1.* && \ + ./configure --prefix=/opt/nginx --user=nginx --group=nginx --with-http_ssl_module --with-ipv6 --with-threads --with-stream --with-stream_ssl_module --with-stream_ssl_preread_module && \ + make && make install && \ + cd .. && rm -rf nginx-1.* + +RUN adduser --system --no-create-home --disabled-login --disabled-password --group nginx + +WORKDIR / + +EXPOSE 443 + +CMD ["/opt/nginx/sbin/nginx", "-c", "/etc/nginx/conf.d/nginx.conf", "-g", "daemon off;"] diff --git a/nginx-terminate/Dockerfile b/nginx-terminate/Dockerfile new file mode 100644 index 0000000..d4ac07d --- /dev/null +++ b/nginx-terminate/Dockerfile @@ -0,0 +1,22 @@ +FROM ubuntu:20.04 + +RUN apt-get update && apt-get -y upgrade && \ + apt-get install -y wget libpcre3-dev build-essential libssl-dev zlib1g-dev && \ + rm -rf /var/lib/apt/lists/* + +WORKDIR /opt + +RUN wget http://nginx.org/download/nginx-1.18.0.tar.gz && \ + tar -zxvf nginx-1.*.tar.gz && \ + cd nginx-1.* && \ + ./configure --prefix=/opt/nginx --user=nginx --group=nginx --with-http_ssl_module --with-ipv6 --with-threads --with-stream --with-stream_ssl_module --with-stream_ssl_preread_module && \ + make && make install && \ + cd .. && rm -rf nginx-1.* + +RUN adduser --system --no-create-home --disabled-login --disabled-password --group nginx + +WORKDIR / + +EXPOSE 443 + +CMD ["/opt/nginx/sbin/nginx", "-c", "/etc/nginx/conf.d/nginx.conf", "-g", "daemon off;"]