Open-source privacy tool

Share secure internet with the people you care about

One command deploys an undetectable proxy server. Share access with family and friends via QR codes — they scan once and connect.

Connection page — what your friends receive

What your friends receive — see the demo

Three steps to secure internet

You need a VPS (any $5/month server) and a terminal on your laptop. Meridian handles everything else.

Step 1 — Install
curl -sSf https://getmeridian.org/install.sh | bash
then
Step 2 — Deploy
meridian deploy

The wizard asks for your server IP and handles the rest. Or pass flags directly — see the CLI reference.

What happens behind the scenes

1
Installs Docker and deploys Xray via the 3x-ui management panel
2
Generates x25519 keypair — unique encryption keys for Reality authentication
3
Hardens the server — UFW firewall (ports 22 + 443 only), SSH key-only auth, BBR congestion control
4
Configures VLESS+Reality on port 443 — impersonates a real TLS server
5
Enables XHTTP transport — additional stealth routed through Caddy, no extra port
6
Outputs QR codes and generates an HTML connection page with setup instructions
Safe to re-run anytime. Fully idempotent — credentials preserved, settings updated in place.

Build your command

Configure flags interactively and copy the full command. Supports all Meridian CLI operations.

Deploy VLESS+Reality proxy. Configures Docker, Xray, firewall, and TLS automatically.

Your VPS public IPv4 address. Leave empty for interactive mode.
Default: root. Non-root users get sudo automatically.
Optional. Adds CDN fallback via Cloudflare and web panel access.
Site that Reality impersonates. Default: www.microsoft.com. Use meridian scan for optimal targets.
Enabled by default. Routed through port 443 via Caddy. Requires v2rayNG 1.9+ or Hiddify.
Add --yes flag. For CI/automation or non-interactive SSH sessions.
meridian deploy


Why censors can't detect it

Traditional VPNs have distinctive traffic signatures. VLESS+Reality is indistinguishable from normal web browsing.

Deep Packet Inspection (DPI)

DPI analyzes traffic patterns to identify proxy protocols. VPNs like OpenVPN and WireGuard have distinctive packet signatures that are trivial to block.

VLESS+Reality produces traffic byte-for-byte identical to a normal HTTPS connection. No headers, no patterns, no packet sizes that distinguish it from regular web browsing.

Active probing

Censors connect to suspicious servers and try to fingerprint them. If a server responds differently than the website it claims to be, it gets blocked.

Reality uses the TLS certificate from a real website (e.g., microsoft.com). When a probe connects, your server completes the handshake using Microsoft's actual certificate. The probe sees a legitimate server. Only clients with your private key get the proxy tunnel.

TLS fingerprinting

Every TLS client sends a unique "Client Hello" fingerprint. Censors flag connections where the fingerprint doesn't match the claimed application.

Meridian uses uTLS to impersonate Chrome's exact TLS fingerprint — the same one used by billions of devices. Your traffic is indistinguishable from someone browsing the web with Chrome.


Scan and go

After deploying, you get a connection page with QR codes. Send it to whoever needs it — they tap once and connect.

Device clock must be accurate within 30 seconds. Enable automatic date/time in your device settings.

Under the hood

Meridian architecture — HAProxy SNI routing, Caddy TLS, Xray Reality
Standalone mode (no domain)

HAProxy sits on port 443 and routes traffic by TLS SNI. Reality connections route to Xray, while Caddy handles everything else — serving connection pages over HTTPS with a Let's Encrypt IP certificate. XHTTP transport runs through Caddy via path-based routing — no extra port exposed.

The 3x-ui panel is reverse-proxied by Caddy on a secret path — accessible via HTTPS, no SSH tunnel needed.

Domain mode (CDN fallback)

Adds three components on top of standalone:

HAProxy inspects TLS SNI without terminating encryption. Caddy terminates TLS with automatic Let's Encrypt certificates. VLESS+WSS provides a CDN fallback through Cloudflare — works even if your server's IP is blocked.


Configuration & operations

Customization

All settings are passed as CLI flags to meridian deploy:

FlagDefaultDescription
--sni HOSTwww.microsoft.comSite that Reality impersonates
--domain DOMAIN(none)Enable domain mode with CDN fallback
--xhttp / --no-xhttpenabledXHTTP transport (through port 443)
--email EMAIL(none)Email for TLS certificates
--name NAMEdefaultName for the first client
--user USERrootSSH user (non-root gets sudo)
--yesSkip confirmation prompts

For optimal stealth, use meridian scan or RealiTLScanner to find an SNI target near your server.

Cloudflare CDN setup

Follow this order to avoid TLS certificate issues:

1. Add domain in Cloudflare, create A record to server IP
2. Keep cloud icon grey ("DNS only")
3. Run meridian deploy — Caddy gets the cert
4. Switch to orange cloud (Proxied)
5. SSL/TLS → Full (Strict), enable WebSockets

Client management

Share access with friends — each gets their own key:

meridian client add alice

List all clients:

meridian client list

Revoke access:

meridian client remove alice
Troubleshooting

Not connecting? Test reachability from your device:

meridian test

Or use the web-based ping tool — no install needed.

Connection fails immediately: Check device clock (±30 seconds).

Was working, now stopped: IP may be blocked. Use CDN fallback or deploy a new server.

AI-powered diagnostics:

meridian doctor --ai
Update & maintenance
ssh root@YOUR_SERVER
cd /opt/3x-ui && docker compose pull && docker compose up -d

Or re-run meridian deploy — safe to repeat anytime.

Uninstall
meridian teardown

Removes the proxy container, configs, and firewall rules. Docker and system packages are kept.

Security notes

Credentials at /etc/meridian/ (server) and ~/.meridian/credentials/ (local). Panel reverse-proxied on a secret HTTPS path. SSH password auth disabled. UFW allows only 22, 80, 443. Docker image pinned. All secrets redacted from output.