Signal использует довольно изящную схему с двумя TLS-туннелями, поэтому для того, чтобы поднять прокси для него, хватит самого обычного Nginx.
Пример конфига:
user www-data;
worker_processes auto;
pid /run/nginx.pid;
error_log /var/log/nginx/error.log;
include /etc/nginx/modules-enabled/*.conf;
events {
worker_connections 768;
}
http {
server {
listen 127.0.0.1:8443 ssl;
root /var/www/html;
ssl_certificate /etc/letsencrypt/live/YOUR_SITE_DOMAIN/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/YOUR_SITE_DOMAIN/privkey.pem;
}
}
stream {
resolver 1.1.1.1 8.8.8.8 valid=300s;
log_format stream_log '$remote_addr [$time_local] "$protocol" '
'$ssl_preread_server_name'
'$status $bytes_sent $bytes_received '
'$session_time "$upstream_addr"';
upstream relay {
server 127.0.0.1:445;
}
server {
listen 127.0.0.1:444 ssl;
proxy_pass relay;
access_log /var/log/nginx/access_term.log stream_log;
error_log /var/log/nginx/error_term.log info;
ssl_certificate /etc/letsencrypt/live/YOUR_PROXY_DOMAIN/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/YOUR_PROXY_DOMAIN/privkey.pem;
}
map $ssl_preread_server_name $sig_name {
chat.signal.org signal-service;
ud-chat.signal.org signal-service;
storage.signal.org storage-service;
cdn.signal.org signal-cdn;
cdn2.signal.org signal-cdn2;
cdn3.signal.org signal-cdn3;
cdsi.signal.org cdsi;
contentproxy.signal.org content-proxy;
sfu.voip.signal.org sfu;
svr2.signal.org svr2;
svrb.signal.org svrb;
updates.signal.org updates;
updates2.signal.org updates2;
default deny;
}
map $ssl_preread_server_name $local_name {
YOUR_PROXY_DOMAIN signal;
default local;
}
upstream signal-service {
server chat.signal.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 signal-cdn3 {
server cdn3.signal.org:443;
}
upstream cdsi {
server cdsi.signal.org:443;
}
upstream content-proxy {
server contentproxy.signal.org:443;
}
upstream sfu {
server sfu.voip.signal.org:443;
}
upstream svr2 {
server svr2.signal.org:443;
}
upstream svrb {
server svrb.signal.org:443;
}
upstream updates {
server updates.signal.org:443;
}
upstream updates2 {
server updates2.signal.org:443;
}
upstream local {
server 127.0.0.1:8443;
}
upstream signal {
server 127.0.0.1:444;
}
upstream deny {
server 127.0.0.1:9;
}
server {
listen 127.0.0.1:445;
proxy_pass $sig_name;
ssl_preread on;
access_log /var/log/nginx/access_sig.log stream_log;
error_log /var/log/nginx/error_sig.log info;
}
server {
listen 443;
proxy_pass $local_name;
ssl_preread on;
access_log /var/log/nginx/access_main.log stream_log;
error_log /var/log/nginx/error_main.log info;
}
}
Здесь
YOUR_PROXY_DOMAIN - это домен для прокси. Можно использовать любой, даже с afraid.org или dynu.com или sslip.io
YOUR_SITE_DOMAIN - это домен для сайта, который вы можете хостить на том же сервере. Сертификат для него также будет отдаваться по умолчанию если стукнуться на 443 порт с пустым SNI.
Прокси-домен может быть поддоменом домена сайта.
Сертификаты можно сгенерить с
certbot certonly --standalone --deploy-hook "systemctl restart nginx" -d YOUR_PROXY_DOMAIN
certbot certonly --standalone --deploy-hook "systemctl restart nginx" -d YOUR_SITE_DOMAIN
После генерации сертификатов и перезапуска Nginx вставляем в Signal ссылку типа https://signal.tube/#YOUR_PROXY_DOMAIN , тыкаем, он добавляет прокси и все работает.
Вместо своего сайта можно в upstream local указать домен и 443 порт какого-нибудь другого сайта - тогда ваш сервер тупо будет проксировать все HTTPS-запросы на него (но будьте осторожны с CDN, чтобы не повторилась история как вот здесь). Cекцию “http” в таком случае можно выкинуть, как и сертификат для сайта.
А еще можно на том же сервере вместо сайта захостить еще и Telegram-прокси с FakeTLS, например 9seconds/mtg: Highly opinionated MTPROTO proxy for Telegram - аналогично в конфиге Nginx меняем в upstream local порт 8443 на порт вашего Telegram-прокси.