Skip to main content
  1. Posts/

SSH configurations for going into Google Cloud Instances

··386 words·2 mins
Author
Hairizuan Noorazman
Software engineering experiments, implementation notes, and lessons learned.

A classic move to reduce the attack surface of Google Cloud Instances is follow the advice below:

  • If service on instance don’t need Public IPs, don’t attach Public IPs to such instances
  • If instance requires Public IPs, ensure that only specific ports that are required are exposed. Clamp down on the rest of the ports and ensure no ingress on them

With these basic principles, it would be simple to think how these would eventually lead to an architecture where users access the instances via a bastion host. A bastion host is a instance that would allow user to ssh in from the “outside” world. The more critical instances would linked together in a private network that is unaccessible from the outside (except for load balancers to receive traffic etc).

Here are some of the better explained articles on the topic:

https://cloud.google.com/solutions/connecting-securely#bastion https://en.wikipedia.org/wiki/Bastion_host

However, if we setup the architecture this way, how can we ssh into private instances from the outside world? It would be unwise to first ssh into the bastion host and then have our private keys there so that we can ssh further. Doing that wouldn’t make sense; it wouldn’t increase security but instead, just made it worst.

So, one of the better ways to do this is to actually use a configuration called ProxyCommand that is part of the ssh utility.

Let’s take an example. Let’s say we have 2 instances:

  • Instance 1:
    • Public IP: 70.70.70.70
    • Private IP: 10.0.0.1
  • Instance 2:
    • Private IP: 10.0.0.2

In order to ssh in Instance 2 from the outside world (e.g. my own local computer), I can run the command as follows:

ssh -o ProxyCommand="ssh -W %h:%p 70.70.70.70" 10.0.0.2

With the command, we are ssh-ing into the Instance 2 by jumping through Instance 1. (So if Instance 1 goes down, our ssh session would end as well)

But rather than typing the above command over and over again, we might as well set the folllowing in the ssh configuration file (~/.ssh/config)

Host Bastion
    HostName 70.70.70.70
    Port 22
    User AdminUser
    IdentityFile ~/.ssh/id_rsa

Host AppServer
    HostName 10.0.0.2
    Port 22
    User AdminUser
    IdentityFile ~/.ssh/id_rsa
    ProxyCommand ssh -W %h:%p Bastion

So, if you type:

ssh AppServer

It would be get you into the server without too much effort from your end to remember what params to add to the ssh command

Related

Cookiecutter template for Google Cloud Run

··429 words·3 mins
While working on a couple of projects that would be deployed on Google Cloud Run, I realized that a couple of them tend to have some sort of similar structure. Due to the number of repositories I would typically handle on a personal basis as well as the amount of context switch I would need to move between projects; it would ideal that all of such projects are automated as much as possible.

Introduction to Google Cloud Run

··731 words·4 mins
There are various serverless compute solutions on the Google Cloud Platfrom; initially it used to be only Appengine and Google Cloud Function. Google Appengine is a solution that allow you to focus on writing up apps and allow Google to take of deployment/scaling/operations. Google Cloud Functions take a step further and allow you as a developer to develop just plain old functions and allow Google to handle the rest of it, thereby making it easier to split your app functionality to parts that require to scale and parts that don’t need to.

Private Go Modules in Google Cloud Build

··1037 words·5 mins
So recently, I’ve been needing to automate my builds for my few Golang projects via Google Cloud Build. However, rather than building docker containers, I needed Golang binaries instead, which kind of meant that I would need to have the CI/CD pipeline have a Go environment/runtime to build them. However, when it comes to these CI/CD solutions, including private Golang packages/modules in siad projects is usually quite troublesome. Private Golang packages usually take the code from private Github/Bitbucket/Gitlab repos and getting the go get command to fetch them successful require a bit of hacks here and there to make it work successfully.