package main import ( "crypto/tls" "crypto/x509" "flag" "fmt" "io/ioutil" "local1/logger" "net/http" "net/http/httputil" "net/url" "os" "strings" ) type Server struct { transport *http.Transport } func NewServer(addr, clientcrt, clientkey, servercrt string) (*Server, error) { caCert, err := ioutil.ReadFile(servercrt) if err != nil { return nil, err } rootCAs := x509.NewCertPool() rootCAs.AppendCertsFromPEM(caCert) clientCert, err := tls.LoadX509KeyPair(clientcrt, clientkey) if err != nil { return nil, err } return &Server{ transport: &http.Transport{ Proxy: func(*http.Request) (*url.URL, error) { return url.Parse(addr) }, TLSClientConfig: &tls.Config{ RootCAs: rootCAs, Certificates: []tls.Certificate{clientCert}, }, }, }, nil } func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) { // fix scheme if necessary fixScheme(r.URL) // if not from localhost if !fromLocalhost(r.RemoteAddr) { denyAccess(w) return } // proxy via stuncaddsies //logger.Log("Proxying", r.URL.String()) proxy := httputil.NewSingleHostReverseProxy(pathlessURL(r.URL)) proxy.Transport = s.transport proxy.ServeHTTP(w, r) return } func fixScheme(u *url.URL) { if u.Scheme == "" { u.Scheme = "http" if strings.Contains(u.Host, "443") { u.Scheme = "https" } } } func fromLocalhost(addr string) bool { return strings.Contains(addr, "[::1]") || addr == "127.0.0.1" || addr == "::1" } func denyAccess(w http.ResponseWriter) { w.WriteHeader(http.StatusUnauthorized) fmt.Fprintln(w, "You shouldn't be here") } func pathlessURL(u *url.URL) *url.URL { return &url.URL{ Scheme: u.Scheme, Opaque: u.Opaque, User: u.User, Host: u.Host, Path: "", RawPath: "", ForceQuery: u.ForceQuery, RawQuery: u.RawQuery, Fragment: u.Fragment, } } func flagEnvFallback(keyFallback map[string]string) map[string]string { results := map[string]*string{} for k, v := range keyFallback { results[k] = flag.String(k, v, "") } flag.Parse() final := map[string]string{} for k := range results { if *results[k] == keyFallback[k] && os.Getenv(strings.ToUpper(k)) != "" { *results[k] = os.Getenv(strings.ToUpper(k)) } final[k] = *results[k] } return final } func main() { conf := flagEnvFallback(map[string]string{ "stunaddr": "https://localhost:20018", "clientcrt": "../../stuncaddsies/mnt/stunclient.crt", "clientkey": "../../stuncaddsies/mnt/stunclient.key", "servercrt": "../../stuncaddsies/mnt/stunserver.crt", "port": "8888", }) if !strings.HasPrefix(conf["port"], ":") { conf["port"] = ":" + conf["port"] } logger.Log(conf) server, err := NewServer(conf["stunaddr"], conf["clientcrt"], conf["clientkey"], conf["servercrt"]) if err != nil { logger.Fatal(err) } logger.Fatal(http.ListenAndServe(conf["port"], server)) }