Drop the bastion in the clouds (AWS, Azure (kinda), and GCP)

I thought I’d put a post together after being inspired by this Cloud Village talk. I recommend giving it a watch. I’m just adding some additional info.

So for many years and still now, a lot of companies still use initialize a bastion. Bastions are servers with the primary purpose of providing access to the internal network from an external network, like the internet. These hosts typically have nothing on them and are hardened as best as they can. So what has changed since the magical clouds have evolved? Do you still need one to reach private virtual machines?

Amazon Web Services (AWS)

For AWS, they offer a service called Systems Manager. This management service helps you automatically collect software inventory, apply patches, create system images, and configure Windows and Linux operating systems. This service called also be used to SSH into your hosts. With the Systems Manager agent installed on the host, you can ssh into a host just using the CLI without the need to maintain a security group.

sorry for the bad graphic :(

As for prerequisites, your local Machine will need aws-cli and the session-manager plugin, aside from obvious access via IAM:

# session manager plugin install
curl "https://s3.amazonaws.com/session-manager-downloads/plugin/latest/mac/sessionmanager-bundle.zip" -o "sessionmanager-bundle.zip"
unzip sessionmanager-bundle.zip
sudo ./sessionmanager-bundle/install -i /usr/local/sessionmanagerplugin -b /usr/local/bin/session-manager-plugin

For your host, you’ll need to install the Systems Manager agent which is installed by default on certain AMIs. You’ll also need to attach an instance role (AmazonSSMRoleForInstancesQuickSetup). Depending on your architecture, you may need to modify some security groups but here, I am using the default VPC, which is open. I removed the security group rules created by default for the instance in scope and ran the following command from my local terminal:

aws ssm start-session — target <instance_id>
Starting session with SessionId: <instance_id>
sh-4.2$ echo "success!"

Azure (AZ)

For Azure, you’ll be looking at Azure Bastion. You’ll deploy an Azure Bastion into a special subnet….

Well, not in Azure. In Azure, you’ll need to create a bastion in every virtual network you’ll want to connect. You’ll also need to create a special subnet called AzureBastionSubnet. If you are having issues deploying, make sure you have the address space set up for this subnet in the virtual network configuration. It’ll also need a prefix of at least /27. While this may not be the cheapest (turn off when not using?), Microsoft has made it super easy to deploy. So not dropping the bastion necessary but all the hard work to config/maintain one?

Totally didn’t steal this from their docs…

Once its deployed, you click on the private virtual machine you want to connect via the portal, Connect, and select Bastion. Enter your credentials and connect. No agents to install, each bastion supports 25 concurrent RDP/50 SSH connections, and you never have to manage a network security group (NSGs).

Google Cloud Platform (GCP)

Google Cloud takes a different route when it comes to a “bastionless” setup. No agents or bastions to configure. First, you’ll need to enable Cloud Identity-Aware Proxy (IAP). This service works at the project level, so you’ll need to enable it per project.

Cloud IAP is an access management service that handles authentication and authorization into VMs, App Engine, Google Kubernetes Engine, and even on-prem apps. Cloud IAP requires an identity which could be a service account or a user and ensures the request will be logged. Once you have authenticated, it’ll check to see what you’re authorized to do based on the IAM policy. In order to connect to a host, the traffic needs to be forwarded which requires an IAP role.

Didn’t steal this from their docs either…

As for prerequisites, your local Machine will just need the google-cloud SDK. For the host itself, there is no additional configuration. You’ll need to do a few other things however:

  • Enable the service under Security > Identity-Aware Proxy
  • This will load an OAuth consent screen for users which you need fill out (just needs an App name, then save). You can set OAuth grant token limits, API Scopes, authorized domains, and even a logo here. Up until recently, this process was completely manual. GCP now offers a way to programming complete this step.
  • Depending on your setup, you need to an ingress firewall rule for 35.235.240.0/20 on ssh (22) and/or rdp (3389) which used by IAP for TCP Forwarding. You can use network tags here or all instances in the VPC for VMs in scope.
  • Ensure your user has the role IAP-secured Tunnel User and can at least see the compute resources (computer viewer)
  • You’ll need to add the flag tunnel-through-iap when you use gcloud to SSH into the host.
gcloud compute ssh <instance_id> --zone <instance_zone> --tunnel-through-iap

Super easy! Hope this quick summary help someone out there. If you’d like to learn more, here are the links from the providers:

Cheers!