test deploy

This commit is contained in:
miloschwartz
2025-07-31 21:44:10 -07:00
parent b918f105b5
commit 647080c1d5
33 changed files with 2045 additions and 107 deletions

View File

@@ -0,0 +1,130 @@
---
title: "Bypass Rules"
description: "Configure rules to allow or deny access to resources without authentication"
---
Rules allow you to either "allow" and bypass the Pangolin auth system (no pin, login, password), or "deny" and fully reject the request. After you create a resource you can select the "Rules" tab on the sidebar and enable rules.
<CardGroup cols={2}>
<Card title="Allow Rules" icon="check">
Bypass authentication completely for matching requests. Users can access resources without any login or PIN.
</Card>
<Card title="Deny Rules" icon="x">
Completely reject requests that match the rule. Useful for blocking admin paths or sensitive endpoints.
</Card>
</CardGroup>
## Types of Rules
Rules are processed from top to bottom in order of their priority. This means you can have multiple rules to bypass auth and to just flat deny users at the end.
Right now you can match on the following items:
### Path
Path match rules allow URL patterns defined with plain text and wildcards (`*`) that match any characters. Patterns and URLs are split into segments (using `/`), and **each segment is matched individually**.
#### Examples:
- `blog/posts`
Matches the exact path `/blog/posts`.
- `blog/*`
Matches any path under `/blog` (e.g., `/blog/travel`).
- `*/2023/*`
Matches paths with `/2023/` as a middle segment (e.g., `/news/2023/summary`).
- `article*`
Matches **segments** starting with "article" (e.g., `/article-123`).
- `*admin*`
Matches **segments** containing "admin" (e.g., `/my-admin-panel`).
- `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:**
Both patterns and URLs are split into segments. For example, `/blog/journal/entry` becomes `["blog", "journal", "entry"]`, while `/blog*` becomes `["blog*"]`.
- **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*/*`).
### CIDR
CIDR (Classless Inter-Domain Routing) notation specifies IP address ranges using an IP address and a network prefix length. The format is [IP address]/[prefix length].
**Examples:**
- `144.234.11.22/24` - Matches all 256 IPs from 192.168.1.0 to 192.168.1.255
- `10.0.0.0/8` - Matches any IP starting with 10 (16.7 million addresses)
- `2001:db8::/32` - Matches a range of IPv6 addresses
- `0.0.0.0/0` - Matches all IPv4 addresses
<Note>
The prefix length (1-32 for IPv4, 1-128 for IPv6) determines how many bits from the left are fixed. Smaller prefix numbers match larger ranges.
</Note>
### IP
Pretty simple: you can match on simply an IP address like your home IP to bypass auth. This is the same as entering a /32 CIDR.
**Examples:**
- `23.234.134.32`
- `34.45.245.64`
- `192.168.1.1`
## Rules for Specific Apps
This table compiles paths that need to be allowed for various apps to work with Pangolin authentication.
| App | Required Bypass Rules |
| -------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Media Management** | |
| Radarr | `/api/*` |
| Sonarr | `/api/*` |
| Lidarr | `/api/*` |
| **Media Servers** | |
| Jellyfin (iOS) | `/system/info/public` |
| Jellyfin (Roku) | `/System/Info/Public`<br />`/Users/AuthenticateByName`<br />`/Users/Public`<br />`/QuickConnect/Initiate`<br />`/QuickConnect/Connect`<br />`/Users/AuthenticateWithQuickConnect` |
| Audiobookshelf (Android) | `/api/*`<br />`/login*`<br />`/s/*`<br />`/ping*`<br />`/feed/*`<br />`/socket*`<br />`/status` |
| **Management & Monitoring** | |
| Tautulli | `/api/*` |
| Harbour | `/api/*` |
| Hoarder App | `/api/*` |
| Uptime Kuma Manager | `/api/*`<br />`/socket.io/*` |
| MeshCentral | `/api/*`<br />`/meshrelay.ashx`<br />`/agent.ashx` |
| **Security & Privacy** | |
| AdGuard Home | `/api/*` |
| Ente Auth | `*api*` |
| Vaultwarden/Bitwarden | `/api/*`<br />`/identity/*`<br />`/wl/*`<br />Always Deny - Path - `/admin/*` |
| **Cloud & Sync** | |
| Nextcloud | `/` (Main interface)<br />`/index.php` (Core handler)<br />`/remote.php` (Remote access)<br />`/status.php` (Status checks)<br />`/ocs` (Collaboration Services API)<br />`/apps` (Applications)<br />`/remote.php/webdav` (WebDAV endpoint)<br />`/remote.php/dav` (CalDAV/CardDAV)<br />`/remote.php/caldav` (Calendar sync)<br />`/remote.php/carddav` (Contacts sync)<br />`/ocs/v1.php` (API endpoints)<br />`/ocs/v2.php` (API v2 endpoints)<br />`/login` (Authentication)<br />`/.well-known/*` (Service discovery)<br />`/.well-known/webfinger` (WebFinger protocol)<br />`/s/*` (Shared files/folders) |
| Onlyoffice | `/cache/*`<br />`*/CommandService.ashx`<br />`*/converter/*`<br />`*/doc/*`<br />`*/downloadas/*`<br />`/downloadfile/*`<br />`*/fonts/*`<br />`/healthcheck`<br />`/methodology/*`<br />`*/plugins.json`<br />`*/sdkjs/*`<br />`*/sdkjs-plugins/*`<br />`*/themes.json`<br />`*/web-apps/*`
| **Photo Management** | |
| Ente Photos | `*api*` |
| Immich | `/api/*`<br />`/.well-known/immich` |
| **File Management** | |
| Filebrowser | `/static/*`<br />`/share/*` <br/> `/api/public/dl/*` <br/> `/api/public/share/*` |
| **Notes & Knowledge Management** | |
| Joplin Notes Server | `/api/*`<br />`/shares/*`<br />`/css/*`<br />`/images/*`<br />Always Deny - Path - `/login/*` (optional) |
| Erugo | `/api/*`<br />`/shares/*`<br />`/build/*`<br />`/get-logo` |
| Memos | `/api/*`<br />`/assets/*`<br />`/explore*`<br />`/memos.api.v1.*`<br />`/auth/callback*`<br />`/auth`<br />`/site.webmanifest`<br />`/logo.webp`<br />`/full-logo.webp`<br />`/android-chrome-192x192.png` |
| Linkding | `/api/*`<br />`/bookmarks/*`<br />Always Deny - Path - `/admin/*` |
| **Communication** | |
| Matrix/Synapse (Clients) | `/_matrix/*`<br />`/_synapse/client/*` |
| Matrix/Synapse (Federation) | `/_matrix/*` |
| **Notifications** | |
| Gotify | `/version`<br />`/message`<br />`/application`<br />`/client`<br />`/stream`<br />`/plugin`<br />`/health` |
| **Home Automation** | |
| Home Assistant | `/api/*`<br />`/auth/*`<br />`/frontend_latest/*`<br />`/lovelace*`<br />`/static/*`<br />`/hacsfile/*`<br />`/local/*` |
| **Project Management** | |
| Jetbrains Youtrack | `/api/*`<br />`/hub/api/*`<br /> |
<Note>
These rules are examples and may need to be adjusted based on your specific app configuration and version.
</Note>

View File

View File

View File

0
manage/domains.mdx Normal file
View File

View File

@@ -0,0 +1,29 @@
---
title: "High Availability"
description: "Learn about Pangolin's high availability options and how to ensure your applications remain accessible"
---
Pangolin provides multiple deployment options to ensure your applications remain highly available and accessible to users worldwide.
<CardGroup cols={3}>
<Card title="Pangolin Cloud" icon="cloud" href="https://pangolin.fossorial.io/auth/signup">
Global network of points of presence with automatic failover and routing to your backend services.
</Card>
<Card title="Hybrid" icon="server" href="mailto:numbat@fossorial.io">
Host your own multiple highly available points of presence with cloud coordination and automatic failover.
</Card>
<Card title="Self-Hosted" icon="server" href="/self-host/quick-install">
Fully self-hosted, self-contained Pangolin server acting as a single point of presence.
</Card>
</CardGroup>
## How It Works
For detailed information about how points of presence work and their advantages, see our [Points of Presence](/manage/points-of-presence) documentation.
## Contact Us
For hybrid deployments, points of presence, and high availability contact us:
- **Email**: [numbat@fossorial.io](mailto:numbat@fossorial.io)

View File

@@ -0,0 +1,58 @@
---
title: "Add Identity Providers"
description: "Configure external identity providers for user authentication"
---
<Note>
Identity providers are only available in self-hosted Pangolin instances.
</Note>
Identity providers let you authenticate Pangolin users using external identity providers. This is useful for organizations that want to use their existing identity provider infrastructure to manage user authentication.
For example, you may have users defined in Authentik, and you want these users to be able to log in to Pangolin using their existing credentials.
<CardGroup cols={2}>
<Card title="What it does" icon="users">
Allows users to authenticate using external identity providers instead of Pangolin's built-in authentication.
</Card>
<Card title="When to use" icon="gear">
Useful for organizations with existing identity infrastructure like Authentik, Keycloak, or Okta.
</Card>
</CardGroup>
## Supported Identity Providers
### OAuth2/OIDC
This can be used to connect to any external identity provider that supports the OpenID Connect protocol such as:
- **Authentik**
- **Keycloak**
- **Okta**
- **Other OIDC-compliant providers**
## How to Add an Identity Provider
<Steps>
<Step title="Access Server Admin">
Select the "Identity Providers" tab in the Server Admin UI.
</Step>
<Step title="Add New Provider">
Click on the "Add Identity Provider" button.
</Step>
<Step title="Select Type">
Select the type of identity provider you want to add (OAuth2/OIDC).
</Step>
<Step title="Configure Settings">
Fill in the required fields for the selected identity provider type.
</Step>
</Steps>
## Auto Provisioning
See [Auto Provision](manage/identity-providers/auto-provisioning) for more information on how to automatically provision users and assign orgs and roles in Pangolin when they log in using an external identity provider.

View File

@@ -0,0 +1,191 @@
---
title: "Auto Provisioning"
description: "Automatically create and manage user accounts from external identity providers"
---
Auto provisioning is a feature that allows you to automatically create and manage user accounts in Pangolin when they log in using an external identity provider. This is useful for organizations that want to streamline the onboarding process for new users and ensure that their user accounts are always up-to-date.
You will be able to programmatically decide the roles and organizations for new users based on the information provided by the identity provider.
<CardGroup cols={2}>
<Card title="What it does" icon="users">
Automatically creates user accounts when users log in through external identity providers.
</Card>
<Card title="Benefits" icon="bolt">
Streamlines onboarding and keeps user accounts up-to-date with external identity systems.
</Card>
</CardGroup>
## Enable Auto Provision
Toggle the "Auth Provision Users" switch when creating or editing an identity provider.
## What if Auto Provisioning is Disabled?
If auto provision is disabled, organization admins will need to manually create the user accounts and select the role for each user. When creating a user, you can select the identity provider that the user will be associated with. A user will not be able to log in using the identity provider if a user is not pre-provisioned in the system.
## How Auto Provisioning Works
It is helpful to think of the auto provisioning process as follows:
<Steps>
<Step title="User Login">
User successfully logs in using an identity provider.
</Step>
<Step title="Account Creation">
Pangolin creates a user account for the user.
</Step>
<Step title="Organization Evaluation">
Pangolin will loop through each organization and evaluate the JMESPath expression for the organization. If the expression does not return true or the same ID as the current organization, the user will not be added to the organization.
</Step>
<Step title="Role Assignment">
For each organization, Pangolin will evaluate the JMESPath expression for the role. If no role is found with the exact name in that organization, the user will not be added to the organization.
</Step>
</Steps>
## Configuration Options
### Organization Policies
You can configure policy for each organization with its own roles selector expression and organization selector expression.
### Default (Fallback) Policy
You can optionally configure a default policy for all organizations. This will be used if the organization does not have its own policy configured.
## Selecting Roles
Use JMESPath to map attributes from the identity provider to roles in Pangolin. See [JMESPath](https://jmespath.org/) for more information on how to use JMESPath.
The expression will be matched against each organization. Meaning:
- The result of the expression must return the exact string of the role name as it is defined in the organization.
- If no matching role is found, the user will not be added to the organization.
### Example
**Expression:**
```
contains(groups, 'admin') && 'Admin' || 'Member'
```
**Identity Provider Data:**
```json
{
...
"sub": "9590c3bfccd1b1a54b35845fb1bb950057dfa50fba43cb8bada58b462c80e207",
"aud": "JJoSvHCZcxnXT2sn6CObj6a21MuKNRXs3kN5wbys",
"exp": 1745790819,
"iat": 1745789019,
"auth_time": 1745789019,
"email": "user@example.com",
"email_verified": true,
"name": "Example User",
"groups": [
"home-lab",
"admin"
]
}
```
This example will return the string "Admin". If the user is not a member of the "admin" group, it will return "Member".
## Selecting Organizations
Use JMESPath to map attributes from the identity provider to organizations in Pangolin. See [JMESPath](https://jmespath.org/) for more information on how to use JMESPath.
The expression will be matched against each organization. Meaning:
- The result of the expression must return true or the organization ID as it is defined in the system.
- If no matching organization is found, the user will not be added to the organization.
You can insert the template variable `{{orgId}}` in the expression. This will be replaced with the organization ID when the expression is evaluated.
### Example 1: Group-based Selection
**Expression:**
```
contains(groups, 'home-lab')
```
**Identity Provider Data:**
```json
{
...
"sub": "9590c3bfccd1b1a54b35845fb1bb950057dfa50fba43cb8bada58b462c80e207",
"aud": "JJoSvHCZcxnXT2sn6CObj6a21MuKNRXs3kN5wbys",
"exp": 1745790819,
"iat": 1745789019,
"auth_time": 1745789019,
"email": "user@example.com",
"email_verified": true,
"name": "Example User",
"groups": [
"home-lab",
"admin"
]
}
```
This example will return true since the user is a member of the "home-lab" group.
### Example 2: Fixed Organization
**Expression:**
```
'home-lab'
```
**Identity Provider Data:**
```json
{
...
"sub": "9590c3bfccd1b1a54b35845fb1bb950057dfa50fba43cb8bada58b462c80e207",
"aud": "JJoSvHCZcxnXT2sn6CObj6a21MuKNRXs3kN5wbys",
"exp": 1745790819,
"iat": 1745789019,
"auth_time": 1745789019,
"email": "user@example.com",
"email_verified": true,
"name": "Example User",
"groups": [
"home-lab",
"admin"
]
}
```
This example will always return 'home-lab' meaning the user will always be added to the "home-lab" organization.
### Example 3: Dynamic Organization Selection
**Expression:**
```
contains(groups, '{{orgId}}')
```
**Identity Provider Data:**
```json
{
...
"sub": "9590c3bfccd1b1a54b35845fb1bb950057dfa50fba43cb8bada58b462c80e207",
"aud": "JJoSvHCZcxnXT2sn6CObj6a21MuKNRXs3kN5wbys",
"exp": 1745790819,
"iat": 1745789019,
"auth_time": 1745789019,
"email": "user@example.com",
"email_verified": true,
"name": "Example User",
"groups": [
"home-lab",
"admin"
]
}
```
When Pangolin evaluates this expression against the "home-lab" organization, it will replace `{{orgId}}` with "home-lab". The result of the expression will return true since the user is a member of the "home-lab" group.

View File

@@ -0,0 +1,92 @@
---
title: "Google SSO"
description: "Configure Google Single Sign-On using OpenID Connect"
---
The following steps will integrate **Google SSO** using **OpenID Connect (OIDC)**.
## Prerequisites
Before you can start, you'll need to create or edit a **Project** in [Google Developers Console](https://console.developers.google.com/).
### Setting up your Project
[Create a new Project](https://console.cloud.google.com/projectcreate), or use an [existing Project](https://console.developers.google.com/) you've already created in the Google Developers Console. Setting the organization isn't required, unless you intend to use SSO for [more than 100 users](https://support.google.com/cloud/answer/13464323) externally (not via Google Workspace).
Once created, or you've opened an existing Project, you may be on the project dashboard, where you will need to open the sidebar. If you are on the welcome page, continue by selecting [OAuth consent screen](https://console.cloud.google.com/auth/overview) in **APIs and services**.
You should see that Google Auth Platform is not configured. Press **Get started** and fill in the relevant information, such as your **App name** and **User support email**. These will be visible when the user is authenticating.
After continuing, you can select an **Audience**. If you are using Pangolin for friends and family, use the **External** Audience. You can only have 100 users authenticated with a "Testing" status.
<Note>
Depending on your use case, you may want to use the **Internal** Audience if you are utilising Google Workspace SSO and paying for access to the [Professional Edition](https://docs.fossorial.io/professional-edition).
</Note>
Once completed, you will then need to open the [Branding](https://console.cloud.google.com/auth/branding) tab.
Locate **Authorized domains**, then press "Add domain" to add an authorized domain. You'll need to authorize the top private (root) domain here, such as `example.com`. Your SSO *may* function without an authorized domain, though setting this field should guarantee functionality.
### Creating an OAuth client ID in your Project
Go to the [Clients](https://console.cloud.google.com/auth/clients) tab, and click "Create client" below the top bar.
<Steps>
<Step title="Select Application Type">
For **Application type**, select `Web application`.
</Step>
<Step title="Set Name">
Any **Name** can be set.
</Step>
<Step title="Leave Redirect URIs Empty">
Leave **Authorised JavaScript origins** and **Authorised redirect URIs** empty.
</Step>
</Steps>
<Note>
We will revisit the **Authorised redirect URIs** field later, as we do not have Pangolin set up for Google yet.
</Note>
After hitting "Create", you will be able to see the **Client ID** and **Client secret**, you may want to copy these somewhere as these will be needed momentarily, though they will still be accessible in the future.
## Configuring Identity Providers in Pangolin
In Pangolin, go to the **Server Admin** section. Select "Identity Providers" before proceeding with the "Add Identity Provider" button.
**Name** should be set to something memorable. The **Provider Type** should be set to the default `OAuth2/OIDC`.
### OAuth2/OIDC Configuration (Provider Credentials and Endpoints)
In the OAuth2/OIDC Configuration, you'll need the following fields:
<ResponseField name="Client ID" type="string" required>
The Client ID from your Web application client.
</ResponseField>
<ResponseField name="Client Secret" type="string" required>
The Client secret from your Web application client.
</ResponseField>
<ResponseField name="Authorization URL" type="string" required>
Set to `https://accounts.google.com/o/oauth2/v2/auth`.
</ResponseField>
<ResponseField name="Token URL" type="string" required>
Set to `https://oauth2.googleapis.com/token`.
</ResponseField>
## Token Configuration
You should leave all of the paths default. In the **Scopes** field, add `openid profile email`.
<Warning>
Currently, the only way to obtain your `sub` identifier attribute via Google is through direct API access. For now, set the **Identifier Path** to `email` and in the **Username** field, and use the associated account's email. We highly recommend increasing the resilience of your Google SSO by setting the optional **Name** field to match the account's (full name attached to their Google account).
</Warning>
When you're done, click "Create Identity Provider"! Then, copy the Redirect URL in the "General" tab as you will now need this for your **Web application client**.
## Returning to Google Developers Console
Lastly, you'll need to return to your **Web application client** in order to add the redirect URI created by Pangolin. Add the URI to **Authorized redirect URIs**, then hit "Save"! Your configuration should now be complete. You'll now need to add an external user to Pangolin, or if you have "Auto Provision Users" enabled, you can now log in using Google SSO.

View File

@@ -0,0 +1,70 @@
---
title: "OAuth2/OIDC"
description: "Configure OpenID Connect identity provider for external authentication"
---
This identity provider follows the OpenID Connect protocol. This means that it can be used to connect to any external identity provider that supports the OpenID Connect protocol such as Authentik, Keycloak, Okta, etc.
<CardGroup cols={2}>
<Card title="What it supports" icon="shield">
Any external identity provider that follows the OpenID Connect standard.
</Card>
<Card title="Common providers" icon="users">
Authentik, Keycloak, Okta, and other OIDC-compliant identity providers.
</Card>
</CardGroup>
## Configuration
You will need to configure the following common settings:
<ResponseField name="Client ID" type="string" required>
The client identifier provided by your identity provider.
</ResponseField>
<ResponseField name="Client Secret" type="string" required>
The client secret provided by your identity provider.
</ResponseField>
<ResponseField name="Authorization URL" type="string" required>
The authorization endpoint URL from your identity provider.
</ResponseField>
<ResponseField name="Token URL" type="string" required>
The token endpoint URL from your identity provider.
</ResponseField>
## Token Configuration
Use JMESPath to select attributes from the claims token. See [JMESPath](https://jmespath.org/) for more information on how to use JMESPath.
Determine how to access information from the claims token returned by the identity provider. This is used to map the user information from the identity provider to the user information in Pangolin.
<ResponseField name="Identifier Path" type="string" required>
This must be unique for each user within an identity provider.
**Example**: `sub` or `user_id`
</ResponseField>
<ResponseField name="Email Path" type="string">
Path to the user's email address in the claims token.
**Example**: `email`
</ResponseField>
<ResponseField name="Name Path" type="string">
Path to the user's display name in the claims token.
**Example**: `name` or `preferred_username`
</ResponseField>
<ResponseField name="Scopes" type="string">
The scopes to request from the identity provider (not JMESPath; must be space-delimited strings).
**Default**: `openid profile email`
<Note>
Generally, `openid profile email` is sufficient for most use cases.
</Note>
</ResponseField>

View File

@@ -0,0 +1,79 @@
---
title: "Pocket ID SSO"
description: "Configure Pocket ID Single Sign-On using OpenID Connect"
---
The following steps will integrate **Pocket ID** with **Pangolin SSO** using OpenID Connect (OIDC).
## Prerequisites
Before you can start, you'll need to have Pocket ID accessible and ensure it's not secured with Pangolin SSO.
### Creating an OIDC Client in Pocket ID
In Pocket ID, create a new OIDC Client.
<Steps>
<Step title="Set Name">
Set the name to something memorable (eg. Pangolin).
</Step>
<Step title="Configure Callback URL">
Set "Callback URLs" to `https://<your-pangolin-domain>/auth/idp/<idp-id>/oidc/callback`.
</Step>
<Step title="Keep Defaults">
All other values can be kept as default.
</Step>
</Steps>
<Note>
The callback URL is displayed in the IdP settings after you create the IdP in Pangolin.
</Note>
After you have created the OIDC Client, take note of the following fields from the top of the page (click "Show more details" to see all of them):
- **Client ID**
- **Client secret**
- **Authorization URL**
- **Token URL**
## Configuring Identity Providers in Pangolin
In Pangolin, go to the **Server Admin** section. Select "Identity Providers" before proceeding with the "Add Identity Provider" button.
**Name** should be set to something memorable (eg. Pocket ID). The **Provider Type** should be set to the default `OAuth2/OIDC`.
### OAuth2/OIDC Configuration (Provider Credentials and Endpoints)
In the OAuth2/OIDC Configuration, you'll need the following fields:
<ResponseField name="Client ID" type="string" required>
The Client ID from your Pocket ID OIDC client.
</ResponseField>
<ResponseField name="Client Secret" type="string" required>
The Client secret from your Pocket ID OIDC client.
</ResponseField>
<ResponseField name="Authorization URL" type="string" required>
The Authorization URL from your Pocket ID OIDC client.
</ResponseField>
<ResponseField name="Token URL" type="string" required>
The Token URL from your Pocket ID OIDC client.
</ResponseField>
## Token Configuration
You should leave all of the paths default. In the **Scopes** field, add `openid profile email`.
<Note>
Set the **Identifier Path** to "preferred_username" for Pocket ID integration.
</Note>
When you're done, click "Create Identity Provider"! Then, copy the Redirect URL in the "General" tab as you will now need this for your **Pocket ID OIDC client**.
## Returning to Pocket ID
Lastly, you'll need to return to your **Pocket ID OIDC client** in order to add the redirect URI created by Pangolin. Add the URI to **Callback URLs**, then save your changes! Your configuration should now be complete. You'll now need to add an external user to Pangolin, or if you have "Auto Provision Users" enabled, you can now log in using Pocket ID SSO.

View File

@@ -0,0 +1,92 @@
---
title: "Zitadel SSO"
description: "Configure Zitadel Single Sign-On using OpenID Connect"
---
The following steps will integrate **Zitadel** with **Pangolin SSO** using OpenID Connect (OIDC).
## Prerequisites
These instructions assume you have a working Zitadel organization and project setup already.
### Creating an Application in Zitadel
You need to configure an application in Zitadel:
<Steps>
<Step title="Create New Application">
Open an existing project and in `Applications` click `New`.
</Step>
<Step title="Configure Application">
Set the name to something memorable (eg. Pangolin).
</Step>
<Step title="Set Application Type">
For `Type of application` choose `Web`.
</Step>
<Step title="Set Authentication Method">
For `Authentication Method` choose `Code`.
</Step>
<Step title="Leave Redirect URIs Blank">
Leave `Redirect URIs` blank for now.
</Step>
</Steps>
<Note>
When you click create, you'll be shown the `ClientSecret` and `ClientId`. Make sure to save these somewhere secure - you won't be able to see the Client Secret again.
</Note>
<Steps>
<Step title="Configure Token Settings">
Click `Token settings` then change `Auth Token Type` to `JWT` and check the `User Info inside ID Token` box finally hit `Save`.
</Step>
<Step title="Note Endpoints">
Open `URLs` and make note of:
- `Authorization Endpoint`
- `Token Endpoint`
</Step>
</Steps>
## Configuring Identity Providers in Pangolin
In Pangolin, go to the **Server Admin** section. Select "Identity Providers" before proceeding with the "Add Identity Provider" button.
**Name** should be set to something memorable (eg. Zitadel). The **Provider Type** should be set to the default `OAuth2/OIDC`.
### OAuth2/OIDC Configuration (Provider Credentials and Endpoints)
In the OAuth2/OIDC Configuration, you'll need the following fields:
<ResponseField name="Client ID" type="string" required>
The Client ID from your Zitadel application.
</ResponseField>
<ResponseField name="Client Secret" type="string" required>
The Client Secret from your Zitadel application.
</ResponseField>
<ResponseField name="Authorization URL" type="string" required>
Use the `Authorization Endpoint` from your Zitadel application.
</ResponseField>
<ResponseField name="Token URL" type="string" required>
Use the `Token Endpoint` from your Zitadel application.
</ResponseField>
## Token Configuration
You should leave all of the paths default. In the **Scopes** field, add `openid profile email`.
<Note>
Set the **Identifier Path** to "preferred_username" for Zitadel integration.
</Note>
When you're done, click "Create Identity Provider"! Then, copy the Redirect URL in the "General" tab as you will now need this for your **Zitadel application**.
## Returning to Zitadel
Lastly, you need to edit your `Redirect Settings` in your Zitadel application. Add the URL you copied to the `Redirect URIs`, then hit the `+` button and finally `Save`. Your configuration should now be complete. You'll now need to add an external user] to Pangolin, or if you have "Auto Provision Users" enabled, you can now log in using Zitadel SSO.

View File

@@ -0,0 +1,94 @@
---
title: "Integration API"
description: "Learn how to use Pangolin's REST API to automate and script operations with fine-grained permissions"
---
The API is REST-based and supports many operations available through the web interface. Authentication uses Bearer tokens, and you can create multiple API keys with specific permissions for different use cases.
<Info>
For Pangolin self-hosted, the integration API must be enabled. Check out [the documentation](self-host/advanced/integration-api) for how to enable the integration API.
</Info>
## Authentication
All API requests require authentication using a Bearer token in the Authorization header:
<CodeGroup>
```bash cURL
curl -H "Authorization: Bearer YOUR_API_KEY" \
https://api.example.com/v1/
```
```javascript JavaScript
const response = await fetch('https://api.example.com/v1/endpoint', {
headers: {
'Authorization': `Bearer ${apiKey}`
}
});
```
```python Python
import requests
headers = {'Authorization': f'Bearer {api_key}'}
response = requests.get('https://api.example.com/v1/endpoint', headers=headers)
```
</CodeGroup>
## API Key Types
Pangolin supports two types of API keys with different permission levels:
### Organization API Keys
Organization API keys are created by organization admins and have limited scope to perform actions only in that organization.
### Root API Keys
Root API keys have some extra permissions and can execute operations across orgs. They are only available in self-hosted Pangolin:
<Warning>
Root API keys have elevated permissions and should be used carefully. Only create them when you need server-wide access.
</Warning>
## Creating API Keys
<Steps>
<Step title="Access the admin panel">
Navigate to your admin panel:
- **Organization keys**: Organization → API Keys
- **Root keys**: Server Admin → API Keys (self-hosted only)
</Step>
<Step title="Generate a new key">
Click "Create API Key" and provide a descriptive name for the key.
</Step>
<Step title="Configure permissions">
Select the specific permissions your API key needs from the permissions selector.
<Frame caption="API key permissions selector showing available operations">
<img src="/images/permissions.png" alt="API Key Permissions"/>
</Frame>
</Step>
<Step title="Copy and secure your key">
Copy the generated API key immediately. It won't be shown again.
<Warning>
Store API keys securely and never commit them to version control. Use environment variables or secure secret management.
</Warning>
</Step>
</Steps>
## API Documentation
View the Swagger docs here: [https://api.pangolin.fossorial.io/v1/docs](https://api.pangolin.fossorial.io/v1/docs).
Interactive API documentation is available through Swagger UI:
<Frame caption="Swagger UI showing API endpoints and interactive testing">
<img src="/images/swagger.png" alt="Swagger Docs"/>
</Frame>
For self-hosted Pangolin, access the documentation at `https://api.your-domain.com/v1/docs`.

View File

@@ -0,0 +1,94 @@
---
title: "Integration API"
description: "Learn how to use Pangolin's REST API to automate and script operations with fine-grained permissions"
---
The API is REST-based and supports many operations available through the web interface. Authentication uses Bearer tokens, and you can create multiple API keys with specific permissions for different use cases.
<Info>
For Pangolin self-hosted, the integration API must be enabled. Check out [the documentation](self-host/advanced/integration-api) for how to enable the integration API.
</Info>
## Authentication
All API requests require authentication using a Bearer token in the Authorization header:
<CodeGroup>
```bash cURL
curl -H "Authorization: Bearer YOUR_API_KEY" \
https://api.example.com/v1/
```
```javascript JavaScript
const response = await fetch('https://api.example.com/v1/endpoint', {
headers: {
'Authorization': `Bearer ${apiKey}`
}
});
```
```python Python
import requests
headers = {'Authorization': f'Bearer {api_key}'}
response = requests.get('https://api.example.com/v1/endpoint', headers=headers)
```
</CodeGroup>
## API Key Types
Pangolin supports two types of API keys with different permission levels:
### Organization API Keys
Organization API keys are created by organization admins and have limited scope to perform actions only in that organization.
### Root API Keys
Root API keys have some extra permissions and can execute operations across orgs. They are only available in self-hosted Pangolin:
<Warning>
Root API keys have elevated permissions and should be used carefully. Only create them when you need server-wide access.
</Warning>
## Creating API Keys
<Steps>
<Step title="Access the admin panel">
Navigate to your admin panel:
- **Organization keys**: Organization → API Keys
- **Root keys**: Server Admin → API Keys (self-hosted only)
</Step>
<Step title="Generate a new key">
Click "Create API Key" and provide a descriptive name for the key.
</Step>
<Step title="Configure permissions">
Select the specific permissions your API key needs from the permissions selector.
<Frame caption="API key permissions selector showing available operations">
<img src="/images/permissions.png" alt="API Key Permissions"/>
</Frame>
</Step>
<Step title="Copy and secure your key">
Copy the generated API key immediately. It won't be shown again.
<Warning>
Store API keys securely and never commit them to version control. Use environment variables or secure secret management.
</Warning>
</Step>
</Steps>
## API Documentation
View the Swagger docs here: [https://api.pangolin.fossorial.io/v1/docs](https://api.pangolin.fossorial.io/v1/docs).
Interactive API documentation is available through Swagger UI:
<Frame caption="Swagger UI showing API endpoints and interactive testing">
<img src="/images/swagger.png" alt="Swagger Docs"/>
</Frame>
For self-hosted Pangolin, access the documentation at `https://api.your-domain.com/v1/docs`.

View File

@@ -0,0 +1,116 @@
---
title: "Points of Presence"
description: "Learn about Pangolin's global network of points of presence and how they provide highly available, low-latency access to your applications"
---
Pangolin's points of presence (PoPs) are strategically located servers around the world that serve as entry points for user traffic to your applications. They form the foundation of Pangolin's distributed architecture, providing global high availability and optimal performance.
## Contact Us
For hybrid deployments, points of presence, and high availability contact us:
- **Email**: [numbat@fossorial.io](mailto:numbat@fossorial.io)
## What Are Points of Presence?
Points of presence are geographically distributed servers that:
- **Serve as Entry Points**: Handle incoming user requests before routing them to your applications
- **Provide Global Coverage**: Located worldwide to minimize latency for users in different regions
- **Enable High Availability**: Multiple locations ensure your applications remain accessible even if individual locations fail
- **Handle Authentication**: Verify user identity and enforce access policies before allowing access
<Info>
Think of points of presence as the "front doors" to your applications - users connect to the closest one, and it securely routes their requests to your backend services.
</Info>
## How Points of Presence Work
### Geographic Routing
When a user requests access to your application:
1. **DNS Resolution**: The user's request is automatically routed to the closest available point of presence
2. **Authentication**: The point of presence verifies the user's identity and permissions
3. **Tunnel Routing**: Authenticated requests are sent through secure tunnels to your applications
4. **Response Delivery**: Responses follow the same path back to the user
<Check>
This routing happens automatically and transparently - users always get the best possible performance without any manual configuration.
</Check>
### Automatic Failover
Pangolin's points of presence provide built-in high availability:
- **Health Monitoring**: Each point of presence continuously monitors its health and connectivity
- **Automatic Failover**: If one location becomes unavailable, traffic automatically routes to the next closest location
- **Load Distribution**: Traffic is automatically balanced across multiple locations to prevent overload
- **Global Redundancy**: Multiple points of presence ensure your applications remain accessible during regional outages
## Advantages of Points of Presence
### Global Performance
- **Low Latency**: Users connect to the geographically closest point of presence
- **Optimized Routing**: Automatic selection of the best available location
- **Edge Computing**: Processing happens closer to users for faster response times
### High Availability
- **Fault Tolerance**: No single point of failure - if one location goes down, others remain available
- **Automatic Recovery**: Failed locations are automatically bypassed and traffic is rerouted
- **Regional Redundancy**: Multiple locations per region provide additional redundancy
### Security and Compliance
- **Distributed Security**: Security controls are enforced at every point of presence
- **Regional Compliance**: Points of presence can be configured to meet regional data requirements
- **Encrypted Transit**: All traffic between points of presence and your applications is encrypted
### Scalability
- **Automatic Scaling**: New points of presence are automatically added as needed
- **Load Balancing**: Traffic is distributed across multiple locations to handle high volumes
- **Global Distribution**: Support for applications with users worldwide
## Deployment Models
### Pangolin Cloud
Pangolin Cloud includes a global network of points of presence that provide:
- **Automatic Management**: Points of presence are automatically deployed, monitored, and maintained
- **Global Coverage**: Strategic locations worldwide for optimal performance
- **Built-in High Availability**: Multiple redundant locations ensure 99.9%+ uptime
- **Zero Configuration**: No setup or management required on your part
<Card title="Try Pangolin Cloud" icon="cloud" href="https://pangolin.fossorial.io/auth/signup">
Get started with Pangolin Cloud and experience global points of presence with automatic high availability.
</Card>
### Self-Hosted Pangolin
Self-hosted Pangolin operates as a single point of presence:
- **Single Location**: Your Pangolin instance serves as the only entry point
- **Limited Availability**: No built-in redundancy - if your server goes down, access is lost
- **Manual Management**: You're responsible for server maintenance and uptime
- **Regional Limitation**: Performance depends on your server's location
<Warning>
Self-hosted Pangolin provides only a single point of presence and is not highly available. Consider Pangolin Cloud or hybrid deployment for production environments requiring high availability.
</Warning>
### Hybrid Deployment
Hybrid deployment allows you to host your own points of presence while leveraging Pangolin's cloud coordination:
- **Your Infrastructure**: Host points of presence on your own servers or cloud infrastructure
- **Cloud Coordination**: Pangolin Cloud handles failover logic and coordination between your points of presence
- **Automatic Failover**: If your points of presence go down, traffic automatically fails over to Pangolin Cloud
- **Data Control**: Traffic flows through your servers, giving you control over data transit costs and privacy
- **Custom Locations**: Deploy points of presence in specific regions or data centers of your choice
<Tip>
Hybrid deployment is ideal for organizations that need high availability while maintaining control over their infrastructure and data transit.
</Tip>

View File

@@ -0,0 +1,116 @@
---
title: "Raw TCP & UDP"
description: "Configure raw TCP and UDP traffic through Pangolin tunnels"
---
<Note>
This feature is only available in self-hosted Pangolin instances.
</Note>
Pangolin supports raw TCP and UDP traffic because Newt can pass anything through the tunnel.
These resources can either be:
1. **Publically Proxied:** Map the resource to a port on the host Pangolin server, so you can access the resource from `<server-public-ip>:<mapped-port>`. This is useful if you want to access the resource over the public internet, such as exposing a game server like Minecraft.
2. **Internal Exposure:** Map services accessible on the same network as the site to an internal port on the site address. This is useful if you only want internal exposure to a resource when connected with a client.
## Proxied Resources
Proxied resources require extra configuration to expose on the Pangolin server. You'll need to configure firewall rules, Docker port mappings, and Traefik entry points. These steps require a server restart.
<Steps>
<Step title="Create the resource">
In the Pangolin dashboard, go to Resources and click Add Resource. Select "Raw TCP/UDP resource", enable Public Proxy, and enter your desired publicly mapped port. This is the port you'll use to access the proxied resource.
</Step>
<Step title="Configure firewall">
Open your desired ports on your VPS firewall, just like you did for ports 51820, 443, and 80. This is highly OS and VPS dependent.
<Note>
In this example, we're exposing two resources: TCP 1602 and UDP 1704.
</Note>
</Step>
<Step title="Configure Docker">
Add port mappings to your `docker-compose.yml` file:
```yaml title="docker-compose.yml" highlight={4,5}
gerbil:
ports:
# ... existing ports ...
- 1704:1704/udp # ADDED: Your UDP port
- 1602:1602 # ADDED: Your TCP port
```
</Step>
<Step title="Configure Traefik">
Add entry points to your `config/traefik/traefik_config.yml`:
```yaml title="traefik_config.yml" highlight={12-15}
entryPoints:
web:
address: ":80"
websecure:
address: ":443"
http:
tls:
certResolver: letsencrypt
transport:
respondingTimeouts:
readTimeout: 30m
tcp-1602:
address: ":1602/tcp"
udp-1704:
address: ":1704/udp"
```
<Info>
**Important**: Always name your entry points in the format `protocol-port` (e.g., `tcp-1602`, `udp-1704`). This naming is required for Pangolin's dynamic configuration.
</Info>
</Step>
<Step title="Restart the stack">
Restart your Docker stack to apply all changes:
```bash
sudo docker compose down
sudo docker compose up -d
```
</Step>
</Steps>
<Note>
In this example, we expose port 1602 for TCP and port 1704 for UDP. You can use any available ports on your VPS.
</Note>
## Internal Exposure with Clients
Internal exposure resources are only accessible when connected via an Olm client. This approach is perfect for secure access to services without exposing them to the public internet.
When you run Newt with `--accept-clients`, it operates fully in user space without creating a virtual network interface on the host. This means:
- **No special permissions required** for the container or binary
- **No virtual network interface** created on the host
- **Client-only access** through Pangolin's tunnel
- **Secure internal routing** to your services
### Example: SSH Access
Here's how to set up SSH access to your server when connected with a client:
<Steps>
<Step title="Create the resource">
In the Pangolin dashboard, create a new Raw TCP/UDP resource and set the port to `2022` (or any available port).
</Step>
<Step title="Add the target">
Configure the resource to target `localhost:22` (your SSH service).
</Step>
<Step title="Connect and access">
When connected with a Newt client, you can SSH to your server using `<site-address>:2022`.
</Step>
</Steps>
<Note>
This approach is ideal for secure remote access without exposing SSH directly to the internet.
</Note>

83
manage/sites/add-site.mdx Normal file
View File

@@ -0,0 +1,83 @@
---
title: "Add Site"
description: "Create a site to connect to a remote network and expose resources"
---
A site is a connection to a remote network that allows Pangolin to establish a tunnel to that network. Sites are the foundation for exposing resources because all resources exist on a site. Newt is the software connector that facilitates the connection and addresses the targets on the remote networks.
## How Sites Work
### The Connection Process
1. **Site Creation**: You create a site in Pangolin's dashboard
2. **Newt Registration**: Newt registers with Pangolin using the site credentials
3. **Tunnel Establishment**: Newt establishes a WireGuard tunnel to the remote network
4. **Resource Exposure**: Resources on the remote network become accessible through the tunnel
### Why Sites Matter
Sites are the first step to exposing resources with Pangolin because:
- **Resources exist on sites**: All resources must be associated with a site
- **Newt addresses targets**: Newt is what actually connects to the targets on remote networks
- **Tunnel enables access**: The tunnel allows Pangolin to expose resources without opening ports or needing a public IP
- **Secure communication**: All traffic flows through encrypted WireGuard tunnels
## Site Types
Pangolin supports three different types of sites, each designed for different use cases and deployment scenarios.
<Card title="Newt Tunnel (Recommended)">
This site allows you to expose resources on a remote network via a fully managed tunnel. This requires the Newt connector to be running on the remote network. It's the easiest to use and requires the least amount of setup. No NAT configuration required.
</Card>
<CardGroup cols={2}>
<Card title="Local Site">
Use this if you want to expose resources on the same host as the Pangolin server (this is for self-hosted Pangolin only). No tunnels are created. Ports must be opened on the host running Pangolin (this has to happen anyway for Pangolin to work).
</Card>
<Card title="Basic WireGuard">
This is self-hosted only. This uses a raw WireGuard connection without Newt, thus there is no websocket connection, requiring more manual management. These sites require NAT to address targets running on other hosts on the remote network. Otherwise, you can only expose resources on the remote WireGuard peer itself.
</Card>
</CardGroup>
## Adding a Site
<Steps>
<Step title="Navigate to Sites">
In the Pangolin dashboard, go to the **Sites** section and click **Add Site**.
</Step>
<Step title="Choose site type">
Select the appropriate site type based on your needs:
- **Newt Tunnel**: For remote networks with Newt connector
- **Local Site**: For resources on the same host as Pangolin
- **Basic WireGuard**: For direct WireGuard connections
</Step>
<Step title="Configure site details">
Configure the basic information:
- **Site Name**: A descriptive name for your site
</Step>
<Step title="Generate Newt credentials">
Pangolin will generate:
- **Newt ID**: Unique identifier for the Newt client
- **Secret**: Authentication secret for secure connection
- **Endpoint**: The Pangolin server endpoint
</Step>
<Step title="Configure Newt">
Use the generated credentials to configure Newt on the remote network. See [Configure Newt](/manage/sites/configure-newt) for detailed instructions.
</Step>
<Step title="Verify connection">
Once Newt is running, the site status should show as "Online" in the dashboard. Sometimes it takes a few moments for the status to update.
</Step>
</Steps>
## Notes
- Sites require Newt to be running on the remote network
- Each site can host multiple resources
- Connection status is monitored automatically

View File

@@ -0,0 +1,464 @@
---
title: "Configure Newt"
description: "Configure Newt for connecting to Pangolin sites"
---
Newt is a fully user space [WireGuard](https://www.wireguard.com/) tunnel client and TCP/UDP proxy, designed to securely expose private resources controlled by Pangolin. By using Newt, you don't need to manage complex WireGuard tunnels and NATing.
## Preview
<Frame caption="Newt interface preview">
<img src="/images/newt-preview.png" alt="Newt Preview"/>
</Frame>
## How Newt Works
### Registers with Pangolin
Using the Newt ID and a secret, the client will make HTTP requests to Pangolin to receive a session token. Using that token, it will connect to a websocket and maintain that connection. Control messages will be sent over the websocket.
### Receives WireGuard Control Messages
When Newt receives WireGuard control messages, it will use the information encoded (endpoint, public key) to bring up a WireGuard tunnel using [netstack](https://github.com/WireGuard/wireguard-go/blob/master/tun/netstack/examples/http_server.go) fully in user space. It will ping over the tunnel to ensure the peer on the Gerbil side is brought up.
### Receives Proxy Control Messages
When Newt receives proxy control messages, it will use the information encoded to create a local low level TCP and UDP proxies attached to the virtual tunnel in order to relay traffic to programmed targets.
## Configuration Arguments
### Required Arguments
<ResponseField name="id" type="string" required>
Newt ID generated by Pangolin to identify the client.
**Example**: `31frd0uzbjvp721`
</ResponseField>
<ResponseField name="secret" type="string" required>
A unique secret used to authenticate the client ID with the websocket.
**Example**: `h51mmlknrvrwv8s4r1i210azhumt6isgbpyavxodibx1k2d6`
<Warning>
Keep this secret private and secure. It's used for authentication.
</Warning>
</ResponseField>
<ResponseField name="endpoint" type="string" required>
The endpoint where both Gerbil and Pangolin reside for websocket connections.
**Example**: `https://pangolin.example.com`
</ResponseField>
### Optional Arguments
<ResponseField name="mtu" type="integer">
MTU for the internal WireGuard interface.
**Default**: `1280`
</ResponseField>
<ResponseField name="dns" type="string">
DNS server to use for resolving the endpoint.
**Default**: `8.8.8.8`
</ResponseField>
<ResponseField name="log-level" type="string">
The log level to use for Newt output.
**Options**: `DEBUG`, `INFO`, `WARN`, `ERROR`, `FATAL`
**Default**: `INFO`
</ResponseField>
<ResponseField name="ping-interval" type="string">
Interval for pinging the server.
**Default**: `3s`
</ResponseField>
<ResponseField name="ping-timeout" type="string">
Timeout for each ping.
**Default**: `5s`
</ResponseField>
<ResponseField name="docker-socket" type="string">
Set the Docker socket path for container discovery integration.
**Example**: `/var/run/docker.sock`
</ResponseField>
<ResponseField name="docker-enforce-network-validation" type="boolean">
Validate the container target is on the same network as the Newt process.
**Default**: `false`
</ResponseField>
<ResponseField name="health-file" type="string">
Check if connection to WireGuard server (Pangolin) is ok. Creates a file if ok, removes it if not ok. Can be used with Docker healthcheck to restart Newt.
**Example**: `/tmp/healthy`
</ResponseField>
<ResponseField name="updown" type="string">
Script to be called when targets are added or removed.
**Example**: `/path/to/updown.sh`
</ResponseField>
<ResponseField name="tls-client-cert" type="string">
Client certificate (p12 or pfx) for mutual TLS (mTLS) authentication.
**Example**: `/path/to/client.p12`
</ResponseField>
<ResponseField name="accept-clients" type="boolean">
Enable WireGuard server mode to accept incoming Olm client connections.
**Default**: `false`
</ResponseField>
<ResponseField name="generateAndSaveKeyTo" type="string">
Path to save generated private key (used with accept-clients).
**Example**: `/var/key`
</ResponseField>
<ResponseField name="native" type="boolean">
Use native WireGuard interface when accepting clients (requires WireGuard kernel module and Linux, must run as root).
**Default**: `false` (uses userspace netstack)
</ResponseField>
<ResponseField name="interface" type="string">
Name of the WireGuard interface (used with native mode).
**Default**: `newt`
</ResponseField>
<ResponseField name="keep-interface" type="boolean">
Keep the WireGuard interface after shutdown (used with native mode).
**Default**: `false`
</ResponseField>
## Environment Variables
All CLI arguments can be set using environment variables as an alternative to command line flags. Environment variables are particularly useful when running Newt in containerized environments.
<ResponseField name="PANGOLIN_ENDPOINT" type="string">
Endpoint of your Pangolin server (equivalent to `--endpoint`)
</ResponseField>
<ResponseField name="NEWT_ID" type="string">
Newt ID generated by Pangolin (equivalent to `--id`)
</ResponseField>
<ResponseField name="NEWT_SECRET" type="string">
Newt secret for authentication (equivalent to `--secret`)
</ResponseField>
<ResponseField name="MTU" type="integer">
MTU for the internal WireGuard interface (equivalent to `--mtu`)
**Default**: `1280`
</ResponseField>
<ResponseField name="DNS" type="string">
DNS server to use for resolving the endpoint (equivalent to `--dns`)
**Default**: `8.8.8.8`
</ResponseField>
<ResponseField name="LOG_LEVEL" type="string">
Log level (equivalent to `--log-level`)
**Default**: `INFO`
</ResponseField>
<ResponseField name="DOCKER_SOCKET" type="string">
Path to Docker socket for container discovery (equivalent to `--docker-socket`)
</ResponseField>
<ResponseField name="PING_INTERVAL" type="string">
Interval for pinging the server (equivalent to `--ping-interval`)
**Default**: `3s`
</ResponseField>
<ResponseField name="PING_TIMEOUT" type="string">
Timeout for each ping (equivalent to `--ping-timeout`)
**Default**: `5s`
</ResponseField>
<ResponseField name="UPDOWN_SCRIPT" type="string">
Path to updown script for target add/remove events (equivalent to `--updown`)
</ResponseField>
<ResponseField name="TLS_CLIENT_CERT" type="string">
Path to client certificate for mTLS (equivalent to `--tls-client-cert`)
</ResponseField>
<ResponseField name="DOCKER_ENFORCE_NETWORK_VALIDATION" type="boolean">
Validate container targets are on same network (equivalent to `--docker-enforce-network-validation`)
**Default**: `false`
</ResponseField>
<ResponseField name="HEALTH_FILE" type="string">
Path to health file for connection monitoring (equivalent to `--health-file`)
</ResponseField>
<ResponseField name="ACCEPT_CLIENTS" type="boolean">
Enable WireGuard server mode (equivalent to `--accept-clients`)
**Default**: `false`
</ResponseField>
<ResponseField name="GENERATE_AND_SAVE_KEY_TO" type="string">
Path to save generated private key (equivalent to `--generateAndSaveKeyTo`)
</ResponseField>
<ResponseField name="USE_NATIVE_INTERFACE" type="boolean">
Use native WireGuard interface (Linux only, equivalent to `--native`)
**Default**: `false`
</ResponseField>
<ResponseField name="INTERFACE" type="string">
Name of the WireGuard interface (equivalent to `--interface`)
**Default**: `newt`
</ResponseField>
<ResponseField name="KEEP_INTERFACE" type="boolean">
Keep the WireGuard interface after shutdown (equivalent to `--keep-interface`)
**Default**: `false`
</ResponseField>
<ResponseField name="CONFIG_FILE" type="string">
Load the config JSON from this file instead of in the home folder.
</ResponseField>
<Note>
When both environment variables and CLI arguments are provided, CLI arguments take precedence.
</Note>
## Basic Configuration Examples
### Binary Example
```bash
newt \
--id 31frd0uzbjvp721 \
--secret h51mmlknrvrwv8s4r1i210azhumt6isgbpyavxodibx1k2d6 \
--endpoint https://example.com
```
### Docker Compose with Environment Variables (Recommended)
```yaml title="docker-compose.yml"
services:
newt:
image: fosrl/newt
container_name: newt
restart: unless-stopped
environment:
- PANGOLIN_ENDPOINT=https://example.com
- NEWT_ID=2ix2t8xk22ubpfy
- NEWT_SECRET=nnisrfsdfc7prqsp9ewo1dvtvci50j5uiqotez00dgap0ii2
- HEALTH_FILE=/tmp/healthy
```
### Docker Compose with CLI Arguments
```yaml title="docker-compose.yml"
services:
newt:
image: fosrl/newt
container_name: newt
restart: unless-stopped
command:
- --id 31frd0uzbjvp721
- --secret h51mmlknrvrwv8s4r1i210azhumt6isgbpyavxodibx1k2d6
- --endpoint https://example.com
- --health-file /tmp/healthy
```
## Advanced Features
### Accept Client Connections
When the `--accept-clients` flag is enabled (or `ACCEPT_CLIENTS=true` environment variable is set), Newt operates as a WireGuard server that can accept incoming client connections from other devices. This enables peer-to-peer connectivity through the Newt instance.
#### Client Tunneling Modes
Newt supports two WireGuard tunneling modes:
##### Userspace Mode (Default)
By default, Newt uses a fully userspace WireGuard implementation using [netstack](https://github.com/WireGuard/wireguard-go/blob/master/tun/netstack/examples/http_server.go). This mode:
- **Does not require root privileges**
- **Works on all supported platforms** (Linux, Windows, macOS)
- **Does not require WireGuard kernel module** to be installed
- **Runs entirely in userspace** - no system network interface is created
- **Is containerization-friendly** - works seamlessly in Docker containers
<Note>
This is the recommended mode for most deployments, especially containerized environments.
</Note>
##### Native Mode (Linux only)
When using the `--native` flag or setting `USE_NATIVE_INTERFACE=true`, Newt uses the native WireGuard kernel module. This mode:
- **Requires root privileges** to create and manage network interfaces
- **Only works on Linux** with the WireGuard kernel module installed
- **Creates a real network interface** (e.g., `newt0`) on the system
- **May offer better performance** for high-throughput scenarios
- **Requires proper network permissions** and may conflict with existing network configurations
<Warning>
Native mode requires Linux with WireGuard kernel module and must run as root.
</Warning>
#### Native Mode Requirements
To use native mode:
1. Run on a Linux system
2. Install the WireGuard kernel module
3. Run Newt as root (`sudo`)
4. Ensure the system allows creation of network interfaces
**Docker Compose example:**
```yaml title="docker-compose.yml"
services:
newt:
image: fosrl/newt
container_name: newt
restart: unless-stopped
environment:
- PANGOLIN_ENDPOINT=https://example.com
- NEWT_ID=2ix2t8xk22ubpfy
- NEWT_SECRET=nnisrfsdfc7prqsp9ewo1dvtvci50j5uiqotez00dgap0ii2
- ACCEPT_CLIENTS=true
```
### Docker Socket Integration
Newt can integrate with the Docker socket to provide remote inspection of Docker containers. This allows Pangolin to query and retrieve detailed information about containers running on the Newt client, including metadata, network configuration, port mappings, and more.
**Configuration:**
You can specify the Docker socket path using the `--docker-socket` CLI argument or by setting the `DOCKER_SOCKET` environment variable. On most Linux systems the socket is `/var/run/docker.sock`. When deploying Newt as a container, you need to mount the host socket as a volume for the Newt container to access it.
```yaml title="docker-compose.yml"
services:
newt:
image: fosrl/newt
container_name: newt
restart: unless-stopped
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
environment:
- PANGOLIN_ENDPOINT=https://example.com
- NEWT_ID=2ix2t8xk22ubpfy
- NEWT_SECRET=nnisrfsdfc7prqsp9ewo1dvtvci50j5uiqotez00dgap0ii2
- DOCKER_SOCKET=/var/run/docker.sock
```
<Note>
If the Docker socket is not available or accessible, Newt will gracefully disable Docker integration and continue normal operation.
</Note>
#### Hostnames vs IPs
When the Docker Socket Integration is used, depending on the network which Newt is run with, either the hostname (generally considered the container name) or the IP address of the container will be sent to Pangolin:
- **Running in Network Mode 'host'**: IP addresses will be used
- **Running in Network Mode 'bridge'**: IP addresses will be used
- **Running in docker-compose without a network specification**: Docker compose creates a network for the compose by default, hostnames will be used
- **Running on docker-compose with defined network**: Hostnames will be used
#### Docker Enforce Network Validation
When run as a Docker container, Newt can validate that the target being provided is on the same network as the Newt container and only return containers directly accessible by Newt. Validation will be carried out against either the hostname/IP Address and the Port number to ensure the running container is exposing the ports to Newt.
<Warning>
If the Newt container is run with a network mode of `host`, this feature will not work. Running in `host` mode causes the container to share its resources with the host machine, making it impossible to retrieve specific host container information for network validation.
</Warning>
**Configuration:**
Validation is `false` by default. It can be enabled via setting the `--docker-enforce-network-validation` CLI argument or by setting the `DOCKER_ENFORCE_NETWORK_VALIDATION` environment variable.
### Updown Scripts
You can pass in an updown script for Newt to call when it is adding or removing a target:
```bash
--updown "python3 test.py"
```
The script will be called with arguments when a target is added or removed:
```bash
python3 test.py add tcp localhost:8556
python3 test.py remove tcp localhost:8556
```
<Info>
Returning a string from the script in the format of a target (`ip:dst` so `10.0.0.1:8080`) will override the target and use this value instead to proxy.
</Info>
<Note>
You can look at `updown.py` as a reference script to get started!
</Note>
### mTLS Authentication
Newt supports mutual TLS (mTLS) authentication if the server has been configured to request a client certificate.
**Requirements:**
- Only PKCS12 (.p12 or .pfx) file format is accepted
- The PKCS12 file must contain:
- Private key
- Public certificate
- CA certificate
- Encrypted PKCS12 files are currently not supported
**Binary Example:**
```bash
newt \
--id 31frd0uzbjvp721 \
--secret h51mmlknrvrwv8s4r1i210azhumt6isgbpyavxodibx1k2d6 \
--endpoint https://example.com \
--tls-client-cert ./client.p12
```
**Docker Compose Example:**
```yaml title="docker-compose.yml"
services:
newt:
image: fosrl/newt
container_name: newt
restart: unless-stopped
environment:
- PANGOLIN_ENDPOINT=https://example.com
- NEWT_ID=2ix2t8xk22ubpfy
- NEWT_SECRET=nnisrfsdfc7prqsp9ewo1dvtvci50j5uiqotez00dgap0ii2
- TLS_CLIENT_CERT=./client.p12
```
<Note>
Get your `id` and `secret` from the Pangolin dashboard when creating a Newt client.
</Note>

View File

View File

@@ -0,0 +1,165 @@
---
title: "Install Newt"
description: "Install Newt as a binary or Docker container"
---
Newt can be installed as either a static binary executable or a Docker container. Configuration is passed via CLI arguments in both cases.
<Warning>
You **must first create a site and copy the Newt config** in Pangolin before running Newt.
</Warning>
<CardGroup cols={2}>
<Card title="Binary Installation" icon="download">
- Static executable
- Cross-platform support
- Easy to install and run
- Systemd service support
</Card>
<Card title="Docker Installation" icon="docker">
- Containerized deployment
- Environment variables
- Docker Compose support
- Easy management
</Card>
</CardGroup>
## Binary Installation
### Quick Install (Recommended)
Use this command to automatically install Newt. It detects your system architecture automatically and always pulls the latest version, adding Newt to your PATH:
```bash
curl -fsSL https://docs.fossorial.io/get-newt.sh | bash
```
### Manual Download
Binaries for Linux, macOS, and Windows are available in the [GitHub releases](https://github.com/fosrl/newt/releases) for ARM and AMD64 (x86_64) architectures.
Download and install manually:
```bash
wget -O newt "https://github.com/fosrl/newt/releases/download/{version}/newt_{architecture}" && chmod +x ./newt
```
<Note>
Replace `{version}` with the desired version and `{architecture}` with your architecture. Check the [release notes](https://github.com/fosrl/newt/releases) for the latest information.
</Note>
### Running Newt
Run Newt with the configuration from Pangolin:
```bash
newt \
--id 31frd0uzbjvp721 \
--secret h51mmlknrvrwv8s4r1i210azhumt6isgbpyavxodibx1k2d6 \
--endpoint https://example.com
```
### Permanent Installation
Install to your PATH (may need to run as root):
```bash
mv ./newt /usr/local/bin
```
<Note>
The quick installer will do this step for you.
</Note>
### Systemd Service
Create a basic systemd service:
```ini title="/etc/systemd/system/newt.service"
[Unit]
Description=Newt
After=network.target
[Service]
ExecStart=/usr/local/bin/newt --id 31frd0uzbjvp721 --secret h51mmlknrvrwv8s4r1i210azhumt6isgbpyavxodibx1k2d6 --endpoint https://example.com
Restart=always
User=root
[Install]
WantedBy=multi-user.target
```
<Warning>
Make sure to move the binary to `/usr/local/bin/newt` before creating the service!
</Warning>
## Docker Installation
### Pull the Image
Pull the latest Newt image from Docker Hub:
```bash
docker pull fosrl/newt:latest
```
### Run with Docker
Run Newt with CLI arguments from Pangolin:
```bash
docker run -it fosrl/newt --id 31frd0uzbjvp721 \
--secret h51mmlknrvrwv8s4r1i210azhumt6isgbpyavxodibx1k2d6 \
--endpoint https://example.com
```
### Docker Compose
#### Environment Variables (Recommended)
```yaml title="docker-compose.yml"
services:
newt:
image: fosrl/newt
container_name: newt
restart: unless-stopped
environment:
- PANGOLIN_ENDPOINT=https://example.com
- NEWT_ID=2ix2t8xk22ubpfy
- NEWT_SECRET=nnisrfsdfc7prqsp9ewo1dvtvci50j5uiqotez00dgap0ii2
```
#### CLI Arguments
```yaml title="docker-compose.yml"
services:
newt:
image: fosrl/newt
container_name: newt
restart: unless-stopped
command:
- --id 31frd0uzbjvp721
- --secret h51mmlknrvrwv8s4r1i210azhumt6isgbpyavxodibx1k2d6
- --endpoint https://example.com
```
Start the service:
```bash
docker compose up -d
```
## Platform-Specific Installation
### Unraid
Newt is available in the Unraid Community Applications store. Search for "Newt" and follow the installation prompts. Enter the ID, secret, and endpoint from Pangolin in the template fields.
<Frame caption="Newt available in Unraid Community Applications store">
<img src="/images/unraid_store.png" alt="Newt on CA" />
</Frame>
### Portainer and Other UIs
Container management UIs like Portainer typically allow passing commands and environment variables to containers similar to Docker Compose. Look for a commands or arguments configuration section and follow the relevant guides.