diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..3c429d9 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,5 @@ +target/ +.git/ +*.md +certs/ + diff --git a/.gitignore b/.gitignore index 1d155a9..cdb34d8 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,2 @@ -/target -remote-cert.crt -/quotes -ca.crt +/target/ +certs/ diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..60c327b --- /dev/null +++ b/Dockerfile @@ -0,0 +1,37 @@ +# Build stage +FROM rust:1.88.0-slim-bookworm AS builder + +# Build arguments for feature control +# On x86_64: use "default" for full features including Azure/TPM +# On ARM (cross-compile not supported for TPM): features will be ignored, uses --no-default-features +ARG FEATURES=default + +RUN apt-get update && apt-get install -y \ + pkg-config clang libclang-dev \ + openssl libssl-dev libtss2-dev \ + perl make \ + && rm -rf /var/lib/apt/lists/* + +WORKDIR /app +COPY . . + +# On x86_64: build with requested features +# On ARM: build without azure/TPM features (cross-compilation not supported for TPM libs) +RUN if [ "$(dpkg --print-architecture)" = "amd64" ]; then \ + cargo build --release --features "$FEATURES"; \ + else \ + echo "WARNING: Building on ARM without Azure/TPM features (cross-compilation not supported)" && \ + cargo build --release --no-default-features; \ + fi + +# Runtime stage +FROM debian:bookworm-slim + +RUN apt-get update && apt-get install -y \ + ca-certificates libssl3 libtss2-dev \ + && rm -rf /var/lib/apt/lists/* + +COPY --from=builder /app/target/release/attested-tls-proxy /usr/local/bin/ + +ENTRYPOINT ["/usr/local/bin/attested-tls-proxy"] + diff --git a/README.md b/README.md index a59830e..555d3e7 100644 --- a/README.md +++ b/README.md @@ -121,7 +121,7 @@ Attestation exchange messages are formatted as follows: SCALE is used by parity/substrate and was chosen because it is simple and actually matches the formatting used in TDX quotes. So it was already used as a dependency (via the [`dcap-qvl`](https://docs.rs/dcap-qvl) crate). -### Attestation Generation and Verification: +### Attestation Generation and Verification Attestation input takes the form of a 64 byte array. @@ -224,3 +224,69 @@ This aims to have a similar command line interface to `cvm-reverse-proxy` but th - If no measurements file is specified, `--allowed-remote-attestation-type` must be given. - `--log-dcap-quote` logs all attestation data (not only DCAP), but [currently] only remote attestation data, not locally-generated data. + +## Docker + +### Building the Image + +```bash +docker build -t attested-tls-proxy . + +# With custom features (e.g., without azure/TPM): +docker build --build-arg FEATURES="" -t attested-tls-proxy . +``` + +**Note for Apple Silicon (M1-M4) Mac users:** When building on ARM Macs, the Docker build will automatically compile without Azure/TPM features (`--no-default-features`) because the TPM libraries cannot be cross-compiled. For production builds with full Azure support, use an x86_64 system. + +### Running + +The same image supports all subcommands (server, client, get-tls-cert, etc.): + +```bash +# Show help +docker run --rm attested-tls-proxy --help + +# Run as server +docker run --rm attested-tls-proxy server \ + --listen-addr 0.0.0.0:443 \ + --target-addr 127.0.0.1:8080 \ + --tls-private-key-path /path/to/key.pem \ + --tls-certificate-path /path/to/cert.pem \ + --allowed-remote-attestation-type none + +# Run as client +docker run --rm attested-tls-proxy client \ + --listen-addr 0.0.0.0:8080 \ + target-server:443 \ + --allowed-remote-attestation-type none +``` + +### Testing with Docker Compose + +A `docker-compose.yml` is provided to test the full proxy chain: + +1. **Generate test certificates:** + ```bash + mkdir -p certs && cd certs + ../scripts/generate-cert.sh proxy-server 127.0.0.1 + # Convert key to PKCS#8 format (required by the proxy) + openssl pkcs8 -topk8 -inform PEM -outform PEM -nocrypt -in server.key -out server.pkcs8.key + mv server.pkcs8.key server.key + ``` + +2. **Start all services:** + ```bash + docker compose up --build + ``` + +3. **Test the proxy:** + ```bash + # Test via proxy-client (HTTP) + curl http://localhost:8080 + # Should return the nginx welcome page + + # Test TLS directly to proxy-server + openssl s_client -connect localhost:8443 -CAfile certs/ca.crt -servername proxy-server + # Should show "Verify return code: 0 (ok)" + ``` + diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..7913884 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,53 @@ +services: + # Simple HTTP backend + backend: + image: nginx:alpine + networks: + testnet: + ipv4_address: 172.28.0.10 + + # Proxy server - connects to backend, accepts TLS from client + proxy-server: + build: . + command: + - server + - --listen-addr=0.0.0.0:8443 + - --tls-private-key-path=/certs/server.key + - --tls-certificate-path=/certs/server.crt + - --allowed-remote-attestation-type=none + - "172.28.0.10:80" + volumes: + - ./certs:/certs:ro + ports: + - "8443:8443" + depends_on: + - backend + networks: + testnet: + ipv4_address: 172.28.0.11 + + # Proxy client - accepts HTTP, forwards to proxy-server over TLS + proxy-client: + build: . + command: + - client + - --listen-addr=0.0.0.0:8080 + - proxy-server:8443 + - --tls-ca-certificate=/certs/ca.crt + - --allowed-remote-attestation-type=none + volumes: + - ./certs:/certs:ro + ports: + - "8080:8080" + depends_on: + - proxy-server + networks: + testnet: + +networks: + testnet: + driver: bridge + ipam: + config: + - subnet: 172.28.0.0/16 +