Securing Your Home Network: Implementation of Pangolin and Newt for Secure Internet-Facing Applications (Part 1)

In today’s connected world, self-hosting applications presents a significant challenge: how do you make services available online without compromising your entire home network? Traditional solutions like port forwarding or VPNs often create security vulnerabilities or management headaches.

This two-part guide explores implementing a modern, secure architecture using Pangolin and Newt that keeps your network safe while making selected applications accessible.

Understanding the Challenge

When self-hosting applications that need internet accessibility, several problems emerge:

  1. Security perimeter expansion: Traditional port forwarding exposes your network’s edge directly to the internet
  2. Authentication complexity: Managing access control across multiple applications
  3. Network isolation difficulties: Preventing compromised services from affecting other systems
  4. Dynamic IP complications: Maintaining connections when home IP addresses change
  5. SSL certificate management: Securing connections properly at scale

The solution combines several technologies - hosting Pangolin on a VPS (Virtual Private Server) while running applications locally with careful network isolation.

Architecture Overview: The Separated Concerns Approach

Our architecture creates three distinct security domains:

  1. Internet-facing VPS: Hosts only Pangolin stack components
  2. Exposed applications network: Contains only services intended for external access
  3. Private home network: Remains completely isolated from internet exposure

This separation follows the principle of least privilege - only the minimal necessary components receive internet exposure.

Key Components

1. Cloud VPS

  • Hosts the Pangolin stack, functioning as the secure gateway
  • Exposes only necessary ports (80, 443, 51820)
  • Contains no actual application data or sensitive information
  • Functions as a “reverse bastion” for secure tunneling

2. Pangolin Stack (on VPS)

  • Pangolin Server: Management interface and authentication system
  • Gerbil: WireGuard tunnel manager
  • Traefik: Reverse proxy with SSL termination
  • CrowdSec: Security protection layer

3. Newt Client (on isolated local network)

  • Runs in a confined environment (dedicated VLAN or container network)
  • Only connects to approved application containers
  • Maintains encrypted tunnel to VPS
  • Limited network visibility

4. Application containers

  • Run on isolated network segment
  • Only communicate with Newt and necessary dependencies
  • Unaware of direct internet exposure

Detailed Network Isolation Implementation

graph TD
    subgraph Internet["INTERNET"]
        VPS["CLOUD VPS<br/>PANGOLIN STACK"]
    end

    subgraph HomeNetwork["HOME NETWORK (192.168.1.0/24)"]
        Router["HOME ROUTER/FIREWALL"]
        
        subgraph VLAN10["MANAGEMENT VLAN (192.168.10.0/24)"]
            Proxmox["PROXMOX<br/>TYPE 1 HYPERVISOR"]
            Admin["Admin Workstation"]
        end
        
        subgraph RIG["PHYSICAL SERVER<br/>i5 12600K, 64GB DDR4, NVME 250GB, 2x4TB HDD"]
            Proxmox
        end
        
        subgraph VLAN20["EXPOSED APPS VLAN (192.168.20.0/24)<br/>LIMITED NETWORK VISIBILITY"]
            ExposedVM["UBUNTU VM<br/>ISOLATED NETWORK"]
            
            subgraph ExposedContainers["DOCKER NETWORK: exposed-apps (172.20.0.0/16)"]
                Newt["NEWT CLIENT<br/>(WireGuard Tunnel)"]
                NextcloudContainer["Nextcloud<br/>172.20.0.10"]
                JellyfinContainer["Jellyfin<br/>172.20.0.11"]
                HomeAssistantContainer["Home Assistant<br/>172.20.0.12"]
                DashboardContainer["Homarr Dashboard<br/>172.20.0.13"]
                OtherExposedApps["Other Exposed<br/>Applications"]
            end
        end
        
        subgraph VLAN30["PRIVATE APPS VLAN (192.168.30.0/24)<br/>NO INTERNET EXPOSURE"]
            PrivateVM["UBUNTU VM<br/>INTERNAL ONLY"]
            
            subgraph PrivateContainers["DOCKER NETWORK: private-apps (172.30.0.0/16)"]
                AdGuardHome["AdGuard Home"]
                SecurityTools["Security Tools<br/>CrowdSec, Fail2Ban,<br/>WatchYourLAN"]
                PrivateServices["Private Services<br/>Database, Storage, etc."]
            end
        end
        
        subgraph VLAN40["PENTESTING VLAN (192.168.40.0/24)<br/>ISOLATED + MONITORED"]
            KaliVM["KALI LINUX VM<br/>CTF/PENTESTING<br/>USUALLY OFFLINE"]
        end
    end
    
    subgraph VPS_COMPONENTS["PANGOLIN STACK ON VPS"]
        PANGOLIN["PANGOLIN SERVER<br/>(Management interface)"]
        GERBIL["GERBIL<br/>(WireGuard tunnels manager)"]
        TRAEFIK["TRAEFIK<br/>(Reverse proxy with SSL)"] 
        CROWDSEC_VPS["CROWDSEC<br/>(Security layer)"]
    end
    
    Router --> VLAN10
    Router --> VLAN20
    Router --> VLAN30
    Router --> VLAN40
    
    VPS --> VPS_COMPONENTS
    
    VPS <-->|Encrypted WireGuard Tunnel<br/>No port forwarding needed| Newt
    
    Newt <-->|Proxies requests to| ExposedContainers
    
    ENDUSER["END USERS"] -->|HTTPS Requests| VPS
    
    classDef exposed fill:#f9d5e5,stroke:#333,stroke-width:1px;
    classDef private fill:#eeeeee,stroke:#333,stroke-width:1px;
    classDef infrastructure fill:#d5e8f9,stroke:#333,stroke-width:1px;
    classDef vps fill:#d9f,stroke:#333,stroke-width:2px;
    classDef internet fill:#f5f5f5,stroke:#666,stroke-width:1px;
    
    class VLAN20,ExposedVM,ExposedContainers,Newt,NextcloudContainer,JellyfinContainer,HomeAssistantContainer,DashboardContainer,OtherExposedApps exposed;
    class VLAN30,PrivateVM,PrivateContainers,AdGuardHome,SecurityTools,PrivateServices private;
    class RIG,Proxmox,VLAN10,Admin,Router,VLAN40,KaliVM infrastructure;
    class VPS,VPS_COMPONENTS,PANGOLIN,GERBIL,TRAEFIK,CROWDSEC_VPS vps;
    class Internet,ENDUSER internet;

Network Segmentation Explained

The key to this setup is proper network segmentation using VLANs (Virtual Local Area Networks) or similar isolation techniques:

  1. Management VLAN (192.168.10.0/24)

    • Contains hypervisor management interface
    • Admin access only
    • Strict firewall rules
  2. Exposed Apps VLAN (192.168.20.0/24)

    • Contains only the VM running Newt and exposed applications
    • Cannot access other network segments
    • Docker containers further isolate applications (172.20.0.0/16)
    • Newt only has permissions to access specific containers
  3. Private Apps VLAN (192.168.30.0/24)

    • Contains sensitive services never exposed to internet
    • No route to Newt or exposed applications
    • Complete isolation from internet-facing components
  4. Pentesting VLAN (192.168.40.0/24)

    • Isolated environment for security testing
    • Heavily monitored
    • Usually powered off when not in use

Firewall Rules Implementation

The firewall configuration creates strict boundaries between network segments:

  1. From Management VLAN:

    • Allow established connections
    • Allow SSH to Exposed and Private VLANs
    • Allow Proxmox management to all VMs
    • Deny all other traffic
  2. From Exposed Apps VLAN:

    • Allow established connections
    • Allow DNS to specific servers
    • Block all access to Management VLAN
    • Block all access to Private VLAN
    • Allow outbound internet (WireGuard tunnel only)
  3. From Private Apps VLAN:

    • Allow established connections
    • Allow DNS and DHCP
    • Block all access to Exposed VLAN
    • Allow controlled access to Management VLAN (monitoring)
    • Block direct internet access

Setting Up the VPS Pangolin Stack

The VPS component serves as our secure gateway to the internet. Here’s how to set it up:

1. VPS Requirements

  • Ubuntu 24.04 LTS or similar
  • Minimum 2 vCPU, 4GB RAM
  • 40GB SSD storage
  • Unmetered or generous bandwidth allocation
  • Public IPv4 address
  • Provider with good uptime (Linode, DigitalOcean, Vultr, etc.)

2. Initial Server Hardening

# Update system
sudo apt update && apt upgrade -y

# Install basic security tools
sudo apt install -y ufw fail2ban unattended-upgrades

# Configure firewall
ufw default deny incoming
ufw default allow outgoing
ufw allow ssh
ufw allow 80/tcp
ufw allow 443/tcp
ufw allow 51820/udp
ufw enable

# Configure automatic updates
sudo dpkg-reconfigure --priority=low unattended-upgrades

3. Installing Docker and Docker Compose

# Install requirements
sudo apt install -y apt-transport-https ca-certificates curl software-properties-common

# Install Docker and docker compose (only for ubuntu)
wget https://gist.githubusercontent.com/hhftechnology/64c9ee84795b01bfac73de24a702db7c/raw/fbe6c596284e405e7c9be613b489ad53d24a4467/install-docker.sh
chmod +x install-docker.sh
sudo  ./install-docker.sh

# Create Docker network
docker network create pangolin

4. Pangolin Stack Deployment (you have 2 options manual via compose with crowdsec or auto install)

Manual

Create a project directory and set up the Docker Compose configuration:

mkdir -p /opt/pangolin
cd /opt/pangolin

Create a docker-compose.yml file with the following content:

networks:
  pangolin:
    external: true
services:
  pangolin:
    image: fosrl/pangolin:1.0.0-beta.14 #use whatever latest version avaliable but dont use latest tag
    container_name: pangolin
    restart: unless-stopped
    networks:
      - pangolin
    volumes:
      - ./config:/app/config
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:3001/api/v1/"]
      interval: "3s"
      timeout: "3s"
      retries: 5

  gerbil:
    image: fosrl/gerbil:latest
    container_name: gerbil
    restart: unless-stopped
    depends_on:
      pangolin:
        condition: service_healthy
    networks:
      - pangolin
    extra_hosts:
      - "pangolin:172.19.0.2" #read crowdsec guide why ip is used.
    command:
      - --reachableAt=http://gerbil:3003
      - --generateAndSaveKeyTo=/var/config/key
      - --remoteConfig=http://pangolin:3001/api/v1/gerbil/get-config
      - --reportBandwidthTo=http://pangolin:3001/api/v1/gerbil/receive-bandwidth
    volumes:
      - ./config/:/var/config
    cap_add:
      - NET_ADMIN
      - SYS_MODULE
    ports:
      - 51820:51820/udp
      - 443:443
      - 80:80

  crowdsec:
    image: crowdsecurity/crowdsec:latest
    container_name: crowdsec
    environment:
      GID: "${GID-1000}"
      COLLECTIONS: crowdsecurity/traefik
    networks:
      - pangolin
    volumes:
      - ./config/crowdsec:/etc/crowdsec
      - ./config/crowdsec/db:/var/lib/crowdsec/data
      - ./config/traefik/logs:/var/log/traefik
    restart: unless-stopped

  traefik:
    image: traefik:v3.3.3
    container_name: traefik
    restart: unless-stopped
    network_mode: service:gerbil
    depends_on:
      pangolin:
        condition: service_healthy
    command:
      - --configFile=/etc/traefik/traefik_config.yml
    volumes:
      - ./config/traefik:/etc/traefik:ro
      - ./config/letsencrypt:/letsencrypt
      - ./config/traefik/logs:/var/log/traefik

Create the initial configuration directories:

mkdir -p config/traefik config/letsencrypt config/crowdsec

Auto Install

1. Downloading and Running the Installer

Installer binaries for Linux can be found in the Github releases for ARM and AMD64 (x86_64).

For example, on amd64 download the installer with either wget or curl and make it executable:

wget -O installer "https://github.com/fosrl/pangolin/releases/download/1.0.0-beta.14/installer_linux_amd64" && chmod +x ./installer

The downloaded files will be named installer in the current directory.

The installer must be run as root. If you’re not already root, switch to the root user or use sudo:

sudo ./installer

The installer will place all files in the current directory. If you want to install Pangolin in a different directory, you can move the installer to that directory and run it there.

2. Basic Configuration

The installer will prompt you for the following basic information:

  1. Base Domain Name: Enter your base fully qualified domain name (without any subdomains) Example: example.com
  2. Dashboard Domain Name: The domain where the application will be hosted. This is used for many things, including generating links. You can run Pangolin on a subdomain or root domain. Example: proxy.example.com
  3. Let’s Encrypt Email: Provide an email address for SSL certificate registration with Lets Encrypt. This should be an email you have access to.
  4. Tunneling You can choose not to install Gerbil for tunneling support - in this config it will just be a normal reverse proxy. See how to use without tunneling.
3. Admin User Setup

You’ll need to configure the admin user. This is the first user in the system. You will log in initially with this user.

  1. Admin Email: Defaults to admin@yourdomain.com but can be customized
  2. Admin Password: Must meet these requirements:
    • At least 8 characters
    • At least one uppercase letter
    • At least one lowercase letter
    • At least one digit
    • At least one special character
4. Security Settings

Configure security options:

  1. Signup Without Invite: Choose whether to disable user registration without invites (defaults to disabled). This removes the “Sign Up” button on the login form and is recommended for private deployments.
  2. Organization Creation: Decide if users can create their own organizations (defaults to enabled)
5. Email Configuration

Decide whether to enable email functionality. This allows Pangolin to send transactional emails like OTP or email verification requests.

If enabled, you’ll need to provide:

  • SMTP host
  • SMTP port (defaults to 587)
  • SMTP username
  • SMTP password
  • No-reply email address. This is the sender email address that Pangolin will email from. Many times this should be the same as the username.
6. Docker Installation

If Docker isn’t already installed, the installer will:

  1. Detect your Linux distribution
  2. Offer to install Docker automatically
  3. Install the appropriate version for your distribution
7. Container Deployment

After configuration, the installer will:

  1. Pull the necessary Docker containers
  2. Create required directories:
    • config/
    • config/letsencrypt/
    • config/db/
    • config/logs/
  3. Generate configuration files
  4. Start the containers using Docker Compose
Post-Installation

After successful installation:

  1. The system will be accessible at your configured domain
  2. You can log in using the admin email and password you provided

5. Configuring Pangolin (skip this if you have used auto installer)

After starting the containers for the first time, Pangolin will generate a default configuration. We’ll need to modify it to match our requirements:

# Start the stack to generate initial config
docker compose up -d
sleep 10
docker compose down

# Now edit the configuration
nano config/config.yml

Edit the configuration file with appropriate values:

app:
  dashboard_url: "https://pangolin.yourdomain.com"
  base_domain: "yourdomain.com"
  log_level: "info"
  save_logs: true

server:
  external_port: 3000
  internal_port: 3001
  next_port: 3002
  internal_hostname: "pangolin"
  session_cookie_name: "pangolin_session"
  resource_access_token_param: "p_token"
  resource_session_request_param: "p_session_request"
  trust_proxy: true
  dashboard_session_length_hours: 168
  resource_session_length_hours: 720

traefik:
  cert_resolver: "letsencrypt"
  http_entrypoint: "web"
  https_entrypoint: "websecure"
  prefer_wildcard_cert: true
  additional_middlewares: ["crowdsec-bouncer@file"]

gerbil:
  start_port: 51820
  base_endpoint: "yourdomain.com"
  use_subdomain: false
  subnet_group: 100.80.0.0/20
  block_size: 24
  site_block_size: 30

rate_limits:
  global:
    window_minutes: 1
    max_requests: 100

users:
  server_admin:
    email: "admin@yourdomain.com"
    password: "YourSecureAdminPassword123!"

flags:
  require_email_verification: false
  disable_signup_without_invite: true
  disable_user_create_org: true
  allow_raw_resources: true
  allow_base_domain_resources: false

6. Starting the Pangolin Stack

Start the stack and verify all components are running:

docker compose up -d
docker compose ps

You should now be able to access the Pangolin dashboard at your configured domain. Log in with the admin credentials you specified in the config file.

Next Steps in Part 2

In the next part, we’ll cover:

  1. Setting up the isolated network for exposed applications
  2. Configuring Newt in a confined environment
  3. Connecting exposed applications securely
  4. Implementing proper monitoring and logging
  5. Testing the security boundaries

By properly segmenting your network and using this architecture, you’ll gain the ability to expose selected applications to the internet without compromising your entire home network’s security.

2 Likes