Envoy
Stellen Sie RustFS hinter Envoy mit TLS-terminierten Routen für die S3-API und die Console bereit.
Verwenden Sie Envoy, um TLS zu terminieren und getrennte Hostnamen zur RustFS-S3-API und zur Console (Weboberfläche) zu leiten. In dieser Bereitstellung betreiben Sie Envoy und eine RustFS-Instanz mit einem Knoten in einem Docker-Netzwerk. Sie benötigen Docker Engine, zwei DNS-Einträge und ein TLS-Zertifikat, das beide Hostnamen abdeckt (die Anleitung verwendet zum Testen ein selbst signiertes Zertifikat).
Diese Anleitung verwendet diese Beispiel-Hostnamen:
s3.example.comfür die S3-APIconsole.example.comfür die Console
Ersetzen Sie sie durch Hostnamen, die auf den Docker-Host zeigen.
S3 vom Wurzelpfad bereitstellen
Veröffentlichen Sie die S3-API nicht unter einem Pfad wie /s3/. AWS Signature Version 4 enthält den Anfragepfad und den Host, daher kann das Umschreiben eines der beiden Werte signierte Anfragen ungültig machen. Envoy leitet den eingehenden Header Host unverändert weiter, wodurch Signaturen gültig bleiben.
Die Bereitstellungsverzeichnisse anlegen
Legen Sie Verzeichnisse für die Envoy-Konfiguration und das TLS-Zertifikat an:
mkdir -p rustfs-envoy/certs
cd rustfs-envoyErzeugen Sie für lokale Tests ein selbst signiertes Zertifikat, das beide Hostnamen abdeckt:
openssl req -x509 -newkey rsa:2048 -nodes \
-keyout certs/privkey.pem -out certs/fullchain.pem -days 30 \
-subj "/CN=*.example.com" \
-addext "subjectAltName=DNS:s3.example.com,DNS:console.example.com"
chmod 644 certs/privkey.pemMachen Sie das Zertifikat für den Benutzer ohne Root-Rechte lesbar, unter dem das Envoy-Image läuft. Ein privater Schlüssel mit 600 erzeugt den irreführenden Fehler Failed to load incomplete private key.
Envoy konfigurieren
Legen Sie die Konfiguration mit einem HTTPS-Listener und zwei virtuellen Hosts an. Route-Timeouts sind deaktiviert (timeout: 0s), damit lange Streaming-S3-Uploads nicht abgeschnitten werden:
static_resources:
listeners:
- name: https
address: {socket_address: {address: 0.0.0.0, port_value: 8443}}
filter_chains:
- transport_socket:
name: envoy.transport_sockets.tls
typed_config:
"@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext
common_tls_context:
tls_certificates:
- certificate_chain: {filename: /certs/fullchain.pem}
private_key: {filename: /certs/privkey.pem}
filters:
- name: envoy.filters.network.http_connection_manager
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
stat_prefix: rustfs_https
route_config:
virtual_hosts:
- name: s3
domains: ["s3.example.com", "s3.example.com:*"]
routes:
- match: {prefix: "/"}
route: {cluster: rustfs_s3, timeout: 0s}
- name: console
domains: ["console.example.com", "console.example.com:*"]
routes:
- match: {prefix: "/"}
route: {cluster: rustfs_console, timeout: 0s}
http_filters:
- name: envoy.filters.http.router
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
clusters:
- name: rustfs_s3
connect_timeout: 5s
type: STRICT_DNS
lb_policy: ROUND_ROBIN
load_assignment:
cluster_name: rustfs_s3
endpoints:
- lb_endpoints:
- endpoint: {address: {socket_address: {address: rustfs, port_value: 9000}}}
- name: rustfs_console
connect_timeout: 5s
type: STRICT_DNS
lb_policy: ROUND_ROBIN
load_assignment:
cluster_name: rustfs_console
endpoints:
- lb_endpoints:
- endpoint: {address: {socket_address: {address: rustfs, port_value: 9001}}}Die Domäneneinträge host:* sind wichtig: Clients senden auf Nicht-Standard-Ports Host: s3.example.com:8443, und Envoy vergleicht die Authority einschließlich des Ports.
Envoy starten
Starten Sie Envoy im selben Docker-Netzwerk wie RustFS und veröffentlichen Sie nur den Proxy-Port:
docker run -d --name envoy --network oo-rustfs_default -p 8443:8443 \
-v "$PWD/envoy.yaml":/envoy.yaml:ro \
-v "$PWD/certs":/certs:ro \
envoyproxy/envoy:v1.34-latest -c /envoy.yamlBeide Endpunkte prüfen
Richten Sie die Beispiel-Hostnamen mit curl --resolve auf den Proxy (in der Produktion übernimmt das DNS):
curl -sk --resolve s3.example.com:8443:127.0.0.1 \
https://s3.example.com:8443/health/ready -o /dev/null -w "s3 api: %{http_code}\n"
curl -sk --resolve console.example.com:8443:127.0.0.1 \
https://console.example.com:8443/rustfs/console/ -o /dev/null -w "console: %{http_code}\n"s3 api: 200
console: 200-k überspringt die Zertifikatsprüfung, weil das Zertifikat selbst signiert ist. Bei einem vertrauenswürdigen Zertifikat lassen Sie es weg.
Signierte S3-Anfragen über Envoy senden
Richten Sie einen beliebigen S3-Client auf den Proxy aus, als wäre er RustFS. Konfigurieren Sie den Client mit https://s3.example.com:8443 als Endpunkt und mit pfadbasierter Adressierung (Path-Style). Wenn dem Proxy-Zertifikat vertraut wird, laufen signierte Anfragen mit AWS Signature Version 4 unverändert durch. Fügen Sie für einen schnellen Test über unverschlüsseltes HTTP einen HTTP-Listener auf Port 8080 mit demselben Virtual-Host-Routing wie der HTTPS-Listener hinzu und verwenden Sie dann den Endpunkt http://s3.example.com:8080:
rc alias set rustfs-envoy http://s3.example.com:8080 <your-access-key> <your-secret-key>
rc ls rustfs-envoy/rclone-demo/[ ] 0B seed/
[2026-09-29 11:12:41] 5 B write-test.txtDie Signaturen bleiben gültig, weil Envoy den ursprünglichen Header Host an RustFS weiterleitet.
Backends mit mehreren Knoten
Fügen Sie für eine verteilte RustFS-Bereitstellung jeden Knoten zum S3-Cluster hinzu:
- name: rustfs_s3
connect_timeout: 5s
type: STRICT_DNS
lb_policy: ROUND_ROBIN
load_assignment:
cluster_name: rustfs_s3
endpoints:
- lb_endpoints:
- endpoint: {address: {socket_address: {address: node1, port_value: 9000}}}
- lb_endpoints:
- endpoint: {address: {socket_address: {address: node2, port_value: 9000}}}
- lb_endpoints:
- endpoint: {address: {socket_address: {address: node3, port_value: 9000}}}
- lb_endpoints:
- endpoint: {address: {socket_address: {address: node4, port_value: 9000}}}Der Console-Cluster folgt demselben Muster auf Port 9001.
Fehlerbehebung
Failed to load incomplete private key from path
Der Envoy-Container läuft als Benutzer ohne Root-Rechte und kann einen root-eigenen Schlüssel mit 600 nicht lesen. Setzen Sie die Schlüsseldateien mit chmod 644 (oder ändern Sie den Eigentümer auf den Container-Benutzer, UID 1001 im offiziellen Image).
Routen antworten mit 404 bei den richtigen Hostnamen
Envoy vergleicht die Authority einschließlich des Ports. Fügen Sie die Varianten host:* zur Liste domains jedes virtuellen Hosts hinzu, wie in der Konfiguration oben.
Access Denied von RustFS bei weitergeleiteten Anfragen
Prüfen Sie, dass der Proxy den Pfad und den Header Host nicht umschreibt. Signierte Anfragen müssen RustFS mit dem Host erreichen, für den der Client signiert hat.