diff --git a/manage/blueprints.mdx b/manage/blueprints.mdx index a43c5e0..2b3f9f8 100644 --- a/manage/blueprints.mdx +++ b/manage/blueprints.mdx @@ -21,10 +21,11 @@ Some features in this documentation are marked with **(EE)**, which means they r ## Blueprint Mental Model -A blueprint can contain up to three top-level sections: +A blueprint can contain up to four top-level sections: -- **`public-resources`**: Internet-facing HTTP, TCP, or UDP resources +- **`public-resources`**: Internet-facing HTTP, TCP, UDP, SSH, RDP, or VNC resources - **`private-resources`**: Client-only access to hosts or CIDR ranges +- **`public-policies`**: Reusable authentication and access policy objects - **`sites`**: Site-level settings such as container label discovery ```yaml @@ -36,6 +37,10 @@ private-resources: : ... +public-policies: + : + ... + sites: : ... @@ -142,13 +147,13 @@ Use container labels when the resource definition should live inside your Compos ## Quick Start YAML Example -This example shows all three top-level sections in one file: +This example shows three common top-level sections in one file: ```yaml public-resources: web-app: name: Web App - protocol: http + mode: http full-domain: app.example.com auth: sso-enabled: true @@ -187,6 +192,11 @@ Public resources expose services through Pangolin. - Use **`http`** for websites, APIs, and dashboards - Use **`tcp`** or **`udp`** for raw public services bound to a port on the Pangolin server +- Use **`ssh`**, **`rdp`**, or **`vnc`** for protocol-specific resources + + +Use `mode` for new blueprints. `protocol` is still accepted for backward compatibility and is normalized to `mode`. + ### HTTP Resource Example @@ -194,7 +204,7 @@ Public resources expose services through Pangolin. public-resources: app: name: App - protocol: http + mode: http full-domain: app.example.com host-header: app.internal tls-server-name: app.internal @@ -229,7 +239,7 @@ When applying a blueprint via Newt (using `--blueprint-file` or container labels public-resources: mqtt: name: Mosquitto MQTT - protocol: tcp + mode: tcp proxy-port: 1883 targets: - site: my-site @@ -261,7 +271,7 @@ public-resources: method: http ``` -When a resource is targets-only, `name` and `protocol` are not required. +When a resource is targets-only, `name` and `mode` are not required. ### Authentication Example @@ -271,7 +281,7 @@ Authentication is configured inside `auth` and is supported only for HTTP resour public-resources: secure-app: name: Secure App - protocol: http + mode: http full-domain: secure.example.com auth: pincode: 123456 @@ -296,7 +306,7 @@ The `maintenance` object lets you present a maintenance page for a public HTTP r public-resources: app: name: App - protocol: http + mode: http full-domain: app.example.com maintenance: enabled: true @@ -323,6 +333,7 @@ Private resources define what Pangolin clients can reach after they connect to y - Use **`mode: host`** for a single host or DNS name - Use **`mode: cidr`** for an entire network range - Use **`mode: http`** to expose an internal HTTP endpoint to clients via a private domain +- Use **`mode: ssh`** for SSH access workflows (including native auth-daemon mode) When applying a blueprint via Newt (using `--blueprint-file` or container labels), `sites` is optional. If omitted, the resource is assigned to the site of the Newt that applied the blueprint. @@ -477,7 +488,7 @@ Use this section when you need the full schema. The order below mirrors the blue public-resources: app: name: App - protocol: http + mode: http full-domain: app.example.com targets: - hostname: app @@ -493,6 +504,13 @@ private-resources: destination: 192.168.1.10 tcp-ports: "22" +public-policies: + default-member: + name: Default Member Policy + sso: true + apply-rules: false + rules: [] + sites: my-site: name: My Site @@ -514,6 +532,13 @@ sites: Container label: `pangolin.private-resources.internal-net.mode=cidr` + + Reusable policy definitions keyed by policy ID. + + YAML: `public-policies: { default-member: { ... } }` + Container label: `pangolin.public-policies.default-member.name=Default Member Policy` + + Site-level settings keyed by site ID. @@ -546,7 +571,8 @@ sites: public-resources: web-app: name: Web App - protocol: http + mode: http + policy: default-member full-domain: app.example.com enabled: true host-header: internal.example.local @@ -596,15 +622,31 @@ public-resources: Container label: `pangolin.public-resources.web-app.name=Web App` - - Resource type. + + Resource mode. Preferred over `protocol`. - **Options**: `http`, `tcp`, `udp` + **Options**: `http`, `tcp`, `udp`, `ssh`, `rdp`, `vnc` + + YAML: `mode: http` + Container label: `pangolin.public-resources.web-app.mode=http` + + + + Deprecated resource type field. Use `mode` instead. + + **Options**: `http`, `tcp`, `udp`, `ssh`, `rdp`, `vnc` YAML: `protocol: http` Container label: `pangolin.public-resources.web-app.protocol=http` + + Policy key to attach from `public-policies`. + + YAML: `policy: default-member` + Container label: `pangolin.public-resources.web-app.policy=default-member` + + Optional SSL/TLS flag present in the schema. @@ -620,12 +662,27 @@ public-resources: - Public port for raw TCP or UDP resources. Required when `protocol` is `tcp` or `udp`. + Public port for raw TCP or UDP resources. Required when `mode` is `tcp` or `udp`. YAML: `proxy-port: 3000` Container label: `pangolin.public-resources.raw-api.proxy-port=3000` + + Enables Proxy Protocol on TCP resources. + + YAML: `proxy-protocol: true` + Container label: `pangolin.public-resources.raw-api.proxy-protocol=true` + + + + Proxy Protocol version when `proxy-protocol` is enabled. + + **Minimum**: `1` + YAML: `proxy-protocol-version: 1` + Container label: `pangolin.public-resources.raw-api.proxy-protocol-version=1` + + Disables the resource without removing it. @@ -755,6 +812,14 @@ public-resources: YAML: `priority: 10` Container label: `pangolin.public-resources.web-app.rules[0].priority=10` + + + Enables or disables the rule. + + **Default**: `true` + YAML: `enabled: true` + Container label: `pangolin.public-resources.web-app.rules[0].enabled=true` + @@ -879,6 +944,30 @@ public-resources: + + Auth-daemon configuration for supported modes. + + + + PAM behavior. Passthrough will require entering the username, password, or private key when connecting. Push will sync a Pangolin user with the configuration from the roles onto the auth-daemon and not prompt a log in. + + **Options**: `passthrough`, `push` + **Default**: `passthrough` + + + + Auth-daemon mode. To use the built in ssh server inside of the site connector use `native`. For external ssh servers, use `remote` or `site` depending on where the server is. + + **Options**: `site`, `remote`, `native` + **Default**: `site` + + + + Remote auth-daemon port. Required when `auth-daemon.mode` is `remote`. + + + + Backend destinations for the resource. @@ -1106,11 +1195,12 @@ private-resources: Private resource type. - **Options**: `host`, `cidr`, `http` + **Options**: `host`, `cidr`, `http`, `ssh` - `host`: A single host or IP. If `destination` is a domain, `alias` is required. - `cidr`: An entire IPv4 or IPv6 CIDR range. - `http`: An internal HTTP endpoint exposed to clients via `full-domain`. + - `ssh`: SSH access resource. `destination` may be omitted only when `auth-daemon.mode` is `native` (or when `auth-daemon` is omitted). YAML: `mode: cidr` Container label: `pangolin.private-resources.internal-net.mode=cidr` @@ -1132,17 +1222,42 @@ private-resources: Container label: `pangolin.private-resources.internal-net.site=my-site` - + Host, IP, or CIDR block the client should reach. The accepted format depends on `mode`: - `host`: a valid IPv4/IPv6 address, or a hostname/domain (when using a domain, `alias` must also be set) - `cidr`: a valid IPv4 or IPv6 CIDR block - `http`: a host or IP for the upstream HTTP endpoint + - `ssh`: optional only for `auth-daemon.mode: native`; required otherwise YAML: `destination: 10.0.0.0/24` Container label: `pangolin.private-resources.internal-net.destination=10.0.0.0/24` + + Auth-daemon configuration. + + + + PAM behavior. Passthrough will require entering the username, password, or private key when connecting. Push will sync a Pangolin user with the configuration from the roles onto the auth-daemon and not prompt a log in. + + **Options**: `passthrough`, `push` + **Default**: `passthrough` + + + + Auth-daemon mode. To use the built in ssh server inside of the site connector use `native`. For external ssh servers, use `remote` or `site` depending on where the server is. + + **Options**: `site`, `remote`, `native` + **Default**: `site` + + + + Remote auth-daemon port. Required when `auth-daemon.mode` is `remote`. + + + + Upstream port for the destination. Typically used with `mode: http` to point at the internal HTTP endpoint's port. @@ -1237,16 +1352,123 @@ private-resources: +### Resource Policy Object (`public-policies`) + +```yaml +public-policies: + default-member: + name: Default Member Policy + sso: true + auto-login-idp: null + sso-roles: + - Member + sso-users: [] + password: null + pincode: null + basic-auth: null + email-whitelist-enabled: false + whitelist-users: + - "*@example.com" + apply-rules: true + rules: + - action: allow + match: country + value: US + enabled: true +``` + + + + A reusable policy definition that can be referenced by public resources via `policy`. + + + + Display name for the policy. + + + + Enables SSO for the policy. + + **Default**: `true` + + + + Identity provider ID to redirect to automatically. + + + + Roles allowed by this policy. `Admin` is not allowed. + + + + Specific users allowed by this policy. + + + + Optional shared password. + + + + Optional 6-digit PIN. + + + + Optional basic-auth gate. + + + + Basic auth username. + + + + Basic auth password. + + + + Compatibility flag for basic auth behavior. + + **Default**: `true` + + + + + + Enables email whitelist matching. + + **Default**: `false` + + + + Allowed email addresses or wildcard-domain entries like `*@example.com`. + + + + Enables rule evaluation. + + **Default**: `false` + + + + Policy rule list using the same rule schema as public resource rules. + + + + + ## Validation Rules And Constraints ### Core Rules -1. A public resource can be **targets-only**. In that case it may contain only `targets`, and `name` plus `protocol` are not required. -2. When `protocol` is `http`, the resource must have `full-domain` and each target must include `method`. -3. When `protocol` is `tcp` or `udp`, the resource must have `proxy-port`, targets must not include `method`, and `auth` is not allowed. -4. `full-domain` values must be unique across public resources. -5. `proxy-port` values must be unique per protocol within `public-resources`. TCP `3000` and UDP `3000` can coexist, but two TCP resources cannot both use `3000`. -6. `alias` values must be unique across private resources in the blueprint. +1. A public resource can be **targets-only**. In that case it may contain only `targets`, and `name` plus `mode` are not required. +2. For full public resources, `name` plus (`mode` or deprecated `protocol`) are required. +3. When mode/protocol is `http`, the resource must have `full-domain` and each target must include `method`. +4. When mode/protocol is `tcp` or `udp`, the resource must have `proxy-port`, targets must not include `method`, and `auth` is not allowed. +5. `proxy-protocol` and `proxy-protocol-version` are only valid when mode/protocol is `tcp`. +6. If `auth-daemon.mode` is `remote`, `auth-daemon.port` is required. +7. In private resources, `destination` is required unless `mode: ssh` with native auth-daemon mode. +8. `full-domain` values must be unique across public resources. +9. `proxy-port` values must be unique per protocol within `public-resources`. TCP `3000` and UDP `3000` can coexist, but two TCP resources cannot both use `3000`. +10. `alias` values must be unique across private resources in the blueprint. ### Common Validation Errors @@ -1274,6 +1496,18 @@ Raw targets do not use HTTP methods. Authentication settings apply only to HTTP public resources. +### "'proxy-protocol' and 'proxy-protocol-version' can only be set when mode is 'tcp'" + +Only TCP public resources can define proxy protocol behavior. + +### "port is required when auth-daemon mode is 'remote'" + +Set `auth-daemon.port` whenever `auth-daemon.mode: remote` is used. + +### "destination is required unless mode is 'ssh' with auth-daemon mode 'native'" + +For private SSH resources, `destination` can be omitted only for native auth-daemon mode. + ### "Resource must either be targets-only or have both 'name' and 'protocol' fields" Provide both fields for a full public resource definition, or remove everything except `targets`.