diff --git a/pkg/acquisition/modules/appsec/config.go b/pkg/acquisition/modules/appsec/config.go index 9f85eb52d6e..63c5a9a2329 100644 --- a/pkg/acquisition/modules/appsec/config.go +++ b/pkg/acquisition/modules/appsec/config.go @@ -41,8 +41,10 @@ var ( type Configuration struct { ListenAddr string `yaml:"listen_addr"` ListenSocket string `yaml:"listen_socket"` + TLSAuth bool `yaml:"tls_auth"` CertFilePath string `yaml:"cert_file"` KeyFilePath string `yaml:"key_file"` + CaCertPath string `yaml:"ca_cert_file"` Path string `yaml:"path"` Routines int `yaml:"routines"` AppsecConfig string `yaml:"appsec_config"` @@ -82,6 +84,20 @@ func (w *Source) UnmarshalConfig(yamlConfig []byte) error { w.config.Routines = 1 } + if w.config.TLSAuth { + if w.config.CaCertPath == "" { + return errors.New("TLSAuth is enabled, but ca_cert is not provided") + } + + if w.config.CertFilePath == "" { + return errors.New("cert_file is required") + } + + if w.config.KeyFilePath == "" { + return errors.New("key_file is required") + } + } + if w.config.AppsecConfig == "" && w.config.AppsecConfigPath == "" && len(w.config.AppsecConfigs) == 0 { return errors.New("appsec_config or appsec_config_path must be set") } @@ -126,7 +142,7 @@ func loadCertPool(caCertPath string, logger log.FieldLogger) (*x509.CertPool, er } // expandAppsecConfigEntry resolves a single appsec_config(s) entry into the list -// of appsec-config item names to load. A literal entry is returned untouched. An entry containing a glob meta-character +// of appsec-config item names to load. A literal entry is returned untouched. An entry containing a glob meta-character // is matched against the installed appsec-configs with the same matcher used // to expand appsec-rule patterns; it errors when no installed config matches. func expandAppsecConfigEntry(entry string, hub *cwhub.Hub) ([]string, error) { @@ -180,6 +196,49 @@ func resolveAppsecConfigEntries(entries []string, hub *cwhub.Hub) ([]string, err return toLoad, nil } +func (w *Source) configureHTTPServer() error { + w.mux = http.NewServeMux() + + w.server = &http.Server{ + Addr: w.config.ListenAddr, + Handler: w.mux, + Protocols: &http.Protocols{}, + } + + w.server.Protocols.SetHTTP1(true) + w.server.Protocols.SetUnencryptedHTTP2(true) + w.server.Protocols.SetHTTP2(true) + + if w.config.TLSAuth { + tlsConfig := tls.Config{} + + if w.config.CaCertPath == "" { + return fmt.Errorf("missing ca certificate") + } + + if w.config.CertFilePath == "" || w.config.KeyFilePath == "" { + return fmt.Errorf("missing server cert/key") + } + + cert, err := tls.LoadX509KeyPair(w.config.CertFilePath, w.config.KeyFilePath) + if err != nil { + return fmt.Errorf("failed to load server cert/key: %w", err) + } + + caCertPool, err := loadCertPool(w.config.CaCertPath, w.logger) + if err != nil { + return fmt.Errorf("unable to load Appsec CA cert pool: %w", err) + } + + tlsConfig.Certificates = []tls.Certificate{cert} + tlsConfig.ClientCAs = caCertPool + tlsConfig.ClientAuth = tls.RequireAndVerifyClientCert + + w.server.TLSConfig = &tlsConfig + } + return nil +} + func (w *Source) Configure(ctx context.Context, yamlConfig []byte, logger *log.Entry, _ metrics.AcquisitionMetricsLevel) error { if w.hub == nil { return errors.New("appsec datasource requires a hub. this is a bug, please report") @@ -213,18 +272,10 @@ func (w *Source) Configure(ctx context.Context, yamlConfig []byte, logger *log.E w.logger.Infof("Body read timeout not set, using default: %v", *w.config.BodyReadTimeout) } - w.mux = http.NewServeMux() - - w.server = &http.Server{ - Addr: w.config.ListenAddr, - Handler: w.mux, - Protocols: &http.Protocols{}, + if err := w.configureHTTPServer(); err != nil { + return err } - w.server.Protocols.SetHTTP1(true) - w.server.Protocols.SetUnencryptedHTTP2(true) - w.server.Protocols.SetHTTP2(true) - w.InChan = make(chan appsec.ParsedRequest) appsecCfg := appsec.AppsecConfig{Logger: w.logger.WithField("component", "appsec_config")} @@ -414,14 +465,16 @@ func (w *Source) appsecHandler(rw http.ResponseWriter, r *http.Request) { ctx := r.Context() w.logger.Debugf("Received request from '%s' on %s", r.RemoteAddr, r.URL.Path) - apiKey := r.Header.Get(appsec.APIKeyHeaderName) - clientIP := r.Header.Get(appsec.IPHeaderName) - remoteIP := r.RemoteAddr + if !w.config.TLSAuth { + apiKey := r.Header.Get(appsec.APIKeyHeaderName) + clientIP := r.Header.Get(appsec.IPHeaderName) + remoteIP := r.RemoteAddr - if err := w.checkAuth(ctx, apiKey); err != nil { - w.logger.Errorf("Unauthorized request from '%s' (real IP = %s): %s", remoteIP, clientIP, err) - rw.WriteHeader(http.StatusUnauthorized) - return + if err := w.checkAuth(ctx, apiKey); err != nil { + w.logger.Errorf("Unauthorized request from '%s' (real IP = %s): %s", remoteIP, clientIP, err) + rw.WriteHeader(http.StatusUnauthorized) + return + } } // Force client to send the body quickly enough. diff --git a/pkg/acquisition/modules/appsec/run.go b/pkg/acquisition/modules/appsec/run.go index df8c6219187..f86bafd8686 100644 --- a/pkg/acquisition/modules/appsec/run.go +++ b/pkg/acquisition/modules/appsec/run.go @@ -24,10 +24,10 @@ func (w *Source) listenAndServe(ctx context.Context, t *tomb.Tomb) error { serverError := make(chan error, 2) - startServer := func(listener net.Listener, canTLS bool) { + startServer := func(listener net.Listener) { var err error - if canTLS && (w.config.CertFilePath != "" || w.config.KeyFilePath != "") { + if w.config.TLSAuth || w.config.CertFilePath != "" || w.config.KeyFilePath != "" { if w.config.KeyFilePath == "" { serverError <- errors.New("missing TLS key file") return @@ -74,7 +74,7 @@ func (w *Source) listenAndServe(ctx context.Context, t *tomb.Tomb) error { } w.logger.Infof("Appsec listening on Unix socket %s", socket) - startServer(listener, false) + startServer(listener) }(w.config.ListenSocket) // Starting TCP listener @@ -90,7 +90,7 @@ func (w *Source) listenAndServe(ctx context.Context, t *tomb.Tomb) error { } w.logger.Infof("Appsec listening on %s", url) - startServer(listener, true) + startServer(listener) }(w.config.ListenAddr) select { diff --git a/pkg/acquisition/modules/appsec/run_test.go b/pkg/acquisition/modules/appsec/run_test.go new file mode 100644 index 00000000000..585a3e75786 --- /dev/null +++ b/pkg/acquisition/modules/appsec/run_test.go @@ -0,0 +1,155 @@ +package appsecacquisition + +import ( + "context" + "crypto/tls" + "crypto/x509" + "fmt" + "io" + "log" + "net" + "net/http" + "os" + "path/filepath" + "testing" + "time" + + "github.com/sirupsen/logrus" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "gopkg.in/tomb.v2" +) + +func TestSource_listenAndServe(t *testing.T) { + tests := []struct { + name string + clientCrtPath string + clientKeyPath string + useSocket bool + wantErr bool + }{ + { + name: "Test TCP server with trust client cert", + clientCrtPath: "testdata/client.crt", + clientKeyPath: "testdata/client.key", + useSocket: false, + wantErr: false, + }, + { + name: "Test TCP server with untrust client cert", + clientCrtPath: "testdata/selfsined-client.crt", + clientKeyPath: "testdata/selfsined-client.key", + useSocket: false, + wantErr: true, + }, + { + name: "Test Socket server with trust client cert", + clientCrtPath: "testdata/client.crt", + clientKeyPath: "testdata/client.key", + useSocket: true, + wantErr: false, + }, + { + name: "Test Socket server with untrust client cert", + clientCrtPath: "testdata/selfsined-client.crt", + clientKeyPath: "testdata/selfsined-client.key", + useSocket: true, + wantErr: true, + }, + } + + tempDir := t.TempDir() + socketFile := filepath.Join(tempDir, "test.sock") + url := "https://127.0.0.1:7422" + + config := &Configuration{ + ListenAddr: "127.0.0.1:7422", + ListenSocket: socketFile, + TLSAuth: true, + CertFilePath: "testdata/server.crt", + KeyFilePath: "testdata/server.key", + CaCertPath: "testdata/ca.crt", + } + runner := make([]AppsecRunner, 0) + tt := &tomb.Tomb{} + + logger := logrus.New() + // Disable output + logger.SetOutput(io.Discard) + // Create Entry from disabled loggger + testLogger := logrus.NewEntry(logger) + + w := &Source{AppsecRunners: runner, config: *config, logger: testLogger} + + err := w.configureHTTPServer() + require.NoError(t, err) + + // Supress server TLS error messages + w.server.ErrorLog = log.New(io.Discard, "", 0) + + w.mux.HandleFunc("/test", func(rw http.ResponseWriter, r *http.Request) { + rw.WriteHeader(http.StatusOK) + }) + + tt.Go(func() error { + err := w.listenAndServe(context.Background(), tt) + require.NoError(t, err) + return nil + }) + + time.Sleep(1 * time.Second) + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + // init client cert + cert, err := tls.LoadX509KeyPair(tt.clientCrtPath, tt.clientKeyPath) + require.NoError(t, err) + + caCert, err := os.ReadFile("testdata/ca.crt") + require.NoError(t, err) + + caCertPool := x509.NewCertPool() + caCertPool.AppendCertsFromPEM(caCert) + + tlsConfig := &tls.Config{ + Certificates: []tls.Certificate{cert}, + RootCAs: caCertPool, + } + + dialer := &net.Dialer{} + client := &http.Client{ + Transport: &http.Transport{ + TLSClientConfig: tlsConfig, + }, + } + + if tt.useSocket { + client = &http.Client{ + Transport: &http.Transport{ + TLSClientConfig: tlsConfig, + DialContext: func(ctx context.Context, _, _ string) (net.Conn, error) { + return dialer.DialContext(ctx, "unix", socketFile) + }, + }, + } + } + + req, err := http.NewRequestWithContext(t.Context(), http.MethodGet, fmt.Sprintf("%s/test", url), http.NoBody) + require.NoError(t, err) + + resp, err := client.Do(req) + + if tt.wantErr { + require.ErrorContains(t, err, "tls: certificate required") + } else { + require.NoError(t, err) + assert.Equal(t, http.StatusOK, resp.StatusCode) + } + }) + } + + w.server.Close() + tt.Kill(nil) + err = tt.Wait() + require.NoError(t, err) +} diff --git a/pkg/acquisition/modules/appsec/testdata/ca.crt b/pkg/acquisition/modules/appsec/testdata/ca.crt new file mode 100644 index 00000000000..722dced8747 --- /dev/null +++ b/pkg/acquisition/modules/appsec/testdata/ca.crt @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDBzCCAe+gAwIBAgIURyZ0TsCbGUa/8fljwS3uF5m2PBQwDQYJKoZIhvcNAQEL +BQAwEjEQMA4GA1UEAwwHdGVzdC1jYTAgFw0yNjA3MjExODIxNDJaGA8yNTI2MDMy +MjE4MjE0MlowEjEQMA4GA1UEAwwHdGVzdC1jYTCCASIwDQYJKoZIhvcNAQEBBQAD +ggEPADCCAQoCggEBANN1EqTtt4AbMvfzroTtb9i5p+irKqyJUHLGkSHA/pEvGSJn +v2G95aWqMLExx1yD8najcBk/rL7ZSKOo9unqHp0+mXLPXwaBNOfiJIg4vzzBxrhp +rMbP9D+UcBRNau7SS4zJaUo2fxIjhnLXizP/QR+8xPhVPh7euKg/zdzWkXPFe6JI +Ab3Rly4F7XQ9D9PjMkPP4NhiLkTl2yQ7+OMHwDXq+LTusEsW8IPTwdqvzscTRnuD +vfrMWEk1wvU3c0F1uxVOnbrSq6IE7NsdZH9G4dpvHBmz2JGs8SCy90EQa1xxaEsa +HBibLULVF0MQNpGk/n5bBdByHKohYrQyoySMQHkCAwEAAaNTMFEwHQYDVR0OBBYE +FBHTM7QJnIHbvnALhozmlCCl/JU7MB8GA1UdIwQYMBaAFBHTM7QJnIHbvnALhozm +lCCl/JU7MA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAL7DI0D5 +ug+Q3sOnvmPwJv+gVcKrNW69NHJklGr8pUEjxY/SexIz4eh7nhS9nw2wSkcv2m50 +3HQCeOKCEUyt3u9fK6hTEBqj4ifDAKU1cbuM8X0CmLKdmBgfZYZzPzVOVMmbHWef +jPeGJP2v6S+JRIS57Qakz8+FmD1VXLlUywNde4xz71wCX4xx0nanVmiPJHLK3o5l +z6GvxjgISajwT9nRpKp2a+fNvrl/MdqYdGZD5fDS/6IO2BOB6/KLtYsdUAZN8Csd +NYp2pwfRH71LTizRx6FD8jjzhMXScj2dTiH5lmdmaXSQffj3aYediIlaDqfN11EG +YxkIvwGrv+zPSlA= +-----END CERTIFICATE----- diff --git a/pkg/acquisition/modules/appsec/testdata/ca.key b/pkg/acquisition/modules/appsec/testdata/ca.key new file mode 100644 index 00000000000..40277d193fc --- /dev/null +++ b/pkg/acquisition/modules/appsec/testdata/ca.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDTdRKk7beAGzL3 +866E7W/YuafoqyqsiVByxpEhwP6RLxkiZ79hveWlqjCxMcdcg/J2o3AZP6y+2Uij +qPbp6h6dPplyz18GgTTn4iSIOL88wca4aazGz/Q/lHAUTWru0kuMyWlKNn8SI4Zy +14sz/0EfvMT4VT4e3rioP83c1pFzxXuiSAG90ZcuBe10PQ/T4zJDz+DYYi5E5dsk +O/jjB8A16vi07rBLFvCD08Har87HE0Z7g736zFhJNcL1N3NBdbsVTp260quiBOzb +HWR/RuHabxwZs9iRrPEgsvdBEGtccWhLGhwYmy1C1RdDEDaRpP5+WwXQchyqIWK0 +MqMkjEB5AgMBAAECggEADHq7jbPA0WTpimQdf9dSc0ArtmnJpDKbZpas8IjHDVLy +AQuN6isOn0sOwhpduWpJGDLXlgnhvEavCIebgN0SDvYnkLTH1yavdGLuhIKS2LdX +7sC/02Do+YqdXble7vbGwimN1vUl5TBnCiaJ3tj44zJdDonbV2+OBtHzKI4aOfKJ +XmF9IXJ9iVrBt7fPM6AXKj8ksiE4/l05fO4HqBBxj6oUkNqt9yL6m1QKJnB5RCrO +cAufc1zjZDbM+qqn1QHjlaH5YY5VVr/lLsqb/dtGlOlXroWGzWOtglNl3yQbP5pd +tW483LhRU6JuwIIuRBHcAcJo9pXInrJWhMZeASNW7QKBgQD/sspmhqdyYfPT6Tl2 +bj3To9Mpc6O38k/d16oZ9dGUho8ADxuE6yVLMfTj7w67kPkZUa8VqI4vSaqjclpZ +kfQCN8T3OlDaIw7dxc/T/+iJZWCatUE5biYH7To2/R/dlGbDNPxoCb3faEOqtJX1 +06WCcVtuuahpokWDY2QTKl+o7QKBgQDTtOxjaAll65LQlq2PRklVAVzojaubXaQ2 +kyzP4Qr5dRqpRpSEfjZVS1dheJ5luOsxOizajyWSJe+/67ruQVaPraFHWq7M37JN +lfQsxT7pAA6l7/WBFApNMeOqTgjrIFAOSikAjtxf1/g0nV/Xldzt3s3vJyc1vMmb +TLX0d6UAPQKBgQDsyJN3yAAuAxk5RsNosYPdhdrYiva0M9bT14/0xFeVE9o+sr7I +Ir0BWjyuCsV42jJiyOq6wsEQd0ZmX1HdmjP9Dcn/K2iN6GMu6aygZF3hRhjkiy7g +UOk08/Cx1Ut59KAI6vtGGKdUyAfJf7tSzvB40CJccd7MG3IFzrdwrA+zrQKBgBwi +4X/cpdMb2elK/UobZ0ea5MQrf/EoItj1+nCuUg0RWTfCH570PzhayQQ1SafvSaLD +Po7Vk4K29AQnyjI8EMsLonGfRbgIyuOw2EDS/idtUIURPSmohi34QW+y61CEfN9J +T+W5FuTOCTjE6aX3TuN2RxxPsdBchNbU/SG+fPlpAoGBAOFe1M79mJFB3aHSAoos +FjF34rgKBOvUCMzeGg2xw8ZBJHVaFOiBGGhoDNlAhPXmTrzXXZEHvYLvWX8x4Tzm +qtlWWQnAuJYB5tI5NlrlqNDPdPPuJMeYYnMgNReDazfJWAd4gtzNwIcOEDobVpml +zr3pzKzMMF8PsiIOm9/KbWb5 +-----END PRIVATE KEY----- diff --git a/pkg/acquisition/modules/appsec/testdata/ca.srl b/pkg/acquisition/modules/appsec/testdata/ca.srl new file mode 100644 index 00000000000..949020ce07b --- /dev/null +++ b/pkg/acquisition/modules/appsec/testdata/ca.srl @@ -0,0 +1 @@ +1DA74B42EA2A55D319E112DDE173ED48922DE76A diff --git a/pkg/acquisition/modules/appsec/testdata/client.crt b/pkg/acquisition/modules/appsec/testdata/client.crt new file mode 100644 index 00000000000..b53c71c6ff6 --- /dev/null +++ b/pkg/acquisition/modules/appsec/testdata/client.crt @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC+jCCAeKgAwIBAgIUHadLQuoqVdMZ4RLd4XPtSJIt52owDQYJKoZIhvcNAQEL +BQAwEjEQMA4GA1UEAwwHdGVzdC1jYTAgFw0yNjA3MjExODIxNDJaGA8yNTI2MDMy +MjE4MjE0MlowFjEUMBIGA1UEAwwLdGVzdC1jbGllbnQwggEiMA0GCSqGSIb3DQEB +AQUAA4IBDwAwggEKAoIBAQCTvTqc02Zh/UZVJnvH3Foc3HsRkzY03LN9B0fsuMGB +YrQR5p7gDAEerKaSZKbsCr8L/XofXrC9bMauTvlGnj0mxvQW8gG3iAQIHjo29L9e +S70xC7KQg5Ws+DAEzXOFPd4n1uIAQ0ACpkOXgbfx2KE0PTMgZScy8SbV9O1m4ej8 +7qwctgS5MrauDuZT8nS5TJr2bmPWAHknjTzkbWSdf6LfdnI3lGY5kLEIGw00SZI4 +AgkKDdJKplS2y5xTTH2qpZ9ycUUX1AakaavD4jSkkIq6iHLN4RaLiq5JByr9fvMe +2cf+jvKeytB2M+GbUaaInVHZ3kHWW73xDvphUQpqgbq3AgMBAAGjQjBAMB0GA1Ud +DgQWBBSZRZENS7KAjO9uTA37HlfsaKwc0TAfBgNVHSMEGDAWgBQR0zO0CZyB275w +C4aM5pQgpfyVOzANBgkqhkiG9w0BAQsFAAOCAQEAbSM8P3AQOPQyM5segsLH+LZJ +L1loV7tqmwIIPzX4DLkdtvs3titzmae6lc+nePO5iNkdXNG3lXi1YLq4vY+EgInJ +MabNaPlLCuGm5N36VbQKn+p/Iwb7t85KCOrBXxMJjGqW9yzhSrRRxCJWaQ8KBtWf +m/52xRsmTjX/9WOIG76StgaZyk/alOg5zHg2QlEwpt/8uGtwHgTyDUWtL+rUQJWV +h/eBBKgtD1dxP5BTY2G4hkt74WC9/xXBZ2wngKm+8uvaZfW5pr4tc+FodhSDYlmk +h8qiaw/RXh71EHri1G/rVb0/PlfeOW1CFru/X2Kh4UyGbfXBxBg8Fqq30ntsmQ== +-----END CERTIFICATE----- diff --git a/pkg/acquisition/modules/appsec/testdata/client.key b/pkg/acquisition/modules/appsec/testdata/client.key new file mode 100644 index 00000000000..e41aab63c12 --- /dev/null +++ b/pkg/acquisition/modules/appsec/testdata/client.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCTvTqc02Zh/UZV +JnvH3Foc3HsRkzY03LN9B0fsuMGBYrQR5p7gDAEerKaSZKbsCr8L/XofXrC9bMau +TvlGnj0mxvQW8gG3iAQIHjo29L9eS70xC7KQg5Ws+DAEzXOFPd4n1uIAQ0ACpkOX +gbfx2KE0PTMgZScy8SbV9O1m4ej87qwctgS5MrauDuZT8nS5TJr2bmPWAHknjTzk +bWSdf6LfdnI3lGY5kLEIGw00SZI4AgkKDdJKplS2y5xTTH2qpZ9ycUUX1AakaavD +4jSkkIq6iHLN4RaLiq5JByr9fvMe2cf+jvKeytB2M+GbUaaInVHZ3kHWW73xDvph +UQpqgbq3AgMBAAECggEABgXoblKrXA0B1uCHRQTQQwNKxygmb8Lxqa69eW1SLO6z +uFPGdWGNPXgSIGoXE2IgG3fdiIrej2fFtSnbaCF1DRrTrQh3wR479S1vonmZla67 +y1SWlpAEGaBSq4IewWII0mdPIRicyEmJUZNvHDPV5UsmGvN/b3MSahWer3DqrpO9 +Nt1wCoX4EEq3GOgwcCWcEi3YUqHR+jHoUaeZtZDymzRaOnIxG7mg+h2jNlsczBL+ +9beUEeRHHs6BGkPLoLpW2A27I34PFWjrYKxD9Zm0vsqyNMAjUeVI5xyGRPylL22+ +Zb5hSRf4qvAmNGNTaVLRaLXf98/mZzgn+eXT0GSwFQKBgQDHXyjQwseWVP0/rubt +XuAb08SR4cqlbyBroKKzJvkx8Kcduii7rqQ5Cl8r5djWPJ6fWbdKHRezhouvX2JD +3ZcAm5OyktHyTnnLNSmOs9DtUsj6Sqp0/IBtH8XzcJ6KKz/BnfEl0iqZKuyrYQZK +Ve7cYam18ffjjkL/SfAsKtSsWwKBgQC9s7tk/cd7qnwD+N8BgBMEXppxFnts+Vmv +Z4nKwgs1FQs0WPiKPsbHQQxpnnI4gb1pROkVnmi74XJI5I/+soDzuaKMWZ4CkKvB +75uakTzX0f7maq8UNqAUYLz9FiOLGjCQ4NZcD26G9NbXACoBCEL7FHediTgoNSrh +1s1n0Sdp1QKBgQCtaQSMR87n4DaCLLPpZOtS6OgB5z2mlTjCxG6fmteG64W/4orJ +bAalInNTMFFhTkq92YAGM7XIzc8zk6hZ1SQhQDDAUtnPgxiGelASMi8YLThoE4ed +x35A7DD2JE+RaDrFQoZcWif5H4/JJNQe1g2znDLL8ZGmWLfHat0+3WYsHwKBgQCu +pnejziXHTDlrKsidx/06K6MC9NDjjlosrCVnP+kzkNFE+5ivJoa50cCMyOyd64yo +C2KQncwNFc2zIIMV2d/xA/qMPsHD2M/Y+DGJR6f9hv+nwZa5BGWy/TFhzO0iVxVZ +fTa9gROgOnBFd4g0dRe9s6VAq6HBGtoFHE72AtDHlQKBgAMiHi6K9aVpNr2OFhxu +ecfOJg+q5dyaQyNzayielPcKVuL/n1HE2wA9YQQWcdm6iN5+wUeZj5d6LfowU2IV +AjEMGMOGbL7Qj6JRwk5i5IlUsa0mOh6CPlon/9Ot8W1Fz+7kqlThz6oDg2Kr1A7K +cDfIpsyCRJRepf2rzqKYlQeX +-----END PRIVATE KEY----- diff --git a/pkg/acquisition/modules/appsec/testdata/renew-test-certs.sh b/pkg/acquisition/modules/appsec/testdata/renew-test-certs.sh new file mode 100755 index 00000000000..cc7c3bef904 --- /dev/null +++ b/pkg/acquisition/modules/appsec/testdata/renew-test-certs.sh @@ -0,0 +1,33 @@ +#!/bin/sh + +# run this before June 24th, 2525. +# https://www.youtube.com/watch?v=LE1drY3A418 + +openssl req -x509 -newkey rsa:2048 -nodes \ + -keyout ca.key -out ca.crt \ + -days 182500 \ + -subj "/CN=test-ca" + +openssl req -newkey rsa:2048 -nodes \ + -keyout server.key -out server.csr \ + -subj "/CN=test-server" + +echo "subjectAltName=DNS:localhost,IP:127.0.0.1" > ext.cnf + +openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial \ + -out server.crt -days 182500 -sha256 \ + -extfile ext.cnf + +rm server.csr ext.cnf + +openssl req -newkey rsa:2048 -nodes \ + -keyout client.key -out client.csr \ + -subj "/CN=test-client" + +openssl x509 -req -in client.csr -CA ca.crt -CAkey ca.key -CAcreateserial \ + -out client.crt -days 182500 -sha256 + +rm client.csr + +openssl req -x509 -newkey rsa:2048 -keyout selfsined-client.key -out selfsined-client.crt -sha256 \ + -days 182500 -nodes -subj "/CN=test-client" diff --git a/pkg/acquisition/modules/appsec/testdata/selfsined-client.crt b/pkg/acquisition/modules/appsec/testdata/selfsined-client.crt new file mode 100644 index 00000000000..7ee3cc6122b --- /dev/null +++ b/pkg/acquisition/modules/appsec/testdata/selfsined-client.crt @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDDzCCAfegAwIBAgIUSTtQzgXd4mATBFVypg5dL949U78wDQYJKoZIhvcNAQEL +BQAwFjEUMBIGA1UEAwwLdGVzdC1jbGllbnQwIBcNMjYwNzIxMTgyMTQyWhgPMjUy +NjAzMjIxODIxNDJaMBYxFDASBgNVBAMMC3Rlc3QtY2xpZW50MIIBIjANBgkqhkiG +9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxuLGgkvbi38Pxd+C/n8xrNiPkoNPoVb2osBs +UdC4FUl80PNrsqrPVJMo7tLDeHsmUDADVX8T8ovz+tY8Bq1DTZ1dsLN7cOW5pIHn +jd2kmzQXdsC1rzDECmeU5DLfliud+zCjASAWTLyc9VdwFoVZK9jvYsF1rWT+lBiN +12d/0hvhNWSy9nsGmSCa/LpGTEeItX1zJifJ+pQ+x36/c9eP8bZlFOYJxBrGf9mV +3wQGtOuanS/nlxfTt8Z1aFf+2BEW4ZNX7p5e0Uje95qqb27IqXe7bHVeoG5B2JsA +B6wzuDBJOa2Al/fPFkgPbbRhDg6rtxyMQS+Ddf80/otJJUN+PwIDAQABo1MwUTAd +BgNVHQ4EFgQUTMWmzWMinIpaDccp7R6Eys9foqEwHwYDVR0jBBgwFoAUTMWmzWMi +nIpaDccp7R6Eys9foqEwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOC +AQEAeWady9lvtgYpkDvfZdpM/b+/A4Im7pVcL1zD7iqFKp3CwW1APGP3JxbIOQTC +6LVFG0uP8IuIEQSIM30cDS7QEMTs9W80VmFcjDz8EaNy1Fa98NhXxCr6+CjZV1Zh +3y6MGykcIYdZREA0CvX1QlRTgo8IuwCVREraCjiuoZNEEGg5yzYwWVGOKFdQBzRY +6+e26Tr6ptGwnwX2nXX2QR/wgFgI9rdc2MyYTkwDzUZ2zfn8bwpJYgSw3zrsWQNU +U30PjWOIDGIvJqJ/IWOi/iRSw+MrnNgrtCgPVSUvaHutZl8YNwhJMJLimDzcroYf +1TK8C9bCAiu3gdfwqpaymr+RhQ== +-----END CERTIFICATE----- diff --git a/pkg/acquisition/modules/appsec/testdata/selfsined-client.key b/pkg/acquisition/modules/appsec/testdata/selfsined-client.key new file mode 100644 index 00000000000..6e87e46bff1 --- /dev/null +++ b/pkg/acquisition/modules/appsec/testdata/selfsined-client.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDG4saCS9uLfw/F +34L+fzGs2I+Sg0+hVvaiwGxR0LgVSXzQ82uyqs9Ukyju0sN4eyZQMANVfxPyi/P6 +1jwGrUNNnV2ws3tw5bmkgeeN3aSbNBd2wLWvMMQKZ5TkMt+WK537MKMBIBZMvJz1 +V3AWhVkr2O9iwXWtZP6UGI3XZ3/SG+E1ZLL2ewaZIJr8ukZMR4i1fXMmJ8n6lD7H +fr9z14/xtmUU5gnEGsZ/2ZXfBAa065qdL+eXF9O3xnVoV/7YERbhk1funl7RSN73 +mqpvbsipd7tsdV6gbkHYmwAHrDO4MEk5rYCX988WSA9ttGEODqu3HIxBL4N1/zT+ +i0klQ34/AgMBAAECggEAB+xzAi/pgEZAp55/BoqkvQEnvyuSGZhwXQ2TgzLwkpCJ +830vNkAN4I24XMNy3DLz1NAE4fwdHFWtE7pDS/TNMKNrXyXXbikI21/9jK5e53wM +z0NgOamUteFokirgs4frVF2csOfJW6dMDY49Pfh0FAYhi2qvuIfEiLvtsr5B3moB +82ucS1gB61uzQ0xi2zSHP6wyUwld1px7HNc5/Br7P41SUz6qFUb8rNMoB1YWZxbp +5QrYjCEnSMdhAZtCZgEzZFmZ0VYo5SAFuI/vCT+pQ0P1h5EqkjIkNJuCJJpoE1rb +fY/8aHdEKFX5Thg+suVVB46vE2ZWckEarH7zLXPTYQKBgQDn93++Sp48cedRcdXn +aL82LliejLUwgMo4VXa/uQE3fHdI7tFQoBbuWFGuKbaAudqSQoUVsNSHvzzN1FC3 +tPkAaJH92jqbYI3oHjz+r/ckE2qwch+wTQG9YqOMn4/yRoWad8atx/ihbLNZl+G1 +got9ar/Pzj/1PVhvWyYGT0L4LwKBgQDbfd0j1hdMObGgtMrdBFcoDdEANRP/JwGl +DbI5pJWAgb2aLmp7YIDCs1yuTXW/hE0J7V7fufmfg2enSRg9TnhUrag2ASy8jJVt +baV7ADU3EzwgGrhNa5JS+Mn7SdusoemLtq14EzDTsc3PBsrYuw/infcY/zM5DwaS +Gtp1fJVG8QKBgB0XSfr4aq3T7xmkuBnEZi6KU2zW4qZJkJLODQ1wSznFL0SDRtbg +rN+JTf0UmCG+rS2oj/4vZgf8MMjzdogDdzLY6m42nyD7U/CnUijysoDguoGUXmsC +zVQN+crZ+/h7ZagAm3cR3BmKg1eaF6Fm1M2OxK1wBU9hOSUF/lfOOuzbAoGAVW3z +uJMHll+OR2KW4tdhpPFbu5ztH45rEXb3O4BXwCC/T1dpkoPJGf79v8neXqB767U8 +DBAynGdk3LOSf6ofI7ZDlmF2rBx7vI/ErM8z5y/RYx2DRn7sAOdcljX1Dogmgn6j +ney6QGsgE8gtA5YrZKTfHBeYNEko4Y0aIkhPQcECgYEAsSB2neCNRDCTDLwaJnd+ +QGVtr14vsXilmDGBVLZKJg6nCOixU0C1CzQQQXWCePNYfm5IAyFbGeVpnLowvWhM +lM30RKGLDDFHptkkYmKgfqYt4+kcHMbaCdIS3aQdR4qpyR8v4H3rUOFXZMOsLNG0 +lqk6hUG6q4JsHkVkmzpOd/E= +-----END PRIVATE KEY----- diff --git a/pkg/acquisition/modules/appsec/testdata/server.crt b/pkg/acquisition/modules/appsec/testdata/server.crt new file mode 100644 index 00000000000..5e2a9b66fc0 --- /dev/null +++ b/pkg/acquisition/modules/appsec/testdata/server.crt @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDFjCCAf6gAwIBAgIUHadLQuoqVdMZ4RLd4XPtSJIt52kwDQYJKoZIhvcNAQEL +BQAwEjEQMA4GA1UEAwwHdGVzdC1jYTAgFw0yNjA3MjExODIxNDJaGA8yNTI2MDMy +MjE4MjE0MlowFjEUMBIGA1UEAwwLdGVzdC1zZXJ2ZXIwggEiMA0GCSqGSIb3DQEB +AQUAA4IBDwAwggEKAoIBAQCWFmvX816FE3Szykul5yIW+H4gSzzvsn3XUK7ubZ6/ +fD7X10Du5iCzASz3Qzkwv/f2Rn9JccjbHHOiTgSEMRTXL44ck2N1v6Lyax+Ux8d2 +Ho28lkXyNPYpGKMvPBxxVLO85D9rmZsCIu8PM/6avDd++2RpHKiCXAo0DhjGDg93 +tVL7mFBGDRKygzrJsNUFaAFh4Rc6vDthLNLWvBf/NBH0GJJU7y6exHiRf8E2lTKS +Ynk2PG8XzGYmVkENk5i3DHuwFC6LCmxStaEVJXO6aG+JiOsN4s0mqY+rk5i2R2C0 +ULJSamrDYCU57LJiwxAO00XDLJPjQqAXFazqusZUYRzVAgMBAAGjXjBcMBoGA1Ud +EQQTMBGCCWxvY2FsaG9zdIcEfwAAATAdBgNVHQ4EFgQU98/1D8UEmYZNMW2ZuZ7w +pXYogqwwHwYDVR0jBBgwFoAUEdMztAmcgdu+cAuGjOaUIKX8lTswDQYJKoZIhvcN +AQELBQADggEBAM06H3sM/mx9hiifr8X4gF6Hi5GpFTMnaW0+fkMPD/op2amBhHj7 +bQW+Un+HvZtAyYj1O1h0PwwJ8Exu3UpTcbpyJFmR3+JZHO6HWm+VZphrEvfLKW91 +PpGOWE5SkA73/82VZx+Onxzw4b2EUu/sQqt/+OXGJp3oZsSW+2hGY2/xi6saKxnb +SedbQohtJgg5A63otRwLvNOEqLvshqEgt/TDtaKd/jWWOhuxsReKRH9UqFyUh3or +le516T61biNfKQhU1keyn46XL1hq/akD+bWn/zy1LSbJhEI6iO94Px3/orzlY3wo +4YEfRMs5lXgU8QTPWqHOsfl82u6PK3SiTKw= +-----END CERTIFICATE----- diff --git a/pkg/acquisition/modules/appsec/testdata/server.key b/pkg/acquisition/modules/appsec/testdata/server.key new file mode 100644 index 00000000000..080aef67b8a --- /dev/null +++ b/pkg/acquisition/modules/appsec/testdata/server.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCWFmvX816FE3Sz +ykul5yIW+H4gSzzvsn3XUK7ubZ6/fD7X10Du5iCzASz3Qzkwv/f2Rn9JccjbHHOi +TgSEMRTXL44ck2N1v6Lyax+Ux8d2Ho28lkXyNPYpGKMvPBxxVLO85D9rmZsCIu8P +M/6avDd++2RpHKiCXAo0DhjGDg93tVL7mFBGDRKygzrJsNUFaAFh4Rc6vDthLNLW +vBf/NBH0GJJU7y6exHiRf8E2lTKSYnk2PG8XzGYmVkENk5i3DHuwFC6LCmxStaEV +JXO6aG+JiOsN4s0mqY+rk5i2R2C0ULJSamrDYCU57LJiwxAO00XDLJPjQqAXFazq +usZUYRzVAgMBAAECggEAF2GtUdJwcG9gQC0c/V7FZQo3zeyitN3b9Gn1op/RuheP +S71VOJKB2BkwCeI/W9ygMs33QPgYuCfVzNx2ICjsS/y02TdN6Jde+YCeRiWcaYan +gpBvm6TMD4luzKpC7RXqvVvalHb02s+Z6gap3K3DQIVF9okYKFzR2xuyGNKybq3E +BMb+YBKvsrMOabKhvirGWlcreaHGXw81hiTpsRRIETfGvhNfmZxQ1Kr2Dk7CaHvg +rW4O46FSwJaxi2Dv3TEiilbPNeSu+v/Un36dsKqWDCEVF3Uwp4pdtE1YYe5JlyVd +RVPg5vh4i68hlIfX2ShxpPPLJkvbl8q1i8ROpRUMCQKBgQDI5WAjqPfvkCCnS+4i +j9x51w8RBwp7GvuUJSowDk+UoUsoabrjidZDpenWxAzkib2BqWx2fo3cyHLf9TXK +pYdfcdSlSJpuZBQUTN6kAUbBiRe65BlkOdF7P6YgnCQ9sxr0buF0DkhQGe2OdH0E +wNatpWeWT2k7+ECNqJMROcZsDQKBgQC/QVpQp+m7xo0ZVIzYg5x0Nqo8fgUo7mZW +T5HMG+Uugmc2e6cw2TGR1sKy4f3HF2/szermHt1tevaDg4iRp87Fqbz8nS1KsrcM +Qcxh9E/d9ojddJT4jMjnYMmG8GQT+xL9vct3h3rzLbuYwmO/V7ux5rvEWZh9WPPx +NEfBGsmZ6QKBgAdpfxyRtWQfWzUQ9h5MVIQiTSoBqn9URYf3vxC61nDTaqR5Ei4m +/cLNMk18OkWMV3ObPqc4kB9fPe3JbEynwtDgsEnQ3fHIu3zsQSKn8WZemoOIuu8Z +uwLjHEwDtsqX+xydoq/Xfw+FhWBGJ/6u5rzNZ38COw29YRRY7eQqz4lZAoGAW2dH +W460NQqyOm3fFkboCd5qQ5jSrHorLIrAmjSmtjCaVT6Ja94RQ6rIyCcbWwAHfLv4 +zFvp5T3D/JxrM3loZ600ZeJUWAPLWa9El3fkh6cgR/5Eh/j4tyPZjITsv2PZ8qy3 +RfvYtcmgg2Q7uaGbUW19RVywdQ+DHj6nIFHGEakCgYA7hnFbHiGv4B9QXlGpacxr +7x8Wa7A9XukCflPQcxTj9jk/bQwvvMfTs/wdrZDj3RlJ3lw9462lPhZQS3t6y4O1 +rwO0/i2EIlFPlK3UwbUvW0i00lZm+b7auxeftZOUrIkz20Ez0mdTRWql0JX6RYjX +QJEzJFAcwKb4fnXVSkp0GA== +-----END PRIVATE KEY-----