|
| 1 | +# mTLS Go Sample |
| 2 | + |
| 3 | +This sample demonstrates mutual TLS between a Go HTTPS server and a Go client. The server only accepts requests from clients that present a certificate signed by the shared demo CA, and the client verifies the server certificate before sending the request. |
| 4 | + |
| 5 | +## Run with Docker Compose |
| 6 | + |
| 7 | +```bash |
| 8 | +docker compose up --build |
| 9 | +``` |
| 10 | + |
| 11 | +What happens: |
| 12 | + |
| 13 | +1. `cert-generator` creates a demo CA plus server and client certificates in a shared Docker volume. |
| 14 | +2. `mtls-server` starts on `https://localhost:8443` and requires a valid client certificate. |
| 15 | +3. `mtls-client` starts an API on `http://localhost:8080`. |
| 16 | +4. Hitting `GET /hello` on the client API makes an mTLS request to `mtls-server` and returns the upstream response. |
| 17 | + |
| 18 | +Try it: |
| 19 | + |
| 20 | +```bash |
| 21 | +curl http://localhost:8080/hello |
| 22 | +``` |
| 23 | + |
| 24 | +## Run locally without Compose |
| 25 | + |
| 26 | +Generate demo certificates: |
| 27 | + |
| 28 | +```bash |
| 29 | +docker build -t mtls-certs -f Dockerfile.certs . |
| 30 | +docker run --rm \ |
| 31 | + -e HOST_UID="$(id -u)" \ |
| 32 | + -e HOST_GID="$(id -g)" \ |
| 33 | + -v "$(pwd)/certs-local:/certs" \ |
| 34 | + mtls-certs |
| 35 | +``` |
| 36 | + |
| 37 | +Start the server: |
| 38 | + |
| 39 | +```bash |
| 40 | +SERVER_CERT_FILE="$(pwd)/certs-local/server.crt" \ |
| 41 | +SERVER_KEY_FILE="$(pwd)/certs-local/server.key" \ |
| 42 | +CA_CERT_FILE="$(pwd)/certs-local/ca.crt" \ |
| 43 | +go run ./cmd/server |
| 44 | +``` |
| 45 | + |
| 46 | +In another terminal, run the client in API mode: |
| 47 | + |
| 48 | +```bash |
| 49 | +CLIENT_CERT_FILE="$(pwd)/certs-local/client.crt" \ |
| 50 | +CLIENT_KEY_FILE="$(pwd)/certs-local/client.key" \ |
| 51 | +CA_CERT_FILE="$(pwd)/certs-local/ca.crt" \ |
| 52 | +CLIENT_API_ADDR=":8080" \ |
| 53 | +SERVER_URL="https://localhost:8443/hello" \ |
| 54 | +go run ./cmd/client |
| 55 | +``` |
| 56 | + |
| 57 | +Call the client API: |
| 58 | + |
| 59 | +```bash |
| 60 | +curl http://localhost:8080/hello |
| 61 | +``` |
| 62 | + |
| 63 | +Optional: one-shot client mode (no API server) is still available by omitting `CLIENT_API_ADDR`. |
| 64 | + |
| 65 | +## Big Payload Mode (50KB to 3MB) |
| 66 | + |
| 67 | +Run the client in big payload mode: |
| 68 | + |
| 69 | +```bash |
| 70 | +CLIENT_CERT_FILE="$(pwd)/certs-local/client.crt" \ |
| 71 | +CLIENT_KEY_FILE="$(pwd)/certs-local/client.key" \ |
| 72 | +CA_CERT_FILE="$(pwd)/certs-local/ca.crt" \ |
| 73 | +CLIENT_API_ADDR=":8080" \ |
| 74 | +CLIENT_MODE="bigpayload" \ |
| 75 | +BIGPAYLOAD_SERVER_URL="https://localhost:8443/payload" \ |
| 76 | +go run ./cmd/client |
| 77 | +``` |
| 78 | + |
| 79 | +The client exposes: |
| 80 | + |
| 81 | +- `POST /bigpayload` for large payload testing |
| 82 | +- request and response sizes must be between `51200` bytes (50KB) and `3145728` bytes (3MB) |
| 83 | +- response size defaults to request size, but can be overridden with header `X-Response-Size-Bytes` or query `response_size_bytes` |
| 84 | + |
| 85 | +Examples: |
| 86 | + |
| 87 | +```bash |
| 88 | +# 50KB request, 50KB response |
| 89 | +head -c 51200 /dev/zero | curl -sS \ |
| 90 | + -X POST http://localhost:8080/bigpayload \ |
| 91 | + -H "Content-Type: application/octet-stream" \ |
| 92 | + --data-binary @- \ |
| 93 | + -o /tmp/resp-50kb.bin |
| 94 | +wc -c /tmp/resp-50kb.bin |
| 95 | +``` |
| 96 | + |
| 97 | +```bash |
| 98 | +# 1MB request, 2MB response |
| 99 | +head -c 1048576 /dev/zero | curl -sS \ |
| 100 | + -X POST "http://localhost:8080/bigpayload?response_size_bytes=2097152" \ |
| 101 | + -H "Content-Type: application/octet-stream" \ |
| 102 | + --data-binary @- \ |
| 103 | + -o /tmp/resp-2mb.bin |
| 104 | +wc -c /tmp/resp-2mb.bin |
| 105 | +``` |
| 106 | + |
| 107 | +```bash |
| 108 | +# 3MB request, 3MB response |
| 109 | +head -c 3145728 /dev/zero | curl -sS \ |
| 110 | + -X POST http://localhost:8080/bigpayload \ |
| 111 | + -H "Content-Type: application/octet-stream" \ |
| 112 | + --data-binary @- \ |
| 113 | + -o /tmp/resp-3mb.bin |
| 114 | +wc -c /tmp/resp-3mb.bin |
| 115 | +``` |
| 116 | + |
| 117 | +The client logs upstream payload sizes after every request, and the server logs the handled request/response sizes too. |
0 commit comments