From 2c32f3c8c3e452288a0461d889a956651ae568e0 Mon Sep 17 00:00:00 2001 From: Suyash Kumar Date: Sat, 2 Feb 2019 18:35:52 -0500 Subject: [PATCH] Implement Optional HTTP Redirection, colored terminal log (#12) This change implements optional HTTP redirection to the TLS/HTTPS fromURL where ssl-proxy is serving TLS traffic. This makes it easy to redirect any traffic coming in at http://mysite:80 to https://mysite where ssl-proxy is serving TLS certificates. This closes #11. This feature always redirects HTTP traffic from port 80. --- main.go | 42 +++++++++++++++++++++++++++++++++--------- 1 file changed, 33 insertions(+), 9 deletions(-) diff --git a/main.go b/main.go index d8020bf..bd127bd 100644 --- a/main.go +++ b/main.go @@ -2,6 +2,7 @@ package main import ( "flag" + "fmt" "log" "net/http" "net/url" @@ -16,11 +17,12 @@ import ( ) var ( - to = flag.String("to", "http://127.0.0.1:80", "the address and port for which to proxy requests to") - fromURL = flag.String("from", "127.0.0.1:4430", "the tcp address and port this proxy should listen for requests on") - certFile = flag.String("cert", "", "path to a tls certificate file. If not provided, ssl-proxy will generate one for you in ~/.ssl-proxy/") - keyFile = flag.String("key", "", "path to a private key file. If not provided, ssl-proxy will generate one for you in ~/.ssl-proxy/") - domain = flag.String("domain", "", "domain to mint letsencrypt certificates for. Usage of this parameter implies acceptance of the LetsEncrypt terms of service.") + to = flag.String("to", "http://127.0.0.1:80", "the address and port for which to proxy requests to") + fromURL = flag.String("from", "127.0.0.1:4430", "the tcp address and port this proxy should listen for requests on") + certFile = flag.String("cert", "", "path to a tls certificate file. If not provided, ssl-proxy will generate one for you in ~/.ssl-proxy/") + keyFile = flag.String("key", "", "path to a private key file. If not provided, ssl-proxy will generate one for you in ~/.ssl-proxy/") + domain = flag.String("domain", "", "domain to mint letsencrypt certificates for. Usage of this parameter implies acceptance of the LetsEncrypt terms of service.") + redirectHTTP = flag.Bool("redirectHTTP", false, "if true, redirects http requests from port 80 to https at your fromURL") ) const ( @@ -84,9 +86,24 @@ func main() { mux := http.NewServeMux() mux.Handle("/", p) - log.Printf("Proxying calls from https://%s (SSL/TLS) to %s", *fromURL, toURL) + log.Printf(green("Proxying calls from https://%s (SSL/TLS) to %s"), *fromURL, toURL) - // Determine if we should serve with autogenerated LetsEncrypt certificates or not + // Redirect http requests on port 80 to TLS port using https + if *redirectHTTP { + redirectTLS := func(w http.ResponseWriter, r *http.Request) { + http.Redirect(w, r, "https://"+*fromURL+r.RequestURI, http.StatusMovedPermanently) + } + go func() { + log.Println(fmt.Sprintf("Also redirecting https requests on port 80 to https requests on %s", *fromURL)) + err := http.ListenAndServe(":80", http.HandlerFunc(redirectTLS)) + if err != nil { + log.Println("HTTP redirection server failure") + log.Println(err) + } + }() + } + + // Determine if we should serve over TLS with autogenerated LetsEncrypt certificates or not if validDomain { // Domain is present, use autocert // TODO: validate domain (though, autocert may do this) @@ -106,9 +123,16 @@ func main() { } s.Handler = mux log.Fatal(s.ListenAndServeTLS("", "")) + } else { + // Domain is not provided, serve TLS using provided/generated certificate files + log.Fatal(http.ListenAndServeTLS(*fromURL, *certFile, *keyFile, mux)) } - // Domain is not provided, serve using provided/generated certificate files - log.Fatal(http.ListenAndServeTLS(*fromURL, *certFile, *keyFile, mux)) +} +// green takes an input string and returns it with the proper ANSI escape codes to render it green-colored +// in a supported terminal. +// TODO: if more colors used in the future, generalize or pull in an external pkg +func green(in string) string { + return fmt.Sprintf("\033[0;32m%s\033[0;0m", in) }