|
| 1 | +# How to run Envbuilder from behind a proxy |
| 2 | + |
| 3 | +Envbuilder can be used from behind transparent TLS proxies that would normally risk interrupting TLS verification. |
| 4 | + |
| 5 | +A summary of how to configure Envbuilder to run behind an HTTPS proxy is provided in the next session. Thereafter an illustrative example is provided that can be followed to prove the concept from first principles before applying it in production. |
| 6 | + |
| 7 | +## Summary |
| 8 | +TODO (sas): set various envs and boom! |
| 9 | + |
| 10 | +## Example |
| 11 | +Envbuilder clones a repository that contains your devcontainer.json and optional Dockerfile so that it can build your container. If the clone is done using HTTPS, then TLS verification will have to succeed, or be disabled. If a transparent HTTPS proxy is present, TLS verification will fail unless Envbuilder trusts the certificate used by the transparent proxy. Therefore, we need to tell Envbuilder how to trust your transparent proxy. |
| 12 | + |
| 13 | +The summary in the previous section shows how to configure Envbuilder using Terraform for Docker and Kubernetes. For this example we'll use docker directly to avoid complexity that might result in confusion. Docker is also more likely than Terraform to already be installed in your testing environment. |
| 14 | + |
| 15 | +Before we introduce an HTTPS proxy, let's prove that envbuilder runs normally. Run the following docker command to obtain a shell within an Envbuilder built environment: |
| 16 | +```bash |
| 17 | +docker run -it --rm \ |
| 18 | + -e ENVBUILDER_INIT_SCRIPT='/bin/sh' \ |
| 19 | + -e ENVBUILDER_GIT_URL='https://github.com/coder/envbuilder.git' \ |
| 20 | + ghcr.io/coder/envbuilder:latest |
| 21 | +``` |
| 22 | + |
| 23 | +Notice the log lines: |
| 24 | +``` |
| 25 | +#1: 📦 Cloning https://github.com/coder/envbuilder.git to /workspaces/envbuilder...` |
| 26 | +... |
| 27 | +#1: 📦 Cloned repository! [711.221369ms] |
| 28 | +``` |
| 29 | + |
| 30 | +After some time building, a shell will be presented inside the devcontainer environment specified in envbuilder's own repository. Assuming that envbuilder built and ran successfully, go ahead and exit the container: |
| 31 | +```bash |
| 32 | +exit |
| 33 | +``` |
| 34 | + |
| 35 | +Let's now break Envbuilder by introducing a transparent TLS intercepting proxy. To do this, we'll use [mitmproxy](https://mitmproxy.org/). Start mitmproxy in a container, by running the following: |
| 36 | +``` |
| 37 | +docker run --rm -d --name mitmproxy -v ./certs:/home/mitmproxy/.mitmproxy -p 8080:8080 -p 127.0.0.1:8081:8081 mitmproxy/mitmproxy mitmweb --web-host 0.0.0.0 |
| 38 | +``` |
| 39 | + |
| 40 | +Confirm that mitmproxy is running: |
| 41 | +```bash |
| 42 | +docker ps |
| 43 | +``` |
| 44 | +yields: |
| 45 | +``` |
| 46 | +CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES |
| 47 | +46f655140824 mitmproxy/mitmproxy "docker-entrypoint.s…" About an hour ago Up About an hour 0.0.0.0:8080->8080/tcp, 127.0.0.1:8081->8081/tcp mitmproxy |
| 48 | +``` |
| 49 | + |
| 50 | +A new directory called certs should also be present in your current working directory. It will contain a CA certificate called `mitmproxy-ca-cert.pem`. This will be what we provide to Envbuilder to help it trust our proxy. |
| 51 | + |
| 52 | +Optionally, inspect the certificates served by mitmproxy: |
| 53 | +``` |
| 54 | +openssl s_client -proxy localhost:8080 -servername github.com -connect github.com:443 | head -n 10 |
| 55 | +``` |
| 56 | +In the output, notice that we are served a certificate that is ostensibly for github.com. However, its issuer common name is mitmproxy and s_client couldn't verify the certificate: |
| 57 | +``` |
| 58 | +depth=0 CN = github.com |
| 59 | +verify error:num=20:unable to get local issuer certificate |
| 60 | +verify return:1 |
| 61 | +depth=0 CN = github.com |
| 62 | +verify error:num=21:unable to verify the first certificate |
| 63 | +verify return:1 |
| 64 | +depth=0 CN = github.com |
| 65 | +verify return:1 |
| 66 | +CONNECTED(00000003) |
| 67 | +--- |
| 68 | +Certificate chain |
| 69 | + 0 s:CN = github.com |
| 70 | + i:CN = mitmproxy, O = mitmproxy |
| 71 | + a:PKEY: rsaEncryption, 2048 (bit); sigalg: RSA-SHA256 |
| 72 | + v:NotBefore: Nov 7 15:43:48 2024 GMT; NotAfter: Nov 9 15:43:48 2025 GMT |
| 73 | +--- |
| 74 | +Server certificate |
| 75 | +-----BEGIN CERTIFICATE----- |
| 76 | +``` |
| 77 | + |
| 78 | +Let's rerun Envbuilder using the proxy to see how it responds. To do this, we use the same command as before, except that we also set the `https_proxy` environment variable: |
| 79 | +```bash |
| 80 | +docker run -it --rm \ |
| 81 | + -e https_proxy=https://172.17.0.2:8080 \ |
| 82 | + -e ENVBUILDER_INIT_SCRIPT='/bin/sh' \ |
| 83 | + -e ENVBUILDER_GIT_URL='https://github.com/coder/envbuilder.git' \ |
| 84 | + ghcr.io/coder/envbuilder:latest |
| 85 | +``` |
| 86 | +From the logs, notice that certificate verification fails: |
| 87 | +``` |
| 88 | +Failed to clone repository: clone "https://github.com/coder/envbuilder.git": Get "https://github.com/coder/envbuilder.git/info/refs?service=git-upload-pack": proxyconnect tcp: tls: failed to verify certificate: x509: certificate signed by unknown authority |
| 89 | +``` |
| 90 | + |
| 91 | +To fix this, we need to provide a ca certificate that Envbuilder can use to verify the certificate that mitmproxy serves instead of github's actual certificate. Envbuilder provides a few environment variables to accomplish this. They are all documented in the summary section above. For this example, we have the ca certificate saved in a directory. The easiest way to provide it is therefore to mount it as a volume in the envbuilder container and tell envbuilder to use it. For this, we can use the `SSL_CERT_FILE` environment variable. The command to run Envbuilder is now: |
| 92 | +```bash |
| 93 | +docker run -it --rm \ |
| 94 | + -v $PWD/certs:/certs \ |
| 95 | + -e SSL_CERT_FILE=/certs/mitmproxy-ca-cert.pem \ |
| 96 | + -e https_proxy=https://172.17.0.2:8080 \ |
| 97 | + -e ENVBUILDER_INIT_SCRIPT='/bin/sh' \ |
| 98 | + -e ENVBUILDER_SETUP_SCRIPT='printenv' \ |
| 99 | + -e ENVBUILDER_GIT_URL='https://github.com/coder/envbuilder.git' \ |
| 100 | + ghcr.io/coder/envbuilder:latest |
| 101 | +``` |
0 commit comments