[{"data":1,"prerenderedAt":214},["ShallowReactive",2],{"seo-verification":3,"blog-netbird-self-hosted-wireguard-mesh-vpn-on-a-vps-ma-en":6,"promo-bar-likely":213},{"google":4,"bing":5},"EycwPY2XMyTkVzas3n1ygeNJFGAH513qrMjfDljzsMQ","",{"key":7,"data":8},"blog-netbird-self-hosted-wireguard-mesh-vpn-on-a-vps-ma-en",{"id":9,"slug":10,"slugs":11,"title":15,"excerpt":16,"readTime":17,"views":18,"isPinned":19,"noindex":19,"publishedAt":20,"updatedAt":21,"category":22,"categories":27,"featuredImage":29,"bgImage":30,"posterImage":31,"relatedSolution":29,"intro":32,"sections":33,"ctaTitle":148,"ctaBody":149,"ctaButton":150,"ctaUrl":151,"relatedPosts":152},291,"netbird-self-hosted-wireguard-mesh-vpn-on-a-vps",{"fr":12,"en":10,"ar":13,"es":14},"deployer-netbird-controle-vpn-mesh-vps","netbird-شبكة-vpn-مشبكة-wireguard-باستضافة-ذاتية","desplegar-netbird-vpn-mesh-wireguard-en-vps","Netbird: Self-Hosted WireGuard Mesh VPN on a VPS","Link client VPSs without opening a port: deploy the Netbird control plane (combined server, relay, web UI) and isolate each client.",18,4,false,"2026-08-21T00:00:00+00:00","2026-11-09T20:55:15+00:00",{"id":23,"name":24,"slug":25,"color":26,"icon":25},3,"Deployment","deploiement","bg-success\u002F10 text-success",[28],{"id":23,"name":24,"slug":25,"color":26,"icon":25},null,"\u002Fblog\u002Fcovers\u002Fbg.svg","\u002Fblog\u002Fcovers\u002Fdeployer-netbird-controle-vpn-mesh-vps-poster.svg","You manage servers spread across several client accounts and end up opening ports, maintaining separate UFW rules or distributing static WireGuard keys by hand. Headscale addresses the same need for a flat network — we covered it in \u003Ca href=\"\u002Fen\u002Fblog\u002Fself-host-headscale-on-a-vps-your-own-tailscale-control-server\">a dedicated guide\u003C\u002Fa>. Netbird is another answer, designed for managing several isolated networks: peer groups, per-network access rules and a built-in web interface. This guide deploys the Netbird control plane (more than 30,000 GitHub stars, AGPLv3 on the server side) on a dedicated VPS, connects three nodes in a mesh without opening a single public port, then covers per-client isolation, publishing a service with `netbird expose`, and troubleshooting.",[34,38,41,44,69,72,75,78,112,115,119,122,125,134,137,145],{"type":35,"title":36,"body":37},"h2","Static WireGuard, Headscale, Netbird: three different approaches","Static WireGuard (see \u003Ca href=\"\u002Fen\u002Fblog\u002Fwireguard-on-a-vps-a-fast-lean-and-private-vpn\">our WireGuard guide\u003C\u002Fa>) relies on a fixed configuration: each peer must know the public key and reachable address of its counterparts, and every new peer means editing `\u002Fetc\u002Fwireguard\u002Fwg0.conf` on the others. Effective for two or three fixed servers. Unmanageable once an agency fleet mixes VPSs, roaming laptops and offices behind CGNAT: adding a machine means touching all the others; removing a technician means revoking their key everywhere.\n\nHeadscale reimplements the Tailscale coordination server: you keep the official Tailscale clients and get a flat network with no user cap. Isolation between clients goes through a single ACL policy file for the whole network. It is the right choice for a single team that wants to stay in the Tailscale ecosystem.\n\nNetbird takes the opposite route: it brings its own client, its own control plane and a notion of **groups** linked by granular access rules, managed from the web interface included out of the box. A single instance can host several fully partitioned fleets, which makes it the natural tool for an agency managing separate clients.",{"type":35,"title":39,"body":40},"Netbird architecture: one combined server","The current installation script no longer deploys four separate containers. It generates a Docker Compose stack of three services:\n\n**`netbird-server`** — the combined server. A single container brings together **Management** (WireGuard key distribution, access rule enforcement, REST API), **Signal** (exchange of ICE connection descriptors between peers), the **Relay** and an embedded **STUN** server. It is configured by a single `config.yaml`, which replaces the former `management.json` and `relay.env`. SQLite storage by default, PostgreSQL as an option.\n\n**`netbird-dashboard`** — the web interface that consumes the Management API: groups, peers, access rules, enrollment keys, no command line needed.\n\n**`netbird-traefik`** — the reverse proxy that terminates TLS (automatic Let's Encrypt certificate) and routes gRPC, WebSocket and API traffic to the server.\n\nTwo changes matter compared with older tutorials. The relay is no longer COTURN: since v0.29, Netbird uses its own implementation, which carries relayed connections over port 443 (WebSocket over TCP, or QUIC over UDP) instead of allocating a range of UDP ports. And authentication is built in: since v0.62, an embedded identity provider (based on Dex) manages local users, with no Zitadel or Keycloak to deploy. A fifth service, the **Netbird proxy**, is added if you enable it to publish services on the internet (see below).\n\nAll traffic between clients travels over **end-to-end encrypted WireGuard**: the server only sees enrollment metadata, never application traffic. On licensing, the client is under BSD-3-Clause; the `management\u002F`, `signal\u002F`, `relay\u002F` and `combined\u002F` directories of the repository are under AGPLv3.",{"type":35,"title":42,"body":43},"Prerequisites","**A VPS dedicated to the control plane.** Plan a VPS separate from your client nodes. The Netbird documentation asks for at least 1 vCPU and 2 GB of RAM; a VPS Solo is fine to start with.\n\n**Ports to open on the control VPS:**\n\n`80` (TCP) — Let's Encrypt validation and redirect to HTTPS.\n`443` (TCP) — Dashboard, Management API and gRPC, Signal, Relay over WebSocket.\n`3478` (UDP) — STUN embedded in the server.\n\nThe UDP range `49152-65535` is no longer needed: it only served the COTURN relay of versions before v0.29, and stays open only if old clients still depend on it. Client nodes have **no inbound port to open**: the Netbird client makes outbound connections to the control plane.\n\n**Software required on the control VPS:** Docker with the Compose plugin, `jq` and `curl`, and a domain name whose A record points to the VPS IP (`netbird.yourdomain.com`). If you enable the Netbird proxy, add a `*.netbird` CNAME to that same name. Behind Cloudflare, the Netbird documentation sets both records to DNS only.\n\n**On each client node:** the `netbird` client (Debian\u002FRPM package or static binary), root or sudo access.",{"type":45,"title":46,"steps":47},"steps","Deploy the control plane and connect three nodes",[48,51,54,57,60,63,66],{"title":49,"body":50},"Run the installation script","On the control VPS, download the official script and run it:\n\n```bash\ncurl -fsSL https:\u002F\u002Fgithub.com\u002Fnetbirdio\u002Fnetbird\u002Freleases\u002Flatest\u002Fdownload\u002Fgetting-started.sh | bash\n```\n\nThe script asks for your domain (`netbird.yourdomain.com`), then for the reverse proxy to use: keep option `[0]` (built-in Traefik, automatic TLS). It then offers to enable the Netbird proxy, which you can also add later. It generates `docker-compose.yml`, `config.yaml` and `dashboard.env` (plus `proxy.env` if the proxy is enabled), then starts the stack. For an unattended install (cloud-init, CI), export `NETBIRD_DOMAIN`, `NETBIRD_LETSENCRYPT_EMAIL` and `NETBIRD_NON_INTERACTIVE=true` beforehand.",{"title":52,"body":53},"Check that the services respond","From the installation directory, confirm the containers are up:\n\n```bash\ndocker compose ps\n```\n\nYou should see `netbird-traefik`, `netbird-dashboard` and `netbird-server` in the `running` state (plus the proxy if enabled). When in doubt, most configuration errors show up in the server log:\n\n```bash\ndocker compose logs -f netbird-server\n```",{"title":55,"body":56},"Create the admin account and a Setup Key","Open `https:\u002F\u002Fnetbird.yourdomain.com` in a browser. The script deploys Netbird **without any user**: you are redirected to the `\u002Fsetup` page, where you create the administrator account (email, name, password). This page is only available while no user exists.\n\nIn the **Setup Keys** menu, click **Create Setup Key**. Give it a name (`vps-client-a`), choose the `Reusable` type (to enroll several machines with the same key) and an expiry period. Copy the key: you will need it on each node.",{"title":58,"body":59},"Enroll node 1","On the first client VPS, install the Netbird client:\n\n```bash\ncurl -fsSL https:\u002F\u002Fpkgs.netbird.io\u002Finstall.sh | sh\n```\n\nThen connect it to the control plane by pointing at your instance (without `--management-url`, the client targets Netbird's cloud service):\n\n```bash\nnetbird up \\\n  --management-url https:\u002F\u002Fnetbird.yourdomain.com \\\n  --setup-key \u003CYOUR_SETUP_KEY>\n```\n\nConfirm the connection:\n\n```bash\nnetbird status\n```\n\nYou should read `Management: Connected` and `Signal: Connected`, along with a mesh IP in the `100.64.x.x` range assigned by your server.",{"title":61,"body":62},"Enroll nodes 2 and 3","Repeat exactly the same procedure on the other two client VPSs. Same `curl` command to install the client, same `netbird up` command with the same `--management-url` and the same `--setup-key` (if it is of the `Reusable` type).\n\nOnce all three nodes are enrolled, check from node 1 that the peers are visible:\n\n```bash\nnetbird status --detail\n```\n\nThe output lists each peer with its mesh IP, state and latency. Since v0.82, `netbird status --table` shows the same information as a table.",{"title":64,"body":65},"Test mesh connectivity with no public port open","Before testing, check the firewall state on node 1 — no inbound port should be open to the other nodes:\n\n```bash\nsudo ufw status numbered\n```\n\nOnly the SSH port (22) should appear. Now ping node 2 through its mesh IP (shown in `netbird status --detail`, for example `100.64.0.2`):\n\n```bash\nping -c 3 100.64.0.2\n```\n\nThe ping goes through the WireGuard tunnel established between the peers. If a direct connection is impossible, the relay built into the server takes over on port 443: the ping works either way, with no extra UFW rule.",{"title":67,"body":68},"Tell direct and relayed connections apart","To find out whether a peer connects directly or through the relay:\n\n```bash\nnetbird status --detail\n```\n\nThe `Connection type` field shows `P2P` for a direct connection or `Relayed` when traffic goes through the relay. To list only relayed peers:\n\n```bash\nnetbird status -d --filter-by-connection-type Relayed\n```\n\n`P2P` is the expected state between two VPSs with a public IPv4. `Relayed` remains end-to-end encrypted but adds latency: the Troubleshooting section says what to check.",{"type":35,"title":70,"body":71},"Multi-client isolation: groups and access rules","Netbird's strength over Headscale is partitioning by **group**, driven from the interface. One thing to know first: when the account is created, Netbird sets a **Default** policy that lets every peer in the special `All` group talk to every other. As long as it exists, no isolation holds. To separate client A's servers from client B's:\n\n**1. Create one group per client** in the web interface (`client-a`, `client-b`) and an `agency-ops` group for the team's workstations.\n\n**2. Assign each peer to its group.** In the peer's page, in the groups section, add the matching group. A Setup Key can also assign a group automatically to every machine enrolled with it: plan one key per client.\n\n**3. Define the access rules** (Access Control → Policies). A `client-a-internal` policy allows traffic between peers of the `client-a` group. An `ops-ssh` policy lets only the `agency-ops` group reach port 22 of the client groups: a compromised machine in the mesh then cannot serve as a pivot to every VPS. No rule is created between `client-a` and `client-b`.\n\n**4. Delete the Default policy** once the replacement policies are in place. In the reverse order, all communication between peers stops.\n\nResult: an administrator's workstation for client A reaches VPS A through its mesh IP but cannot see VPS B, and the `agency-ops` group remains the only cross-cutting member. You can also define **Network Routes**: a peer acts as a router for a private subnet (e.g. `192.168.10.0\u002F24`) and exposes it to the other peers of the group, with no Netbird client on each machine of that subnet.",{"type":35,"title":73,"body":74},"Close public SSH: listen on the mesh interface only","Once the nodes are enrolled, administration no longer needs an SSH port open to the internet: `ssh admin@100.64.0.2` travels entirely inside the encrypted tunnel. The Netbird client creates the WireGuard interface `wt0` (default name); allow SSH on that interface, then deny it elsewhere:\n\n```bash\nsudo ufw allow in on wt0 to any port 22 proto tcp\nsudo ufw deny 22\u002Ftcp\nsudo ufw status numbered\n```\n\nUFW applies the first matching rule: the `wt0` rule must appear before the deny. Keep your current SSH session open and test a new connection through the mesh IP before closing it: if the tunnel does not come up, you still have a way out. The `ops-ssh` policy seen above then limits who, inside the mesh, can reach that port.",{"type":35,"title":76,"body":77},"`netbird expose`: publish a local service without opening a port","The mesh links your machines together. To make a service reachable **from the internet** without touching the VPS firewall, Netbird has offered the `netbird expose` command since v0.66 (February 2026). It relies on the Netbird proxy: on a self-hosted instance, the proxy must be enabled (at install time or later), with a wildcard DNS record pointing to the server.\n\nAn administrator must first allow the feature: **Settings → Clients → Peer Expose**, restricting the allowed peer groups if needed. Then, on the VPS where, for example, Grafana runs on `127.0.0.1:3000`:\n\n```bash\nnetbird expose 3000 --with-name-prefix grafana --with-user-groups supervision-admins\n```\n\nThe command prints a public URL on the proxy domain and keeps the session open; `Ctrl+C` removes it. The service is **ephemeral**: the client renews it every 30 seconds, and the server deletes it roughly 90 to 120 seconds after the last renewal if the client disappears. Port 3000 stays closed on the VPS firewall.\n\nWithout an authentication option, the URL is **public** to anyone who knows it. Three protections exist for HTTP: `--with-user-groups` (SSO login, limited to the listed groups), `--with-password \u003Cpassword>` (a password you choose) and `--with-pin \u003C6 digits>`. `--protocol tcp` publishes a non-HTTP service, with no authentication possible. Each peer can hold 10 simultaneous sessions, and the command fails if Block Inbound Connections is enabled on the peer. For a permanent service, create it in the Dashboard instead.",{"type":79,"title":80,"headers":81,"rows":86},"comparison","Netbird, Headscale and manual WireGuard at a glance",[82,83,84,85],"Criterion","Self-hosted Netbird","Headscale","Manual WireGuard",[87,92,97,102,107],[88,89,90,91],"Peer management","Automatic, control plane and web interface","Automatic, official Tailscale clients","Manual, a `wg0.conf` file on each node",[93,94,95,96],"NAT and CGNAT","Embedded STUN, relay on port 443","DERP servers (optional embedded DERP server)","Requires a public IP or port forwarding",[98,99,100,101],"Partitioning","Groups and policies in the interface","ACL policy file (HuJSON)","None, apart from each peer's `AllowedIPs`",[103,104,105,106],"Publishing a service","`netbird expose` or the Netbird proxy","Not built in","SSH tunnel or a reverse proxy you set up yourself",[108,109,110,111],"License","BSD-3 (client), AGPLv3 (server)","BSD-3-Clause","Free software (Linux kernel and tools)",{"type":35,"title":113,"body":114},"Day-to-day operations","**Renew or revoke a Setup Key.** In the web interface, Setup Keys → your key → Revoke. Peers already enrolled keep their connection; new enrollment attempts with that key are refused. Create a new key for future enrollments.\n\n**Revoke a peer.** Peers → select the peer → Delete. The node is removed from the mesh; on the client side, the connection to Management drops and the WireGuard tunnels to that peer are torn down.\n\n**API access for automation.** Netbird exposes a documented REST API. Create a service user (Team → Service Users) and its access token, then drive everything from your Ansible scripts or CI pipelines:\n\n```bash\ncurl -s https:\u002F\u002Fnetbird.yourdomain.com\u002Fapi\u002Fpeers \\\n  -H 'Authorization: Token \u003CPAT>'\n```\n\n**Monitoring.** The combined server exposes its Prometheus metrics on `\u002Fmetrics`, port `9090` by default (the `server.metricsPort` key in `config.yaml`): a single scrape target covers Management, Signal and Relay. Connect Grafana to it to follow connected peers and relay activity.\n\n**Upgrading.** From the installation directory, pull the new images, then recreate the containers:\n\n```bash\ndocker compose pull netbird-server dashboard\ndocker compose up -d --force-recreate netbird-server dashboard\n```\n\nAdd `proxy` to both commands if it is enabled. If `docker-compose.yml` pins versions, update the `image:` tags first: `docker compose pull` does not change them. Peers lose the control plane for a few seconds during the restart; schedule the operation outside busy hours. Traefik is upgraded separately from Netbird.",{"type":116,"title":117,"body":118},"tip","Hardening: MFA on the Dashboard and data backups","The embedded identity provider handles two-factor authentication for local accounts: **Settings → Authentication → Local MFA** requires a TOTP code from every user. You can also connect an OIDC provider (Keycloak, Authentik, Microsoft Entra ID…) and apply your own MFA policy there.\n\nThe persistent state of your network (Management database, encryption keys) lives in the `netbird_data` Docker volume, mounted on `\u002Fvar\u002Flib\u002Fnetbird`: losing it means re-enrolling all your peers. Stop the stack to get a consistent copy, back up the configuration files and the volume, then restart:\n\n```bash\ndocker compose stop\nmkdir -p backup\ncp docker-compose.yml config.yaml dashboard.env backup\u002F\ndocker compose cp -a netbird-server:\u002Fvar\u002Flib\u002Fnetbird\u002F backup\u002F\ndocker compose start\n```\n\nIf the proxy is enabled, add `proxy.env` and `traefik-dynamic.yaml`. Keep at least seven days of backups, off the VPS.",{"type":35,"title":120,"body":121},"Troubleshooting","**Peers stuck in `Relayed`.**\nThe relay works, but the direct connection fails. First check that UDP port 3478 on the control VPS is open (`ufw status`), then that the nodes can send outbound UDP. On a VPS with a public IP and no NAT, a host firewall that drops unsolicited inbound UDP is enough to break the direct connection; the Netbird documentation then suggests `sudo ufw allow in proto udp to any port 49152:65535`, at the cost of a wider opening, or accepting the relay. A `Connected` peer that does not answer pings often points to the same block, on the `wt0` interface side.\n\n**UDP blocked by a corporate network.**\nNothing to configure: since v0.36, the client tries the relay over QUIC (UDP\u002F443) and over WebSocket (TCP\u002F443), and keeps whichever answers first. If only outbound TCP\u002F443 gets through, the peer stays connected, in relayed mode.\n\n**Peer stuck in `Connecting`.**\nEnrollment succeeded but the tunnel does not form. Check that `netbird status` does show `Signal: Connected`, that the server announces a correct public address (the `exposedAddress` field of `config.yaml`) and that ports 443\u002FTCP and 3478\u002FUDP are reachable from the node.\n\n**Reading the logs.**\nOn the server, `docker compose logs -f netbird-server`. On the client, the log is written by default to `\u002Fvar\u002Flog\u002Fnetbird\u002Fclient.log`. For a full diagnosis, `netbird debug for 5m` switches the client to detailed logging for five minutes, then produces a diagnostic archive (`netbird debug bundle` produces it right away).\n\n**DNS resolution between peers.**\nNetbird assigns a DNS name to each peer, shown in the **Domain Name** field of its page. If pinging by name fails while `ping 100.64.0.2` works, check that the service is running on the peer (`sudo netbird service status`) and that the system's DNS does go through Netbird (`resolvectl status`).",{"type":35,"title":123,"body":124},"Netbird proxy stuck on \"Issuing certificate…\"","When the proxy is enabled, one symptom keeps coming back: the service you created stays on \"Issuing certificate…\" (status `certificate_pending`, or `certificate_failed`) and is never reachable. Netbird issue #5517, opened on 5 March 2026, is still open as of 7 November 2026 with 36 comments and the `triage-needed` label. The most frequent message in the proxy log, `no viable challenge type found`, only says that the certificate authority got no valid answer to its challenges: there is no single cause. Start by reading the log (`docker compose logs proxy | grep -i acme`) and note the exact error, then rule out the causes one by one.",{"type":126,"title":127,"items":128},"ul","Diagnostic order for a certificate that does not come through",[129,130,131,132,133],"**Certificate folder permissions** — a `permission denied` error on `\u002Fcerts` is the only case settled by a repository collaborator: no update will fix it, the file system permissions are at fault. Check which user the container runs as before changing permissions.","**DNS, CAA and ports** — the name must resolve to the proxy and no CAA record may exclude Let's Encrypt. Port 443 must be reachable from the internet for the `tls-alpn-01` challenge (the default), port 80 for `http-01`. Let's Encrypt validates from several regions of the world: geo-blocking makes validation fail.","**CDN or upstream proxy** — Cloudflare and some appliances do not pass the `acme-tls\u002F1` ALPN protocol through. In that case switch to `NB_PROXY_ACME_CHALLENGE_TYPE=http-01` in `proxy.env`.","**Traefik in front** — if Traefik passes TLS through to the proxy, its HTTPS entry point must carry `allowACMEByPass=true`, which the installation script sets on `websecure`. On an existing Traefik, use the name of your own entry point; participants in the issue had to add it to the HTTP entry point as well, others already had it with no result.","**What is not established** — none of these leads is \"the\" cause: test them on your own installation before drawing conclusions.",{"type":35,"title":135,"body":136},"Closed origin: the certificate through DNS-01 with lego","The `tls-alpn-01` and `http-01` challenges require the authority to reach your proxy from the internet, which conflicts with an origin closed to a CDN's ranges or with geo-blocking. The `dns-01` challenge removes that constraint: it proves control of the domain with a temporary TXT record created through your DNS provider's API. The Netbird proxy does not support it natively: the request (issue #5450, opened on 25 February 2026) is still open. The Netbird documentation does, however, describe a \"private proxy with lego\" setup: lego obtains and renews a wildcard certificate over DNS-01, a deploy hook drops it into a shared volume, and the proxy hot-reloads it after each renewal.",{"type":126,"title":138,"items":139},"Points to watch in the lego setup",[140,141,142,143,144],"**Proxy variables** — `NB_PROXY_WILDCARD_CERT_DIR` points to the wildcard certificate folder, `NB_PROXY_PRIVATE=true` enables private listeners on the mesh. Pin a proxy image that knows both variables.","**Private mode closes nothing on its own** — `NB_PROXY_PRIVATE` does not disable the proxy's ordinary listener. Remove the published ports and the ingress routes (Traefik labels, Caddy, nginx) leading to the container yourself.","**Wildcard scope** — `*.proxy.yourdomain.com` covers only one level of subdomain. A name outside that coverage falls back to the built-in ACME, which cannot succeed if the proxy is fully private.","**Certificate exposure** — the wildcard and the base domain appear in Certificate Transparency logs, not the names of the services it covers; a compromised wildcard key, on the other hand, affects all of those names.","**Operations** — use Let's Encrypt's production ACME server (its test certificates are not trusted), back up the lego and certificate volumes, and pin tested versions of lego and the proxy.",{"type":35,"title":146,"body":147},"What the mesh changes for fleet management","A self-hosted Netbird mesh replaces three layers you maintain by hand: WireGuard key distribution, UFW rules between servers and the documentation of cross access. Each new client VPS enrolls with one command; each revocation is immediate and centralized. Public SSH can be closed, and `netbird expose` publishes a service on demand without opening a port.\n\nGroup isolation lets you grow without risk of collision: the servers of two different clients cannot see each other, even when they run on the same infrastructure. And the control plane stays under your control: no dependency on a third-party SaaS, no seat limit, no per-node subscription.\n\nTo go further, describe node provisioning in Ansible (see \u003Ca href=\"\u002Fen\u002Fblog\u002Fautomating-vps-server-management-with-ansible\">our Ansible guide\u003C\u002Fa>): installing the client, the `netbird up` command and the UFW rules on `wt0` become idempotent tasks in a reusable role.","Your VPS and your clients' accounts on one account","Your ServOrbit.com client area brings your domains, hosting and VPS together, with their due dates. The Reseller space adds your clients' cPanel accounts. Add a VPS dedicated to the Netbird control plane.","Explore the agency offer","\u002Fsolutions\u002Fagences",[153,178,197],{"id":154,"slug":155,"slugs":156,"title":160,"excerpt":161,"readTime":162,"views":163,"isPinned":19,"noindex":19,"publishedAt":164,"updatedAt":165,"category":166,"categories":172,"featuredImage":29,"bgImage":30,"posterImage":174,"relatedSolution":175},164,"self-host-headscale-on-a-vps-your-own-tailscale-control-server",{"fr":157,"en":155,"ar":158,"es":159},"self-host-headscale-tailscale-vps","استضافة-headscale-على-vps-خادم-تحكم-tailscale-خاص-بك","auto-alojar-headscale-en-un-vps-servidor-tailscale","Self-Host Headscale on a VPS: Your Own Tailscale Control Server","Replace Tailscale's cloud control server with Headscale on your own VPS — unlimited users, full WireGuard mesh networking, magic DNS and ACLs, with no SaaS dependency.",19,2,"2026-07-05T00:00:00+00:00","2026-11-08T01:13:12+00:00",{"id":167,"name":168,"slug":169,"color":170,"icon":171},8,"Security & Monitoring","securite-monitoring","bg-rose-500\u002F10 text-rose-400","security",[173],{"id":167,"name":168,"slug":169,"color":170,"icon":171},"\u002Fblog\u002Fcovers\u002Fself-host-headscale-tailscale-vps-poster.svg",{"categorySlug":176,"appSlug":177},"networking-vpn","headscale",{"id":179,"slug":180,"slugs":181,"title":185,"excerpt":186,"readTime":187,"views":163,"isPinned":19,"noindex":19,"publishedAt":188,"updatedAt":189,"category":190,"categories":194,"featuredImage":29,"bgImage":30,"posterImage":196,"relatedSolution":29},236,"automating-vps-server-management-with-ansible",{"fr":182,"en":180,"ar":183,"es":184},"ansible-automatiser-serveurs-vps","أتمتة-إدارة-خوادم-vps-باستخدام-ansible","automatizar-servidores-vps-con-ansible","Automating VPS Server Management with Ansible","Learn how to automate VPS fleet management with Ansible: inventory, playbooks, roles and Vault for a reproducible, auditable infrastructure.",10,"2026-08-08T00:00:00+00:00","2026-09-07T11:26:10+00:00",{"id":163,"name":191,"slug":192,"color":193,"icon":192},"Automation","automatisation","bg-brand-action\u002F10 text-brand-action",[195],{"id":163,"name":191,"slug":192,"color":193,"icon":192},"\u002Fblog\u002Fcovers\u002Fansible-automatiser-serveurs-vps-poster.svg",{"id":198,"slug":199,"slugs":200,"title":204,"excerpt":205,"readTime":167,"views":206,"isPinned":19,"noindex":19,"publishedAt":207,"updatedAt":208,"category":209,"categories":210,"featuredImage":29,"bgImage":30,"posterImage":212,"relatedSolution":29},228,"initial-linux-server-hardening",{"fr":201,"en":199,"ar":202,"es":203},"durcissement-serveur-linux-initial","تصليب-الخادم-linux-الأولي","hardening-inicial-servidor-linux","Initial Linux Server Hardening","Create a sudo user, configure SSH with keys, enable UFW and fail2ban on Ubuntu or Debian in under an hour.",1,"2026-08-06T00:00:00+00:00","2026-10-20T23:18:07+00:00",{"id":167,"name":168,"slug":169,"color":170,"icon":171},[211],{"id":167,"name":168,"slug":169,"color":170,"icon":171},"\u002Fblog\u002Fcovers\u002Fdurcissement-serveur-linux-initial-poster.svg",true,1794270457143]