User Tools

Site Tools


Setting up a bastion host on a VPS, with pfSense


pfSense is debatably the world's most popular firewall, which is produced by a local “Mom and Pop” shop, Netgate; hailing from Austin, Texas, USA. I've purchased SG-2440 units from Netgate (and have used their SG-4860 units), which reside on unreliable connections (e.g. residential and basic commercial contracts) with ephemeral IP addresses 1), filtered/throttled traffic, and/or too much risk for running a DMZ configuration as “Set it, and forget it.™”

A significant amount of cooperative research/projects between friends/colleagues, and myself occur from the comfort of our homes and workshops. Thankfully, there are many more out there, whom understand that it doesn't make sense to spend so much time and money driving somewhere else to simply sit in front of your laptop, when you can stay at home to accomplish more with less:

My friends and I use remote GPU servers for Machine Learning which cannot be accessed from a WAN, and where we frequently need an easy way to work together on software and models. The 3 common scenarios that we face on an almost weekly, if not daily, basis:

  1. In private, with an SG-2440 operating in split-tunnel capacity across IPsec.
  2. In private and/or workshops, with test machines 2), connected together by leap-frogging across Tinc.
  3. In public, with our laptops operating in full-tunnel capacity across OpenVPN.

pfSense can handle all of the above scenarios.

If this was outside of private use? An expensive A reliable implementation would be a Virtual private cloud via Google, Amazon, or Microsoft.

For series of screenshots, rather than vertically fill this article with them, you can click on each of the images, to view a larger version.


    • A few other VPS providers allow raw disk access. I've heard of people having success with Vultr.
  • DNS entry for this bastion host, specifically for the Web HTTPS Configuration section below.
  • Optional - if you have a Dynamic IP: DDNS entry for your administrative location(s).
    • IMHO, FreeDNS is one of the best services available. I've had a pro account with them for a long time, have never seen it go down, and have never been disappointed with the experience or contact with the owner, Joshua Anderson.
  • Optional, but recommended: SSH client (e.g. iTerm2 or PuTTY)

If you're not signed up with Linode (or Vultr) yet, you can use my Linode referral code or my Vultr referral code, which will help me cover my server costs. Thanks! :-)



Linode, LLC is an American privately owned virtual private server provider company based in Galloway, New Jersey, United States.



A Virtual Private Server (VPS) is a virtual machine sold as a service by an Internet hosting service.

A VPS runs its own copy of an operating system (OS), and customers may have superuser-level access to that operating system instance, so they can install almost any software that runs on that OS. For many purposes they are functionally equivalent to a dedicated physical server, and being software-defined, are able to be much more easily created and configured. They are priced much lower than an equivalent physical server. However, as they share the underlying physical hardware with other VPSs, performance may be lower, depending on the workload of any other executing virtual machines. Dedicated Servers may also be more efficient with CPU dependent processes such as hashing algorithms.


  • Click on Add a Linode.
  • Select which configuration best suits your needs.
    • Specifically, choose the region closest to you (or the majority of your team) to reduce latency.
    • Based on how many simultaneous connections you plan on running, you may need to use a more powerful configuration.

  • You will be redirected to the main menu, and from there, your new VPS is available.

  • From the main menu, select Dashboard, and then click on the Settings tab.
  • Rename your new instance to reflect the purpose of your upcoming pfSense installation.
  • Rename the display group to Firewall, which helps as you continue adding servers over time.
  • After you click save, you will be redirected to the main menu, and from there, your VPS will have it's new label, and reside under the Firewall category.

Hard drive

  • From the main menu, select Dashboard, and then click on Create a new Disk - you will perform this twice.

Disk setup for pfSense to be installed from.
Label: Installer
Type: unformatted / raw
Size: 1024 MB
Disk setup for pfSense to be run on.
Label: pfSense
Type: unformatted / raw
Size: Remainder (Linode should fill this value by itself)

  • Upon completion, your storage quota will be fully allocated, and your unformatted disks will be listed as a part of your VPS.

Configuration profiles

Linode allows you to setup system boot parameters, as well as run-time environments for your VPS. Rather than a “One size fits all™” approach, they allow you to set these as profiles that can be toggled at anytime, with appropriate responses 3).

You'll want to setup 3 profiles:

  1. Rescue
  2. Install
  3. Run
Profile for setting up installation.
Profile for installation.
Profile for run-time.

  • Upon completion, your VPS dashboard should resemble the picture below.
  • Select Rescue and click on the Boot button.

Installation environment

  • While your VPS is booting, click on the Remote Access tab.
  • Take note of your Public and Private IP addresses, you'll need these for Setting up pfSense.
  • I prefer to connect via SSH, but for the sake of simplicity, you could probably use Launch Lish Console or Launch Graphical Web Console.

  • Go to, and update the following parameters:
    • Version: (whichever the latest version is)
    • Architecture: AMD64 (64-bit)
    • Installer: USB Memstick Installer
    • Console: Serial
    • Mirror: (whichever is closest to you)
  • As you update parameters, the Download button's URL will be updated. Right-click on Download, and copy the download URL.
  • Be sure to copy the SHA-256 Checksum as well. Subsequently, this is how you'll verify the download.
You should see a screen similar to this one.
  • After launching into your VPS' console which is running Finnix for Rescue mode, run the following commands to download the installer's disk image.
    sudo update-ca-certificates
    curl --output pfSense.img.gz https://DOWNLOADURL
  • Verify your download:
    sha256sum pfSense.img.gz | grep CHECKSUM-GOES-HERE
  • If the checksum passed (you should see the same value returned, otherwise it will be blank), now you can write the downloaded image to your VPS' Installer disk:
    pv /root/pfSense.img.gz | gunzip -c | dd of=/dev/sdb

If you're feeling lucky, you can skip the 3 aforementioned steps (download, verify, and write) and write directly to the drive from the pfSense URL:

curl https://DOWNLOADURL | gunzip -c | dd of=/dev/sdb
  • Once this process completes, go back to your dashboard, change the Configuration Profile to Install, and click on the Reboot button:



Installer booting up.

Set your terminal to vt100.
Select Install.
You'll probably want to stick with default keymap of US.
Auto / Guided Disk Setup should suffice.
The installer will fetch necessary files.
Upon completion, halt the system: shutdown -h now

  • Go back to your dashboard, change the Configuration Profile to Run, and click on the Reboot button:

pfSense booting up.


Under normal circumstances, pfSense sets its web interface (“webConfigurator”) to respond on the LAN interface with a default username and password.

Since there is only 1 interface, that means that pfSense's web interface is responding to the entire world on the WAN interface - with the default username and password!

Before proceeding, please read this section in its entirety, and to be sure that you fully understand the ramifications.

  • On pfSense's preliminary run, it will ask a series of questions for configuring the single NIC (WAN).
  • As soon as you see “Starting webConfigurator…done.” appear on the console, the web service is now responding to the entire world, with the default username and password, and you must immediately browse to https://PUBLIC-IP-ADDRESS/ and login.
    • Username: admin
    • Password: pfsense
You will receive certificate errors until you set up an HTTPS certificate.
Now to login, and change the administrative password, posthaste! 😱
syslogd provides real-time updates to the console about logins to the web interface.
  • When you login to the web interface, syslog will post information about those logins to the console. Until you change the password, maintain a vigilant eye on web connections, and be sure that it's your IP address.
  • If you see a successful login from an IP address that isn't you, you should assume that your VPS is compromised!
    • Delete the VPS from your Linode account, immediately!
    • Remake the VPS (so that you receive a new, public IP address).
  • It almost goes without saying, but this is a critical juncture of this entire article 4), and you should only perform this from a trusted, private IP (e.g. your house).
If you're doing this on a Public Wi-Fi connection at a coffee shop or a hotel, without a trusted VPN connection?

You are doing it wrong.

Setup wizard

As of version 2.4.2, the Setup Wizard miscounts the steps, and jumps from Step 4 to Step 6.

Step 1: General information.
Step 2: Upsell-upsell-upsell.
Step 3: FQDN and DNS.
Step 4: NTP and timezone.
Step 5: WAN Interface configuration (use the information from Remote Access to fill this in)
Step 6: Administrative password. This needs to be changed, ASAP, and set to something very secure! 5)
Step 7: Click to reload new configuration.
Step 8: The firewall is reloading.
Step 9: Reload confirmed.

Only when you've reached the final step of the reload being confirmed should you verify via the console that no other IP address accessed the firewall while it was set with default username and password.

I cannot stress this enough.

  • After the setup wizard completes, you will be taken to the main menu (or you can click on the logo at the top left to get there).

pfSense Main Menu.




  • Click on Firewall → Aliases → IP → Add
    • Name: admin_ipv4
    • Hosts: (For each host that you'll administer this bastion host from, add the Static IP and/or DDNS service's FQDN.)
  • Click on Firewall → Aliases → Ports → Add
    • Name: admin_tcp
    • Port(s):
      • 22 (SSH)
      • 80 (HTTP)
      • 443 (HTTPS)
      • (Whichever port that you'll change the web interface to, since we're going to use HTTPS for OpenVPN)


  • Click on Firewall → Rules → WAN → [ Add ↑ ] (to place rule at top)
    • Action: Pass
    • Interface: WAN
    • Address Family: IPv4
    • Protocol: TCP
    • Source: Single host or alias : admin_ipv4
    • Destination: Destination Port Range : (other) : admin_tcp : (other) : admin_tcp
    • Log: Log packets that are handled by this rule
    • Description: Admin : IPv4 TCP

VPS' Private IP

  • Click on Firewall → Virtual IPs → Add
    • Type: IP Alias
    • Interface: WAN
    • Address type: Single address
    • Address(es): (use the information from Remote Access to fill this in)
    • Description: Linode - LAN IPv4


  1. Click on System → Package Manager → Available Packages → ACME (Let's Encrypt) → Install
  2. Click on Services → Acme Certificates → Account keys → Add
  3. Click on Services → Acme Certificates → Certificates → Add

There are several ways to confirm ownership of the domain that your bastion host resides on. For now, the specific configuration that best suits your needs falls outside of the scope of this article. I've had great success with FreeDNS as I had mentioned in the Introduction, as well as Linode and Digital Ocean.

Admin access

Click on System → Advanced → Admin Access

  • Protocol: HTTPS
  • SSL Certificate: (select the certificate that you created in the HTTPS section.)
  • TCP Port: (use something other than 443, so that OpenVPN can respond on TCP 443).
  • WebGUI redirect: Disable webConfigurator redirect rule.
  • Anti-lockout: Disable webConfigurator anti-lockout rule.
  • (Optional) Secure Shell Server: Enable Secure Shell.
  • (Optional) Authentication Method: Disable password login for Secure Shell (RSA/DSA key only).
  • (Optional) SSH port: Leave this blank for the default of 22.
  • Console menu: Password protect the console menu.


Congratulations, you now have a solid starting point for a Bastion host, which will provide a much needed asset to your toolkit. I have a mountain of draft articles that I still need to finish for this blog, with the two most pertinent to this article being:

  1. How I use this bastion host to bridge GPU servers together for my friends and I.
  2. How I could use a setup like this to reverse-VPN into a location whose ingress ports are blocked.

That said, this command for jumping across SSH, from your new bastion host after following this article, may come of use to you:

ssh -J

See also


1) Yes, I know about DDNS.
2) Bare metal, Virtual Machines, and/or Docker containers running on our own Docker images - even NAT traversal can become difficult to manage.
3) e.g. if the system is running, the three-finger salute is sent to the VM by the KVM hypervisor, when the system reboot sequence is reached, it is then booted into the newly-selected profile.
4) There's no proper encryption or authentication in place.
5) Mixed-case alpha-numeric, symbols, and at least 40 characters long.

External links

2017/12/20/setup-bastion-host-vps-with-pfsense.txt · Last modified: 2018/12/09 15:13 by Administrator