Creating a Bastion for SSH access on GCP
in Google Cloud (GCP) with discrimiNAT
On some occasions you may want a bastion host present in your VPC. For example:
- accessing a discrimiNAT instance over SSH
- accessing a host without a public IP
psst… should you ever need a great alternative to a swarm of squid proxies for outbound filtering, consider discrimiNAT for a cloud-native solution
Table of Contents
Creating a Bastion Host
Let’s create a new instance pretty much as usual, taking care that:
- it’s in the right region
- it doesn’t need too much grunt as it will only pass minimal traffic through
We will need to add a small detail in the networking section, though. See the next image.
Add the network tag
bypass-discriminat to this instance. The presence of this network tag enables the traffic to and from this instance to have higher precedence than the control laid out by the discrimiNAT firewall, therefore bypassing it. This will allow you to directly connect to this instance, from your public IP to its public IP.
Your bastion host on GCP is now ready!
Accessing a discrimiNAT instance through the Bastion
The discrimiNAT image is hardened per CIS Benchmark for Ubuntu Linux 18.04 LTS Benchmark v1.0.0 Level 2 Server. Therefore, SSH access to it requires your posture to be sound and secure. Let’s check with a few commands on your machine:
The SSH Agent should have only one identity loaded. This is to prevent it from trying one identity after another to the server, causing the server to block the user after too many failures. So it’s safer to just have the one identity that will work.
If the output shows more than one line, you may clear all of them out with the command
ssh-add -D. If the previous command still shows some lines, check the
.sshdirectory in your home directory for unexpected private key files.
To add a specific private key to the SSH Agent, run the command:
And then check with
ssh-add -Lwhether only one line in the output is present.
Check the Compute Metadata -> SSH Keys in Google Cloud (GCP) console for the username of the key loaded above.
Finally, SSH into the discrimiNAT instance using the bastion host as ProxyJump. This is needed because discrimiNAT will only allow SSH connections from private IPs (i.e. within the VPC), so you cannot connect to it from a public IP.
You will need the public IP address of the bastion, the private IP address of the target discrimiNAT instance, and this command:
ssh -J <username>@<public IP of bastion> <username>@<private IP of discriminat instance>
An example of a fully formed command from the example deployment in the screenshots is:
If you manage to lock yourselves out of a discrimiNAT instance due to repeated authentication failures, either terminate the instance and let the managed instance group bring back a new one, or wait 15 minutes.
Accessing a host without a public IP through the Bastion
This could be much simpler if your target instances are not fussy about where you connect from and how many keys you present. However, since the targets do not have a public IP address at all in this case, you still need to use a bastion host, so there is connectivity to and from them. The commands are the same as above:
Verify the right keys are loaded in your SSH Agent:
Connect using the bastion host as ProxyJump:
ssh -J <username>@<public IP of bastion> <username>@<private IP of target instance>