{"id":21354990,"url":"https://github.com/salrashid123/tee_server_proxy","last_synced_at":"2025-03-16T05:23:34.252Z","repository":{"id":159853802,"uuid":"634887748","full_name":"salrashid123/tee_server_proxy","owner":"salrashid123","description":"mTLS proxy containers for GCP Confidential Compute","archived":false,"fork":false,"pushed_at":"2023-05-06T00:47:01.000Z","size":70,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-01-22T17:47:12.947Z","etag":null,"topics":["google-cloud","google-cloud-platform","tls","trusted-computing","trusted-execution-environment"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/salrashid123.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-05-01T13:21:18.000Z","updated_at":"2023-06-24T18:54:48.000Z","dependencies_parsed_at":null,"dependency_job_id":"fe58a8f3-4a25-4ebc-b240-7ca52fb0d7c8","html_url":"https://github.com/salrashid123/tee_server_proxy","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/salrashid123%2Ftee_server_proxy","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/salrashid123%2Ftee_server_proxy/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/salrashid123%2Ftee_server_proxy/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/salrashid123%2Ftee_server_proxy/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/salrashid123","download_url":"https://codeload.github.com/salrashid123/tee_server_proxy/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243828625,"owners_count":20354533,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["google-cloud","google-cloud-platform","tls","trusted-computing","trusted-execution-environment"],"created_at":"2024-11-22T04:15:31.855Z","updated_at":"2025-03-16T05:23:34.246Z","avatar_url":"https://github.com/salrashid123.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"\n# mTLS proxy containers for GCP Confidential Compute\n\nThis repo is a basic demo of a type of \"systemd\" for a container which seeks to simply bootstrap mTLS certificates for the 'background' application to use.\n\nEssentially, this is either a go (or nodejs) application running in a container that on start, reads mTLS certificates from GCP [Secret Manager](https://cloud.google.com/secret-manager).\n\nOnce it read the certificates, it will then provide them to background applications to use.\n\nBasically its a way to acquire mTLS certificates for applications that may not have the capability to specifically read them from GCP.\n\n\n\u003e\u003e this repo is *not* supported by google\n\n- Its not good container practice to run multiple applications in one container...anyway why do all this and not just `systemd`?\n\nGood question!....the intent for all this is to use with GCP [Confidential Space](https://cloud.google.com/docs/security/confidential-space) instances.  These VMs just run containers with a specific profile for very secure workloads.\n\nOne characteristic is that the not even the VM operator can access the runtime (eg ssh in) and the runtime container can demonstrate that it is running a specific workload prior to receiving sensitive data or decryption keys.\n\nEach container is treated as a `Trusted Execution Environment (TEE)` is initially startsup with no credentials (no certificates, no decryption keys).  It uses the TEE's [Attestation Service](https://cloud.google.com/docs/security/confidential-space#attestation-process) to 'prove' to a remote system the application is in a trusted environment.  Once that step is done, it will receive decryption keys or credentials.\n\nFor `TEE --\u003e TEE` traffic, one such credential would be mTLS keypairs issued by the remote party.  This ensures each TEE is actually communicating with another authorized TEE (and vice versa).\n\nIts fairly well know how an application can retrieve or decrypt data within a GCP TEE:\n\n- [Constructing Trusted Execution Environment (TEE) with GCP Confidential Space](https://github.com/salrashid123/confidential_space#mtls-using-acquired-keys)\n- [Multiparty Consent Based Networks (MCBN)](https://github.com/salrashid123/mcbn)\n\nbut the real issue this repo addresses is what happens if the \"application\" (redis, mysql, etc) has no built in mechanism to acquire mTLS keypairs thorough Confidential Space?\n\nIn this case, we needed a 'bootstrap' application which understands how to interact with GCP Confidential Space, acquire the credentials, and then furbish it to the backend application.\n\nThe bootstrap application in this case is a simple golang app that uses the attestation token to retrieve mTLS secrets from a collaborators Secret Manager.\n\nOnce it acquires the mTLS keys, it will [os/exec](https://pkg.go.dev/os/exec#Cmd.Run) the background application and await its completion.\n\nBasically, is a container which starts a go application that gets keys, provides those keys to a background application and launches the background app.\n\nSee\n\n- [Run multiple services in a container](https://docs.docker.com/config/containers/multi-service_container/)\n\n\n- As for why not use `systemd`? \n\nWell, running systemd requires **a lot** of additional software which can compromise the TEE itself.  Its far better to use minimal container surface.  In most of the examples, i just \"copied\" the static-compiled binary over into a [distroless/base](https://github.com/GoogleContainerTools/distroless).  \n \nI recognize not all background services can run on distroless images...\n\n---\n\n\nAnyway, there are four variations described here with different background applications and key requirements.\n\n* `Redis`\n  \n  In ths mode the foreground application acquires keys and provides those keys to redis as its own startup arguments for mTLS\n\n* `Postgres`\n  \n  In ths mode the foreground application acquires keys and provides those keys to postgres as its own startup arguments for mTLS\n\n* `Envoy (HTTPFilter)`\n\n  The foreground application acquires keys and writes the keys to the filesystem.  Envoy [HTTPFilter](https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_filters/http_filters) is started which uses those keys for mTLS\n\n* `Envoy (NetworkFilter)`\n\n  The foreground application acquires keys and writes the keys to the filesystem.  Envoy [NetworkFilter](https://www.envoyproxy.io/docs/envoy/latest/configuration/listeners/network_filters/network_filters) is started which uses those keys for mTLS\n\n* [Multiparty Consent Based Networks (MCBN)](https://github.com/salrashid123/mcbn)\n\n  This mode describes a very rare situation where multiple collaborators each provide a partial key to use for TLS between TEEs.  In this, mTLS is not used in the traditional RSA keypair mode but the actual `TEE-\u003eTEE` traffic is only allowed if each collaborator provides their key share. \n\n\n\n\n\n### Setup\n\n\nWe will primarily use GCP Secret Manager to store the mTLS secrets so upload those\n\n```bash\ngcloud secrets create ca --replication-policy=automatic   --data-file=certs/ca.pem\ngcloud secrets create server-cert --replication-policy=automatic   --data-file=certs/server.crt\ngcloud secrets create server-key --replication-policy=automatic   --data-file=certs/server.key\n\ngcloud auth application-default login\n```\n\nThen edit the following in ths repo and replace the `PROJECT_ID` value you use\n\n```bash\n# edit the following\n- server_envoy_http_proxy/main.go\n- server_envoy_network_proxy/main.go\n- server_redis/main.go\n- server_postgres/main.go\n- psk/main.js\n```\n\n---\n\n### client -\u003e container(redis_backend) \n\nFor Redis, build the container and test:\n\n```bash\ncd server_redis/\ndocker build -t  server_redis .\n\ndocker run -ti -v \"$HOME\"/.config/gcloud:/root/.config/gcloud  -p 16379:16379 server_redis\n```\n\nAt this point the redis container listens on `:16379` for mTLS traffic where the keys were downloaded from Secret Manger\n\nYou can verify using the test redis client:\n\n```bash\ncd client\ngo run main.go\n```\n\n---\n\n### client -\u003e container(postgres_backend) \n\nFor Postgres, we use the default docker image and [entrypoint](https://github.com/docker-library/postgres/blob/master/docker-entrypoint.sh) after bootstrapping the certificates.\n\nWe also setup postgres cert based auth (which IMO, i s basic, it uses the CN field as the username; i suspect you can do more but my knowledge is basic).\n\n`main.go` sets up the startup parameters:\n\n```golang\n\t\tcmd := exec.Command(\"/usr/local/bin/docker-entrypoint.sh\", \"postgres\", \"--port=5432\", \"--ssl=on\", \"--ssl_cert_file=/config/server.crt\", \"--ssl_key_file=/config/server.key\", \"--ssl_ca_file=/config/ca.pem\", \"--hba_file=/config/pg_hba.conf\")\n\t\t//cmd.Env = os.Environ()\n\t\t//cmd.Env = append(cmd.Env, \"POSTGRES_PASSWORD=mysecretpassword\")\n```\n\nthe `pg_hba.conf` file enforces certs:\n\n```conf\n# TYPE  DATABASE        USER            ADDRESS                 METHOD\nlocal   postgres        all                                     peer\nhostssl all             all             0.0.0.0/0               cert\n```\n\nto use\n\n```bash\ncd server_postgres/\ndocker build -t  server_postgres .\n\ndocker run -ti -v \"$HOME\"/.config/gcloud:/root/.config/gcloud   -p 5432:5432  server_postgres \n```\n\nAt this point the postgres container listens on `:5432` for mTLS traffic where the keys were downloaded from Secret Manger\n\nYou can verify using the a postgres client with client certs\n\n```bash\n# change vm's public address to /etc/hosts\n127.0.0.1\tserver.domain.com\n\n# POSTGRES_PASSWORD=mysecretpassword\n$ psql \"host=server.domain.com port=5432 user=postgres sslmode=verify-full sslcert=certs/postgres.crt sslkey=certs/postgres.key sslrootcert=certs/ca.pem\"\n\n  postgres=# SHOW SERVER_VERSION;\n          server_version         \n  --------------------------------\n  15.2 (Debian 15.2-1.pgdg110+1)\n  (1 row)\n```\n\nnote the  `postgres.crt` has the CN field thats the username....like i said, its a real basic way to do auth...\n\n  `C=US, O=Google, OU=Enterprise, CN=postgres`\n\n---\n\n### client -\u003e container(envoy_http_proxy -\u003e http_backend) \n\nFor envoy HTTP backend, the envoy config simply sends a static echo response back\n\n```bash\ncd server_envoy_http_proxy/\n\ndocker build -t  server_envoy_http_proxy .\ndocker run -ti -v \"$HOME\"/.config/gcloud:/root/.config/gcloud   -p 8081:8081 server_envoy_http_proxy\n```\n\nNow that the envoy background process is running, send mTLS traffic\n\n```bash\ncurl -v     --connect-to server.domain.com:443:127.0.0.1:8081 --cacert certs/ca.pem  \\\n    --cert certs/client.crt  \\\n    --key certs/client.key  https://server.domain.com/ \n```\n---\n\n### client -\u003e container(envoy_network_proxy -\u003e tcp_backend) \n\nFor envoy Network backend, we will launch two processes in the background:  envoy in TCP mode which handles mTLS and a background TCP application _which just happens to be an http server_.\n\n```bash\ncd server_envoy_network_proxy/\n\ncd backend_app/\nGOOS=linux GOARCH=amd64 go build -o server\ncp server ../\nrm server\n\ndocker build -t  server_envoy_network_proxy .\ndocker run -ti -v \"$HOME\"/.config/gcloud:/root/.config/gcloud   -p 8081:8081 server_envoy_network_proxy\n```\n\nNow that the envoy background process is running, send mTLS traffic (again, we just happen to be running an http TCP server so curl works here)\n\n```bash\ncurl -v     --connect-to server.domain.com:443:127.0.0.1:8081 --cacert certs/ca.pem  \\\n    --cert certs/client.crt  \\\n    --key certs/client.key  https://server.domain.com/ \n```\n\n\n### client -\u003e container(node_psk -\u003e echo) \n\nThis demonstrates the multiparty consent network described earlier.\n\nFor this, we need to seed secret manager with each collaborators partal `TLS-PSK` keys\n\n```bash\ncd psk/\n\necho -n \"2c6f63f8c0f53a565db041b91c0a95add8913fc102670589db3982228dbfed90\" \u003e alice.psk\necho -n \"b15244faf36e5e4b178d3891701d245f2e45e881d913b6c35c0ea0ac14224cc2\" \u003e bob.psk\n\ngcloud secrets create alice_psk --replication-policy=automatic   --data-file=alice.psk\ngcloud secrets create bob_psk --replication-policy=automatic   --data-file=bob.psk\n```\n\nThen build and run the node application.  The node application simulates the go application above but we are only using node as the \"only application\" since very few systems support defining TLS-PSK keys (see  [golang#6379](https://github.com/golang/go/issues/6379), [envoy#13237](https://github.com/envoyproxy/envoy/issues/13237)).  Ideally you could use the node app as a TCP proxy for a background application you would run.  This is not demonstrated in thsi repo\n\n```bash\ndocker build -t  psk_nodejs .\ndocker run -ti -v \"$HOME\"/.config/gcloud:/root/.config/gcloud   -p 8081:8081 psk_nodejs\n```\n\nNow that the node app has all the keys, run the client\n\n```bash\ncd client/\nnode main.js\n```\n\n### tmpfs\n\nTODO:  write certificates to any `/tmpfs` that that is mapped to the container\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsalrashid123%2Ftee_server_proxy","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsalrashid123%2Ftee_server_proxy","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsalrashid123%2Ftee_server_proxy/lists"}