From c56d8df5e3e4b9fa4b257ee52878388da642e6fc Mon Sep 17 00:00:00 2001 From: Jason Simmons Date: Thu, 16 Apr 2020 11:23:15 -0400 Subject: [PATCH 1/2] Adds HTTPS logic to agnhost netexec The agnhost image used for testing has a `netexec` path which supports two new flags, `--tls-cert-file` and `--tls-private-key-file`. If the former is provided, the HTTP server will be upgraded to HTTPS, using the certificate (and private key) provided. By default, there are keys already mounted into the container at `/localhost.crt` and `/localhost.key`, which contain PEM-encoded TLS certs with IP SANs for `127.0.0.1` and `[::1]`. --- test/images/agnhost/netexec/netexec.go | 28 ++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/test/images/agnhost/netexec/netexec.go b/test/images/agnhost/netexec/netexec.go index e37847569f7..d36764fd4ff 100644 --- a/test/images/agnhost/netexec/netexec.go +++ b/test/images/agnhost/netexec/netexec.go @@ -44,13 +44,15 @@ var ( sctpPort = -1 shellPath = "/bin/sh" serverReady = &atomicBool{0} + certFile = "" + privKeyFile = "" ) // CmdNetexec is used by agnhost Cobra. var CmdNetexec = &cobra.Command{ Use: "netexec", - Short: "Creates HTTP, UDP, and (optionally) SCTP servers with various endpoints", - Long: `Starts a HTTP server on given port with the following endpoints: + Short: "Creates HTTP(S), UDP, and (optionally) SCTP servers with various endpoints", + Long: `Starts a HTTP(S) server on given port with the following endpoints: - /: Returns the request's timestamp. - /clientip: Returns the request's IP address. @@ -97,6 +99,10 @@ responding to the same commands as the UDP server. func init() { CmdNetexec.Flags().IntVar(&httpPort, "http-port", 8080, "HTTP Listen Port") + CmdNetexec.Flags().StringVar(&certFile, "tls-cert-file", "", + "File containing an x509 certificate for HTTPS. (CA cert, if any, concatenated after server cert)") + CmdNetexec.Flags().StringVar(&privKeyFile, "tls-private-key-file", "", + "File containing an x509 private key matching --tls-cert-file") CmdNetexec.Flags().IntVar(&udpPort, "udp-port", 8081, "UDP Listen Port") CmdNetexec.Flags().IntVar(&sctpPort, "sctp-port", -1, "SCTP Listen Port") } @@ -125,10 +131,17 @@ func main(cmd *cobra.Command, args []string) { if sctpPort != -1 { go startSCTPServer(sctpPort) } - startHTTPServer(httpPort) + + addRoutes() + if len(certFile) > 0 { + // only start HTTPS server if a cert is provided + startHTTPSServer(httpPort, certFile, privKeyFile) + } else { + startHTTPServer(httpPort) + } } -func startHTTPServer(httpPort int) { +func addRoutes() { http.HandleFunc("/", rootHandler) http.HandleFunc("/clientip", clientIPHandler) http.HandleFunc("/echo", echoHandler) @@ -141,6 +154,13 @@ func startHTTPServer(httpPort int) { // older handlers http.HandleFunc("/hostName", hostNameHandler) http.HandleFunc("/shutdown", shutdownHandler) +} + +func startHTTPSServer(httpsPort int, certFile, privKeyFile string) { + log.Fatal(http.ListenAndServeTLS(fmt.Sprintf(":%d", httpPort), certFile, privKeyFile, nil)) +} + +func startHTTPServer(httpPort int) { log.Fatal(http.ListenAndServe(fmt.Sprintf(":%d", httpPort), nil)) } From d0f19815d2d3ea53474921952d683092795935e7 Mon Sep 17 00:00:00 2001 From: Jason Simmons Date: Tue, 21 Apr 2020 09:43:58 -0400 Subject: [PATCH 2/2] Updates agnhost image VERSION and README --- test/images/agnhost/README.md | 8 ++++++-- test/images/agnhost/VERSION | 2 +- test/images/agnhost/agnhost.go | 2 +- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/test/images/agnhost/README.md b/test/images/agnhost/README.md index bc630551f71..9224f80614a 100644 --- a/test/images/agnhost/README.md +++ b/test/images/agnhost/README.md @@ -375,7 +375,7 @@ HTTP server: ### netexec -Starts a HTTP server on given port with the following endpoints: +Starts a HTTP(S) server on given port with the following endpoints: - `/`: Returns the request's timestamp. - `/clientip`: Returns the request's IP address. @@ -407,6 +407,10 @@ Starts a HTTP server on given port with the following endpoints: Returns a JSON with the fields `output` (containing the file's name on the server) and `error` containing any potential server side errors. +If `--tls-cert-file` is added (ideally in conjunction with `--tls-private-key-file`, the HTTP server +will be upgraded to HTTPS. The image has default, `localhost`-based cert/privkey files at +`/localhost.crt` and `/localhost.key` (see: [`porter` subcommand](#porter)) + It will also start a UDP server on the indicated UDP port that responds to the following commands: - `hostname`: Returns the server's hostname @@ -419,7 +423,7 @@ responding to the same commands as the UDP server. Usage: ```console - kubectl exec test-agnhost -- /agnhost netexec [--http-port ] [--udp-port ] [--sctp-port ] + kubectl exec test-agnhost -- /agnhost netexec [--http-port ] [--udp-port ] [--sctp-port ] [--tls-cert-file ] [--tls-private-key-file ] ``` ### nettest diff --git a/test/images/agnhost/VERSION b/test/images/agnhost/VERSION index 123a39a8e91..e3d0696453e 100644 --- a/test/images/agnhost/VERSION +++ b/test/images/agnhost/VERSION @@ -1 +1 @@ -2.14 +2.15 diff --git a/test/images/agnhost/agnhost.go b/test/images/agnhost/agnhost.go index ade9f23c1e8..1bdedeb6382 100644 --- a/test/images/agnhost/agnhost.go +++ b/test/images/agnhost/agnhost.go @@ -49,7 +49,7 @@ import ( ) func main() { - rootCmd := &cobra.Command{Use: "app", Version: "2.14"} + rootCmd := &cobra.Command{Use: "app", Version: "2.15"} rootCmd.AddCommand(auditproxy.CmdAuditProxy) rootCmd.AddCommand(connect.CmdConnect)