Connecting to a Google Cloud VM Behind IAP From a Windows Machine Using a *nix/WSL Development Machine
Establishing an SSH connection transparently is useful for connecting to a Google Cloud VM using the ms-vscode-remote.remote-ssh
(Remote - SSH) extension in VSCode, for example, allowing us to avoid manual port-forwarding or setting up a dedicated tunnel.
- An SSH agent must be running on the on the client machine. On Windows, enable and start the OpenSSH Authentication Agent service.
Create a tunnel to the Google Cloud VM <instance_name>
behind Google's IAP with the SSH ProxyCommand option then establish an SSH connection through it.
-
The first SSH connection, defined in the ProxyCommand, creates the tunnel from the Windows machine to the target VM.
- ProxyCommand in the
Host *.gcloud
host specification establishes an SSH connection to<local_development_host>
. gcloud compute ssh ...
establishes an SSH connection to<remote_jump_host>
through thegcloud
SSH wrapper, tunneling through Google IAP.nc <instance_name> 22
establishes a TCP connection to the SSH port 22 on<instance_name>
within the Google Cloud network.
- ProxyCommand in the
-
The second SSH connection is the actual connection established by calling
ssh [<username>@]<instance_name>.gcloud
, accepting arguments from the SSH command and parameters in theHost *.gcloud
host specification. The tunnel from the first SSH connection transparently connects the user to the target VM, as if callingssh [<username>@]<instance_name>
from inside the Google Cloud network.
# ~\.ssh\config
# Usage: ssh [<username>@]<instance_name>.gcloud
Host *.gcloud
UserKnownHostsFile ~\.ssh\gcloud_known_hosts
ProxyCommand ssh <local_development_host> gcloud compute ssh --tunnel-through-iap <remote_jump_host> --command='nc $(echo "%n" | rev | cut -f2- -d"." | rev) 22'
UserKnownHostsFile ~\.ssh\gcloud_known_hosts
isolates the known_hosts entries for this virtual host from the default known_hosts entries, since connections have a synthetic.gcloud
appended to their host.ssh <local_development_host>
establishes an SSH connection to the development machine. It should connect successfully if run in isolation. Examples could bessh dev
, wheredev
is another host specification, orssh -i <path_to_keyfile> [<user>@]<local_development_host>
.gcloud compute ssh --tunnel-through-iap <remote_jump_host> --command='nc $(echo "%n" | rev | cut -f2- -d"." | rev) 22'
uses thegcloud
CLI to establish an SSH connection through Google's IAP, then runsnc <instance_name> 22
to create a TCP tunnel to the target VM.<remote_jump_host>
is a VM in Google Cloud that can connect to the target VM, or the target VM itself. Examples could be[<user>@]<remote_jump_host>
,%r@<remote_jump_host>
where%r
is<username>
from the SSH command arguments orUser <username>
from the host specification, or%r@$(echo "%n" | rev | cut -f2- -d"." | rev)
to infer the remote hostname from the SSH command arguments.$(echo "%n" | rev | cut -f2- -d"." | rev)
takes the remote hostname<instance_name>.gcloud
,%n
from the SSH command arguments and strips the.gcloud
suffix.
# ~\.ssh\config
# Usage: ssh [<username>@]<instance_name>.gcloud
Host *.gcloud
UserKnownHostsFile ~\.ssh\gcloud_known_hosts
ProxyCommand ssh -A <local_development_host> ssh-add $HOME/.ssh/google_compute_engine && gcloud compute ssh --tunnel-through-iap <remote_jump_host> --command='nc $(echo "%n" | rev | cut -f2- -d"." | rev) 22'
If the Google Cloud private key is stored on the development machine SSH agent forwarding can be used to add the key to the OpenSSH Windows SSH agent from the development machine. SSH agent forwarding shares the agent with the machine it connects to, so this approach saves syncing the private key with the Windows machine.
ssh -A <local_development_host>
forwards the SSH agent from the Windows machine to the development machine.ssh-add $HOME/.ssh/google_compute_engine
adds thegoogle_compute_engine
private key to the agent. Substitute this for the correct path if not using thegcloud
CLI default.