SSL/TLS Proxy
In this section we’ll explore how to secure Chroma with a TLS-terminated HTTPS proxy. Below we’ll give two examples of how to do this using Envoy and Nginx. The certificates are self-signed and generated using OpenSSL, but in the future we’ll also provide examples of how to achieve this with Let’s Encrypt and certbot.
Getting The cert
To manually generate a certificate follow the steps here.
Envoy
The following envoy configuration will create a listener on port 443 that will forward all requests to the chromadb.
1. static_resources:
2. listeners:
3. - name: listener_0
4. address:
5. socket_address:
6. address: 0.0.0.0
7. port_value: 443
8. filter_chains:
9. - filters:
10. - name: envoy.filters.network.http_connection_manager
11. typed_config:
12. "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
13. stat_prefix: ingress_http
14. route_config:
15. name: chroma_route
16. virtual_hosts:
17. - name: local_chromadb
18. domains: [ "*" ]
19. routes:
20. - match:
21. prefix: "/"
22. route:
23. cluster: chromadb_service
24. prefix_rewrite: "/"
25. http_filters:
26. - name: envoy.filters.http.router
27. typed_config:
28. "@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
29. transport_socket:
30. name: envoy.transport_sockets.tls
31. typed_config:
32. "@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext
33. common_tls_context:
34. tls_certificates:
35. - certificate_chain:
36. filename: "/etc/envoy/certs/servercert.pem"
37. private_key:
38. filename: "/etc/envoy/certs/serverkey.pem"
39. clusters:
40. - name: chromadb_service
41. connect_timeout: 0.25s
42. type: LOGICAL_DNS
43. lb_policy: ROUND_ROBIN
44. load_assignment:
45. cluster_name: chromadb_service
46. endpoints:
47. - lb_endpoints:
48. - endpoint:
49. address:
50. socket_address:
51. address: chromadb
52. port_value: 8000
Finally the docker compose to tie things up where we have added a cert-gen step to automatically generate the certificates, prior to starting the envoy and chromadb services.
1. version: '3'
2. networks:
3. net:
4. driver: bridge
5. services:
6. cert-gen:
7. image: openquantumsafe/openssl3
8. volumes:
9. - ./certs:/certs
10. - ./openssl.cnf:/etc/ssl/openssl.cnf
11. command: |
12. sh -c "[ -f /certs/servercert.pem ] || \
13. openssl req -new -newkey rsa:2048 -sha256 -days 365 -nodes -x509 -keyout /certs/serverkey.pem -out /certs/servercert.pem -subj '/O=Chroma/C=US' -config /etc/ssl/openssl.cnf"
14. environment:
15. - CHROMA_DOMAIN=${CHROMA_DOMAIN:-localhost}
16. envoy:
17. image: bitnami/envoy
18. volumes:
19. - ./envoy.yaml:/opt/bitnami/envoy/conf/envoy.yaml
20. - ./certs:/etc/envoy/certs
21. - ./wait-for-certs.sh:/usr/local/bin/wait-for-certs.sh
22. ports:
23. - "443:443"
24. networks:
25. - net
26. depends_on:
27. - cert-gen
28. entrypoint: |
29. sh -c "/usr/local/bin/wait-for-certs.sh && \
30. /opt/bitnami/envoy/bin/envoy -c /opt/bitnami/envoy/conf/envoy.yaml"
31. chromadb:
32. image: chromadb/chroma:0.5.5
33. volumes:
34. - ./chromadb:/chroma/chroma
35. environment:
36. - IS_PERSISTENT=TRUE
37. - ANONYMIZED_TELEMETRY=${ANONYMIZED_TELEMETRY:-TRUE}
38. networks:
39. - net
40. depends_on:
41. - envoy
Nginx
Use the following Nginx config (nginx.conf) as a starting point and build from there:
1. server {
2. listen 443 ssl;
3. server_name localhost;
5. ssl_certificate /etc/nginx/certs/servercert.pem;
6. ssl_certificate_key /etc/nginx/certs/serverkey.pem;
8. location / {
9. proxy_pass http://chromadb:8000;
10. proxy_set_header Host $host;
11. proxy_http_version 1.1; # Use HTTP/1.1
12. proxy_set_header X-Real-IP $remote_addr;
13. proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
14. proxy_set_header X-Forwarded-Proto $scheme;
15. }
16. }
Create a docker-compose.yml file with the following content:
Config Files
For the following docker-compose.yaml to operate successfully openssl.cnf and nginx.conf files need to be present in the same directory.
1. version: '3'
2. networks:
3. net:
4. driver: bridge
5. services:
6. cert-gen:
7. image: openquantumsafe/openssl3
8. volumes:
9. - ./certs:/certs
10. - ./openssl.cnf:/etc/ssl/openssl.cnf
11. command: |
12. sh -c "[ -f /certs/servercert.pem ] || \
13. openssl req -new -newkey rsa:2048 -sha256 -days 365 -nodes -x509 -keyout /certs/serverkey.pem -out /certs/servercert.pem -subj '/O=Chroma/C=US' -config /etc/ssl/openssl.cnf"
14. environment:
15. - CHROMA_DOMAIN=${CHROMA_DOMAIN:-localhost}
16. chromadb:
17. image: chromadb/chroma:0.5.5
18. volumes:
19. - ./chromadb:/chroma/chroma
20. environment:
21. - IS_PERSISTENT=TRUE
22. - ANONYMIZED_TELEMETRY=${ANONYMIZED_TELEMETRY:-TRUE}
23. ports:
24. - "8000:8000"
25. networks:
26. - net
27. nginx:
28. image: nginx:latest
29. depends_on:
30. - cert-gen
31. - chromadb
32. ports:
33. - "443:443"
34. volumes:
35. - ./nginx.conf:/etc/nginx/conf.d/default.conf
36. - ./certs:/etc/nginx/certs
37. networks:
38. - net
July 31, 2024
