- Consolidated documentation from Ralph Loop iterations - Archived 20+ outdated/superseded files to .archive/ - Kept essential docs: OIDC integration, mobile setup, quick start - Added operational scripts for health monitoring and backup - Research artifacts preserved in .tasks/artifacts/ Current state: - 3 VPS sites (fry, proton, photon) ONLINE in Pangolin - brn-home site pending for local services (Jellyfin, etc.) - Mobile access configuration pending Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
24 KiB
Pangolin Self-Hosting Research
Research Date: 2026-01-20 Purpose: RESEARCH-001 - Comprehensive documentation for self-hosting Pangolin control plane
Executive Summary
Pangolin is an open-source, identity-based remote access platform built on WireGuard. It functions as a self-hosted tunneled reverse proxy with identity-aware access control, providing a secure alternative to Cloudflare Tunnels and similar managed services. Pangolin combines two primary use cases: tunneled reverse proxy for web applications and VPN-style access for private network resources, all managed through a centralized control plane.
Key Architecture Components:
- Pangolin Server (Control Plane): Centralized dashboard and management plane hosted on a VPS
- Newt (Site/Client Connector): Tunnel client installed on private networks to connect backend services
- WireGuard Tunnels: Encrypted tunneling protocol for secure communication
- Traefik: Underlying reverse proxy technology
- Identity Providers: OIDC/OAuth2 integration for authentication
1. Installation Methods for Self-Hosting Pangolin Control Plane
1.1 Quick Install (Recommended for Most Users)
Official Installer Script: The quickest method uses Pangolin's automated installer script that handles all dependencies and configuration.
Prerequisites:
- Linux server (Ubuntu 22.04/24.04 or Debian 11/12 recommended)
- Root or sudo access
- Public IPv4 address
- Domain name with DNS configured
- Email address for Let's Encrypt SSL certificates
- Open firewall ports:
- TCP 80 (HTTP & Let's Encrypt validation)
- TCP 443 (HTTPS)
- UDP 51820 (WireGuard tunnels)
Installation Command:
curl -fsSL https://get.pangolin.net | sudo bash
The installer will:
- Install required dependencies (Docker, Docker Compose, WireGuard kernel module)
- Generate configuration files
- Set up Traefik reverse proxy
- Configure SSL certificates via Let's Encrypt
- Create initial admin account
- Start all services
Post-Installation:
- Access dashboard at
https://your-domain.com - Log in with admin credentials sent to provided email
- Complete organization setup
1.2 Manual Docker Compose Installation
For users requiring full control over configuration, manual Docker Compose deployment is available.
File Structure:
pangolin/
├── docker-compose.yml
├── config/
│ ├── pangolin.yml # Pangolin configuration
│ ├── traefik.yml # Traefik static configuration
│ └── traefik-dynamic.yml # Traefik dynamic configuration
├── data/
│ ├── pangolin/ # Application data
│ ├── traefik/ # Traefik certificates
│ └── postgres/ # Database (if using PostgreSQL)
└── logs/
Docker Compose Configuration:
version: '3.8'
services:
pangolin:
image: fosrl/pangolin:latest
container_name: pangolin
restart: unless-stopped
cap_add:
- NET_ADMIN
sysctls:
- net.ipv4.conf.all.src_valid_mark=1
- net.ipv4.ip_forward=1
- net.ipv6.conf.all.forwarding=1
volumes:
- ./config/pangolin.yml:/app/config.yml:ro
- ./data/pangolin:/app/data
- /dev/net/tun:/dev/net/tun
environment:
- CONFIG_FILE=/app/config.yml
ports:
- "51820:51820/udp"
networks:
- pangolin
traefik:
image: traefik:latest
container_name: traefik
restart: unless-stopped
volumes:
- ./config/traefik.yml:/etc/traefik/traefik.yml:ro
- ./config/traefik-dynamic.yml:/etc/traefik/dynamic.yml:ro
- ./data/traefik:/letsencrypt
- /var/run/docker.sock:/var/run/docker.sock:ro
ports:
- "80:80"
- "443:443"
networks:
- pangolin
postgres:
image: postgres:15-alpine
container_name: pangolin-db
restart: unless-stopped
environment:
- POSTGRES_DB=pangolin
- POSTGRES_USER=pangolin
- POSTGRES_PASSWORD=<secure_password>
volumes:
- ./data/postgres:/var/lib/postgresql/data
networks:
- pangolin
networks:
pangolin:
driver: bridge
Starting the Stack:
docker compose up -d
1.3 Alternative Installation Methods
Unraid Deployment:
- Community applications available in Unraid App Store
- Template-based deployment with GUI configuration
- Integration with Unraid Docker management
Kubernetes Deployment:
- Helm charts available for production deployments
- Supports horizontal scaling of control plane
- Advanced orchestration for enterprise use cases
2. OIDC Integration Configuration
Pangolin supports external identity providers via OAuth2/OIDC for Single Sign-On (SSO), enabling centralized authentication for both the Pangolin dashboard and applications behind the proxy.
2.1 Supported Identity Providers
- Google Workspace - Native integration
- Microsoft Entra ID (Azure AD) - Native integration
- Generic OAuth2/OIDC - Any compliant provider
- Authelia - Tested with v4.39.15+
- Authentik - Community-supported integration
- Zitadel - Native support
- Pocket ID - Native support
2.2 OIDC Provider Configuration
Step 1: Create OAuth2/OIDC Application in Identity Provider
In your IdP (e.g., Authentik, Authelia, Google), create a new OAuth2/OIDC application with the following settings:
Redirect URIs (Critical):
https://<pangolin-domain>/api/v1/auth/callback
https://<pangolin-domain>/api/v1/auth/callback/google # If using Google
https://<pangolin-domain>/api/v1/auth/callback/microsoft # If using Microsoft
For custom authentication domains:
https://auth.<your-company>.com/api/v1/auth/callback
Required Scopes:
openid(required)profile(recommended)email(recommended)groups(optional, for role-based access)
Client Configuration:
- Client Type: Confidential
- Grant Type: Authorization Code
- PKCE: Enabled (recommended)
- Token Endpoint Auth Method: client_secret_post or client_secret_basic
Step 2: Configure Pangolin Identity Provider
In Pangolin Dashboard:
-
Navigate to Settings → Identity Providers → Add Identity Provider
-
Select provider type:
- Google for Google Workspace
- Azure Entra ID for Microsoft
- Generic OAuth2/OIDC for other providers
-
Enter configuration details:
For Generic OAuth2/OIDC:
Provider Name: Your IdP Name
Provider Type: OAuth2/OIDC
# Discovery URL (auto-populates endpoints)
OIDC Discovery URL: https://your-idp.com/.well-known/openid-configuration
# Manual configuration (if discovery not available)
Authorization Endpoint: https://your-idp.com/oauth/authorize
Token Endpoint: https://your-idp.com/oauth/token
Userinfo Endpoint: https://your-idp.com/oauth/userinfo
JWKS URI: https://your-idp.com/oauth/jwks
# Client credentials
Client ID: <from_your_idp>
Client Secret: <from_your_idp>
# Scopes
Scopes: openid profile email groups
# User Mapping
Username Claim: preferred_username
Email Claim: email
Display Name Claim: name
Groups Claim: groups (optional)
For Google Workspace:
Provider Type: Google
Client ID: <google_client_id>
Client Secret: <google_client_secret>
Hosted Domain: your-domain.com (optional, restricts to specific domain)
For Microsoft Entra ID:
Provider Type: Azure Entra ID
Client ID: <azure_client_id>
Client Secret: <azure_client_secret>
Tenant ID: <azure_tenant_id>
2.3 Auto-Provisioning Users
Pangolin supports automatic user provisioning from IdP:
Configuration Options:
- Auto-provision on first login: Create user accounts automatically when users authenticate
- Group mapping: Map IdP groups to Pangolin roles/organizations
- Just-in-Time (JIT) provisioning: Update user attributes on each login
Example Configuration:
auto_provisioning:
enabled: true
default_role: user
group_mapping:
- idp_group: "admin"
pangolin_role: "admin"
- idp_group: "developers"
pangolin_role: "developer"
2.4 Custom Authentication Domains
For branded authentication experiences:
- Configure custom domain in Pangolin settings
- Set authentication domain:
auth.yourcompany.com - Update DNS records to point to Pangolin server
- Update redirect URIs in IdP configuration
3. Site Configuration (Defining Backend Services)
Sites in Pangolin represent network locations where backend services run. The Newt client connects these sites to the Pangolin control plane via WireGuard tunnels.
3.1 Understanding Sites vs Resources
Sites:
- Physical or virtual network locations (e.g., home lab, office network, VPS)
- Run the Newt client to establish WireGuard tunnels
- Can host multiple resources/services
- Types:
- Newt Sites: Traditional tunnel-based sites for private networks
- Remote Nodes: Exit nodes for client VPN access
Resources:
- Individual services/applications exposed through Pangolin
- Defined within sites
- Types:
- Public Resources (HTTPS): Web applications accessible via public URLs
- Private Resources: TCP/UDP services for VPN-style access
3.2 Creating a Site
Via Dashboard:
- Navigate to Sites → Add Site
- Configure site settings:
Site Name: Home Lab
Description: Private home network services
Site Type: Newt Site
# Tunnel Configuration
WireGuard IP Range: 10.0.1.0/24 (auto-assigned)
Listen Port: 51820 (default)
# Site Location (optional)
Location: Home Network
Tags: homelab, production
- Copy the generated installation command with credentials
Installation Command Format:
newt --id <site_id> --key <site_key> --endpoint <pangolin_server>:51820
3.3 Defining Resources (Backend Services)
HTTPS Resources (Public Web Applications):
- Navigate to Resources → Add Resource
- Select resource type: HTTPS Resource
Resource Name: Internal Wiki
Public URL: wiki.yourdomain.com
# Backend Configuration
Site: Home Lab
Backend Type: HTTP
Backend Address: 192.168.1.100:8080
Backend Protocol: http
# Health Checks
Health Check: Enabled
Health Check Path: /health
Health Check Interval: 30s
# Access Control
Access Level: Authenticated Users Only
Allowed Groups: developers, admins
# Additional Settings
Enable WebSocket: Yes (for real-time apps)
Custom Headers: X-Forwarded-Proto: https
Private Resources (TCP/UDP Services):
For services accessed via Pangolin client VPN:
Resource Name: SSH Server
Resource Type: TCP
# Backend Configuration
Site: Home Lab
Backend Address: 192.168.1.50:22
Protocol: TCP
# Access Control
Access Level: Specific Users
Allowed Users: admin@company.com, ops@company.com
3.4 Advanced Site Configuration
Environment Variables (for Newt):
# Custom configuration
NEWT_CONFIG_FILE=/etc/newt/config.yml
NEWT_LOG_LEVEL=info
NEWT_RECONNECT_INTERVAL=10s
Configuration File (/etc/newt/config.yml):
server:
endpoint: pangolin.yourdomain.com:51820
id: <site_id>
key: <site_key>
tunnel:
mtu: 1420
keepalive: 25
persistent_keepalive: true
logging:
level: info
format: json
output: /var/log/newt/newt.log
health:
enable: true
interval: 30s
3.5 DNS Configuration for Resources
For HTTPS Resources:
Create DNS A/CNAME records pointing to Pangolin server:
wiki.yourdomain.com A <pangolin_server_ip>
app1.yourdomain.com A <pangolin_server_ip>
app2.yourdomain.com A <pangolin_server_ip>
Wildcard Domain (Advanced):
*.yourdomain.com A <pangolin_server_ip>
Configure wildcard domain in Pangolin settings to automatically route all subdomains.
4. Client Deployment (Newt Client for VPS/Mobile)
The Newt client serves dual purposes:
- Site Connector: Install on private networks to expose backend services
- VPN Client: Install on user devices for accessing private resources
4.1 Newt Site Connector Deployment
For VPS/Server Sites:
Installation Methods:
A. Binary Installation (Linux):
# Download latest release
curl -fsSL https://get.pangolin.net/newt | sudo bash
# Or manual installation
wget https://github.com/fosrl/newt/releases/latest/download/newt-linux-amd64
chmod +x newt-linux-amd64
sudo mv newt-linux-amd64 /usr/local/bin/newt
# Run with credentials from Pangolin dashboard
newt --id <site_id> --key <site_key> --endpoint <pangolin_server>:51820
B. Docker Deployment (Recommended):
Create docker-compose.yml for Newt site:
version: '3.8'
services:
newt:
image: fosrl/newt:latest
container_name: newt-site
restart: unless-stopped
cap_add:
- NET_ADMIN
sysctls:
- net.ipv4.conf.all.src_valid_mark=1
devices:
- /dev/net/tun
environment:
- NEWT_SERVER_ENDPOINT=pangolin.yourdomain.com:51820
- NEWT_SITE_ID=<site_id>
- NEWT_SITE_KEY=<site_key>
volumes:
- ./config:/etc/newt
network_mode: host # Required for proper networking
C. Systemd Service (Production):
Create /etc/systemd/system/newt.service:
[Unit]
Description=Pangolin Newt Site Connector
After=network.target
[Service]
Type=simple
User=root
ExecStart=/usr/local/bin/newt \
--id <site_id> \
--key <site_key> \
--endpoint pangolin.yourdomain.com:51820 \
--config /etc/newt/config.yml
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target
Enable and start:
sudo systemctl daemon-reload
sudo systemctl enable newt
sudo systemctl start newt
sudo systemctl status newt
D. Kubernetes Deployment:
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: newt-site
namespace: pangolin
spec:
selector:
matchLabels:
app: newt-site
template:
metadata:
labels:
app: newt-site
spec:
hostNetwork: true
containers:
- name: newt
image: fosrl/newt:latest
securityContext:
capabilities:
add:
- NET_ADMIN
env:
- name: NEWT_SERVER_ENDPOINT
value: "pangolin.yourdomain.com:51820"
- name: NEWT_SITE_ID
valueFrom:
secretKeyRef:
name: newt-credentials
key: site-id
- name: NEWT_SITE_KEY
valueFrom:
secretKeyRef:
name: newt-credentials
key: site-key
4.2 Newt VPN Client Deployment
For End-User Devices (Accessing Private Resources):
A. Desktop Clients (Windows/Mac/Linux):
Download from Pangolin dashboard or releases page:
- Windows:
newt-windows-amd64.exe - macOS:
newt-darwin-amd64(Intel) ornewt-darwin-arm64(Apple Silicon) - Linux:
newt-linux-amd64
Installation Steps:
-
Create client in Pangolin dashboard:
- Navigate to Clients → Add Client
- Configure client settings:
Client Name: John's Laptop Client Type: VPN Client Allowed Resources: SSH Server, Database Server User: john@company.com
-
Copy generated credentials
-
Run Newt client:
newt --mode client \ --id <client_id> \ --key <client_key> \ --endpoint pangolin.yourdomain.com:51820
B. Mobile Clients (iOS/Android):
Currently, mobile clients use standard WireGuard configuration:
- Generate WireGuard config in Pangolin dashboard
- Export configuration as QR code or config file
- Import into WireGuard mobile app:
- iOS: WireGuard from App Store
- Android: WireGuard from Google Play
Example WireGuard Config:
[Interface]
PrivateKey = <client_private_key>
Address = 10.0.2.5/24
DNS = 1.1.1.1
[Peer]
PublicKey = <pangolin_server_public_key>
Endpoint = pangolin.yourdomain.com:51820
AllowedIPs = 10.0.0.0/16, 192.168.1.0/24
PersistentKeepalive = 25
C. Configuration Management:
Client Configuration File (config.yml):
client:
id: <client_id>
key: <client_key>
name: Johns-Laptop
server:
endpoint: pangolin.yourdomain.com:51820
public_key: <server_public_key>
tunnel:
mtu: 1420
dns_servers:
- 1.1.1.1
- 8.8.8.8
routes:
- 10.0.0.0/16 # Pangolin internal network
- 192.168.1.0/24 # Home lab network
access:
auto_connect: true
reconnect_on_failure: true
kill_switch: false # Block internet if VPN disconnects
4.3 Updating Newt Clients
Manual Update:
# Stop service
sudo systemctl stop newt
# Download latest version
curl -fsSL https://get.pangolin.net/newt | sudo bash
# Restart service
sudo systemctl start newt
Docker Update:
docker compose pull
docker compose up -d
Auto-Update Configuration:
updates:
auto_update: true
channel: stable # or beta, nightly
check_interval: 24h
5. Integration Points with Authentik
Based on research, here's how Pangolin integrates with Authentik for your use case:
5.1 Authentik Configuration
Create OAuth2/OIDC Provider in Authentik:
-
In Authentik Admin Interface:
- Navigate to Applications → Providers → Create Provider
- Select OAuth2/OpenID Provider
-
Configure Provider:
Name: Pangolin Authorization Flow: default-provider-authorization-implicit-consent Client Type: Confidential Client ID: <generate_or_custom> Client Secret: <generate_secure_secret> Redirect URIs: - https://pangolin.photon.obnh.io/api/v1/auth/callback Scopes: - openid - profile - email - groups Subject Mode: Based on User's hashed ID Include claims in id_token: Yes -
Create Application:
- Navigate to Applications → Applications → Create
Name: Pangolin Slug: pangolin Provider: Pangolin (from step 2) Launch URL: https://pangolin.photon.obnh.io
5.2 Pangolin Configuration for Authentik
In Pangolin Dashboard:
- Navigate to Settings → Identity Providers → Add Identity Provider
- Select Generic OAuth2/OIDC
Provider Name: Authentik
Provider Type: OAuth2/OIDC
# Discovery
OIDC Discovery URL: https://auth.photon.obnh.io/application/o/pangolin/.well-known/openid-configuration
# Or manual configuration
Authorization Endpoint: https://auth.photon.obnh.io/application/o/authorize/
Token Endpoint: https://auth.photon.obnh.io/application/o/token/
Userinfo Endpoint: https://auth.photon.obnh.io/application/o/userinfo/
JWKS URI: https://auth.photon.obnh.io/application/o/pangolin/jwks/
# Credentials
Client ID: <from_authentik>
Client Secret: <from_authentik>
# Scopes
Scopes: openid profile email groups
# Claims Mapping
Username Claim: preferred_username
Email Claim: email
Display Name Claim: name
Groups Claim: groups
# Provisioning
Auto-provision Users: Enabled
Default Role: user
6. Production Deployment Checklist
6.1 Security Hardening
- Enable firewall with only required ports open (80, 443, 51820)
- Use strong passwords and rotate secrets regularly
- Enable 2FA/MFA for admin accounts
- Configure rate limiting in Traefik
- Enable HTTPS-only (HSTS headers)
- Implement fail2ban or CrowdSec for intrusion detection
- Regular security updates and patching
- Audit logs enabled and monitored
6.2 Backup Strategy
Critical Data to Backup:
/data/pangolin/- Application data and database/data/traefik/acme.json- SSL certificates/config/- Configuration files- Database dumps (if using PostgreSQL)
Backup Script Example:
#!/bin/bash
BACKUP_DIR="/backups/pangolin-$(date +%Y%m%d)"
mkdir -p "$BACKUP_DIR"
# Stop services
docker compose stop
# Backup data
tar -czf "$BACKUP_DIR/pangolin-data.tar.gz" /opt/pangolin/data/
tar -czf "$BACKUP_DIR/pangolin-config.tar.gz" /opt/pangolin/config/
# Backup database
docker exec pangolin-db pg_dump -U pangolin pangolin > "$BACKUP_DIR/database.sql"
# Start services
docker compose start
# Retain last 7 days
find /backups -name "pangolin-*" -mtime +7 -exec rm -rf {} \;
6.3 Monitoring
Metrics to Monitor:
- WireGuard tunnel status
- Active client connections
- Resource health checks
- Certificate expiration (Let's Encrypt)
- Disk space and memory usage
- Authentication failures
Integration Options:
- Prometheus + Grafana for metrics
- ELK stack for log aggregation
- Uptime monitoring (UptimeRobot, Healthchecks.io)
7. Common Use Cases
7.1 Home Lab Exposure
- Expose home services (Jellyfin, Home Assistant, Plex) without port forwarding
- Centralized authentication via Authentik
- SSL certificates automatically managed
7.2 Multi-Site Corporate Network
- Connect multiple office locations
- Centralized access control for all resources
- VPN access for remote employees
7.3 Hybrid Cloud Architecture
- Bridge on-premises and cloud resources
- Single pane of glass for access management
- Secure communication between cloud regions
8. Troubleshooting
8.1 Common Issues
Newt Cannot Connect to Server:
- Verify UDP port 51820 is open on firewall
- Check WireGuard kernel module:
lsmod | grep wireguard - Verify credentials are correct
- Check logs:
docker logs newt-site
SSL Certificate Issues:
- Ensure DNS points to server IP
- Verify ports 80/443 are accessible
- Check Let's Encrypt rate limits
- Review Traefik logs:
docker logs traefik
Authentication Failures:
- Verify IdP redirect URIs match exactly
- Check client ID/secret are correct
- Review Pangolin logs for OIDC errors
- Test IdP discovery URL is accessible
8.2 Logging
Enable Debug Logging:
# In pangolin.yml
logging:
level: debug
format: json
outputs:
- type: file
path: /app/logs/pangolin.log
- type: stdout
View Logs:
# Pangolin
docker logs -f pangolin
# Newt
docker logs -f newt-site
# Traefik
docker logs -f traefik
9. Additional Resources
Official Documentation
- Main Documentation: https://docs.pangolin.net/
- GitHub Repository: https://github.com/fosrl/pangolin
- Newt Client: https://github.com/fosrl/newt
- Community Discord: https://discord.gg/pangolin
Integration Guides
- Authentik Integration: https://docs.goauthentik.io/integrations/services/pangolin/
- Authelia Integration: https://www.authelia.com/integration/openid-connect/clients/pangolin/
- CrowdSec Integration: https://www.crowdsec.net/blog/web-defense-with-pangolin-and-crowdsec
Community Resources
- Unraid Deployment Guide: https://forums.unraid.net/topic/193431-secure-external-access-to-plex-more-using-pangolin-tunneled-reverse-proxy/
- Docker Compose Examples: https://github.com/fosrl/pangolin/blob/main/docker-compose.yml
- YouTube Tutorials: Search "Pangolin self-hosting" for video guides
10. Conclusion
Pangolin provides a robust, self-hosted alternative to managed tunneling services with enterprise-grade features:
Key Advantages:
- Complete data ownership and control
- Identity-aware access control with OIDC/OAuth2
- No port forwarding required on client networks
- Automatic SSL certificate management
- Centralized management for distributed resources
- Open-source and community-driven
Ideal for:
- Home lab enthusiasts requiring secure external access
- Organizations needing multi-site connectivity
- Teams requiring centralized identity management
- Privacy-conscious users avoiding third-party services
Next Steps for Implementation:
- Provision VPS with required specifications
- Configure DNS records for Pangolin domain
- Run installation script or deploy via Docker Compose
- Configure Authentik OIDC integration
- Deploy Newt clients on target networks
- Define resources and access policies
- Test connectivity and authentication flows
- Implement monitoring and backup strategies
This research provides a comprehensive foundation for deploying Pangolin as a self-hosted control plane integrated with Authentik for identity management.