πŸ›°

VPN infrastructure: Russian entry node, European exit

our own product: a relay in Russia, a persistent tunnel and a node in the Netherlands

A VPN that does not get blocked on the cross-border path: an entry relay in Russia with SNI routing, a persistent frp tunnel and a standalone exit node on Marzban with VLESS Reality and Cloudflare WARP.

In production Β· in-house product
1 command
moves the VPN to a new domain: certificate, nginx and subscriptions, with live sessions intact
10 of 10
subscription requests answered with the first tunnel taken down: the second independent tunnel carried them
44 domains
of AI services, plus all torrent traffic, exit through Cloudflare WARP

The task

The address of the exit VPN server was being suppressed on the Russian side. Measurements on 20 August 2026 showed that 35–60% of TCP connection attempts from Russia to that address were lost, while cloudflare.com and google.com showed no loss, and from the Netherlands the same address also showed 0%. Ping (ICMP) to the server ran without loss, and three sessions set up around the filter lived for 305 seconds without a single failure.

What was filtered was neither an app nor the VLESS protocol, but the pair of Russia and that address, and only at connection setup (the TCP handshake, the exchange of service packets at the start of a connection). Every new client opened its own cross-border connection and hit the filter all over again. A second requirement: changing the domain should take minutes, not hours of manual repair. A third: torrent traffic must not lead to hosting-provider complaints.

The solution

Stop opening a new cross-border connection for every client and keep one persistent connection into which all of them are multiplexed. Multiplexing means carrying many streams inside one connection. What is implemented:

  • An entry relay in Russia: nginx terminates TLS on the user-facing domain and routes traffic by SNI on a single port.
  • A persistent frp tunnel from the relay to the exit server instead of direct connections; a second independent tunnel was added in version 3.0.0.
  • Proxying of the VLESS WebSocket tunnel and of the Marzban panel with subscriptions; a tunnel path without an Upgrade header answers 404, like a page that does not exist.
  • Domains split by role: traffic, subscriptions, admin.
  • A domain change in one command without dropping client sessions; automatic certificate renewal with a deploy hook.
  • A standalone node in the Netherlands: Marzban, VLESS Reality, torrents and AI services exiting through Cloudflare WARP.
  • TCP forwarding for the UNLOCK greeting-card service through the Netherlands node when the direct path between Russia and the exit server is closed.

How it works

SNI routing on a single port

SNI is the site name a client announces at the start of a TLS connection. The relay reads it and decides where to send the stream: to a website, to the panel or into the tunnel. Websites, the VPN and the tunnel therefore share one HTTPS port and look identical from outside. Since 18 September 2026 the relay carries only the VPN: the websites moved to a separate server.

A persistent frp tunnel instead of a connection per client

frp is a reverse-proxy tool that keeps one long-lived connection between nodes. The filter that fires at connection setup no longer sees new connections. A pool of persistent connections to the panel, instead of a new one per request, completes the design.

Tunnel drops and the second tunnel

The analysis in version 3.0.0 found 46 tunnel drops per day, with no error in the log before each break. The cause is the tcpMux mode: frp turns off its own heartbeat, the multiplexer has a fixed 10-second write timeout, and on a lossy link a single missed ping killed a healthy session. The keepalive interval was raised from 30 to 120 seconds and a second independent tunnel was added. With the first tunnel taken down, the subscription answered 10 requests out of 10.

Splitting domains: traffic, subscriptions, admin

Each domain has one role. The traffic domain carries a continuous WebSocket, which will be noticed sooner or later. A subscription is requested rarely, in short HTTPS calls. The payoff: if the traffic domain is blocked, the update channel survives, and the client taps "refresh subscription" and gets a config with a new address. The admin panel does not sit on any public domain; it listens on a separate port that admits only the exit server's address. The limit of the design: all domains point to one IP address, and a block by address takes them down together.

A standalone node in the Netherlands: VLESS Reality and Cloudflare WARP

A separate node with its own Marzban panel, database and keys, sharing nothing with the main exit server. VLESS Reality disguises the connection as TLS traffic to someone else's website and needs neither a domain nor a certificate. BitTorrent traffic (detected by protocol) and 44 AI-service domains go through Cloudflare WARP, so the hosting provider sees only an encrypted connection to Cloudflare. All other web traffic goes direct. Requests to private subnets are blocked, traffic is accounted per user, and SSH is protected from password guessing by fail2ban.

Domain change and certificate renewal

A full-migration script updates the certificate, the nginx config and the subscriptions. Changes are applied with nginx -s reload, so client sessions are not dropped. Let's Encrypt certificates are renewed through webroot without stopping nginx, and a deploy hook makes nginx re-read the renewed certificate: previously certbot updated the files while nginx kept serving the old one.

Results

  • A domain change is one command, with no dropped live sessions.
  • The fallback works: with the first tunnel taken down, the subscription answered 10 of 10 requests.
  • Torrent traffic and 44 AI-service domains exit through Cloudflare WARP, and the hosting provider sees only an encrypted connection to Cloudflare.
  • Leak check for torrent traffic: all 44 client connections went to the WARP container, with no direct connections to peers.

Technologies and why

  • nginx β€” TLS termination and SNI routing on one port.
  • Xray / VLESS Reality β€” the VPN protocol; Reality removes the need for a domain and certificate on the exit node.
  • Marzban β€” a panel for users, subscriptions and traffic accounting.
  • frp β€” the persistent multiplexing tunnel between nodes.
  • Cloudflare WARP β€” the exit for torrents and AI services.
  • certbot β€” Let's Encrypt certificates with automatic renewal.
  • Docker β€” deployment of nginx, frp, Marzban and WARP.
  • MariaDB β€” the Marzban user database.

Status

In production: relay 4.0.0 and the Netherlands node 1.3.0, both dated 18 September 2026. This is the base of the Tech Poly VPN service.

Next on the README roadmap: serving subscriptions from a separate machine, a second relay in another network, an automatic subscription refresh interval in clients, a domain and certificate for the Netherlands node's panel, and automatic backup of the Marzban database.

Questions about this project

How is the VPN route from Russia to Europe built?
The entry node in Russia accepts clients on a TLS domain and routes websites, the panel and the VPN by SNI on a single port. All VPN traffic then goes into one persistent frp tunnel to the exit server abroad. Separately, a standalone node in the Netherlands runs Marzban with VLESS Reality.
Why not connect to the exit server directly?
Measurements on 20 August 2026 showed that 35–60% of TCP handshakes from Russia to the exit server's address were lost, while ping had no loss. The filter targeted the pair of Russia and that address, and only at the moment a connection was set up. One persistent tunnel instead of a new connection per client avoids that filter.
What happens if the traffic domain gets blocked?
Domains have separate roles: one carries traffic, another serves subscriptions, and the admin panel sits on a closed port. If the traffic domain is blocked, the client refreshes its subscription through the second domain and receives a config with a new address. The limit: all domains point to one IP address, so an address-level block still takes them all down.
How do you avoid hosting-provider complaints about torrents?
On the Netherlands node, BitTorrent traffic and 44 AI-service domains exit through Cloudflare WARP, so the hosting provider only sees an encrypted connection to Cloudflare. Ordinary web traffic goes direct, which avoids captchas. Torrents over WARP are slower than direct ones, because WARP does not accept inbound connections.
How do you change the VPN domain without dropping clients?
A script moves the route to a new domain with one command: the certificate, the nginx config and the subscriptions are updated. Live sessions survive because nginx reloads its config instead of restarting. Renewed certificates are picked up by a certbot deploy hook.
What are the weak points of this setup?
All relay domains point to one IP address, so a block by address takes them down together. The first tunnel was a single point of failure; a second independent tunnel was added in version 3.0.0. The README does not say whether it is deployed on the production servers.

Need something similar?

Tell us about the task β€” we'll show how we solved it and estimate the scope.