WebUI hardening

Describe the problem

I just installed NetBird on a dedicated server that I will be using soley for VPN purposes and thus needs to be hardened. In particular, the WebUI, without MFA, being freely accessible, bothers me a lot.

I am using the default Traefik-based reverse proxy setup and what I would like to achieve is that I can use port forwarding over SSH to access the webUI. That said, I am far more experienced with Caddy than Traefik… so I need a pointer here :slight_smile:

Basically, I want to restrict the webUI to only be accessible from the local maschine when using a tunnel (ssh -L 8080:server:80 user@server). Any advice?

To Reproduce

  1. Use the install script to create the docker-compose setup.
  2. Set the reverse proxy to the default Traefik one (which is the default)
  3. Create the initial user in the web interface

Expected behavior

I only want the webUI “hidden”. The rest - signaling, relay, etc., should be completely public so the VPN works, obviously. :slight_smile: My goal is to thus introduce some hardening.

(I am aware MFA is coming, I saw the Github ticket, but I still would like to go forward with the hardening.)

Are you using NetBird Cloud?

No.

NetBird version

netbird version 0.67.1
Netbird Dashboard: 2.36.0

Is any other VPN software installed?

No. This server is 100% dedicated to Netbird. I only plan to set up some form of mdns/broadcast traffic proxying to handle a few aspects WireGuard does not cover purely on L3.

Debug output

Output:

Peers detail:
 netboi.netbird.selfhosted:
  NetBird IP: 10.0.0.2
  Public key: XXry/kDxu9vKijSUPAyJwWLGibnwg10tK2qYH3knwFA=
  Status: Connected
  -- detail --
  Connection type: P2P
  ICE candidate (Local/Remote): host/host
  ICE candidate endpoints (Local/Remote): 100:::51820/100::1:51820
  Relay server address: rels://anon-FANQ7.domain:443
  Last connection update: 29 minutes, 28 seconds ago
  Last WireGuard handshake: 1 minute, 19 seconds ago
  Transfer status (received/sent) 33.3 KiB/23.2 KiB
  Quantum resistance: false
  Networks: 10.1.0.0/24
  Latency: 7.924326ms

Events:
  [INFO] SYSTEM (30ac0b93-75ec-4387-969b-d58879db9c86)
    Message: Network map updated
    Time: 35 minutes, 31 seconds ago
  [INFO] SYSTEM (fada3ea7-baaa-44cc-b735-f669824de0c0)
    Message: Network map updated
    Time: 29 minutes, 28 seconds ago
  [INFO] SYSTEM (68c5f6f9-a794-482f-b1e2-eceb5bc35e2d)
    Message: Network map updated
    Time: 26 minutes, 42 seconds ago
OS: linux/arm64
Daemon version: 0.67.1
CLI version: 0.67.1
Profile: default
Management: Connected to https://anon-FANQ7.domain:443
Signal: Connected to https://anon-FANQ7.domain:443
Relays:
  [stun:anon-FANQ7.domain:3478] is Checking...
  [rels://anon-FANQ7.domain:443] is Available
Nameservers:
FQDN: drachennetz.netbird.selfhosted
NetBird IP: 10.0.0.1/24
Interface type: Kernel
Quantum resistance: false
Lazy connection: false
SSH Server: Enabled
Networks: -
Peers count: 1/1 Connected

Create and upload a debug bundle

Not really applicable here? I can upload one - but I doubt this matters for this case.

Screenshots

None - not applicable.

Additional context

This installation is as fresh as can be - the bird literally hatched about half a hour ago :slight_smile: I am migrating from Headscale to Netbird currently.

Have you tried these troubleshooting steps?

  • Reviewed client troubleshooting (if applicable)
  • Checked for newer NetBird versions
  • Searched for similar issues on GitHub (including closed ones)
  • Restarted the NetBird client
  • Disabled other VPN software
  • Checked firewall settings

There isn’t directly a way of doing this without also breaking the API that Netbird depends on for it’s communication with the VPN (when the connection isn’t made yet, like authentication). Furthermore, to authenticate users, you’d also need to confirm credentials and from a user side. This can only be done with the WebUI.

However, what you CAN do, is setup SSO (like authentik) and force people to authenticate/MFA through that before logging into Netbird. See the following documentation:

That should get you roughly on the way.