Sponsored by RamNode - Get a $5 credit to launch your own VPS with RamNode. Use code KOROMATECH.

 Click Here to Claim Your $5 Credit


In a previous post, I walked through what a VPS is and how to spin one up from scratch In RamNode. If you haven't read that one yet, go check it out first, because this post builds directly on top of it. Today we're taking things a step further and putting that VPS to real work.

We're going to try to understand what Pangolin is, how it works, and how Install it on a  VPS so we can deliver secure remote access to out internal network without punching a hole in our home firewall. 

What Pangolin Actually Is

Pangolin is an open source, self-hosted platform that combines a reverse proxy, a secure tunnel, and identity-based access control into a single solution. If you've used something like Cloudflare Tunnel, Tailscale, Authentik, and a traditional reverse proxy separately, imagine all of that rolled into one service you run yourself.

There are two pieces to understand. On one side, you have a lightweight client (commonly called the "newt" client) that runs inside your internal network. On the other side, you have the Pangolin server itself, which lives on your VPS. The newt client is what reaches out and connects to the Pangolin server to establish the tunnel.

Once you install the newt client somewhere inside your environment, it opens a connection outward to your VPS, not the other way around. Because outbound traffic is allowed through almost every firewall and NAT setup by default, that connection succeeds without any port forwarding on your end. Once it's established, the tunnel stays alive using periodic keep-alive packets, quietly holding the door open from the inside.

The VPS never reaches directly into your network. It can only send traffic through the tunnel that your newt client created and is actively maintaining. That's the core of why this approach is considered safer than opening port 80 or 443 directly on your home firewall. Under the hood, Pangolin uses WireGuard tunnels to make all of this possible.

The Part That Tends to Get Left Out

This is the piece I feel doesn't get talked about enough when people describe Pangolin. Yes, it lets you avoid opening ports on your home firewall, but you still have to open ports somewhere for any of this to work, and that's your VPS.

That means leaving ports 80 and 443 open on the VPS so it can serve web traffic, plus leaving the WireGuard port open so the newt client can establish its tunnel.  Your VPS becomes your application's gateway to the outside world, so it needs to be locked down accordingly. The open ports don't disappear when you use something like Pangolin, they just move. They move from your home network to your VPS. 

Choosing and Preparing a VPS

Before creating the VPS, it's worth deciding on your security posture first. Three groups of ports need to be open:

  • TCP 80 and 443, the standard web ports for HTTP and HTTPS traffic.
  • A pair of UDP ports (Pangolin's defaults are commonly 51820 and a secondary port in that range) used to establish and maintain the encrypted tunnel between the server and the newt client.
  • TCP 22 for SSH management, and this one should never be open to the entire internet. Restrict it to your own public IP address or a trusted management network only.

On RamNode, you'll manage this at the network level through security groups. Create a group with those ports open, each added individually with the correct protocol (TCP or UDP), and attach it to the VPS instance once it's created. Whatever default "allow everything" group gets attached automatically when you spin up the instance, remove it and replace it with your locked-down version.

When creating the instance itself, a modest VPS is plenty for this use case. RamNode's entry-level tiers handle this comfortably. Choose a recent LTS release of your preferred Linux distribution, attach your SSH key rather than relying on a password alone, and once it's running, make note of the public IPv4 address. You'll need it almost immediately for the DNS step.

Getting a Domain Pointed in the Right Direction

Pangolin requires a domain. When you run the installer, it asks for a base domain and a dashboard domain, and it uses that information to automatically request an SSL certificate through Let's Encrypt. Without a domain, the installer has nothing to issue a certificate for.

Here's the sequence: before running the installer, go to wherever your domain's DNS is hosted and point it at your VPS's public IP. Once that's in place, you tell Pangolin what the domain is during installation, and because DNS is already resolving correctly, it can issue the certificate automatically as part of setup.

Getting a domain and choosing a DNS host is outside the scope of this post, they can be the same company or two different ones, whichever you prefer. Once you have a domain, make sure its nameservers point at whichever DNS host you've chosen. From there, you'll create a handful of A records, and each one serves a distinct purpose.

The first A record points your root domain at the VPS's public IP. The second points a subdomain you'll use for the Pangolin dashboard at that same IP. After that, you'll need one A record for every application you plan to expose through Pangolin, because each application needs its own unique domain name resolving to your VPS. Pangolin uses that domain name to figure out which internal service a given request should be routed to.

If you're using a DNS host that offers a proxying or CDN layer in front of your records (Cloudflare being the common example): turn that proxying off for now on every record involved in this setup. Those proxy layers tend to filter and block things during initial configuration, and you can easily spend an hour chasing a "misconfiguration" that's actually just the proxy quietly interfering. Once everything is confirmed working, you can revisit and re-enable it if it fits your setup.

Running the Installer

With the VPS ready and DNS pointed correctly, the installation itself is straightforward. Pangolin ships a quick installer that handles everything, including installing Docker if it isn't already present.

SSH into your VPS, run a system update, then pull down and run the installer. From there it walks you through a series of prompts:

It'll ask where to install Pangolin (the default system location is fine for most setups), whether you want the enterprise edition or the free community version (community is more than enough for personal or lab use), and whether you want a separate Postgres database or the built-in lightweight database (for a small environment, the built-in option is the right call, there's no separate database to manage). It'll then ask for your base domain and confirm the default dashboard subdomain, both of which should match the A records you already created.

 It asks for an email address to use with Let's Encrypt for certificate requests. It asks whether to install the tunneling component (say yes, this is the core piece that makes the whole tunnel possible), whether to enable email functionality (optional, skip it for now if you don't need it yet), whether your server is IPv6 capable, and whether to install the GeoIP database (worth enabling, since it lets you block or allow traffic by country or ISP later as an extra layer of security).

Once you confirm you want to start the containers and choose Docker as your runtime, the installer takes over. Give it a few minutes. When it finishes, it will hand you a setup token and a URL for the dashboard. Keep that token somewhere safe, you need it to create the initial admin user, and without it you can't complete setup.

Organizations, Sites, and Resources

Once you're in the dashboard and have created your admin account, Pangolin will ask you to create an organization, then a site. A few concepts are worth understanding before you click through these screens.

An organization is the top-level container that owns everything else you set up, all your sites and resources live under it. A site represents a server or location where your services actually run, in most home lab setups this is simply your internal network. If your environment is segmented, you can install a separate newt client in each segment and grant different sites access to different resources, keeping things isolated from each other.

Resources are the actual applications or services you want to expose, whatever you're running internally that you want reachable from outside. Resources come in two flavors. Public resources are reachable without authentication, or with authentication layered on top if you choose to require it, useful for something like a personal website you're comfortable exposing. Private resources require explicit authentication or device-level permission before they're even visible, which is the real zero trust piece of the puzzle. A private resource stays effectively invisible to anyone who hasn't been explicitly granted access, even if they know the URL.

When you create a site, you'll choose the newt client as your connection method, give the site a name, and select the operating system where the client will run. Pangolin then gives you the exact commands to install and connect the client, along with an option to set it up as a persistent system service so it reconnects automatically after a reboot. If you intend this setup to be permanent, that persistence step matters, because without it, a simple restart of your internal server breaks the tunnel until you manually reconnect it.

A couple of things worth knowing before you run those client commands. If anything on your network inspects or filters outbound traffic, make sure your Pangolin domain is excluded from that filtering, or the client may fail to connect. And if you're using a DNS proxy layer like the one mentioned earlier, keep it disabled during this step specifically, the client typically performs an initial connectivity check using ICMP, and proxy layers that don't respond to ICMP will cause that check to fail even when everything else is configured correctly.

Once the client connects successfully, your site will show as online in the dashboard, along with the endpoint it detected for your internal network.

Exposing Your First Application

With a site online, adding a resource is the last step. You give it a name, choose the subdomain it should live at (matching the A record you created earlier), select the site to route through, and point it at the local address and port of the service you want exposed. Enabling health checks here is worth doing, it gives you an at-a-glance green or red status so you always know whether the path from Pangolin to your internal service is actually working.

Before treating anything as done, spend a minute in the access rules for that resource. This is where you decide who can actually reach it. You can require a PIN, a passcode, an email allowlist, or tie access to an existing Pangolin login. It is genuinely important to enable at least one of these for anything meaningful. Leaving a resource completely open means anyone who discovers or guesses the URL can walk straight in, and that's the one thing you want to actively avoid.

Once configured, test it from a private or incognito browser window, not a session where you're already logged into Pangolin, so you're seeing exactly what an outside visitor would see. You should hit an authentication prompt before ever reaching the actual application.

Staying Safe Once It's Running

Opening up any part of your internal network to the internet always carries risk, no matter how carefully it's wrapped in tunnels and access rules. A few habits go a long way here. Keep a tight firewall on the VPS itself even with Pangolin's tunnel in place, and keep both the VPS and Pangolin patched and up to date, since these are now your internet-facing components and deserve the most attention. 

Consider a web application firewall in front of Pangolin if you want an additional filtering layer for malicious traffic. Default to private resources for anything that only you need to reach, rather than exposing things publicly by default. And if you want to go a step further, run the newt client from an isolated network segment rather than your main network, so that if anything is ever compromised, the blast radius is contained.

None of this is meant to be alarmist, it's just the honest tradeoff of exposing anything to the public internet. Take the extra half hour to lock things down properly. It's worth it.

Command Reference Guide

Everything below assumes you already have a VPS provisioned with SSH access, the security group or firewall rules described in Part One applied, and DNS records pointing at your VPS's public IP. Replace placeholders like your-domain.com, pangolin.your-domain.com, and YOUR_VPS_IP with your own values.

Update the VPS

  • apt update && apt upgrade -y

Download and run the Pangolin installer

  • curl -fsSL https://github.com/fosrl/pangolin/releases/latest/download/installer -o installer
  • chmod +x installer
  • ./installer

The installer will prompt you interactively. Have the following ready before you start:

  • Base domain, e.g. your-domain.com
  • Dashboard subdomain, e.g. pangolin.your-domain.com
  • An email address for Let's Encrypt certificate requests

Answer the prompts as they come:

  • Installation directory: accept the default unless you have a reason not to
  • Enterprise edition: no, unless you specifically need it
  • Separate Postgres database: no, for small or personal setups the built-in database is sufficient
  • Base domain and dashboard domain: enter the values you prepared above
  • Certificate email: enter your email
  • Install tunneling component: yes
  • Enable email functionality: optional, can be configured later from the dashboard
  • IPv6 support: match your actual server capability
  • Install GeoIP database: yes, recommended
  • Start containers now: yes
  • Container runtime: Docker (default) or Podman
  • Install Docker if missing: yes

When it finishes, copy the setup token and the dashboard URL it prints. You'll need the token to complete first-time setup in the browser.

Complete first-time setup in the browser

Navigate to the dashboard URL provided by the installer. Enter the setup token, then create your admin email and password. Log in, and create your initial organization when prompted.

Create a site and install the newt client

From the dashboard, add a new site, choose the newt client as the connection type, name it, and select the operating system for the machine that will run it. Pangolin will generate two commands specific to your site's endpoint, ID, and secret. They'll look roughly like this (use the exact values Pangolin gives you, these are placeholders):

Install the newt client

  • curl -fsSL https://your-domain.com/get-newt -o newt
  • chmod +x newt

Connect the client to your Pangolin server

  • ./newt --id YOUR_SITE_ID --secret YOUR_SITE_SECRET --endpoint https://pangolin.your-domain.com

Run these on the internal machine (a lightweight container or VM works fine) that has network access to whatever service you want to expose.

Make the connection persistent with systemd

If you want the tunnel to survive a reboot, set up a systemd service rather than relying on the manual command above. A typical unit file looks like this:

# /etc/systemd/system/newt.service
[Unit]
Description=Newt Client for Pangolin
After=network.target

[Service]
ExecStart=/usr/local/bin/newt --id YOUR_SITE_ID --secret YOUR_SITE_SECRET --endpoint https://pangolin.your-domain.com
Restart=always
RestartSec=5
User=root


[Install]
WantedBy=multi-user.target

Then enable and start it:

  • systemctl daemon-reload
  • systemctl enable newt.service
  • systemctl start newt.service

Useful management commands going forward:

  • systemctl status newt.service
  • systemctl restart newt.service
  • systemctl stop newt.service

Add a resource to expose an application

This step happens entirely in the dashboard rather than the command line. Under your site, choose Add Resource, give it a name, and set the subdomain to match the A record you created for that application, for example app.your-domain.com. Point the target at the internal service's local IP address, protocol (HTTP or HTTPS), and port. Enable health checks, then configure access rules under that resource, PIN, passcode, email allowlist, or Pangolin login, before considering it done.

Verify the tunnel and site status

Back in the dashboard, your site should show as online once the newt client has connected successfully, along with its detected endpoint. If it shows offline or the client fails to connect, check the following in order:

  • Any DNS proxy layer in front of your domain is temporarily disabled
  • No outbound traffic filtering on your internal network is blocking the Pangolin domain
  • The machine running the newt client can actually reach the internal service you're trying to expose

Once your resource shows healthy and access rules are in place, test it from a private or incognito browser session to confirm it behaves as expected for an outside visitor.

Final Thought

There's something satisfying about watching a request leave your browser, cross the internet, hit a small VPS you set up yourself, and land on an application running quietly at home, all without a single inbound port sitting open on your own network. That's really what this whole setup buys you. Not just convenience, but a meaningfully smaller attack surface and a lot more control over who gets to see what.

Remember to keep your VPS patched, keep an eye on what you're exposing and why, and default to the more restrictive option whenever you're unsure. Start with one application, get comfortable with how the pieces talk to each other, and only then start adding more. 

About the author

Quiet Engineer

A lifelong learner with a passion for tech and soccer. Koroma Tech is where I share my journey and help others along the way. I enjoy taking on challenges and see each one as a chance to learn and grow.

>