<commit_before># Securely connecting to Google Compute Engine

When running a web service on a publicly-accessible machine such as a Google
Compute Engine VM with an external IP, it's important to not send or receive sensitive
information from the server in plain text, such as via plain HTTP.

Sensitive information could include information such as login credentials,
commands to create or destroy resources or files, or even logs or output of
processes running on the VM.

In other words, the entire communication between your host and the deployed VM
should be over a secure, encrypted connection.

There are several options to enable secure communication between your desktop or
laptop and a VM running on Google Compute Engine:

* [Port forwarding over SSH](#port-forwarding-over-ssh)
* [SOCKS proxy over SSH](#socks-proxy-over-ssh)
* [HTTPS and SSL](#https-and-ssl)
* [VPN](#vpn)

HTTPS/SSL and VPN are both advanced topics; users are encouraged to first
explore port forwarding or SOCKS proxy approaches first as they are easier and
require little to no setup or configuration.

## Port forwarding over SSH

To forward a single port from your desktop to a VM on Google Compute Engine, you
can use the `gcloud` command to start a server on a given local port which will
forward all traffic to a remote host over an SSH connection.

To use this, first ensure that you know what VM instance and port are providing
the service you would like to connect to securely. Then, run the command:

```bash
gcloud compute ssh ${VM} \
    --project ${PROJECT} \
    --zone ${ZONE} \
    --ssh-flag="-L ${LOCAL_PORT}:localhost:${REMOTE_PORT}"
```

where:

* `${VM}` is the name of the instance you would like to connect to
* `${PROJECT}` is your Google Cloud Platform project
* `${ZONE}` is the zone your VM is running in
* `${LOCAL_PORT}` is the port you would like to listen on locally
* `${REMOTE_PORT}` is the port on the server you would like to connect to

For example, let's assume that `${LOCAL_PORT}` is 2222 and `${REMOTE_PORT}` is
8888. That means that if you open http://localhost:2222/ in your browser, the
HTTP connection will go over the SSH tunnel you have just created over to your
remote host and connect to the host identified as `${VM}` via SSH and then
connect to port 8888 on the same machine, but over an encrypted, secure SSH
connection.

The `gcloud` command will create and maintain an SSH connection, and this
approach will only work while it is active. As soon as you exit the SSH session
that `gcloud` creates, http://localhost:2222/ will stop working.

If you want to create more than one port forwarding rule, you can either specify
them on a single command line by repeating the flags, e.g.,

```bash
gcloud compute ssh ${VM} \
    --project ${PROJECT} \
    --zone ${ZONE} \
    --ssh-flag="-L ${LOCAL_PORT_1}:localhost:${REMOTE_PORT_1}" \
    --ssh-flag="-L ${LOCAL_PORT_2}:localhost:${REMOTE_PORT_2}"
```

or run a new `gcloud` command each time to create a separate tunnel. Note that
you can't add or remove port forwarding from an existing connection without
exiting and re-establishing the connection from scratch.

## SOCKS proxy over SSH

To connect to a number of different hosts in your cloud deployment, the easiest
way is to change your browser to do the lookups directly from your network in
the cloud. This lets you use the short name of the hosts instead of looking up
each host's IP address, opening up ports for each service, or creating an SSH
tunnel for each (host, port) pair.

### Overview

The approach we use here is as follows:

1. set up a single SSH tunnel to one of the hosts on the network, and create a
   SOCKS proxy on that host

1. change the browser configuration to do all the lookups via that SOCKS proxy
   host

Note that since you're tunneling *all* traffic via that host, you don't want to
browse the web in general using that browser or that specific profile, as you
will be using your cloud host's bandwidth for this.

In general, you might want to use a separate browser profile and switch to it
when necessary.

### Start the SOCKS proxy

```bash
gcloud compute ssh ${VM} \
    --project ${PROJECT} \
    --zone ${ZONE} \
    --ssh-flag="-D ${PORT}" \
    --ssh-flag="-N"
```

where:

* `${PROJECT}` is your Google Cloud Platform project
* `${ZONE}` is the zone your VM is running in
* `${PORT}` is the port you would like to listen on locally on `localhost`
* `${VM}` is the name of the instance you would like to connect to

Note that in this case, you don't need to specify a remote port, because a SOCKS
proxy does not bind to any specific remote port: any connectino you will make
via the SOCKS proxy will be resolved relative to the host you connect to.

This means that you will be able to connect to any other VM on the sae network
as the `${VM}` you connected to just by using its short name, and you will be
able to connect to any port on those VMs.

This approach is much more flexible than the simple port-forwarding method, but
will also require you to change the settings in your web browser to utilize the
proxy.

Next, configure your browser to use the proxy.

### Chrome setup for SOCKS proxy

Chrome uses system-wide proxy settings by default, so we need to specify a
different proxy using command-line flags. Launching Chrome by default creates an
instance of an already-running profile, so to enable us to run multiple copies
of Chrome simultaneously, one which is using the proxy and others which are not,
we need a new profile.

First, create a directory to hold the profile, e.g.:<commit_msg>Fixed typos.<commit_after># Securely connecting to Google Compute Engine

When running a web service on a publicly-accessible machine such as a Google
Compute Engine VM with an external IP, it's important to not send or receive sensitive
information from the server in plain text, such as via plain HTTP.

Sensitive information could include information such as login credentials,
commands to create or destroy resources or files, or even logs or output of
processes running on the VM.

In other words, the entire communication between your host and the deployed VM
should be over a secure, encrypted connection.

There are several options to enable secure communication between your desktop or
laptop and a VM running on Google Compute Engine:

* [Port forwarding over SSH](#port-forwarding-over-ssh)
* [SOCKS proxy over SSH](#socks-proxy-over-ssh)
* [HTTPS and SSL](#https-and-ssl)
* [VPN](#vpn)

HTTPS/SSL and VPN are both advanced topics; users are encouraged to explore port
forwarding or SOCKS proxy approaches first as they are easier and require little
to no setup or configuration.

## Port forwarding over SSH

To forward a single port from your desktop to a VM on Google Compute Engine, you
can use the `gcloud` command to start a server on a given local port which will
forward all traffic to a remote host over an SSH connection.

To use this, first ensure that you know what VM instance and port are providing
the service you would like to connect to securely. Then, run the command:

```bash
gcloud compute ssh ${VM} \
    --project ${PROJECT} \
    --zone ${ZONE} \
    --ssh-flag="-L ${LOCAL_PORT}:localhost:${REMOTE_PORT}"
```

where:

* `${VM}` is the name of the instance you would like to connect to
* `${PROJECT}` is your Google Cloud Platform project
* `${ZONE}` is the zone your VM is running in
* `${LOCAL_PORT}` is the port you would like to listen on locally
* `${REMOTE_PORT}` is the port on the server you would like to connect to

For example, let's assume that `${LOCAL_PORT}` is 2222 and `${REMOTE_PORT}` is
8888. That means that if you open http://localhost:2222/ in your browser, the
HTTP connection will go over the SSH tunnel you have just created over to your
remote host and connect to the host identified as `${VM}` via SSH and then
connect to port 8888 on the same machine, but over an encrypted, secure SSH
connection.

The `gcloud` command will create and maintain an SSH connection, and this
approach will only work while it is active. As soon as you exit the SSH session
that `gcloud` creates, http://localhost:2222/ will stop working.

If you want to create more than one port forwarding rule, you can either specify
them on a single command line by repeating the flags, e.g.,

```bash
gcloud compute ssh ${VM} \
    --project ${PROJECT} \
    --zone ${ZONE} \
    --ssh-flag="-L ${LOCAL_PORT_1}:localhost:${REMOTE_PORT_1}" \
    --ssh-flag="-L ${LOCAL_PORT_2}:localhost:${REMOTE_PORT_2}"
```

or run a new `gcloud` command each time to create a separate tunnel. Note that
you can't add or remove port forwarding from an existing connection without
exiting and re-establishing the connection from scratch.

## SOCKS proxy over SSH

To connect to a number of different hosts in your cloud deployment, the easiest
way is to change your browser to do the lookups directly from your network in
the cloud. This lets you use the short name of the hosts instead of looking up
each host's IP address, opening up ports for each service, or creating an SSH
tunnel for each (host, port) pair.

### Overview

The approach we use here is as follows:

1. set up a single SSH tunnel to one of the hosts on the network, and create a
   SOCKS proxy on that host

1. change the browser configuration to do all the lookups via that SOCKS proxy
   host

Note that since you're tunneling *all* traffic via that host, you don't want to
browse the web in general using that browser or that specific profile, as you
will be using your cloud host's bandwidth for this.

In general, you might want to use a separate browser profile and switch to it
when necessary.

### Start the SOCKS proxy

```bash
gcloud compute ssh ${VM} \
    --project ${PROJECT} \
    --zone ${ZONE} \
    --ssh-flag="-D ${PORT}" \
    --ssh-flag="-N"
```

where:

* `${PROJECT}` is your Google Cloud Platform project
* `${ZONE}` is the zone your VM is running in
* `${PORT}` is the port you would like to listen on locally on `localhost`
* `${VM}` is the name of the instance you would like to connect to

Note that in this case, you don't need to specify a remote port, because a SOCKS
proxy does not bind to any specific remote port: any connection you make via the
SOCKS proxy will be resolved relative to the host you connect to.

This means that you will be able to connect to any other VM on the same network
as the `${VM}` you connected to just by using its short name, and you will be
able to connect to any port on those VMs.

This approach is much more flexible than the simple port-forwarding method, but
will also require you to change the settings in your web browser to utilize the
proxy.

Next, configure your browser to use the proxy.

### Chrome setup for SOCKS proxy

Chrome uses system-wide proxy settings by default, so we need to specify a
different proxy using command-line flags. Launching Chrome by default creates an
instance of an already-running profile, so to enable us to run multiple copies
of Chrome simultaneously, one which is using the proxy and others which are not,
we need a new profile.

First, create a directory to hold the profile, e.g.:
{'fraction_non_alphanumeric': 0.06553115194979829, 'fraction_numerical': 0.004661586732406992, 'mean_word_length': 4.045680687471732, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1973909', 'n_tokens_mistral': 3052, 'n_tokens_neox': 2919, 'n_words': 1790}