English · Русский · Technical (EN) · Техническое (RU)
1.8.10-beta
What's new in 1.8.10-beta — full changelog
- Fixes for what 1.8.9 met on its first day. The panel no longer stays blank behind an ad or tracker blocker (uBlock Origin, AdGuard, Brave), a Docker update no longer asks to re-run the installer for an optional setting nobody set, and the csqtt 2.5 server no longer logs a web-panel password it never uses (2.5 servers move to 2.5.1-2 and restart once).
- The subscription page names the csqtt version. Each csqtt card says CSQTT 2.1 or CSQTT 2.5, and its download names the app's version.
- A server that doesn't update to releases says so. A server installed or last updated from a branch other than main shows "from dev" beside its version, with the way back to releases; the panel's header does the same for its own server.
Easy-to-use self-hosted WireGuard & AmneziaWG control panel with TURN-PROXY support. Deploy your own VPN in minutes.
swgPanel is a control panel for running your own WireGuard / AmneziaWG VPN across one or more servers. You add your users in the browser, hand them a QR code, and they’re connected. Everything — who has access, which servers they use, how much they’re using — lives on one dashboard that you host yourself.
Run it for yourself, your household, your team, or a whole community — a fast private VPN with no monthly subscription and no one else sitting in the middle of your traffic.
This is a complete, plain-language guide — enough to install swgPanel and use it even if you’re not technical. If you are technical and want the internals — architecture, every flag, the API, security — read the Technical guide.
Click any tile to enlarge · more screenshots throughout this guide
- What it does
- Before you begin
- The three roles (in plain words)
- Step 1 — Install the panel
- Step 2 — Add your servers
- Step 3 — Add users and hand out access
- Subscriptions & access control
- Who can reach a device
- Using it day to day
- Keeping it running
- A few things worth knowing
- Learn more
- Special thanks
- One page to run everything. Add servers, add users, hand out access — all from the web panel.
- Access in a QR code. Create a person, show them the QR, they scan it in the WireGuard/AmneziaWG app — no fiddly config files to email around.
- Subscriptions — one private link per user. Instead of a one-off QR, each person gets their own swgSub page: a phone-friendly link with the config and QR for every server they're on — WireGuard, AmneziaWG, and TURN-PROXY forks like WINGS-N, hack-diaz, anton48 and others — plus protocol/relay badges, light/dark mode, and one-tap copy / download / share. The unlock key rides in the link's
#fragment, so the server stores only ciphertext and never sees anyone's private keys. How to set them up ↓ - Suspend access in one click. Block a person — or just one of their devices — instantly, without deleting them. Their tunnels stop and their subscription page goes dark; unblock to restore with the same keys, nothing to re-issue.
- See what’s happening, live. Who’s online, how much they’re downloading, which servers are busy — updated every few seconds.
- Single or multiple servers. Put servers in different countries; a person can fail over between them.
- Panel here or apart. Run the panel on the same server as a VPN node, or on a separate box that only manages your nodes — either works.
- Hard to block. Uses AmneziaWG (a stealthier WireGuard) and can route traffic cleverly by destination, so it keeps working where plain VPNs get blocked.
- AmneziaWG 3.1 when you want it. Each AmneziaWG interface runs 2.0, which every AmneziaWG app understands, or 3.1, which adds header protection and random trailers. Pick it when you create the interface and switch either way later: the panel first shows who the switch cuts off until they re-import, network gateways first, and refuses while a WINGS-N turn proxy points there. A 3.1 interface wears a blue badge. Which apps connect ↓
- Leave an AmneziaWG field out, and pick the mesh's protocol. Type
-in any AmneziaWG cell — an interface's or the defaults' — and that line is not written at all (a blank cell stays automatic); the servers need this update to hold one. Links between your servers are AmneziaWG 2.0 by default, or 3.1 or plain WireGuard, for the whole fleet or for one link; a pair where one server cannot run 3.1 is linked at 2.0, and its server says why. - Disguise the handshake. On an AmneziaWG interface, Edit interface → Advanced settings has Disguise as: Off, a QUIC (HTTP/3) packet or a DNS query, drawn fresh each time you pick one, sent before every handshake in place of the built-in set every install uses by default (one pick brings it back). Devices keep working when you change it — each side sends its own — and pick up the new disguise when they next re-import. The panel shows the size and monthly cost of what it sends, and refuses a line some app could not read.
- Filter out the junk. Block ads, trackers, malware, adult content, gambling and more — per server, from curated category lists — and watch a live Protection panel show what's being caught, per category, plus which user is behind the torrents and port-scans it flags.
- Turn-proxies built in. Integrates with the leading vk-turn-proxy relay servers and their client apps — wrap traffic through VK TURN relays to slip past even the toughest blocks, all from the panel.
- WDTT servers. A whole VPN server that hides inside a VK-video-call-shaped stream. Where a turn-proxy fronts a tunnel you already have, a WDTT server is the tunnel — create it like any other interface, pick one of four forks, and hand people a password instead of a key. Its config lands on their subscription page next to everything else, app download included.
- csqtt servers too. The same idea on a newer, faster datapath — create it like any other interface and hand out a password. Each server runs csqtt 2.1 or 2.5 (switchable, keeping its users); a 2.5 server can tell every user's app which apps, domains and addresses skip the tunnel. Note that csqtt is free for personal use only; running one commercially needs a licence from its author (details).
- Bring what you already have. Already running WireGuard, AmneziaWG, WDTT or csqtt on a box by hand? The panel finds those servers and offers to adopt them — keys, port, subnet and existing users intact, nothing to re-issue and no downtime.
- You’re in control. It’s self-hosted, stores no passwords or keys it doesn’t need, and never phones home.
📸 More screenshots — click to expand
Subscription pages — each user's private swgSub link, with config + QR for every server (WireGuard, AmneziaWG, and TURN-PROXY forks):
You need one server to run the panel on — a cheap VPS (virtual server) from any hosting provider is plenty. It should have:
- A public IP address (so your users can reach it).
- A recent Linux (Ubuntu/Debian and most others are fine).
- NixOS is fully supported too — panel, node, or both. It does not take the command below; there
you declare swgPanel in your
configuration.nixinstead. See the NixOS guide.
- NixOS is fully supported too — panel, node, or both. It does not take the command below; there
you declare swgPanel in your
sudo/root access, and a way to paste a command into it (SSH).
That’s it. If you want a domain name (like vpn.example.com) you can point it at the server first — the
installer will get a real HTTPS certificate for it automatically. No domain? It still works — and if the
server has a public IP, the installer can get a real certificate for the bare IP as well.
You can add more servers later — each extra server is one more command, run the same way.
Every server you set up plays one of three roles. You don’t have to memorise these — the installer asks you in plain language — but it helps to know the words:
- Host — just the control panel. The web page and the brains. It doesn’t carry any VPN traffic itself.
- Master — the control panel and a VPN server on the same box. Simplest for a one-server setup: one command gives you the panel and your first VPN server together.
- Node — just a VPN server. An extra server that carries traffic and reports back to your panel.
And there are two ways to install any of them — pick whichever you like:
- Bare-metal — installs straight onto the server (a little faster).
- Docker — runs in containers (tidy, easy to move around).
You can mix freely: a Docker panel with bare-metal servers, and so on.
Copy the command onto your server and run it. It asks you a few simple questions and sets everything up, including HTTPS.
sudo bash -c "$(curl -fsSL https://raw.githubusercontent.com/SanityProtocol/swg-panel/main/bootstrap.sh)"Already
root? Many fresh Debian/VPS images log you in as root with nosudoinstalled — just drop the leadingsudoand runbash -c "$(curl …)" …. (The same applies to every command below.)
Why not
curl … | sudo bash? On Ubuntu 26.04sudois sudo-rs, which runs a piped script in the background of your terminal — the installer then freezes at its first question. Handing the script tobash -c, as above, works with everysudo.
On NixOS? This command refuses to run, on purpose — it would write into
/opt, whichnixos-rebuildneither manages nor sees, and leave you an install your own configuration cannot update or remove. Import this repo's flake and declareservices.swg-panelinstead: NixOS guide.
The first question is how to run it — bare-metal (directly on the host, best throughput) or Docker (in containers). The second is the role: choose Master to make this box your panel and your first VPN server in one go (recommended if you only have one server), or Host for just the panel. It then asks for your domain and a password, and when it finishes prints your panel’s web address and login — open it and sign in.
Want the details on bare-metal vs Docker, or to run
docker composeyourself? See the Technical guide.
If you chose Master above, you already have your first VPN server — you can skip to Step 3. To add more servers (called nodes), do this for each one:
-
In the panel, open Nodes → Add node. It shows you a ready-to-paste command with a key already filled in — one for bare-metal, one for Docker. They look like this.
For a bare-metal server:
sudo bash -c "$(curl -fsSL https://raw.githubusercontent.com/SanityProtocol/swg-panel/main/bootstrap.sh)" -- nodeFor a Docker server:
sudo bash -c "$(curl -fsSL https://raw.githubusercontent.com/SanityProtocol/swg-panel/main/bootstrap.sh)" -- docker node -
Run that command on the new server. It asks for your panel’s address and the key (both pre-filled if you copied the panel’s command), then connects itself back to the panel. It doesn’t ask you to configure any VPN — you do that in the panel, where you can see what you’re doing.
If that server was already running WireGuard, AmneziaWG, WDTT or csqtt, those show up on its page in the panel as cards offering Adopt or Ignore — or Take over, when something is still running it. Either way the server is taken over exactly as it is — same keys, same port, same users — so everyone’s existing configs keep working and nothing goes down. That includes a server run by the AmneziaVPN app in its own Docker container. The panel can see it even though it lives in a separate network namespace, shows you its subnet, port and users first, and Take over stands the same server up natively — same key, same port, same obfuscation — so the configs already on your users’ phones keep working. Its users come across with the names you gave them in Amnezia. That container is only stopped, never deleted: start it again to go back.
The same goes for a WDTT or csqtt server installed in Docker — every fork ships that option. The panel reads such a server’s settings from inside its container, so a machine that also ran one directly on the box (both sitting at the same default path) can’t have the two mixed up. Taking one over copies its identity and its users from the container and stops the container, not just the program inside it: one set to restart would otherwise come straight back and fight the new server for the port.
The new server reaches out to the panel on its own — you never have to open special access to it, no inbound ports, no SSH keys shared around. Within a few seconds it shows up in your Nodes list.
- Go to Peers → New peer, give it a name (e.g. a person or a device), and pick which server(s) it may use.
- The panel shows a QR code and a config file. The person opens the WireGuard or AmneziaWG app on their phone/computer, scans the QR (or imports the file), and they’re online.
- Using a turn-proxy on that server? Getting its config is just as easy — the panel shows the proxy’s address and a wrap key to drop into the vk-turn-proxy client app, right alongside the QR.
- On a WDTT or csqtt server there’s no key to scan: the person gets a link that opens straight in the matching app (or a QR, for the apps that scan one), and the panel points them at the right app for their phone or computer.
That’s the whole flow. The secret half of their key is created in your browser and shown once — so save/hand over the config there and then. Need to give the same person a second device? Just make another peer.
Rather than sending someone a QR every time, give each person one private link. It opens a phone-friendly page with the config and QR for every server they're on, and it keeps itself up to date — put them on another server and it simply appears there. Here's one: WireGuard · AmneziaWG · WINGS-N.
Turn it on (once, for the whole panel):
- Settings → Client configs — set your encryption key. Subscription pages are built from encrypted configs, so this comes first.
- Settings → Subscriptions → On. Switch on Auto-generate subscription links for new users if you'd like every new person to get one without you asking.
- Settings → Panel access — set the address the page is served on. If the panel tells you the subscription server isn't installed, re-run the install command from Step 1 — that adds the missing piece and keeps everything you already have.
Give someone their link. Open them under Users, press Enable subscription, and copy the link. Send it however you like — but treat it like a password: whoever holds it holds that person's configs.
Taking access away. Three controls that look alike and aren't:
- Block is the one that actually cuts access — on a person, or on a single device. Their tunnels stop within seconds and their page goes dark. Unblock puts it all back with the same keys, so there's nothing to re-issue and nothing for them to re-scan.
- Disable URL only switches off the link. Anyone already connected stays connected. It's for a link that has gone somewhere it shouldn't — not for cutting someone off.
- Rotate token hands them a fresh link and kills the old one, without interrupting their access.
You can also give a subscription an expiry date, and the panel warns you a few days before it runs out.
Every device on a server has an address inside the tunnel, and without a rule any other device on that server could open connections to it — its shared folders, printer, remote desktop. Each interface has a setting for that, Who can open connections to devices here, with three levels:
| Level | Who can open a connection to a device on this interface |
|---|---|
| Everyone on this node | any device on the same server |
| Same user and their groups (default) | the owner's other devices, and the devices of people who share a group with the owner |
| Nobody | no other device — the device's own connections still work |
- The default protects. An interface nobody has set is at Same user and their groups — including every interface that existed before this setting, so after the upgrade strangers' devices stop reaching each other. Settings → Interfaces holds the level new interfaces start with; changing it never touches an existing interface, and the same place lists the interfaces set to Everyone on this node.
- Groups. Put people who should reach each other — a family, a team — in a group under Users → Groups. A group only matters on interfaces set to Same user and their groups.
- You can see what it stopped. An interface's settings show how many packets to its devices were stopped, and the Nodes screen tells you while anything was.
Its limits:
- It never affects internet access, or the networks behind a device — those have their own "who can reach them" setting.
- A device at Same user and their groups or Nobody is never reached from another server, not even by its owner's device there.
- A WDTT or csqtt server whose build can't prove which user a device belongs to (today: csqtt before 2.1.9-2, xxcipherx before 2.0.0.72, ildarmaga before 1.5.0-3, qWDTT's RAW connections before 1.4.3-2, and ildarmaga's RAW connections on every build) treats Same user and their groups as Nobody, and its settings say so.
- The server's own LAN machines and containers can open connections only to devices at Everyone on this node.
- A proxy running on the server itself connects as the server, so the level does not apply to it.
- IPv6 addresses added to a config by hand are not covered: any device on the server reaches them over IPv6.
- With flow offloading on the server, a connection already open when a level tightens keeps working until it has been idle for the offload timeout (30 s by default); new connections are refused at once.
- The level relies on connection tracking: a host firewall rule that turns it off (NOTRACK) for client traffic breaks the replies to a protected device's own connections.
- A server running an older version doesn't enforce it: the interface shows not enforced until you update that server.
- Nothing is kept across a restart: after a server reboots, its devices can reach each other until it next hears from the panel — seconds normally, the whole outage if the panel is unreachable.
- Going back to a version without this setting on a Docker or NixOS server leaves the last rules in force
until the server reboots or you run
nft delete table inet swg_reachon it. A bare-metal server removes them itself.
- Watch the dashboard. The Overview page shows who’s online, the busiest servers, and where traffic is going — live, or over the last hour, day, week, month, or any days you pick from the last 33 (Custom on the side rail). Its top talkers are counted exactly, the same way as the Peers and Users pages.
- Add or remove users anytime. Changes reach your servers within seconds. Remove someone and their access stops on the next check-in.
- Change the panel’s login under Settings → Authentication — it takes effect immediately. While you’re there, switch on two-factor authentication (Google Authenticator) for stronger sign-in security.
- Count days in your own time zone. Servers usually run on UTC, so the panel’s day would end at 03:00 in Moscow. Pick your zone under Settings → Display → Days are counted in: traffic totals, the charts and the turn-proxy update hour follow it. The charts draw what they recorded before the change shifted by the difference until it scrolls out of them (up to 33 days).
- See how much each person used — for any stretch of days. The Peers and Users pages (users and groups) count every device’s traffic through counter restarts and reinstalls, for All time, a Day, Week or Month, or any dates you pick from the menu on the right edge; a user’s or a group’s graph icon opens their graph with every device (or member) behind it, including devices deleted or handed to someone else. A person’s total adds up their devices, so traffic between two of their own devices (for example to a home network shared through the VPN) counts on both. History is kept for ever by default — Settings → Display → Data shows how much disk it uses, and can keep the hour-by-hour detail for the last 33 days only; totals for any period are always kept.
- Route certain sites through a certain country (optional). For example, send streaming out through a server abroad and keep everything else local. Set it per server under Settings → Routing & Blocking. A rule can also apply to chosen people only: open its settings (the sliders button before its destination) and choose people, groups or single devices. The same window is where a rule that forwards to another server picks which of that server's addresses the traffic leaves it by — useful when a server has several and a site expects one of them. For a Direct rule it picks this server's own address — one for the whole interface. A server's own default can be a rule list too — Settings → Network → Default exit → Routing (smart cascade): one list for its interfaces set to Auto and for the traffic other servers send out through it, and each rule can narrow itself to this node's own clients or to traffic cascaded in. A Forward to node rule there sends traffic cascaded in one hop further — to a server the first one can't reach — and that server lets it out and never forwards it again.
- Get past tougher blocks (optional). If plain VPN traffic is blocked on a network, swgPanel can wrap it through a turn-proxy — set up under a server’s details and in Settings → Turn proxies.
- Feed other tools (optional). The panel can share live status with dashboards like Grafana or Uptime Kuma, and ping a webhook when a server goes offline — Settings → Integrations.
Everything below is one command, run on the server, the same way you installed. Each one asks before it does anything and keeps your data safe.
Run this on any server (panel or VPN server) — it figures out what’s installed and updates it in place, keeping all your settings and users:
sudo bash -c "$(curl -fsSL https://raw.githubusercontent.com/SanityProtocol/swg-panel/main/bootstrap.sh)" -- updateComing from 1.8.6? A plain-WireGuard interface you restored under 1.8.6 came back as AmneziaWG. 1.8.7 restores the right kind, but it can't tell such an interface from one that really is AmneziaWG, so it stays that way: its users need the AmneziaWG app with the config the panel shows now — or delete the interface and create it again as WireGuard.
Going back to an older version? From 1.8.9, on a bare-metal server, two things stay: swg's services go on
logging into the journals 1.8.9 gave them (an older version's journalctl -u … shows only systemd's lines; swg-logs
still reads them), and 1.8.9's torrent guard stays in force with its last policy, whatever the older version's card
says. A reboot ends the guard; once the older version runs, this ends both now:
sudo rm -f /etc/systemd/system/*.service.d/swg-ns.conf && sudo systemctl daemon-reload
sudo systemctl try-restart 'swg-*.service' # back to the system journal (a reboot moves them too)
sudo nft delete table inet swg_p2p; sudo ip rule del pref 6880 2>/dev/null # the torrent guardA Docker server keeps the guard too (the same nft / ip rule line), and one started on an image older than 1.8.7
keeps two more firewall tables that version can't manage, which go on refusing connections the panel has since allowed.
Remove them on that server (a reboot clears them too):
sudo nft delete table inet swg_reach; sudo nft delete table inet swg_shareOn NixOS there is a little more — see Going back to an older build. A server's own mesh AWG params are kept on its links since 1.8.9: an older panel shows none on the server's card, and a link it rebuilds gets the fleet's default. Each release's notes in the changelog say what else going back from it takes.
- Automatic. Every time something changes — you add a person, add a server, change a setting — the panel writes a timestamped backup of that file right next to it, and keeps the last several. If a file ever gets damaged (a bad shutdown, a full disk), the panel quietly restores the newest good backup on its own the next time it starts. You don’t have to do anything.
- Manual (recommended anyway). For an off-server copy, save the panel’s state folder
(
/var/lib/swg-panel, which holds your users and servers) somewhere safe — a copy is all it takes to rebuild the panel elsewhere.
- Re-running any installer is safe. It notices there’s already an install and keeps your data (login, certificate, users, servers) — handy if a command got interrupted, or to change an option.
- Rebuilding a VPN server? Run the recovery helper on it and it finds the server’s leftover identity so
it rejoins your panel without re-enrolling:
sudo bash -c "$(curl -fsSL https://raw.githubusercontent.com/SanityProtocol/swg-panel/main/bootstrap.sh)" -- recovery - Server box gone for good? When the old machine is truly lost — nothing left to recover from — the panel can rebuild the node onto fresh hardware from the identity it holds: the same public keys, so every config and QR already handed out keeps working. It shows exactly what the rebuild will change before the token rotates. Open the node in the panel and rebuild it.
- Lost the whole panel box? Put your saved
/var/lib/swg-panelfolder back on a fresh install and your users and servers are there again; the servers reconnect on their own.
Changed your mind about how a server is installed? You can convert it in place, keeping everything. Just re-run the installer asking for the other method — it offers convert · keep · abort.
To move a server to bare-metal:
sudo bash -c "$(curl -fsSL https://raw.githubusercontent.com/SanityProtocol/swg-panel/main/bootstrap.sh)" -- masterTo move it to Docker:
sudo bash -c "$(curl -fsSL https://raw.githubusercontent.com/SanityProtocol/swg-panel/main/bootstrap.sh)" -- docker masterIt stages the new version fully before removing the old one, so the switch takes only a few seconds and your users barely notice. (A “master” box can convert as a whole, or just its panel half or just its server half.)
Removes swgPanel, asking about each piece first (the panel, a VPN server, the VPN software, any turn-proxies) — nothing goes without a yes, and you can keep your users/servers data for a future reinstall:
sudo bash -c "$(curl -fsSL https://raw.githubusercontent.com/SanityProtocol/swg-panel/main/bootstrap.sh)" -- uninstall- You decide how private it is. A person’s keys are always created in your browser. By default, the panel keeps each config encrypted, locked with an encryption key that only you hold — so you can re-show a QR code any time you’re signed in, while the server itself can never read anyone’s secret key. You set that key up once, under Settings → Client configs. Want nothing kept at all? Switch the same setting to off and the panel keeps only the public parts (public key, address, preshared key); the secret key is then shown once and never stored anywhere.
- Your control panel can be kept off the internet entirely. By default your servers and your browser arrive through the same door. Under Settings → Panel access you can switch the panel's pages to your server only, reached over an SSH tunnel — and the address your servers use then answers only what a server asks for and nothing else. Your servers don't notice. Neither can it lock you out: both addresses keep working until you open the new one and confirm it, and everything goes back on its own if you don't.
- A hiccup won’t lock anyone out. If the panel is briefly unreachable, your servers keep running with the access they already have and catch up on the next check-in.
- Force-DNS sees encrypted DNS; it doesn’t stop it. In the Force-DNS routing mode a server answers its users’ ordinary DNS and routes by the site names it sees. A device that uses its own encrypted DNS (DoH, DoT or DoQ) is marked instead of cut off: its rules by site name don’t match, its rules by IP still do. To stop encrypted DNS, turn on the interface’s DoH / DoT / DoQ block.
- AmneziaWG 3.1 needs a 3.1 app. These connect: Amnezia VPN 5.0.1.5 or newer, AmneziaWG on iPhone
and Mac (App Store), on Android (the GitHub release — the Google Play build is still 2.0) and on Windows,
WG Tunnel 5.6 or newer, FreeTurn 4.3. These cannot: the Google Play AmneziaWG, WINGS V, Keenetic and
MikroTik routers — and Amnezia VPN 5.0.0.5 or older imports a 3.1 config without complaint and never
connects. The server needs 3.1 too (its AmneziaWG kernel module, or
amneziawg-gowhere there is none, and itsawgtools); on one that isn't, the switch is greyed out and says which part. The cost, measured: +1–2 % CPU at the rates a VPS carries; a server that is already CPU-bound loses 7–20 % of its throughput ceiling to the header masks, and no setting takes that back. - Blocking by site name, per mode. Hybrid SNI and Kernel SNI refuse each connection to a blocked name and
never block another site on its address. Force-DNS blocks by the address a name resolves to, so a blocked site
that shares its address with an allowed one stays reachable. Domain block lists (ads, malware) run on Force-DNS
and Hybrid SNI only — on Kernel SNI they are too long for an in-kernel scan. A Kernel SNI site rule matches the site
and its subdomains, and can also catch a longer name that carries it inside (
example.com.evil.net). No mode sees a name hidden by ECH, or a request sent inside a connection already open to another site on the same server. - A rule for chosen people covers the devices a server can tell apart. Their WireGuard and AmneziaWG devices
always; WDTT and csqtt devices only where the server's build can prove which user is sending — the same builds as
in Who can reach a device — and the rule's row says how many devices it doesn't cover. A server running an
older version applies such rules to nobody until you update it, and its card says so. They match site names in
every mode that does, Kernel SNI included — except on a server whose kernel can't tie an address to its device:
there they match by IP address and network only, and the rule's list says so. On Kernel SNI, an address or
network Block rule that overlaps a site-name rule blocks those sites whatever order the two rules are in, for
everyone as for chosen people: the site name is checked after the address. Going back to an
older panel and saving an interface there drops the chosen people from its rules for good. Going back to an
older version on a server that ran these rules — or, on Hybrid SNI or Kernel SNI, a Block rule below an
Exit or Direct rule — run
nft delete table inet swg_smarton it once: it rebuilds its routing within a minute. - The address is one per interface and server. Every rule that sends one interface through that server leaves by it — it's a property of the pair, not of a single rule, which is why it shows on all of them. The far server needs no update: even an older one applies it. An older panel ignores it while it runs — the rules keep forwarding to the right server and that server picks the address itself — and it starts applying again when you upgrade. If a server stops reporting an address something is pinned to, the rule says so: traffic would leave with a source that server can't receive replies on.
- A server's routing list applies to traffic cascaded in once that server is updated. Until then it sends
all of it out the list's Everything else as a plain default — or out its own address when that is Direct or
Block — and its card says so. Traffic an interface pins to one of that server's addresses skips the list, as it
skips a plain default. An interface whose own Everything else is left on Node default goes through the
server's list after its own rules; on Hybrid SNI and Force-DNS a more specific site in the server's list
wins over the interface's broader one, and the interface's rule says so. Once the list has a rule for this
server's own clients, its interfaces set to Auto are routed by it the way a smart interface is: their IPv6 is
dropped, and on Hybrid SNI or Kernel SNI they lose HTTP/3 too. A list with only Everything else changes
nothing for them. Clients cascaded into a Hybrid SNI
or Kernel SNI server lose HTTP/3, as on a smart interface. Their traffic is counted on the dashboard of the
server they connected to. Going back to an older version on a server that ran such a list: run
nft delete table inet swg_smarton it once (and on Kernel SNI alsoipset destroy swga). - An onward hop hides the clients from the last server. Traffic a server's list forwards one hop further reaches that server as coming from the middle server, so abuse is traced through the middle server's connections. A server behind heavy filtering that cascades everything to a neighbour shows its own links abroad as down under Full mesh; switch the fleet to On demand, which never creates them.
- A default exit now also catches routed traffic. Traffic another server sends through this one by a routing rule now leaves by this server's default exit, as whole-interface forwarding always did — with the exit's kill-switch on, it now stops when the exit is down instead of leaving by the server's own address.
- Two servers can't share a subnet across a cascade. An interface's traffic is never sent to a server that uses an overlapping subnet itself, or that another server already sends one — the installers' 10.8.0.0/24 and 10.9.0.0/24, or a server added from another panel — because its replies couldn't be told apart. Rules toward that server are skipped for the interface, a forward to it is off (its traffic leaves by this server's own address), and the sending server's card names both sides; give one of them a different subnet.
- It’s early. This is a Beta — great for tinkering and small setups, not yet for anything critical.
- Technical guide — architecture, every install option and flag, Docker by hand, converting, smart routing, backups & security, and troubleshooting.
- External API — the read-only REST surface, Prometheus metrics and webhooks.
- NixOS — the flake, both delivery methods, and moving a server you already run onto it.
- For LLM agents — the unattended contract: the environment variable for every prompt, health probes that need no credentials, and the handful of things an agent must never touch.
- Русский · Техническое (RU)
swgPanel integrates several excellent open-source projects — huge thanks to their authors. Licences, pinned commits and source for everything we build or bundle: THIRD-PARTY.md. Note that csqtt is noncommercial-only — commercial use needs a separate licence from its author.
Turn-proxy forks — wrap WireGuard/AmneziaWG through VK TURN relays to get past tough blocks:
- WINGS-N — ❤️
- hack-diaz (formerly samosvalishe — proxies installed from samosvalishe keep running, and now update from its new repository, hackdiaz-dev/free-turn-proxy)
- anton48
WDTT — the self-contained, key-owning VPN server the panel runs as an interface, and the apps people connect with:
- amurcanov — the original, and csqtt, its successor
- luminescq
- Endlad2
- ildarmaga
- Ivan4537
- SpaceNeuroX
- lebrit
Routing / geo-data lists — the domain & IP lists behind smart routing:
Content filters / block lists — the ad, tracker, malware & threat-IP feeds behind content filtering:





















