From 64885cca7d9112c4ea01df406a2d8b9c083e1ec2 Mon Sep 17 00:00:00 2001 From: Owen Date: Fri, 19 Dec 2025 12:13:46 -0500 Subject: [PATCH 1/6] Update docs about tunnel stuff --- manage/clients/configure-client.mdx | 84 ++++++++++++----------- manage/resources/private/alias.mdx | 6 +- manage/resources/private/destinations.mdx | 4 +- 3 files changed, 51 insertions(+), 43 deletions(-) diff --git a/manage/clients/configure-client.mdx b/manage/clients/configure-client.mdx index c908687..b8ac5e3 100644 --- a/manage/clients/configure-client.mdx +++ b/manage/clients/configure-client.mdx @@ -21,15 +21,15 @@ Refer to the [documentation in the official repository](https://github.com/fosrl Olm ID generated by Pangolin to identify the client. - + **Example**: `31frd0uzbjvp721` A unique secret used to authenticate the client ID with the websocket. - + **Example**: `h51mmlknrvrwv8s4r1i210azhumt6isgbpyavxodibx1k2d6` - + Keep this secret private and secure. It's used for authentication. @@ -37,7 +37,7 @@ Refer to the [documentation in the official repository](https://github.com/fosrl The endpoint where both Gerbil and Pangolin reside for websocket connections. - + **Example**: `https://pangolin.example.com` @@ -51,81 +51,87 @@ Refer to the [documentation in the official repository](https://github.com/fosrl MTU for the internal WireGuard interface. - + **Default**: `1280` DNS server to use to resolve the endpoint. - + **Default**: `8.8.8.8` Upstream DNS server(s), comma-separated. - + **Default**: `8.8.8.8:53` The log level to use for Olm output. - + **Options**: `DEBUG`, `INFO`, `WARN`, `ERROR`, `FATAL` - + **Default**: `INFO` Interval for pinging the server. - + **Default**: `3s` Timeout for each ping. - + **Default**: `5s` Name of the WireGuard interface. - + **Default**: `olm` Enable API server for receiving connection requests. - + **Default**: `false` HTTP server address (e.g., ':9452'). - + **Default**: `:9452` Unix socket path (or named pipe on Windows). - + **Default**: `/var/run/olm.sock` (Linux/macOS) or `olm` (Windows) Disable hole punching. - + **Default**: `false` Override system DNS settings. - + + **Default**: `false` + + + + Force connectivity to the upstream DNS server to go via the tunnel to a resource. + **Default**: `false` Disable relay connections. - + **Default**: `false` @@ -159,87 +165,87 @@ When both environment variables and CLI arguments are provided, CLI arguments ta MTU for the internal WireGuard interface (equivalent to `--mtu`) - + **Default**: `1280` DNS server to use to resolve the endpoint (equivalent to `--dns`) - + **Default**: `8.8.8.8` Upstream DNS server(s), comma-separated (equivalent to `--upstream-dns`) - + **Default**: `8.8.8.8:53` Log level (equivalent to `--log-level`) - + **Default**: `INFO` Interval for pinging the server (equivalent to `--ping-interval`) - + **Default**: `3s` Timeout for each ping (equivalent to `--ping-timeout`) - + **Default**: `5s` Name of the WireGuard interface (equivalent to `--interface`) - + **Default**: `olm` Enable API server for receiving connection requests (equivalent to `--enable-api`) - + Set to "true" to enable - + **Default**: `false` HTTP server address (equivalent to `--http-addr`) - + **Default**: `:9452` Unix socket path or Windows named pipe (equivalent to `--socket-path`) - + **Default**: `/var/run/olm.sock` (Linux/macOS) or `olm` (Windows) Disable hole punching (equivalent to `--disable-holepunch`) - + Set to "true" to disable - + **Default**: `false` Override system DNS settings (equivalent to `--override-dns`) - + Set to "true" to enable - + **Default**: `false` Disable relay connections (equivalent to `--disable-relay`) - + Set to "true" to disable - + **Default**: `false` @@ -249,7 +255,7 @@ When both environment variables and CLI arguments are provided, CLI arguments ta ### Loading secrets from files -You can use `CONFIG_FILE` to define a location of a config file to store the credentials between runs. +You can use `CONFIG_FILE` to define a location of a config file to store the credentials between runs. ``` $ cat ~/.config/olm-client/config.json @@ -276,9 +282,9 @@ $ cat ~/.config/olm-client/config.json } ``` -This file is also written to when olm first starts up. So you do not need to run every time with --id and secret if you have run it once! +This file is also written to when olm first starts up. So you do not need to run every time with --id and secret if you have run it once! -Default locations: +Default locations: - **macOS**: `~/Library/Application Support/olm-client/config.json` - **Windows**: `%PROGRAMDATA%\olm\olm-client\config.json` @@ -286,4 +292,4 @@ Default locations: ### API -Olm can be started with a HTTP or socket API to configure and manage it. See the [API documentation](https://github.com/fosrl/olm/blob/main/API.md) for more details. \ No newline at end of file +Olm can be started with a HTTP or socket API to configure and manage it. See the [API documentation](https://github.com/fosrl/olm/blob/main/API.md) for more details. diff --git a/manage/resources/private/alias.mdx b/manage/resources/private/alias.mdx index d34d91b..9b9d2b4 100644 --- a/manage/resources/private/alias.mdx +++ b/manage/resources/private/alias.mdx @@ -3,7 +3,7 @@ title: "Aliases" description: "Set a friendly alias hostname that resolves to a host" --- -Aliases provide a secondary, user-friendly address for any of your Resources, allowing users to access the Resource using this alternate name in addition to the original address. +Aliases provide a secondary, user-friendly address for any of your Resources, allowing users to access the Resource using this alternate name in addition to the original address. For instance, a router with the address `10.0.0.1` could be assigned the alias `router.internal`, and users could connect using either. Aliases are accessible to anyone who has access to the Resource, and they are exclusively accessible when connected with a Pangolin client, meaning they function without requiring any external DNS record setup. Furthermore, aliases are protocol agnostic, which means they will work with any network protocol, essentially acting as a pseudo-A record for an address that is only functional within the Pangolin environment. @@ -17,7 +17,9 @@ Since aliases cannot be single-label domains, you must avoid using domain names ## Custom Upstream DNS -Aliases work by overriding the DNS of your computer running the client so that all DNS requests are sent to the Pangolin client for resolution. The dns server on your computer is typically `100.96.128.1` which will forward request to an upstream server. By default, we use `9.9.9.9`, but this upstream address can be configured using [the flag](/manage/clients/configure-client) in the CLI / Olm or in the client settings. +Aliases work by overriding the DNS of your computer running the client so that all DNS requests are sent to the Pangolin client for resolution. The dns server on your computer is typically `100.96.128.1` (the first address inside of your utility subnet on the org) when connected to the tunnel which will forward request to an upstream server. By default, we use `9.9.9.9`, but this upstream address can be configured using [the flag](/manage/clients/configure-client) in the CLI / Olm or in the client settings. + +**If you are attempting to set an upstream DNS server that is only accessible via the tunnel, ensure that you create a resource and check the tunnel DNS option in the client configuration settings or use the --tunnel-dns flag.** Otherwise, connectivity to the server may fail when connected to the tunnel. ## Disable Aliases diff --git a/manage/resources/private/destinations.mdx b/manage/resources/private/destinations.mdx index b67cbc4..c8d3a49 100644 --- a/manage/resources/private/destinations.mdx +++ b/manage/resources/private/destinations.mdx @@ -26,9 +26,9 @@ Pangolin smooths away overlapping networks and arbitrarily chooses a single site It is recommended that you create overlapping resources only if absolutely required. If you do, use [Aliases](/manage/resources/private/alias) to explicitly defined which host should be used for a given FQDN or IP address and use the alias to connect. -## Why is ICMP Pinging Not Working? +## ICMP End to End? -Because Newt sites are proxying traffic out of the secure tunnel, ICMP needs to be handled specially just like UDP and TCP. Right now, ICMP **is not supported** through the Pangolin client. If you need to ping hosts on the remote network, consider using TCP or UDP-based tools like `hping3` or `nping` as alternatives. We plan to add ICMP support in a future release. +Pangolin supports testing connectivity to Resources using ICMP ping requests. However, it's important to note that while the Pangolin client can send ICMP echo requests to the destination, the actual ping request is captured and replayed from the Newt binary to the actually destination. This means that requests are not end to end but are still an effective way to test connectivity to a resource. ## Unicast Only? From c52b68395c88dca853189cb7ba27169435bc1c15 Mon Sep 17 00:00:00 2001 From: Owen Date: Fri, 19 Dec 2025 12:17:25 -0500 Subject: [PATCH 2/6] Add new clients_start_port to the config --- self-host/advanced/config-file.mdx | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/self-host/advanced/config-file.mdx b/self-host/advanced/config-file.mdx index 7d802c1..1b22786 100644 --- a/self-host/advanced/config-file.mdx +++ b/self-host/advanced/config-file.mdx @@ -429,7 +429,7 @@ This section contains the complete reference for all configuration options in `c **Default**: `false` - When enabled, uses file-based dynamic configuration instead of API-based updates. + When enabled, uses file-based dynamic configuration instead of API-based updates. @@ -461,6 +461,12 @@ This section contains the complete reference for all configuration options in `c **Example**: `51820` + + Starting port for client WireGuard relay and hole punch port. + + **Example**: `21820` + + Whether to assign unique subdomains to Gerbil exit nodes. @@ -823,6 +829,6 @@ Some configuration values can be set using environment variables for enhanced se | Name | Variable | Config | |------|----------|--------| -| Server Secret | `SERVER_SECRET` | `server.secret` | +| Server Secret | `SERVER_SECRET` | `server.secret` | | Email Password | `EMAIL_SMTP_PASS` | `email.smtp_pass` | | PostgreSQL Connection String | `POSTGRES_CONNECTION_STRING` | `postgres.connection_string` | From 3641ba3b91d5ef26370fb76fe0b6081a3bba5861 Mon Sep 17 00:00:00 2001 From: Owen Date: Mon, 22 Dec 2025 14:39:32 -0500 Subject: [PATCH 3/6] Add maintenance options --- manage/blueprints.mdx | 81 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 77 insertions(+), 4 deletions(-) diff --git a/manage/blueprints.mdx b/manage/blueprints.mdx index cc8892f..bffdd42 100644 --- a/manage/blueprints.mdx +++ b/manage/blueprints.mdx @@ -21,6 +21,10 @@ Pangolin supports two blueprint formats: 1. **YAML Configuration Files**: Standalone configuration files 2. **Docker Labels**: Configuration embedded in Docker Compose files + +Some features in this documentation are marked with **(EE)**, indicating they are available only in the Enterprise Edition of Pangolin. + + ## YAML Configuration Format YAML config can be applied using Docker labels, API, from a Newt site, or in the UI. _Application through a CLI tool is planned._ @@ -83,7 +87,7 @@ public-resources: match: ip value: 1.1.1.1 - action: deny - match: cidr + match: cidr value: 2.2.2.2/32 - action: pass match: path @@ -104,7 +108,7 @@ public-resources: protocol: tcp proxy-port: 3000 targets: - - site: lively-yosemite-toad + - site: lively-yosemite-toad hostname: localhost port: 3000 ``` @@ -159,6 +163,35 @@ public-resources: When using targets-only resources, the `name` and `protocol` fields are not required. All other resource-level validations are skipped for these simplified configurations. +### Maintenance Page Configuration **(EE)** + + +This is an Enterprise Edition (EE) feature only. It allows you to display a maintenance page for a public resource when it's under maintenance or when targets are unhealthy. + + +```yaml +public-resources: + production-app: + name: Production Application + protocol: http + full-domain: app.example.com + maintenance: + enabled: true + type: forced + title: Scheduled Maintenance + message: We are performing system upgrades to improve performance. The service will be back online shortly. + estimated-time: 2 hours + targets: + - site: my-site + hostname: app-server + method: https + port: 443 +``` + +**Maintenance Types:** +- **`forced`**: Always displays the maintenance page regardless of target health status +- **`automatic`**: Displays the maintenance page only when all targets are unhealthy or the sites are offline + ### Private Resources Private resources define proxied resources accessible when connected via an client: @@ -258,7 +291,7 @@ networks: name: pangolin_default ``` -This will create a resource that looks like the following: +This will create a resource that looks like the following: Example resource @@ -295,6 +328,7 @@ This will create a resource that looks like the following: | `headers` | array | No | Custom headers to add to requests | Each header requires `name` and `value` (min 1 char each) | | `rules` | array | No | Access control rules | See Rules section below | | `auth` | object | HTTP only | Authentication configuration | See Authentication section below | +| `maintenance` | object | No | Maintenance page configuration **(EE)** | Enterprise Edition only. See Maintenance Configuration section below | | `targets` | array | Yes | Target endpoints for the resource | See Targets section below | ### Target Configuration @@ -374,6 +408,45 @@ Not allowed on TCP/UDP resources. | `whitelist-users` | array | No | Whitelisted user emails | Must be valid email addresses | | `auto-login-idp` | number | No | Automatic login identity provider ID | Must be a positive integer | +### Maintenance Configuration **(EE)** + + +This is an Enterprise Edition (EE) feature only. It allows you to display a maintenance page for a public resource. + + +The `maintenance` object can be added to any public resource to display a maintenance page to users: + +```yaml +public-resources: + my-service: + name: My Service + protocol: http + full-domain: service.example.com + maintenance: + enabled: true + type: automatic + title: Scheduled Maintenance + message: We are performing scheduled maintenance. Service will resume shortly. + estimated-time: 2 hours + targets: + - site: my-site + hostname: backend-server + method: https + port: 8443 +``` + +| Property | Type | Required | Description | Constraints | +|----------|------|----------|-------------|-------------| +| `enabled` | boolean | No | Whether the maintenance page is enabled | Defaults to `false` | +| `type` | string | No | Maintenance type (`forced` or `automatic`) | `forced` always shows maintenance page; `automatic` shows only when all targets are unhealthy or sites offline | +| `title` | string | No | Title text for the maintenance page | Maximum 255 characters, can be null | +| `message` | string | No | Message text explaining the maintenance | Maximum 2000 characters, can be null | +| `estimated-time` | string | No | Estimated time for maintenance completion | Maximum 100 characters, can be null | + +**Maintenance Types:** +- **`forced`**: Always displays the maintenance page regardless of target health status +- **`automatic`**: Displays the maintenance page only when all targets are unhealthy + ### Rules Configuration | Property | Type | Required | Description | Constraints | @@ -450,4 +523,4 @@ For private resources in `host` mode, the destination must be a valid IP address For private resources in `cidr` mode, the destination must be a valid CIDR notation (e.g., 10.0.0.0/24). ### "Admin role cannot be included in roles" -The `Admin` role is reserved and cannot be included in the `roles` array for private resource configuration. \ No newline at end of file +The `Admin` role is reserved and cannot be included in the `roles` array for private resource configuration. From fa232eb39cb3d1d4a9db297bf13a894c4922c1a5 Mon Sep 17 00:00:00 2001 From: Owen Date: Mon, 22 Dec 2025 14:44:37 -0500 Subject: [PATCH 4/6] Move healthcheck --- docs.json | 6 +++++- manage/{ => resources/public}/healthchecks-failover.mdx | 0 2 files changed, 5 insertions(+), 1 deletion(-) rename manage/{ => resources/public}/healthchecks-failover.mdx (100%) diff --git a/docs.json b/docs.json index 6fcc451..bbee9a4 100644 --- a/docs.json +++ b/docs.json @@ -46,7 +46,7 @@ "pages": [ "manage/resources/public/authentication", "manage/resources/public/targets", - "manage/healthchecks-failover", + "manage/resources/public/healthchecks-failover", "manage/resources/public/raw-resources" ] }, @@ -282,6 +282,10 @@ { "source": "/manage/resources/tcp-udp-resources", "destination": "/manage/resources/public/raw-resources" + }, + { + "source": "manage/healthchecks-failover", + "destination": "manage/resources/public/healthchecks-failover" } ], "seo": { diff --git a/manage/healthchecks-failover.mdx b/manage/resources/public/healthchecks-failover.mdx similarity index 100% rename from manage/healthchecks-failover.mdx rename to manage/resources/public/healthchecks-failover.mdx From e8de8b1d462e359c6fd8c20a3b8af6fc5c1538f5 Mon Sep 17 00:00:00 2001 From: Owen Date: Mon, 22 Dec 2025 15:14:36 -0500 Subject: [PATCH 5/6] Add maintenance page docs --- docs.json | 5 ++-- images/maintenance_page.png | Bin 0 -> 49975 bytes manage/resources/public/maintenance.mdx | 38 ++++++++++++++++++++++++ 3 files changed, 41 insertions(+), 2 deletions(-) create mode 100644 images/maintenance_page.png create mode 100644 manage/resources/public/maintenance.mdx diff --git a/docs.json b/docs.json index bbee9a4..a3302fd 100644 --- a/docs.json +++ b/docs.json @@ -46,8 +46,9 @@ "pages": [ "manage/resources/public/authentication", "manage/resources/public/targets", - "manage/resources/public/healthchecks-failover", - "manage/resources/public/raw-resources" + "manage/resources/public/raw-resources", + "manage/resources/public/maintenance", + "manage/resources/public/healthchecks-failover" ] }, { diff --git a/images/maintenance_page.png b/images/maintenance_page.png new file mode 100644 index 0000000000000000000000000000000000000000..549fd3ec5853e3a11044784bc41c02fb725c05df GIT binary patch literal 49975 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 E2inodN&o-= literal 0 HcmV?d00001 diff --git a/manage/resources/public/maintenance.mdx b/manage/resources/public/maintenance.mdx new file mode 100644 index 0000000..2fc4e38 --- /dev/null +++ b/manage/resources/public/maintenance.mdx @@ -0,0 +1,38 @@ +--- +title: "Maintenance Page" +description: "Show a maintenance page to users when a resources is down for maintenance or targets are unhealthy" +--- + + +Maintenance pages are only available in Enterprise Edition. + + +Pangolin can display a customizable maintenance page to users when a resource is undergoing maintenance or when all targets are unhealthy. This ensures users are informed about the downtime and provides a better user experience. + + + Maintenance Page Preview + + +## Configuration + +Title: The main title text displayed on the maintenance page. + +Message: A descriptive message informing users about the maintenance status. + +Estimated completion time: Optionally provide an estimated time for when the resource will be back online. + +## Enabling Maintenance Page + +To enable the maintenance page for a resource, navigate to the general resource settings in the Pangolin dashboard. Under the "Maintenance Page" section, you can customize the title, message, and estimated completion time. This can also be set using Blueprints. + +## When is the Maintenance Page Shown? + +There are two modes that control when the page is shown: + +#### Forced + +In forced mode, the maintenance page is displayed to all users regardless of the health status of the resource targets. This is useful for planned maintenance windows. + +#### Automatic + +In automatic mode, the maintenance page is shown only when all targets associated with the resource are unhealthy or all of the sites are offline. This is useful for unplanned outages and can be used to inform the user that the resource is temporarily unavailable by customizing the above settings. From 01c75a47105fd144044aa8d98e0d037d5735fb5d Mon Sep 17 00:00:00 2001 From: Owen Date: Mon, 22 Dec 2025 15:14:47 -0500 Subject: [PATCH 6/6] Add wildcards and clarify icmp --- manage/resources/private/alias.mdx | 6 ++++++ manage/resources/private/destinations.mdx | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/manage/resources/private/alias.mdx b/manage/resources/private/alias.mdx index 9b9d2b4..90e816b 100644 --- a/manage/resources/private/alias.mdx +++ b/manage/resources/private/alias.mdx @@ -15,6 +15,12 @@ A alias can only be created for a Resource that is a single host (IP or FQDN). A Since aliases cannot be single-label domains, you must avoid using domain names that do not contain a dot (e.g., `pangolin`). A domain like `pangolin.net`, which includes a dot, is acceptable. Instead of a single-label domain, you should consider using a subdomain of a domain you control, such as `router.mywebsite.com`, or an existing private/internal domain name, like `router.internal` or `router.corp`. +### Wildcards + +Wildcards allow you to define aliases that match multiple hostnames using special characters in the FQDN. For example, in an alias like `*.host-0?.autoco.internal`, the asterisk `*` matches any sequence of characters (including none), and the question mark `?` matches exactly one character. + +If you use a wildcard such as `*.proxy.internal`, it will match any hostname that ends with `.proxy.internal` and has something before the dot—such as `host.proxy.internal`, `longerhost.proxy.internal`, or even `sub.host.proxy.internal`. However, the wildcard will not match the base domain itself (`autoco.internal` without anything before the dot). + ## Custom Upstream DNS Aliases work by overriding the DNS of your computer running the client so that all DNS requests are sent to the Pangolin client for resolution. The dns server on your computer is typically `100.96.128.1` (the first address inside of your utility subnet on the org) when connected to the tunnel which will forward request to an upstream server. By default, we use `9.9.9.9`, but this upstream address can be configured using [the flag](/manage/clients/configure-client) in the CLI / Olm or in the client settings. diff --git a/manage/resources/private/destinations.mdx b/manage/resources/private/destinations.mdx index c8d3a49..56e9122 100644 --- a/manage/resources/private/destinations.mdx +++ b/manage/resources/private/destinations.mdx @@ -28,7 +28,7 @@ It is recommended that you create overlapping resources only if absolutely requi ## ICMP End to End? -Pangolin supports testing connectivity to Resources using ICMP ping requests. However, it's important to note that while the Pangolin client can send ICMP echo requests to the destination, the actual ping request is captured and replayed from the Newt binary to the actually destination. This means that requests are not end to end but are still an effective way to test connectivity to a resource. +Pangolin supports testing connectivity to Resources using ICMP ping requests. However, it's important to note that while the Pangolin client can send ICMP echo requests to the destination, **the actual ping request is captured and replayed from the Newt binary to the actually destination**. This means that requests are not end to end but are still an effective way to test connectivity to a resource. ## Unicast Only?