blg-20250914-pangolin.jpeg

<aside> 💡

Guide to set up Pangolin on a VPS, using fail2ban at the host level to ban non-SNI access and other error access attempts, adding CrowdSec and GeoBlock Traefik middlewares. We do not detail adding Sites to the dashboard.

</aside>

Revision: 20250915-0 (init: 20250914)

Pangolin is an “Identity-Aware Tunneled Reverse Proxy Server with Dashboard UI”. It is designed to securely expose private resources, often from a home network, without requiring the opening of ports on a firewall. It's a self-hosted alternative to services like Cloudflare Tunnels. Pangolin utilizes Traefik as its underlying reverse proxy engine, which handles the actual routing of HTTP traffic. A custom Traefik plugin called Badger works with Pangolin to authenticate requests, while a separate component, Gerbil, manages WireGuard tunnels for secure connectivity. This combination allows for a clean dashboard UI and simplified management of proxies, authentication, and access control.

https://github.com/fosrl/pangolin

This guide performs a Pangolin installation with VPS hardening on Ubuntu 24.04 Linux.

<aside> ⚙

Acknowledgement: Many of the steps presented will reference external sources that provide detailed instructions enabling us to achieve our expected results. We document the adaptations required to achieve our goals, but do not provide the step-by-step instructions outlined in the original guides. End-users are advised to consult the linked source material for complete details.

</aside>

The key steps include:

Artifacts for this guide are at:

geekierblog-artifacts/20250914-pangolin at main ¡ mmartial/geekierblog-artifacts

Pre-requisites

VPS Hardening

After installing Ubuntu 24.04 Server on our VPS of choice, we hardened the system following:

Post-Steps: Ubuntu 24.04 Desktop (Rev: 20250121-0)

<aside> ☝

Steps performed:

Feel free to explore other settings to use in the document above.

</aside>

Ubuntu 24.04 VPS Hardening (Rev: 20240922-0)

<aside> ☝

Steps performed:

Sending emails: Postfix using Fastmail (Rev: 20240531-0)

Unattended Upgrades on Ubuntu Linux (Rev: 20240622-0)

Docker installation

<aside> 💡

If you have installed docker during OS installation, and have it as part of sudo snap list, we recommend the non-snap installation (to access the /opt/pangolin installation folder). Remove the snap one using sudo snap remove docker --purge

</aside>

Install docker:

curl -fsSL [<https://get.docker.com>](<https://get.docker.com/>) | sh
sudo usermod -aG docker $USER

Pangolin Installation

https://docs.digpangolin.com/self-host/quick-install

<aside> ⚠️

Make sure to have a wildcard that points your domain to your VPS address so that **.*example.com subdomain is resolved by the Pangolin service.

Details on this setup and how to obtain the DNS token can be found in:

Traefik Proxy (Rev: 20250210-0)

</aside>

In /opt/pangolin (create if needed, make sure your user can write in the folder), install and answer the questions from the latest installer.

curl -fsSL <https://digpangolin.com/get-installer.sh> | bash

sudo ./installer

An example installation steps could be:

Welcome to the Pangolin installer!
This installer will help you set up Pangolin on your server.

Please make sure you have the following prerequisites:
- Open TCP ports 80 and 443 and UDP ports 51820 and 21820 on your VPS and firewall.

Lets get started!

=== Basic Configuration ===
Do you want to install Pangolin as a cloud-managed (beta) node? (yes/no): no
Enter your base domain (no subdomain e.g. example.com): example.com
Enter the domain for the Pangolin dashboard (default: pangolin.example.com): pangolin.example.com
Enter email for Let's Encrypt certificates: [email protected]
Do you want to use Gerbil to allow tunneled connections (yes/no) (default: yes): yes

=== Email Configuration ===
Enable email functionality (SMTP) (yes/no) (default: no): yes
Enter SMTP host: smtp.fastmail.com
Enter SMTP port (default 587) (default: 587):
Enter SMTP username: [email protected]
Enter SMTP password: generated_app_password
Enter no-reply email address: [email protected]

=== Advanced Configuration ===
Is your server IPv6 capable? (yes/no) (default: yes):

=== Generating Configuration Files ===

Configuration files created successfully!

=== Starting installation ===
Would you like to install and start the containers? (yes/no) (default: yes):
Would you like to run Pangolin as Docker or Podman containers? (default: docker):
Pulling the container images...
[...]

=== CrowdSec Install ===
Would you like to install CrowdSec? (yes/no) (default: no):

=== Setup Token ===
Waiting for Pangolin to generate setup token...
Setup token: TOKEN

This token is required to register the first admin account in the web UI at:
<https://pangolin.example.com/auth/initial-setup>

Save this token securely. It will be invalid after the first admin is created.

Installation complete!

Because we use ufw-docker we must enable the gerbil service to allow connections before we can access the setup URL.

ufw-docker

udw-docker acts as a Firewall for Docker containers, including Pangolin’s deployment. As such, with ufw-docker installed, we need to enable access to gerbil before we can access the WebUI:

sudo ufw-docker allow gerbil 80/tcp
sudo ufw-docker allow gerbil 443/tcp
sudo ufw-docker allow gerbil 51820/udp
sudo ufw-docker allow gerbil 21820/udp

This step can only be performed once the gerbil service has been added. It is likely that since the service is not accessible yet, the web challenge for domain certificate generation during the initial startup failed, and Traefik generated a self-signed certificate. Since we will prefer to use wildcard domains, we will solve this in the next step. A side effect of this is that no certificate for pangolin.example.com was generated or stored in the config/letsencrypt/acme.json file (and therefore posted on the Let’s Encrypt public list — you can check your existing ones at https://crt.sh/)

Using Wildcard Domains

https://docs.digpangolin.com/self-host/advanced/wild-card-domains

https://docs.digpangolin.com/self-host/advanced/config-file

<aside> 💡

Our DNS is Cloudflare; we must “make sure [our] API token has the permissions Zone/Zone/Read and Zone/DNS/Edit and make sure it applies to all zones.”

</aside>

The following are modified configuration files to support wildcard domains using DNS-01 challenge as well a few modifications to the various configuration files.

In /opt/pangolin, run docker compose down to take the services down.

In green are our alterations to the various files, which support, among other things, wildcard certificates for Let’s Encrypt.

Restart the stack by running docker compose up -d

Checking the config/letsencrypt/acme.json there will be only the PrivateKey and Certificates for example.com and *.example.com, no subdomain is listed.

We can check the status by going to:

https://crt.sh/

We also note that at a later date, we will be moving the dynamic_config.yaml file to use the Middleware Manager.

Initial connection

Using Firefox or another browser, go to the specified URL.

Once logged in (make sure to save the login information, add a MFA and maybe a passkey to your admin account), create your Organization, Site (for example your Newt clients or local resources), and Resources (the URLs you want to expose for the given sites).

CleanShot 2025-09-10 at 21.10.51@2x.png

Traefik Dashboard

https://forum.hhf.technology/t/traefik-dashboard-a-vital-prerequisite-for-debugging-pangolin-and-middleware-manager/2208

The Traefik Dashboard is running; we just need to access it from the local system. Since Pangolin is running on the system hosting Traefik. Use the above guide to create a “Local Site” Site and “Traefik Dashboard” Resource making sure only your admin user can access it.

Middleware Manager

https://github.com/hhftechnology/middleware-manager


Untitled

Untitled