Skip to content

Reverse Proxy service modal strips dots from the subdomain input, blocking nested subdomains the API accepts #667

Description

@brizjin

Describe the problem

When creating a Reverse Proxy service, the subdomain input in the dashboard silently strips any character that is not [a-z0-9-], including dots (.). This makes it impossible to create a service on a nested (multi-label) subdomain such as dev.app.example.com — typing the dot just deletes it, so you can only ever enter a single label (app.example.com).

The management API, however, accepts the full multi-label domain and provisions everything correctly: the ACME (TLS-ALPN-01) certificate is issued, the service becomes active, and requests are served / redirected to SSO as expected. So the UI is stricter than the backend, with no functional reason.

Root cause

src/modules/reverse-proxy/domain/ReverseProxyDomainInput.tsx — the subdomain field sanitizes input on change:

onChange={(e) =>
  onSubdomainChange(e.target.value.toLowerCase().replace(/[^a-z0-9-]/g, ""))
}

/[^a-z0-9-]/g removes ., so nested subdomains can never be entered. A single DNS label is [a-z0-9-], but a subdomain may legitimately contain multiple dot-separated labels.

To reproduce

  1. Self-hosted NetBird with the Reverse Proxy feature and a connected proxy cluster whose base domain is e.g. example.com (require_subdomain: false).
  2. Dashboard -> Reverse Proxy -> Services -> Add Service.
  3. In the subdomain field, try to type dev.app (to get dev.app.example.com). The dot is stripped and you end up with devapp.

Compare with the API, which accepts it:

curl -X POST "https://<management>/api/reverse-proxies/services" \
  -H "Authorization: Token <PAT>" -H "Content-Type: application/json" \
  -d '{
    "name": "dev-app",
    "domain": "dev.app.example.com",
    "mode": "http",
    "enabled": true,
    "targets": [{
      "target_id": "<clusterId>", "target_type": "cluster",
      "protocol": "http", "host": "backend.internal", "port": 80,
      "enabled": true, "options": { "direct_upstream": true }
    }],
    "auth": { "bearer_auth": { "enabled": true, "distribution_groups": [] } }
  }'
# -> 201, meta.status "pending" -> "active"; cert issued for dev.app.example.com;
#    visiting https://dev.app.example.com redirects to the IdP for SSO.

Expected behavior

The subdomain input should allow multi-label subdomains (dot-separated labels), matching what the management API already accepts. Validation should permit a dot-separated sequence of DNS labels (e.g. ^[a-z0-9-]+(\.[a-z0-9-]+)*$) instead of stripping . entirely.

Actual behavior

Dots are removed on input, so nested subdomains cannot be created from the dashboard; the only workaround is the REST API.

Are you using NetBird Cloud?

No, self-hosted.

NetBird version

Management/proxy v0.72.x, dashboard v2.39.0.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions