Skip to content

Commit 9299c0f

Browse files
sayborasjulianwiedmann
authored andcommitted
bugtool: Add post-processing masking function for Envoy
[upstream commit 48a9976] This commit is to explicitly mask the below fields from Envoy config dump: - api_key (used in kafka L7 policy) - TLSContext (used in Cilium NetworkPolicy) One round of scanning on existing Cilium protobuf was done. Related docs: https://www.envoyproxy.io/docs/envoy/latest/operations/admin#get--config_dump Signed-off-by: Tam Mach <tam.mach@cilium.io>
1 parent 0191b1e commit 9299c0f

File tree

1 file changed

+46
-4
lines changed

1 file changed

+46
-4
lines changed

Diff for: bugtool/cmd/root.go

+46-4
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import (
2727
"github.com/cilium/cilium/pkg/components"
2828
"github.com/cilium/cilium/pkg/defaults"
2929
"github.com/cilium/cilium/pkg/option"
30+
"github.com/cilium/cilium/pkg/safeio"
3031
)
3132

3233
// BugtoolRootCmd is the top level command for the bugtool.
@@ -170,6 +171,18 @@ func isValidArchiveType(archiveType string) bool {
170171

171172
type postProcessFunc func(output []byte) ([]byte, error)
172173

174+
var envoySecretMask = jsonFieldMaskPostProcess([]string{
175+
// Cilium LogEntry -> KafkaLogEntry{l7} -> KafkaLogEntry{api_key}
176+
"api_key",
177+
// This could be from one of the following:
178+
// - Cilium NetworkPolicy -> PortNetworkPolicy{ingress_per_port_policies, egress_per_port_policies}
179+
// -> PortNetworkPolicyRule{rules} -> TLSContext{downstream_tls_context, upstream_tls_context}
180+
// - Upstream Envoy tls_certificate
181+
"trusted_ca",
182+
"certificate_chain",
183+
"private_key",
184+
})
185+
173186
func runTool() {
174187
// Validate archive type
175188
if !isValidArchiveType(archiveType) {
@@ -216,13 +229,13 @@ func runTool() {
216229
}
217230
} else {
218231
if envoyDump {
219-
if err := dumpEnvoy(cmdDir, "http://admin/config_dump?include_eds", "envoy-config.json"); err != nil {
232+
if err := dumpEnvoy(cmdDir, "http://admin/config_dump?include_eds", "envoy-config.json", envoySecretMask); err != nil {
220233
fmt.Fprintf(os.Stderr, "Unable to dump envoy config: %s\n", err)
221234
}
222235
}
223236

224237
if envoyMetrics {
225-
if err := dumpEnvoy(cmdDir, "http://admin/stats/prometheus", "envoy-metrics.txt"); err != nil {
238+
if err := dumpEnvoy(cmdDir, "http://admin/stats/prometheus", "envoy-metrics.txt", nil); err != nil {
226239
fmt.Fprintf(os.Stderr, "Unable to retrieve envoy prometheus metrics: %s\n", err)
227240
}
228241
}
@@ -516,7 +529,7 @@ func dumpHubbleMetrics(rootDir string) error {
516529
return downloadToFile(httpClient, url, filepath.Join(rootDir, "hubble-metrics.txt"))
517530
}
518531

519-
func dumpEnvoy(rootDir string, resource string, fileName string) error {
532+
func dumpEnvoy(rootDir string, resource string, fileName string, postProcess postProcessFunc) error {
520533
// curl --unix-socket /var/run/cilium/envoy/sockets/admin.sock http:/admin/config_dump\?include_eds > dump.json
521534
c := &http.Client{
522535
Transport: &http.Transport{
@@ -525,7 +538,11 @@ func dumpEnvoy(rootDir string, resource string, fileName string) error {
525538
},
526539
},
527540
}
528-
return downloadToFile(c, resource, filepath.Join(rootDir, fileName))
541+
542+
if postProcess == nil {
543+
return downloadToFile(c, resource, filepath.Join(rootDir, fileName))
544+
}
545+
return downloadToFileWithPostProcess(c, resource, filepath.Join(rootDir, fileName), postProcess)
529546
}
530547

531548
func pprofTraces(rootDir string, pprofDebug int) error {
@@ -589,3 +606,28 @@ func downloadToFile(client *http.Client, url, file string) error {
589606
_, err = io.Copy(out, resp.Body)
590607
return err
591608
}
609+
610+
// downloadToFileWithPostProcess downloads the content from the given URL and writes it to the given file.
611+
// The content is then post-processed using the given postProcess function before being written to the file.
612+
// Note: Please use downloadToFile instead of this function if no post-processing is required.
613+
func downloadToFileWithPostProcess(client *http.Client, url, file string, postProcess postProcessFunc) error {
614+
resp, err := client.Get(url)
615+
if err != nil {
616+
return err
617+
}
618+
defer resp.Body.Close()
619+
if resp.StatusCode != http.StatusOK {
620+
return fmt.Errorf("bad status: %s", resp.Status)
621+
}
622+
623+
b, err := safeio.ReadAllLimit(resp.Body, safeio.MB)
624+
if err != nil {
625+
return err
626+
}
627+
628+
b, err = postProcess(b)
629+
if err != nil {
630+
return err
631+
}
632+
return os.WriteFile(file, b, 0644)
633+
}

0 commit comments

Comments
 (0)