Replace your EC2 Bastion with an AWS NLB

For many years we’ve seen people building servers for the single purpose of allowing hopping between networks, or allowing third parties into your network. Not only do you have to maintain these instances but they also add an exposure point to potential attackers.

Using AWS NLB (Network Load Balancers) this is significantly improved. NLB’s cost roughly the same as a t2.micro, but you save the headache of having another instance to manage (and we should all be moving to serverless as much as we can right?).

Configuring an NLB as a Bastion is quite straightforward, however there is a trick to this which isn’t commonly known and I’ll note this below. So, here’s the steps to doing this. This article will presume you are configuring the Bastion for SSH but we’ve tested this with RDP and MongoDB (where the target had to have multiple TCP ports open)

Create Target Group

  1. In AWS, navigate to EC2 and under Target Groups click Create target Group
  2. Select IP addresses (this is the trick, you can’t use Instances) and then enter the name, change the Protocol to TCP and enter the port that you want to proxy (if you’ll need 1 Target Group per port). Configure the rest of the details (ensure that Health Check matches the TCP port)
  3. Click Next and enter the IP address of the target and click Include as pending below (note, adding more than 1 IP here will mean your connection could be sent to any of the targets, though for some purposes this is absoltely fine) and click Create target group
  4. Create your Load Balancer by going to Load Balancers and clicking Create Load Balancer, click Create under Network Load Balancer.
  5. Enter the usual details, ensuring the Listeners is configured with the same port as entered in step #2 and select Configure Security Settings.
  6. Select the subnets you wish to use (i.e. public facing ones for internet-available NLB or private ones for an internal NLB) click through to Routing
  7. Under Target Group select the Target Group you created earlier (the ports and health checks should copy from the TG) and click through to the Review screen, confirm everything looks good and click Create

And that’s it, give it time for the Health Checks to go through and then test.

If you want to have multiple instances behind 1 NLB, configure a Target Group per EC2 instance and use a separate Listener port for each Target Group (i.e. you could use 2200x range for SSH and 3300x range for RDP).


We’ve tested this quite a bit and it’s worked well for us, hopefully it helps you remove an EC2 instance or 2 from your environment and let you get on with more interesting things than instance management. It’s worth noting that the IP addresses associated with an NLB are static, according to AWS, which is really useful for things like Mongo where you need to add a hosts entry. I’d recommend playing around with this before moving all your devs over to them so that you get a good understanding.

Enthusiastic Automation Engineer, spending far too much time with AWS, Python, Terraform - basically anything that's interesting in the moment.