Pritunl Multi-Domain Setup – Looking for Best Practice Review

Hi everyone,

I maintain a Pritunl setup (self-hosted, behind nginx as reverse proxy) and would like feedback from the community on whether this architecture is sound / best practice, or whether I’ve introduced unnecessary complexity or security risk.

Background

We run 3 independent Pritunl instances (separate DB/session per instance):

  • Instance 1 – main VPN for employees, auth exclusively via SAML (Azure AD / Entra ID), used both by internal users (pulling profiles, docs) and external home-office users (VPN connection from outside). No RADIUS here — SAML is the intended auth method for this instance.
  • Instance 2 – supports SAML (used only for profile retrieval, exclusively through an internally-resolved domain) in addition to RADIUS. This instance only exists because Pritunl doesn’t natively support multiple auth methods at once. RADIUS is needed here because of AlwaysOn VPN — the goal is to eventually replace the existing user tunnel with it. The SAML+RADIUS combination was solved via Pritunl’s plugin system. I wasn’t able to get it working via plugin in a way where specific servers/organizations use only RADIUS while others use only SAML.
  • Instance 3 – fully separate, plain RADIUS server with classic MFA. The RADIUS server was already in use for other purposes, so we kept using it here — we’d actually prefer SAML for this one too, but OpenVPN itself doesn’t support SAML, and Pritunl currently has no native app for Android/iOS.

Domain structure (nginx, one server with multiple server_name blocks)

All three domains per instance ultimately proxy to the same backend instance (10.77.4.10:8443 in this example, for Instance 1), but with different location blocks / sub_filter rewrites depending on the target audience. All three instances share connect.corpvpn.example as the common public domain.

Instance 1

  1. manage.corpvpn.example – access to the Pritunl admin UI
  2. portal.corpvpn.example – “user domain”: pulling profiles, docs page, customized login screen (native username/password fields stripped via sub_filter, only SAML login shown)
  3. connect.corpvpn.example (public) – serves actual VPN client operation for home-office users; also configured as the SSO Domain in Pritunl (i.e. the domain the SAML ACS callback points back to)

Instance 2

  • site2-manage.corpvpn.example (admin)
  • site2-portal.corpvpn.example (portal/profiles)
  • public: connect.corpvpn.example

Instance 3

  • mobile-manage.corpvpn.example (admin)
  • mobile-portal.corpvpn.example (portal)
  • public: connect.corpvpn.example

Redirect logic between domains

  • connect.corpvpn.example (public/SSO) → key/profile paths get 302-redirected to portal.corpvpn.example, since actual profile retrieval should happen there with the customized UI
  • portal.corpvpn.example → paths used for VPN client communication get 302-redirected back to connect.corpvpn.example
  • the SAML callback path is proxied (not redirected!) on both domains, since a 301/302 on a SAML POST request would drop the body

Open questions for the community

  1. Does this setup make sense overall, or do you see fundamental issues with the architecture?
  2. Does the domain split make sense?
  3. What are generally considered best practices for running Pritunl?
  4. What are best practices for reverse proxy setup, combining SAML/RADIUS, multi-instance operation, etc.?

Thanks in advance for any input!

It’s unlikely that one single sign-on domain will work for 3 different installations. Currently only one single sign-on provider can be configured for each Pritunl installation. It can’t have RADIUS and SAML or multiple RADIUS/SAML providers. For SAML there are callbacks where it needs to go back to the correct host.

Generally there should be one domain for the web console. There isn’t any reason to separate admin and user domains. If you are concerned about the security of the admin login open to the internet the nginx server can filter /auth/session and all the authGroup paths shown in pritunl-web/handlers/handlers.go. For RADIUS you would need to allow /auth/session but as long as all the authGroup handlers are blocked there will be no access to admin paths even with a valid session. There is already an extensive dual layer design for the web console. An admin level request isn’t even forwarded past the pritunl-web process into the root pritunl process without a valid NaCl signature. Which is in addition to the HMAC based session that is checked by the root pritunl process.

Below are all the addresses and how to configure them.

Hosts Tab

  • Host Public Address: The public IPv4 address or domain of the Pritunl host. This should always be the public IP of the host for all configurations even when using a load balancer.
  • Host Public IPv6 Address: The public IPv6 address or domain of the Pritunl host. This should always be the public IP of the host for all configurations even when using a load balancer.
  • Host Sync Address: In the advanced host settings. The public address or domain that the web server of the Pritunl servers can be accessed from. If a load balancer is configured that address should be set here.

Top Right Settings

  • Single Sign-On Domain: The public address or domain that is used to validate single sign-on requests through the Pritunl web server for a new VPN connection. This should be the same domain used to access the web console. If a load balancer is configured that address should be set here. Requires valid SSL certificate.