English | 中文
An ultra-lightweight Signal TLS-in-TLS Obfuscation Reverse Proxy tailored specifically for Fly.io's Free Allowance ($5 monthly invoice waiver policy). Written in pure asynchronous Rust with a minimal memory footprint (< 15 MB), completely eliminating the operational burden of managing Nginx containers and Let's Encrypt certificate renewals.
This proxy accurately reproduces the core obfuscation mechanism of the official Signal-TLS-Proxy, while leveraging Fly.io's global Anycast edge network and providing zero-conflict multi-protocol multiplexing on port 443:
[ Client (Signal App / Web Browser) ]
│
│ 1. Outer TLS connection (Port 443, SNI: your-domain.com)
▼
[ Fly.io Global Edge (443) ]
│ • Automated Let's Encrypt certificate issuance and renewals
│ • handlers = ["tls"] (terminates outer TLS without HTTP parsing)
▼
[ Rust Core Proxy Engine (:8080) ]
│ 2. Receives decrypted raw TCP stream
│ 3. Zero-copy multi-protocol inspection:
│ ├─ If Signal TLS (0x16): Sniffs inner SNI (e.g. chat.signal.org) & validates against whitelist
│ └─ If HTTP: Camouflage routing (302 redirect / 404 / /state Dashboard)
▼
┌───────────────┬────────────────────────────┐
│ (Signal TLS) │ (HTTP Web Access) │
▼ ▼ ▼
[ Signal Servers ] [ Camouflage / Dashboard ]
(chat.signal.org:443) (302 Redirect / 404 / Web UI)
- Pure Rust Asynchronous Engine: Built on Tokio with a zero-copy TLS ClientHello SNI parser for high-performance, full-duplex TCP streaming.
- Built-in Web UI: When accessed via a standard web browser, it renders a modern Swiss-style landing page with English/Chinese toggle, dynamic hostname detection for
https://signal.tube/#<your_host>, one-click link copying, and deep-link button to open the Signal app. - Zero Certificate Maintenance: Fully automated edge certificates via Fly.io. No need to run
certbot, cron jobs, or mount persistent volumes. - Zero-Knowledge Privacy: End-to-end encryption takes place directly between the user's device and official Signal servers. The proxy cannot inspect or tamper with any decrypted communication.
- Anti-Abuse Whitelist: Enforces a strict domain whitelist covering official Signal services (
chat.signal.org,storage.signal.org,sfu.voip.signal.org, etc.), preventing port scanners from using your instance as an open relay.
Fly.io enforces an official billing rule: "Monthly invoices under $5.00 USD are automatically waived ($0 charge)".
| Resource | Specification | Estimated Cost | Final Invoiced Amount |
|---|---|---|---|
| Compute Instance | 1 × shared-cpu-1x (256MB RAM) running 24/7 |
~$1.94 / month | $0.00 (Waived under $5 rule) |
| Always On | auto_stop_machines = false (never sleeps) |
Included above | $0.00 |
| Outbound Data | 100 GB / month included free | $0.00 | $0.00 |
| SSL/TLS Certificates | Automated Let's Encrypt managed by Fly.io | Included free | $0.00 |
Tip: Keep the machine size at
shared-cpu-1xwith256MBRAM on a single instance, and your monthly Fly.io bill will remain permanently at $0.00.
💡 No local development tools required (no
flyctl, no Docker, no Rust compiler). The entire setup can be completed via GitHub and the Fly.io Web Console with zero API tokens.
Click the Fork button at the top-right corner of this repository to copy it into your own GitHub account.
- Visit and log in to the Fly.io Dashboard (new accounts require a credit card for verification; actual billing is $0 if kept under $5/mo).
- Click Launch an app from GitHub.
- Authorize Fly.io and select your forked
Sinelrepository. - Fill in the deployment form with the following settings:
| Field | Recommended Value | Notes |
|---|---|---|
| App Name | Unique custom name | e.g. my-signal-proxy-2026 (must be globally unique) |
| Region | sin - Singapore, Singapore or nrt - Tokyo, Japan |
Lower latency for Asian regions. For US West, choose sjc - San Jose or lax - Los Angeles. |
| Internal port | 8080 |
CRITICAL Must be 8080 (the Rust proxy listens on internal port 8080). |
| Machine Sizes • CPU(s) • Memory |
shared-cpu-1x256MB |
Free Tier Requirement. This configuration costs only ~$1.94/month, falling well below the $5 waiver limit. |
| Environment Variables | Leave blank | Code includes sensible pre-configured defaults. |
| Database | Leave unchecked (Managed Postgres) | Not needed; proxy runs entirely in memory. |
| Working directory | Leave blank (default ./) |
Keep default. |
| Config path | Leave blank (default ./fly.toml) |
Automatically applies the included fly.toml with handlers = ["tls"]. |
- Click the purple Deploy button at the bottom. Fly.io will build and launch your application automatically.
Newly created Fly.io applications do not have public IP addresses by default (fly.dev will not resolve until an IP is assigned):
- In the Fly.io Dashboard, navigate to your app's Overview page;
- Scroll down to the Networking section. Under IP addresses, you will see
This app has no IP addresses; - Allocate Free IPs (Please follow carefully):
- Click
Assign Shared IPv4: [REQUIRED, 100% FREE $0.00] Fly.io's Anycast Shared IPv4 routes incoming connections using TLS SNI, matching the TLS-in-TLS proxy architecture seamlessly. - Click
Assign Dedicated IPv6: [RECOMMENDED, 100% FREE $0.00] Grants a free dedicated IPv6 address. - DO NOT click
Assign Dedicated IPv4: Dedicated IPv4 incurs a charge of $2.00/month and is unnecessary for this project. - Ignore
Assign Flycast IPv6: This is for internal 6PN private networks only and cannot be accessed from the public internet.
- Click
- Once allocated, your public IP addresses will be displayed, and your proxy is now accessible from the internet.
Direct fly.dev domains may frequently blocked by national firewalls. Setting up a custom domain is recommended:
- Add Certificate in Fly.io:
- In your app's left sidebar, click Certificates;
- Click Add a Certificate in the top right;
- Enter your subdomain (e.g.
sinel.yourdomain.com) and click Create Certificate; - Fly.io will display the required DNS configuration records.
- Configure DNS Records:
- Log into your DNS provider (e.g., Cloudflare, Namecheap, DNSPod, etc.);
- Add the following DNS records:
- A Record: Name
sinel-> Value: Your assigned Shared IPv4 (If using Cloudflare, ensure proxy status is set to DNS-Only / gray cloud). - AAAA Record: Name
sinel-> Value: Your assigned Dedicated IPv6.
- A Record: Name
- Verify Certificate Status:
- Once DNS propagates, the certificate status on the Fly.io Certificates page will turn into a green checkmark (
Ready) within 1–2 minutes.
- Once DNS propagates, the certificate status on the Fly.io Certificates page will turn into a green checkmark (
Once configured, generate your official standard share link:
https://signal.tube/#signal.yourdomain.com
Connection Methods:
- Web UI Direct Setup: Visit
https://signal.yourdomain.comin your browser. The built-in Web UI allows you to copy the share link or click "Open in Signal" to configure the proxy automatically. - Manual Setup: Open Signal App -> Settings -> Data and Storage -> Use Proxy -> Toggle ON and enter
signal.yourdomain.com:443.
If you prefer using the terminal, you can perform the full setup using flyctl:
# 1. Log in to Fly CLI
fly auth login
# 2. Launch and deploy
fly launch --no-deploy
fly deploy
# 3. Allocate free public IPs and bind custom domain
fly ips allocate-v4 --shared
fly ips allocate-v6
fly certs add signal.yourdomain.comCustomizable via the [env] block in fly.toml or the Secrets tab in the Fly.io console:
| Variable | Default | Description |
|---|---|---|
PORT |
8080 |
Internal listening port inside the container |
HOST |
0.0.0.0 |
Internal listening IP address |
RUST_LOG |
sinel=info,warn |
Log level (debug enables detailed handshake logs) |
ALLOW_ALL_SIGNAL_SUBDOMAINS |
true |
Allows all *.signal.org and *.voip.signal.org subdomains |
EXTRA_ALLOWED_DOMAINS |
(empty) | Comma-separated list of additional allowed destination domains |
ROOT_STATUS_CODE |
(empty) | HTTP status code for root (/): 302 (redirect) or 404 (not found). If unset or STATE_PATH is /, root serves the dashboard |
REDIRECT_URL / MASKED_URL |
https://www.google.com |
Redirect destination when ROOT_STATUS_CODE=302 |
STATE_PATH |
/state |
Path where the Web UI dashboard is served (e.g. /state or /secret-path). If set to /, serves at root |
# Run unit tests (includes ClientHello parsing and whitelist validation)
cargo test
# Run proxy server locally
cargo runThis project is open-source under the MIT License.