Warning
This is a beta of Meridian 4. Nobody gets it automatically: pip, uv, the install script, and meridian update on 3.x all skip it. Your 3.x servers keep working.
Use a separate, fresh server you can wipe. Meridian 3.x and 4 cannot share a server: both need port 443. Meridian 4 refuses to deploy onto a server that still runs 3.x; replacing a 3.x server means tearing it down first, and every one of its users needs a new link.
Try it next to 3.x
You need uv (macOS or Linux; on Windows use WSL). On your computer Meridian 4 keeps its state in ~/.config/meridian, so your 3.x command and ~/.meridian stay untouched:
curl -LsSf https://astral.sh/uv/install.sh | sh # installs uv and uvx; open a new terminal afterwards
alias meridian4='uvx --prerelease allow --from meridian-vpn@latest meridian'
meridian4 deploy 198.51.100.10 # IP of the separate serverPrefer questions to flags? meridian4 setup walks you through one server or several (exits in other countries, relays) in English, Russian, Persian, or Chinese. The alias always runs the newest beta; after a new one comes out, meridian4 apply brings your servers up to date.
Keep ~/.config/meridian. It is how Meridian 4 manages your servers, and there is no recovery command yet: lose it and you have to tear down and deploy again. When 4.0 is released, install meridian the usual way and it manages the same servers; nothing to move or redeploy. Set up with an earlier alias that pointed at ~/.meridian-v4? Drop that part; Meridian finds the folder on its own.
Then, from a device inside the censored network, run:
meridian4 test 198.51.100.10 # does real traffic pass from here?
meridian4 test --probe 198.51.100.10 # does the server look like a proxy from here?Known gaps: a server you remove must still be reachable, or the change cannot finish; removing a node leaves Docker installed on it.
Tell us what you see
Open a Meridian 4 beta report. The most useful details: your country and network type (home ISP or mobile operator), whether your client app connects, and the output of meridian4 test; for deploy problems add meridian4 doctor. People you shared a connection page with can open "Not connecting?" on it, run the check, and send you the copied report: it contains no links or addresses. Outputs hide secrets, but replace IPs, domains, and links before posting.
Warning
Это бета-версия Meridian 4. Она не устанавливается сама: pip, uv, установочный скрипт и meridian update в 3.x её пропускают. Ваши серверы на 3.x продолжают работать.
Используйте отдельный новый сервер, который не жалко переустановить. Meridian 3.x и 4 не могут работать на одном сервере: обоим нужен порт 443. Meridian 4 откажется разворачиваться на сервере, где ещё работает 3.x; чтобы заменить такой сервер, его сначала нужно очистить, и всем его пользователям понадобится новая ссылка.
Как попробовать рядом с 3.x
Нужен uv (macOS или Linux; на Windows через WSL). На вашем компьютере Meridian 4 хранит своё состояние в ~/.config/meridian, поэтому команда 3.x и папка ~/.meridian останутся как есть:
curl -LsSf https://astral.sh/uv/install.sh | sh # ставит uv и uvx; затем откройте новый терминал
alias meridian4='uvx --prerelease allow --from meridian-vpn@latest meridian'
meridian4 deploy 198.51.100.10 # IP отдельного сервераУдобнее отвечать на вопросы, чем писать флаги? meridian4 setup проведёт через настройку одного сервера или нескольких (выходы в других странах, реле) на русском, английском, персидском или китайском. Алиас всегда запускает самую свежую бету; после выхода новой meridian4 apply обновит ваши серверы.
Не удаляйте ~/.config/meridian. Через эту папку Meridian 4 управляет вашими серверами, а команды восстановления пока нет: без неё придётся всё удалить и развернуть заново. Когда выйдет 4.0, установите meridian обычным способом, и он будет управлять теми же серверами: ничего переносить и разворачивать заново не нужно. Настраивали раньше с алиасом, указывавшим на ~/.meridian-v4? Уберите эту часть: Meridian найдёт папку сам.
Затем с устройства внутри сети с блокировками выполните:
meridian4 test 198.51.100.10 # проходит ли реальный трафик отсюда?
meridian4 test --probe 198.51.100.10 # похож ли сервер на прокси, если смотреть отсюда?Известные ограничения: удаляемый сервер должен быть доступен, иначе изменение не завершится; после удаления узла на сервере остаётся Docker.
Расскажите, что получилось
Откройте отчёт о бете Meridian 4. Важнее всего: страна и тип сети (домашний провайдер или мобильный оператор), подключается ли клиентское приложение, и вывод meridian4 test; при проблемах с развёртыванием добавьте meridian4 doctor. Те, с кем вы поделились страницей подключения, могут открыть на ней «Не подключается?», запустить проверку и прислать вам скопированный отчёт: в нём нет ссылок и адресов. Секреты в выводе скрыты, но перед публикацией замените IP-адреса, домены и ссылки.
[4.0.0] - Unreleased
Meridian 4 is a new foundation: the Remnawave panel replaces 3x-ui, and one
reviewed topology in ~/.config/meridian/cluster.yml describes your whole fleet.
Read first: this is not an in-place upgrade
- Meridian 4 cannot manage servers deployed by 3.x, and existing client links
cannot carry over to Remnawave. Your 3.x servers keep working. - To keep managing them, stay on 3.x:
uv tool install 'meridian-vpn<4'. - To move: deploy a fresh server with 4.0, give your users the new links, then
meridian teardownthe old server (it also removes 3x-ui). - 3.x and 4.0 cannot share a server, since both need port 443. 4.0 refuses to
deploy onto a server that still runs 3.x (or 2.x) instead of taking it over. - Requires Python 3.11+.
- Both versions fit on one computer — 4.0 keeps its state in
~/.config/meridian(or$XDG_CONFIG_HOME/meridian) and leaves 3.x state in
~/.meridianalone. A fleet set up with a 4.0 beta in~/.meridian-v4or
~/.meridianis found there, so the release manages it without moving files.
Working in the Remnawave panel
meridian panel— prints the admin panel URL and login (--show-password
for the password) and lists what Meridian manages versus what is yours.- Your panel edits stick — Meridian now owns only each client's existence,
name, and squads. Disabling a client (withclient disableor in the panel),
traffic limits, expiry, and descriptions set in the panel survive every
apply; before, the next apply re-enabled disabled or limited clients, and a
description edit made every apply fail. Disabled, limited, or expired clients
no longer markfleet statusas degraded.
Deploy
-
One command, verified end to end —
meridian deploy IPsets up the panel
and proxy, picks a camouflage target the server can actually use, pushes real
traffic through the delivered subscription, and only then prints "Done" with a
shareable connection page and QR code. Re-running it resumes or redeploys. -
A setup wizard anyone can follow —
meridian setupis a guided,
resumable wizard for one server or many (exits, Realm relays, routing
gateways with failover). It speaks English, Russian, Persian, and Chinese
(asked first, remembered, or--lang), explains each term in one plain
sentence, acceptslocalfor the machine you are on, skips routing questions
unless you have a gateway, suggests five short server names (astra, boba,
foxtrot…), and ends with a plain summary before anything
changes. Runningmeridianalone in a terminal offers to start it. -
Review before change —
meridian planshows whatmeridian applywould do
(exit 0 converged, 1 config error, 2 changes pending, 3 evidence unavailable). -
Paths — Reality, XHTTP, and Hysteria2 on UDP/443 by default;
--domain
adds WSS (Cloudflare CDN fallback). Blocking Russian destinations stays on
by default (--no-geo-blockto turn it off). -
Camouflage next door — without
--sni, a first deploy (andnode add)
scans the server's own subnet and prefers a site whose DNS really points
there and that passes Reality's TLS 1.3 + HTTP/2 check, so the SNI and the
server's IP look like they belong together. Well-known targets remain the
fallback, and real traffic still decides. -
Client IPs stay private unless you ask — by default the panel records
the server's own address for every TCP connection, so it never stores where
users connect from.--client-ips(orforward_client_ipsin the topology)
passes real addresses to Xray and the panel, through the PROXY protocol and
X-Forwarded-For, for Remnawave's per-user IP limits; the camouflage site
never sees the header. -
TLS fingerprint is a setting — every Reality, XHTTP, and WSS link presents
thechromefingerprint by default (XHTTP and WSS used to send none, which
exposed the client library);--fingerprintor the topology's path
fingerprintswitches it when a region starts flagging one. -
Shrink a running fleet —
meridian node removeandmeridian relay remove
edit the topology, show every resource they will delete, and clean up the
panel node, node container, Realm units, firewall rules, and published Hosts.
meridian planlists removals too, and the review covers them. -
Move an exit to another server —
meridian node replace EXIT SERVER
keeps the exit's ID, Reality keys, protocol paths, SNI, WARP and geo-block
settings, and relays, so clients keep working, then cleans up the old server
through the reviewed apply. The control server can't be moved yet. -
meridian fleet upgrade— compares the Remnawave images each server runs
with this CLI's pins, applies the reviewed plan, then runsmeridian check.
Newer or floating tags you chose are kept, and PostgreSQL never moves to a new
major version in place.meridian updatepoints to it when a fleet exists. -
One health command:
meridian check— checks whatever the server is in
your fleet: pre-flight readiness for a new server; panel connection,
containers (including Docker health, so a crash-looping service is flagged),
every compiled port, TLS, and disk for control, exit, and gateway servers;
and each Realm hop for relays. With no server it checks the whole fleet, and
--jsonreturns one typed report.meridian test --probereplacesmeridian probe.preflight,node check,relay check, andprobestill work for
one release. -
"What is blocked?" —
meridian test --probenow tells a blocked server
IP from a blocked camouflage SNI by comparing the server with and without the
SNI against the real camouflage site, and inconclusive stays inconclusive.
It also catches throttling: a ~50 KB download from the control server (and
through the CDN when WSS uses one) that freezes after about 16–24 KB is
flagged with a suggestion to change the IP.meridian checkruns the
download check too when it's run from another machine. -
meridian testsays how each path fails — every delivered path reports
its time to first byte, and a failed one is reported as "connects, but no
traffic passes" or "unreachable".--jsonaddsdata.transports. -
Name the server first, like ssh — every server command takes one target:
an IP, a saved name,user@host:port, orlocal.--userand--ssh-port
default to the saved values (elserootand22) everywhere, including
deploy,node add,relay add, andserver add.--server NAMEstill works. -
relay deployis nowrelay add, matchingnode add,client add, and
server add. The old name keeps working. -
Run Meridian on the server itself — after
meridian deploy local(or on
any saved server whose IP is on this machine), later commands such as
client add,doctor, andnode addrun locally with sudo instead of
SSHing back into the same machine. A copied~/.meridianon a laptop keeps
using SSH. -
Per-domain routes on an exit —
meridian route add EXIT --via warp|direct|block VALUES...sends chosen domains,geosite:lists, or
geoip:ranges through Cloudflare WARP, directly, or nowhere, ahead of the
exit's default egress (for example, AI services that block datacenter IPs).
route listandroute removecomplete it; the wizard keeps existing routes. -
Relays look like nothing in particular — nothing a hosting provider can
list on a relay (service, binary, config path, firewall comment) names
Meridian, Realm, a relay, or a VPN. Existing relays switch on the next apply. -
meridian checkmeasures each relay leg — every hop downloads the exit's
camouflage page through the next hop with the clients' SNI and reports
connect time, first byte, and bytes received; a freeze in the 8–32 KB
throttling window suggests moving the relay to another provider. -
meridian testtests the whole fleet — with no target and several saved
servers it tests every exit and relay entry in turn instead of asking which
one, and exits with the worst result. -
meridian testnames each path like its subscription entry ("Reality ·
Chrome", "XHTTP · Firefox", "Hysteria2 · UDP") instead of calling every
VLESS path "VLESS". -
With several exits, subscriptions list the first server's entries ahead of
later ones within each method instead of sorting them by exit name.
Sharing
- Connection names show where traffic exits — entries lead with the exit's
flag and country ("🇩🇪 DE · Reality · Chrome"), and the panel shows the same
flag on the node. Deploy,node add, and the setup wizard look the country up
once from the address's Regional Internet Registry; set--countrywhen it is
wrong (anycast or leased ranges). - A redesigned connection page — two clear steps (install an app, add the
connection with one tap), the subscription QR beside them on a computer for
setting up a phone, and everything else folded into quiet panels: every
individual connection with Open, Copy, and QR, "Not connecting?" tips with
the self-check, and the router guide. Russian pages no longer rename the
first connection "Основной", andmeridian dev previewshows a realistic
page. Without a--server-name, the header names the exit countries
("🇩🇪 Germany · 🇳🇱 Netherlands") in the page's language. - Connection pages are built from each user's real subscription, so relays and
every enabled protocol appear. - Subscription links live under the connection-page path and never reveal the
admin panel's address. meridian client add|show|list|remove|enable|disable.client removedeletes
the user and their page; links stop working immediately.- Connection pages recommend apps per platform — Happ first, then
FlClashX and Clash Mi (plus Throne on desktop), with a link to the router
guide and a note on subscription refresh and app updates. v2rayNG and
Streisand import links are fixed, Throne import is added, and the broken
v2rayN button is gone. App icons now ship once in a shared cached file, so
each page loads about 70 KB less. - "Check my connection" — the page tests the device clock, whether data
keeps flowing (the throttling freeze), and the subscription from the
visitor's own network, then copies a report without links or secrets that
they can send you. - Every deploy offers every invisible method — without a domain, XHTTP
and Hysteria2 now run on the server's IP address (Let's Encrypt certifies
IPs), next to Reality, so a block on one method leaves the others. A domain
adds WebSocket through the Cloudflare CDN. Hysteria2 is on by default
(--no-hysteria2turns it off), and the wizard only asks for an optional
domain instead of a list of backup methods. - Hysteria2 is disguised — its UDP traffic is wrapped in salamander
obfuscation, so censors see random packets instead of QUIC with a readable
server name. Every subscription format carries the setting automatically. - Entries have readable names — apps show "Reality · Chrome", "XHTTP ·
Firefox", "WebSocket · CDN", or "Hysteria2 · UDP" (plus the exit's name when
you have several, and "via relay" for relay entries) instead of internal IDs. - Every direct TLS method comes in two fingerprints — Reality and XHTTP
are offered with both a Chrome and a Firefox TLS fingerprint, so if
censors block one fingerprint, the other entry keeps working. Automatic
switching never mixes the two: Russian filtering reportedly stretches a
2-minute freeze to 10 minutes when a new fingerprint arrives during it.
Xray JSON apps get a separate "Automatic · Firefox" entry, Mihomo apps can
pick the copies by hand, and sing-box apps (which can't keep them out of
automatic switching) don't get them. - Russian sites work with the VPN on — Xray JSON and Mihomo subscriptions
send local-network,.ru/.su/.рф,geosite:category-ru, andgeoip:ru
traffic directly and refuse foreign QUIC, while the exit's block stays as a
safety net. Plain Base64 imports still need the app's own routing settings. - sing-box apps get a Meridian profile — sing-box-based apps (SFA, SFI,
Karing) pick the fastest working entry automatically, can still choose one
by hand, and send local-network and.ru/.su/.рфsites directly. Nothing
is downloaded at startup, so the app starts even when GitHub is blocked.
sing-box has no XHTTP, so those entries are left out.
Security and correctness
- Large uploads over XHTTP never hit nginx's body limit — nginx's 1 MB
default cut long uploads off on 3.x when a client chose a streaming XHTTP
mode. 4.0 serves packet-up only and now also lifts the limit. - Removing or moving an exit cleans up its certificate — the acme.sh
renewal, the certificate files, and (with the server's last certificate)
the port-80 challenge listener go, instead of renewing forever. - A relay with its own camouflage site really imitates it —
relay add --snigave clients the new name while the exit answered probes with its own
site's certificate (awww.google.comcertificate foryandex.ru), which
gives the relay away. Each relay name now gets its own Reality listener on
the exit, and anything else sent through the relay reaches that site. - Debian 12 deploys finish — fail2ban there found no SSH log file and
stopped right after starting, which failed server preparation; it now reads
the system journal on every supported release, and a package Debian only
remembers is no longer mistaken for an installed one. - Re-running a command resumes it —
relay addfor a relay that is already
declared finishes it instead of failing on a duplicate listener, and a bare
meridian testafter removing servers tests what is left instead of asking
which saved server to use. - Page branding is checked before anything changes — an unknown
--color
or an--iconthat is neither an emoji nor a reachable image stops deploy
with the valid choices; a redeploy that names only some branding flags keeps
the rest.client disable --jsonno longer claims the next apply re-enables
the client. - No request logging on Meridian's web server; panel secrets are never rotated
on restart; the live SSH port is never firewalled; teardown removes everything
Meridian created and nothing it didn't (your own HAProxy/Caddy are left alone). - A copy of
~/.meridianthat is out of date can't undo newer changes. The
control server records the last change applied, andapplyrefuses to run
from an older copy or while another machine is applying. - Mihomo-based apps (FlClash, Clash Verge, ClashMi) and sing-box routers
connect again. By default the Remnawave node's Xray rejects clients that
announce a version below 26.3.27, and those apps announce 1.8.x, so their
Reality connections failed with "authentication failed". Exits now accept any
client that speaks Reality. - Setup no longer opens an untagged
443/udpfirewall rule, and the next apply
removes the one earlier v4 builds left. Removing or moving a node also deletes
theremnawave/nodeimage and its node API firewall rule; Docker itself stays
installed. - Panel and connection-page links typed or copied without the trailing slash
now open; they used to redirect to an internal port and fail. - Subscriptions list Reality first, then XHTTP, WSS, and Hysteria2 last. Apps
use the first entry by default, and Hysteria2 (UDP, often blocked) used to
lead. sing-box and Stash no longer show a duplicate "automatic fallback"
server. - XHTTP links work. Apps sending the default
chromefingerprint speak
HTTP/2, and the server answered in HTTP/1.1, so no traffic passed. - A fresh deploy with Hysteria2 converges. The node started before its
certificate existed, so Xray refused to run and the deploy stopped. - Stock Debian 13 servers deploy and join as exits. The baseline treated a
missingufwas an unreadable check, waited for adnsutilspackage Debian
no longer ships, and WARP neededlsb_release. - Servers without apt (CentOS, Fedora, Alpine) are refused by name before
anything changes, instead of failing halfway at "apt-get: command not found";
meridian checkreports them as a failure rather than a warning. - Reality keys come from the panel instead of a Docker container or an
unverified Xray download on the exit, so a fresh exit withoutunzipor
Docker no longer fails at its Proxy profile. - Adding or removing an exit renames existing subscription entries instead of
leaving the old ones behind. Before, every entry appeared twice, and a stale
Firefox copy slipped into the automatic failover group. meridian checkandmeridian testare fail-closed: skipped evidence is never
reported as a pass.- Downloaded binaries (Xray, Realm, RealiTLScanner) are checksum-verified, and
every container image is pinned to its tested multi-arch digest (amd64 and
arm64), so a re-pushed tag cannot change what a fresh server runs. meridian updatestays on the current major version;--majormoves to the
next one after you have read its release notes.
Remnawave versions
Fresh deploys install the versions below. Meridian requires at least backend
3.4.0 and never downgrades a Remnawave you upgraded yourself; it warns when the
running version is newer than the tested one. meridian fleet upgrade moves
the backend, node, and subscription page to their newest digest-pinned
release in the same major without a Meridian update (--tested keeps the
versions below), and the choice is saved for later applies.
| Component | Version |
|---|---|
remnawave/backend
| 3.4.5 (minimum 3.4.0)
|
remnawave/node
| 3.4.2
|
remnawave/subscription-page
| 8.0.0
|
postgres (panel database)
| 17.11-alpine
|
valkey/valkey (panel cache)
| 9.1.2-alpine
|
| Xray-core (test client) | 26.7.28
|
| Realm (relay forwarder) | 2.9.3
|
RealiTLScanner (meridian scan)
| 0.2.3
|
Not yet available
meridian studio(local web UI) is experimental and needspip install 'meridian-vpn[studio]'.
A running deploy can be cancelled; it stops after its current step and resumes on the next run.
Removed
- 3x-ui, HAProxy and Caddy support; per-server
proxy.ymlcredentials. meridian fleet recover,apply --parallel/--prune-extras, and the
desired_*lists incluster.yml.