mdaverde.com

Edited on March, 18 2018

Proxying to GCP VPC with SOCKSv5

Securely access your VMs (and k8 services) remotely

Intro

“So I deployed to GCP. How do I reach my site?”

When you’re building a web product, eventually you usually want to be able to access your hosted applications through your browser. By default, networks on GCP are private so you’ll need to do some extra setup to reach anything inside.

A not secure but easy way to do this is to configure your VPC to accept public traffic (essentially negating the private part). If you don’t want to use the ephemeral IP addresses, you can even set your instances to use static IPs. This is not sustainable. Eventually, you’ll want to able to securely access your applications without allowing the entire internets in. This is where a proxy comes in.

Setting up a SOCKS server allows you to reach your applications you have hosted on GCP through a proxy. This tutorial will help you set up a SOCKS server that you can configure your clients to use.

Disclaimer: If you have a Mac or Linux, then your ssh cli will already have the ability to set up a SOCKS connection, but if you have Windows you’ll have to use a client like PuTTY.

Configuration awaits

You’ll have to configure each client (i.e. browser, cURL, API debuggers etc.) and there’s a cost in the amount of time you spend setting this up every time, for every client you want access for, and for every network you have.

For example, I use Firefox as my main web browser but also test my web apps in Chrome (that’s all you need to do, right? jk, you 3 Opera users). That meant setting up to use this proxy in both of those browsers. I also use cURL and Insomnia to debug API calls. Both of those clients need to be configured as well. This was just for one network. If you have multiple, you’ll be doing this every time you want to switch.

Note: you can set SOCKS as a system-wide proxy on Mac and some clients are smart enough to pick this up, but in my experience it still is a trial and error to figure out which ones automatically respect the proxy and which ones still require configuration. It might be possible to force the proxy through iptables, but I haven’t tried this.

Use a VPN instead

SOCKS is NOT ideal for a company with several engineers. Most companies set up a VPN tunnel where each device (i.e. employee laptop) has a VPN client installed and configured to be able to talk to the company’s private network(s). Not the long term solution, but in the case you want a quick (but secure) personal setup, you can still use an SSH proxy to route your traffic.

Proxying through a SOCKSv5 tunnel

1. Pick your host

You might already have an instance you want to use, but I usually set up my GCP networks with one bastion host that I can personally access and only through this host can traffic access other parts of the network.

pick-host

Note: to do a bastion host properly, you’ll want to make sure your firewall rules are set up correctly to limit the amount of entry ways.

2. OS Login

To be able to connect to your host, you’ll have to make sure it recognizes your SSH key. There are several ways of letting GCP use your public SSH key. You can allow it on a per-instance, per-account, per-project or even per-organization basis. In the following command, I’m using gcloud’s os-login command to add my public SSH key and allowing it to be used on a per-account basis. If you want to use it just on the single bastion host, you can add it as metadata on the instance.

Notice that you can set an expiry time on it for additional security:

$ gcloud compute os-login ssh-keys add \
    --key-file [KEY_FILE_PATH] \
    --ttl [EXPIRE_TIME]

If you’ve added your public SSH key using the above command, we need to tell your instance about it. To do this, you’ll have to enable the OS Login feature by setting the enable-oslogin metadata value to TRUE. There are several ways of doing this, I just use the GCP console:

gcp-os-login

We’ll want to make note of the username and IP address you’ll be using to access your host later. The following command can be used to get your username:

$ gcloud compute os-login describe-profile

You’re be able to get the external public IP address with gcloud compute instances list or just by looking it up in the console.

3. SOCKS server

Once you’ve registered your SSH key with your gcloud account, you’re now be able to run a local SOCKS server with the following command:

$ ssh -D [PORT] -qCN [USERNAME]@[EXTER.NAL.IP.ADDRESS]

You can specify the port you want your server running on with the -D flag. The other commands are optional: the -q flag runs the server in quiet mode, the -C flag compresses the data before sending it, and the -N flag tells SSH that we won’t be executing a remote commands. If you want this to run as a background process, you can add the -f flag.

4. Browser settings

Time to configure your clients. To configure Firefox, you’ll want to go to: Preferences > Network Proxy: Settings and you’ll see the inputs for setting up a SOCKS proxy:

firefox-proxy-settings

Your host will be localhost and your port will be what you specified earlier.

5. Proxy complete

You’re now be able to visit your private IP addresses through your browser. If you’ve configured everything properly, but behavior is weird you’ll want to check your firewall rules.

Bonus: you can also see your k8 services. My services are usually set up with type: LoadBalancer and the load balancer is an internal one that allocates a private IP address (“external” to k8s though). This will also work with type: NodePort services.

Extra credit: DNS

If you plan on using a SOCKS server for a while, it’s worth it to set up DNS so you don’t have to memorize all of your IP addresses. You’ll want to SSH into your server (gcloud compute ssh [HOST_NAME]) and edit your /etc/hosts file: sudo vim /etc/hosts. Just append your DNS entry at the end of that file:

127.0.0.1 localhost
...other entries...

10.142.0.8 newapp.co.internal # your entry

Note: be careful about which TLDs you use

Some clients require additional configuration for this to work. In Firefox, there’s a checkbox if you want to proxy DNS.

You can now use that domain on your browser/client.

Conclusion

When I was initially getting started, a SOCKS proxy was the technique I used to be able to play with apps in my GCP cloud.

Eventually, you’ll want to move over to using a VPN tunnel. This is actually the only solution if you increase the head count over 2. I haven’t been able to find a written out solution on how this is done start to finish on GCP, so that might be an upcoming post.