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 , 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:
In private, with an SG-2440 operating in split-tunnel capacity across IPsec
In private and/or workshops, with test machines
, connected together by leap-frogging across Tinc
In public, with our laptops operating in full-tunnel capacity across OpenVPN
pfSense can handle all of the above scenarios.
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
Optional - if you have a Dynamic IP: DDNS
entry for your administrative location(s).
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
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.
You will be redirected to the main menu, and from there, your new VPS
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
Disk setup for pfSense to be installed from.
Type: unformatted / raw
Disk setup for pfSense to be run on.
Type: unformatted / raw
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
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 .
You'll want to setup 3 profiles:
Profile for setting up installation. Profile for installation.
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.
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
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:
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
As soon as you see “Starting webConfigurator…done.” appear on the console, <color #ff0000>the web service is now responding to the entire world, with the default username and password</color>, and you must immediately browse to https://PUBLIC-IP-ADDRESS/ and login.
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
Delete the VPS
from your Linode account, immediately!
It almost goes without saying, but this is a critical juncture of this entire article , 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
Click on Firewall → Rules → WAN
→ [ Add ↑ ] (to place rule at top)
Address Family: IPv4
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 System → Package Manager → Available Packages → ACME (Let's Encrypt) → Install
Click on Services → Acme Certificates → Account keys → Add
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.
Click on System → Advanced → Admin Access
(select the certificate that you created in the HTTPS
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.
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:
How I use this bastion host to bridge GPU servers together for my friends and I.
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 firstname.lastname@example.org email@example.com
Yes, I know about DDNS.
Bare metal, Virtual Machines, and/or Docker containers running on our own Docker images - even NAT traversal can become difficult to manage.
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.
There's no proper encryption or authentication in place.
Mixed-case alpha-numeric, symbols, and at least 40 characters long.