Server routing (bridge)
Server routing ties two of your servers together so user traffic splits by direction: some sites open straight from the entry node, the rest travel a tunnel to the exit server. Users notice nothing: same subscription, same addresses, same entry speed.
The menu item lives at 4. Node extensions → Server routing. The first screen asks which bridge you need:
Server routing Details in the wiki: https://wiki.egam.es/configuration/server-routing/ 1.Bridge via Shadowsocks (configured: 1) RU sites through one IP, foreign sites through another; for every user at once 2.Bridge via VLESS Route (configured: 0) a personal exit for everyone: the profile gets one more host in the subscription, the route number is baked into the link 0.Exit Select action (0-2):
You need a panel on this server and a second server.
How it works
Section titled “How it works”The module moves service traffic into a private network without breaking anything on the public path: an outbound Shadowsocks and rules are added to the entry node’s profile config, saying where Russian traffic goes and what stays direct. On the exit server a node comes up with a single service inbound: it serves nothing to users, it only terminates the tunnel.
You pick the direction
Section titled “You pick the direction”The main setup question is where Russian traffic should go. Each option’s hint spells out the consequences right in the menu:
Where should Russian traffic (sites and IPs) go? 1.Straight from the entry node when the entry node is inside RU: RU sites see the entry IP, foreign sites see the exit IP 2.Through the bridge when the entry node is abroad: RU sites see the exit IP, foreign sites see the entry IP Select action (1-2):
“Through the bridge” mode. Foreign sites see the clean foreign entry IP, while Russian services get the native address of the exit server. No “you are logging in from abroad” captchas on Russian services.
| Service | Sees the IP of |
|---|---|
yandex.ru/internet and RU sites |
exit server |
ifconfig.me and foreign |
entry node |
“Straight from the entry node” mode. RU sites stay on the Russian entry, and foreign traffic goes through the second server and gets a foreign address.
| Service | Sees the IP of |
|---|---|
yandex.ru/internet and RU sites |
entry node |
ifconfig.me and foreign |
exit server |
You can flip the mode any time with the single Set up again command: the direction switches without a reinstall because every object is reused.
The wizard asks a few questions in a row. First the exit server: it comes from the servers with configured SSH access (or you type an address by hand, and the script then offers to set up access):
Exit server (from configured SSH targets): 1.root@203.0.113.20:22 (Kazan) 2.Enter an address manually
Then the port, the direction (screen above), the bridge name and the entry node’s profile:
Bridge SS port (Enter — 9999): 9999 Bridge name shown in the panel (Enter — Kazan): Kazan Which profile gets routed through the bridge? Traffic flows through it by the routes you picked — choose the entry node's profile 1.Default-Profile (2 inbounds)
- Exit server. The screen above. If the server has no node yet, the script offers to install everything remotely:
Node 203.0.113.20 is not in the panel. Install it on this server over SSH (docker + remnanode)? (y/n). The exit server needs neither a domain nor certificates: it just listens on the port and terminates the tunnel. - Bridge port. Defaults to
9999;EnterEnterEnterEnterEnterEnter keeps it. - Traffic direction. The table above.
- Bridge name. One name for all panel objects;
EnterEnterEnterEnterEnterEnter fills in the SSH server’s name: squadKazan bridge, service userbridge-kazan, node and profileKazan-bridge. - Entry node profile. The outbound and rules land in it. More profiles can be attached later, for example when a second entry node appears.
While you were answering, the wizard already brought everything up:
Fetching the node link key from the panel... Link key fetched Installing Docker on the remote server (may take a couple of minutes)... Writing the node compose file... Node files written to the server Starting the node container... Waiting for the node to reach the panel (attempt 1)... Node connected to the panel Creating the bridge internal squad... Squad created Creating the bridge service user... Service user created Patching profile 'Default-Profile': outbound + routing rules... Profile 'Default-Profile' updated, the config reaches its nodes Opening the bridge port in ufw on 203.0.113.20... Port opened in ufw
At the end the wizard checks connectivity live: whether the node is connected to the panel, whether the bridge port answers, and reminds you how to verify the result from a client.
Under the hood: rules in the profile
In “Through the bridge” mode the profile config gets an outbound and these rules:
{ "ip": ["geoip:private"], "outboundTag": "BLOCK" },{ "protocol": ["bittorrent"], "outboundTag": "BLOCK" },{ "ip": ["geoip:ru"], "outboundTag": "SR_BRIDGE_SS" },{ "domain": ["geosite:category-ru"], "outboundTag": "SR_BRIDGE_SS" }In “Straight from the entry node” mode geoip:ru and geosite:category-ru switch their outboundTag to DIRECT, and a catch-all rule is added: all remaining profile traffic goes to SR_BRIDGE_SS. With extended RU lists one more rule with ext:geosite-ruex.dat:ru-available-only-inside is appended, always assigned to the bridge.
Bridge menu
Section titled “Bridge menu”Bridges via Shadowsocks: Kazan Bridge: 203.0.113.20:9999 Node 203.0.113.20 connected to the panel Port 9999 answers from this server 1.Attach another profile that profile's entry node goes through the same exit 2.RU lists: extended (restore stock) one switch for all bridges; the list file lands on entry nodes 3.Set up again full setup from scratch: exit server, port, mode, profile 4.Rename the bridge the squad, user, node and profile all get the new name 5.Remove routing profiles return to direct egress; the bridge node and profile stay 0.Exit Select action (0-5):
There can be several bridges: each with its own exit server, its own panel objects and its own attached profiles. If a profile already belongs to another bridge, the script warns and offers to reattach it.
Bridge via VLESS Route
Section titled “Bridge via VLESS Route”The country bridge decides for everyone: one direction per profile. The second type hands the choice to the user. The profile gets an extra host in the subscription, for example “Germany → Moscow”, and selecting it sends all of that user’s traffic through the bridge server: both Russian and foreign sites see its IP. The regular host keeps working as before.
| Subscription host | RU sites see | Foreign sites see |
|---|---|---|
| Germany (regular) | by the profile’s common rules | by the profile’s common rules |
| Germany → Moscow | bridge server IP | bridge server IP |
Hosts switch in the client any time, without a reinstall or a second subscription: a phone can live on “Germany → Moscow” for the banks while the computer stays on plain “Germany”.
How it is built
Section titled “How it is built”The route number is a native host field in the panel (vlessRouteId). The panel bakes the number into the link UUID, the entry node reads it and sends the connection through the right outbound. The user configures nothing: they just pick a host with a clear name.
Under the hood: rules and UUID
The entry node’s profile gets an outbound and rules with route numbers:
{ "vlessRoute": 1, "outboundTag": "DIRECT" },{ "vlessRoute": 2, "outboundTag": "SR_BRIDGE_SS_kazan" }Route 1 is service traffic: direct egress from the entry node; a host for it is created only if the profile is already country-split. The number lives in the third UUID group: user 9d5f42a1-7b3c-4d8e-… on route 2 gets a link with 9d5f42a1-7b3c-0002-…, and that pair of bytes is what the node reads as the number.
The VLESS Route wizard starts with the exit machine: a new server over SSH or an “Exit of bridge …” line from the ones already configured:
Exit server 1.New server (SSH) 2.Exit of bridge 'Kazan' (203.0.113.20:9999)
-
Exit server. The screen above: same line, own service user.
-
Port and name. Defaults are
9999and the SSH server’s name;EnterEnterEnterEnterEnterEnter keeps both. -
Entry node profile. VLESS only: the route rides inside the link UUID, Trojan and Shadowsocks have none. Profiles already taken by other bridges are marked in the list.
-
Route number. A free number is suggested for you, taken ones are not offered:
Route number (Enter picks 2): 2 -
Host name. Defaults to “entry → exit”, for example “Germany → Moscow”.
From there the script works on its own: if a node container already runs on the server without a panel record, it offers to adopt it as is, without a reinstall. ufw on the exit server is enabled automatically: ports already listening publicly stay open, everything else closes.
Bridge menu
Section titled “Bridge menu”Bridge via VLESS Route: Kazan (route 2) Bridge: 203.0.113.20:9999 Node 203.0.113.20 connected to the panel Port 9999 answers from this server Host in the subscription: Germany → Kazan 1.Hide the host from subscriptions the rules stay, the host simply disappears from user subscriptions 2.Attach another profile a second entry node through the same exit and route number 3.Set up again full setup from scratch: exit server, profile, route number, host 4.Rename the bridge the squad, user and subscription host get the new name 5.Remove routing the host is deleted, the rules go, everyone returns to the profile's common rules 0.Exit Select action (0-5):
Tear-down is soft: the host leaves subscriptions, the rules leave the profile, and a user with an old cached link simply falls back to the common rules. Nothing breaks.
Extended RU lists
Section titled “Extended RU lists”The stock geosite:category-ru rule covers all domains in .ru, .su, .рф plus name lists. But Russian services living on foreign domains never make it in and stay behind.
The RU lists item connects the daily-updated lists from the runetfreedom project. One rule is added for domains reachable only from inside Russia (ext:ru-available-only-inside):
Enable the extended RU lists (domains reachable only from inside RU)? Stock rules stay, one ext: rule is added (y/n): y Downloading geosite.dat from runetfreedom... File fetched, checksum matches Mounting the lists into node node.example.com... Adding the ext:ru-available-only-inside rule to bridged profiles... Rule added, profiles updated: 1 Extended RU lists enabled on: node.example.com
Under the hood: files and cron
Directory/usr/local/remnawave_reverse
Directoryserver-routing
- kazan.bridge (bridge: server, port, mode, panel objects)
- ruex.state (extended lists state)
- ruex-update.sh (daily updater)
- ruex-update.log (last 50 log lines)
The crontab -l line looks like: 30 4 * * * bash /usr/local/remnawave_reverse/server-routing/ruex-update.sh. The updater downloads the dat file from four mirrors, checks sha256 and spreads it over the entry nodes; node restarts go through the panel API and only on a real file change.
Verifying from a client
Section titled “Verifying from a client”Connect as a user from a regular squad (the one with the entry node) and open two sites:
yandex.ru/internet shows the entry node’s IP, ifconfig.me shows the exit server’s IP.
yandex.ru/internet shows the exit server’s IP, ifconfig.me shows the entry node’s IP.
Pick the bridge host in the client, for example “Germany → Moscow”: ifconfig.me shows the bridge server’s IP, the regular host returns its usual address.
Removing
Section titled “Removing”Remove routing returns profiles to direct egress, deletes the service user and the squad, and closes the ufw port on the second server. The bridge node and profile stay: they no longer route anything, and you can delete them in the panel by hand if they are not needed.
