diff --git a/docs.json b/docs.json
index 44c2839..6fcc451 100644
--- a/docs.json
+++ b/docs.json
@@ -278,6 +278,10 @@
{
"source": "/community/:slug*",
"destination": "/self-host/:slug*"
+ },
+ {
+ "source": "/manage/resources/tcp-udp-resources",
+ "destination": "/manage/resources/public/raw-resources"
}
],
"seo": {
@@ -285,4 +289,4 @@
"canonical": "https://docs.pangolin.net"
}
}
-}
\ No newline at end of file
+}
diff --git a/images/system-diagram.svg b/images/system-diagram.svg
index 8f1fb2d..5945064 100644
--- a/images/system-diagram.svg
+++ b/images/system-diagram.svg
@@ -1,4 +1,4 @@
-
+
\ No newline at end of file
diff --git a/index.mdx b/index.mdx
index 1ee76a1..f36d7ef 100644
--- a/index.mdx
+++ b/index.mdx
@@ -20,7 +20,7 @@ Users access public resources through any web browser with authentication. Users
Learn about the fundamentals of Pangolin and how they work together to provide simple and secure remote access.
-
+
What are the similarities and differences between Pangolin and traditional reverse proxies and VPNs?
diff --git a/manage/access-control/rules.mdx b/manage/access-control/rules.mdx
index 8e2f471..b7993e7 100644
--- a/manage/access-control/rules.mdx
+++ b/manage/access-control/rules.mdx
@@ -31,30 +31,30 @@ Path match rules allow URL patterns defined with plain text and wildcards (`*`)
#### Examples:
-- `blog/posts`
+- `blog/posts`
Matches the exact path `/blog/posts`.
-- `blog/*`
+- `blog/*`
Matches any path under `/blog` (e.g., `/blog/travel`).
-- `*/2023/*`
+- `*/2023/*`
Matches paths with `/2023/` as a middle segment (e.g., `/news/2023/summary`).
-- `article*`
+- `article*`
Matches **segments** starting with "article" (e.g., `/article-123`).
-- `*admin*`
+- `*admin*`
Matches **segments** containing "admin" (e.g., `/my-admin-panel`).
-- `personal-*/*`
+- `personal-*/*`
Matches paths where the first segment starts with `personal-` and is followed by any segment (e.g., `/personal-blog/post`).
#### Segment-by-Segment Matching
-- **Normalization:**
+- **Normalization:**
Both patterns and URLs are split into segments. For example, `/blog/journal/entry` becomes `["blog", "journal", "entry"]`, while `/blog*` becomes `["blog*"]`.
-- **Validation:**
+- **Validation:**
Each pattern segment must correspond to a URL segment, and wildcards match zero or more characters within that segment. A pattern like `/blog*` only matches the first segment, so URLs with extra segments require additional placeholders (e.g., `/blog*/*`).
### Country
@@ -99,7 +99,7 @@ This table compiles paths that need to be allowed for various apps to work with
| **Media Management** | |
| Radarr | `/api/*` |
| Sonarr | `/api/*` |
-| Lidarr | `/api/*` |
+| Lidarr | `/api/*` |
| **Media Servers** | |
| Jellyfin (iOS) | `/system/info/public` |
| Jellyfin (Roku) | `/System/Info/Public` `/Users/AuthenticateByName` `/Users/Public` `/QuickConnect/Initiate` `/QuickConnect/Connect` `/Users/AuthenticateWithQuickConnect` |
@@ -134,12 +134,12 @@ This table compiles paths that need to be allowed for various apps to work with
| **Notifications** | |
| Gotify | `/version` `/message` `/application` `/client` `/stream` `/plugin` `/health` |
| **Home Automation** | |
-| Home Assistant | `/api/*` `/auth/*` `/frontend_latest/*` `/lovelace*` `/static/*` `/hacsfiles/*` `/local/*` |
+| Home Assistant | `/api/*` `/auth/*` `/frontend_latest/*` `/lovelace/*` `/static/*` `/hacsfiles/*` `/local/*` `/manifest.json` `/sw-modern.js` |
| n8n | `/webhook-test/*/webhook` `/webhook/*/webhook` |
| **Project Management** | |
| Jetbrains Youtrack | `/api/*` `/hub/api/*` |
| **Genealogy** | |
-| Gramps Web | `/api/*`
+| Gramps Web | `/api/*`
| **Analytics** | |
| Umami | `/script.js` `/api/send` |
diff --git a/manage/blueprints.mdx b/manage/blueprints.mdx
index 69d83bb..cc8892f 100644
--- a/manage/blueprints.mdx
+++ b/manage/blueprints.mdx
@@ -49,7 +49,7 @@ YAML config can be applied using Docker labels, API, from a Newt site, or in the
You can also apply blueprints directly through the Pangolin API with an API key. [Take a look at the API documentation for more details.](https://api.pangolin.net/v1/docs/#/Organization/put_org__orgId__blueprint)
- POST to `/org/{orgId}/blueprint` with a base64 encodes JSON body like the following:
+ PUT to `/org/{orgId}/blueprint` with a base64 encodes JSON body like the following:
```json
{
@@ -191,6 +191,10 @@ private-resources:
For containerized applications, you can define blueprints using Docker labels.
+
+Blueprints will **continuously apply** from changes in the docker stack, newt restarting, or when viewing the resource in the dashboard.
+
+
### Enabling Docker Socket Access
To use Docker labels, enable the Docker socket when running Newt:
@@ -207,6 +211,10 @@ DOCKER_SOCKET=/var/run/docker.sock
### Docker Compose Example
+
+The compose file will be the source of truth, any edits through the resources dashboard will be **overwritten** by the blueprint labels defined in the compose stack.
+
+
```yaml
services:
newt:
@@ -362,7 +370,7 @@ Not allowed on TCP/UDP resources.
| `basic-auth` | object | No | Basic authentication configuration | Requires `user` and `password` fields |
| `sso-enabled` | boolean | No | Enable SSO authentication | Defaults to `false` |
| `sso-roles` | array | No | Allowed SSO roles | Cannot include "Admin" role |
-| `sso-users` | array | No | Allowed SSO user emails | Must be valid email addresses |
+| `sso-users` | array | No | Allowed SSO usernames | Must be valid usernames |
| `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 |
diff --git a/manage/clients/install-client.mdx b/manage/clients/install-client.mdx
index ed21841..631e6fd 100644
--- a/manage/clients/install-client.mdx
+++ b/manage/clients/install-client.mdx
@@ -130,7 +130,7 @@ curl -fsSL https://static.pangolin.net/get-olm.sh | bash
#### Windows
-If you would like to use Olm on Windows, wintun.dll is required. Please use latest installer from [GitHub releases](https://github.com/fosrl/olm/releases/latest).V
+If you would like to use Olm on Windows, wintun.dll is required. Please use latest installer from [GitHub releases](https://github.com/fosrl/olm/releases/latest).
#### Manual Download
@@ -190,6 +190,8 @@ services:
container_name: olm
restart: unless-stopped
network_mode: host
+ cap_add:
+ - NET_ADMIN
devices:
- /dev/net/tun:/dev/net/tun
environment:
@@ -207,6 +209,8 @@ services:
container_name: olm
restart: unless-stopped
network_mode: host
+ cap_add:
+ - NET_ADMIN
devices:
- /dev/net/tun:/dev/net/tun
command:
@@ -218,6 +222,7 @@ services:
**Docker Configuration Notes:**
- `network_mode: host` brings the olm network interface to the host system, allowing the WireGuard tunnel to function properly
+- `cap_add: - NET_ADMIN` is required to grant the container permission to manage network interfaces
- `devices: - /dev/net/tun:/dev/net/tun` is required to give the container access to the TUN device for creating WireGuard interfaces
### Windows Service
diff --git a/manage/clients/understanding-clients.mdx b/manage/clients/understanding-clients.mdx
index 5c7752d..7dd7e1b 100644
--- a/manage/clients/understanding-clients.mdx
+++ b/manage/clients/understanding-clients.mdx
@@ -47,7 +47,7 @@ Examples include:
- **CICD**: Access remote resources like a database in an automated deployment pipeline.
- **Servers**: Provide a VPS with access to a resource running in a different network.
-Though you may connect a server via a user account using a CLI client, we reccomend you specifically use a machine client.
+Though you may connect a server via a user account using a CLI client, we recommend you specifically use a machine client.
Machine clients authenticate with an ID and secret string. These credentials are passed via arguments into one of the supported Pangolin CLI clients. They can be revoked and rotated.
@@ -61,7 +61,9 @@ Clients can relay traffic through a Pangolin server - through Gerbil specificall
### NAT Hole Punching
-While functional, it does not always connect reliably and can fall back to relaying. We plan to work to improve the reliability over time by implementing more methods for those behind CGNAT or hard nats.
+NAT hole punching establishes a direct peer-to-peer connection between the client and site, bypassing the need to route traffic through the Pangolin server. The server coordinates the initial connection by helping both peers discover each other's network addresses, allowing them to establish a direct tunnel through their respective NATs and firewalls.
+
+If the site and client are unable to hole punch, they fall back to relaying through your Pangolin server.
Take a look at [some things you can do to improve reliability](/manage/sites/configure-site#nat-traversal-tweaks) if you are not getting reliable hole punching.
diff --git a/manage/sites/configure-site.mdx b/manage/sites/configure-site.mdx
index 361f8cb..2a413d8 100644
--- a/manage/sites/configure-site.mdx
+++ b/manage/sites/configure-site.mdx
@@ -107,12 +107,6 @@ description: "Configure Newt for connecting to Pangolin sites"
**Default**: `false` (clients enabled)
-
- Use native WireGuard interface (requires WireGuard kernel module and Linux, must run as root).
-
- **Default**: `false` (uses userspace netstack)
-
-
Name of the WireGuard interface.
@@ -277,12 +271,6 @@ When both environment variables and CLI arguments are provided, CLI arguments ta
**Default**: `false`
-
- Use native WireGuard interface (Linux only, equivalent to `--native`)
-
- **Default**: `false`
-
-
Name of the WireGuard interface (equivalent to `--interface`)
diff --git a/self-host/advanced/cloudflare-proxy.mdx b/self-host/advanced/cloudflare-proxy.mdx
index 1a40a37..63729b3 100644
--- a/self-host/advanced/cloudflare-proxy.mdx
+++ b/self-host/advanced/cloudflare-proxy.mdx
@@ -54,3 +54,37 @@ gerbil:
```
+
+### Getting the Real Client IP
+
+Pangolin needs to know the original client IP address for features like rate limiting. When Cloudflare proxy is enabled, the API server sees Cloudflare's IP instead of the real client IP.
+
+Cloudflare sets special headers with the real IP that need to be processed by Traefik before forwarding to Pangolin. Configure Traefik to parse these headers using a community plugin for Traefik: [Real IP from Cloudflare Proxy Tunnel](https://plugins.traefik.io/plugins/62e97498e2bf06d4675b9443/real-ip-from-cloudflare-proxy-tunnel).
+
+Add the plugin to your Traefik configuration:
+
+```yaml
+experimental:
+ plugins:
+ cloudflarewarp:
+ moduleName: github.com/BetterCorp/cloudflarewarp
+ version: v1.3.0
+
+entryPoints:
+ websecure:
+ address: ':443'
+ http:
+ middlewares:
+ - cloudflarewarp@file
+```
+
+This creates a middleware called `cloudflarewarp` and applies it to the `websecure` entrypoint.
+
+Then set `trust_proxy: 2` in your Pangolin config file. This tells Pangolin to trust the second-level proxy (Traefik is proxy 1, Cloudflare is proxy 2):
+1
+```yaml
+server:
+ trust_proxy: 2
+```
+
+After making these changes, restart both Traefik and Pangolin for the configuration to take effect.
diff --git a/self-host/manual/docker-compose.mdx b/self-host/manual/docker-compose.mdx
index 5cb68b3..03aa833 100644
--- a/self-host/manual/docker-compose.mdx
+++ b/self-host/manual/docker-compose.mdx
@@ -144,8 +144,6 @@ services:
restart: unless-stopped
volumes:
- ./config:/app/config
- - pangolin-data:/var/certificates
- - pangolin-data:/var/dynamic
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3001/api/v1/"]
interval: "3s"
@@ -187,17 +185,12 @@ services:
volumes:
- ./config/traefik:/etc/traefik:ro # Volume to store the Traefik configuration
- ./config/letsencrypt:/letsencrypt # Volume to store the Let's Encrypt certificates
- # Shared volume for certificates and dynamic config in file mode
- - pangolin-data:/var/certificates:ro
- - pangolin-data:/var/dynamic:ro
+ - ./config/traefik/logs:/var/log/traefik # Volume to store Traefik logs
networks:
default:
driver: bridge
name: pangolin
-
-volumes:
- pangolin-data:
```
## Traefik Static Configuration