Time not wasted: add bypass for non-proxied

master
Bel LaPointe 2018-10-12 11:02:51 -06:00
parent bb51e2ccb0
commit 6ee99fbc5c
1 changed files with 48 additions and 4 deletions

52
main.go
View File

@ -8,19 +8,22 @@ import (
"io" "io"
"io/ioutil" "io/ioutil"
"local1/logger" "local1/logger"
"net"
"net/http" "net/http"
"net/http/httputil" "net/http/httputil"
"net/url" "net/url"
"os" "os"
"strings" "strings"
"time"
) )
type Server struct { type Server struct {
transport *http.Transport transport *http.Transport
whitelist []string whitelist []string
bypass []string
} }
func NewServer(addr, clientcrt, clientkey, servercrt string, whitelist []string) (*Server, error) { func NewServer(addr, clientcrt, clientkey, servercrt string, whitelist []string, bypass []string) (*Server, error) {
caCert, err := ioutil.ReadFile(servercrt) caCert, err := ioutil.ReadFile(servercrt)
if err != nil { if err != nil {
return nil, err return nil, err
@ -36,7 +39,7 @@ func NewServer(addr, clientcrt, clientkey, servercrt string, whitelist []string)
} }
return &Server{ return &Server{
transport: &http.Transport{ transport: &http.Transport{
Proxy: func(*http.Request) (*url.URL, error) { Proxy: func(r *http.Request) (*url.URL, error) {
return url.Parse(addr) return url.Parse(addr)
}, },
TLSClientConfig: &tls.Config{ TLSClientConfig: &tls.Config{
@ -45,6 +48,7 @@ func NewServer(addr, clientcrt, clientkey, servercrt string, whitelist []string)
}, },
}, },
whitelist: whitelist, whitelist: whitelist,
bypass: bypass,
}, nil }, nil
} }
@ -60,11 +64,48 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
denyAccess(w) denyAccess(w)
return return
} }
// proxy via stuncaddsies if toWhitelist(s.bypass, r.URL.Host) {
logger.Log("Bypassing", r.URL.String())
s.passthrough(w, r)
return
}
logger.Log("Proxying", r.URL.String()) logger.Log("Proxying", r.URL.String())
// proxy via stuncaddsies
s.handleHTTP(w, r) s.handleHTTP(w, r)
} }
func (s *Server) passthrough(w http.ResponseWriter, r *http.Request) {
if r.URL.Scheme == "http" {
proxy := httputil.NewSingleHostReverseProxy(pathlessURL(r.URL))
proxy.ServeHTTP(w, r)
return
}
dest_conn, err := net.DialTimeout("tcp", r.Host, 10*time.Second)
if err != nil {
http.Error(w, err.Error(), http.StatusServiceUnavailable)
return
}
w.WriteHeader(http.StatusOK)
hijacker, ok := w.(http.Hijacker)
if !ok {
http.Error(w, "Hijacking not supported", http.StatusInternalServerError)
return
}
client_conn, _, err := hijacker.Hijack()
if err != nil {
http.Error(w, err.Error(), http.StatusServiceUnavailable)
}
transfer := func(destination io.WriteCloser, source io.ReadCloser) {
defer destination.Close()
defer source.Close()
io.Copy(destination, source)
}
go transfer(dest_conn, client_conn)
go transfer(client_conn, dest_conn)
}
func (s *Server) handleHTTP(w http.ResponseWriter, r *http.Request) { func (s *Server) handleHTTP(w http.ResponseWriter, r *http.Request) {
proxy := httputil.NewSingleHostReverseProxy(pathlessURL(r.URL)) proxy := httputil.NewSingleHostReverseProxy(pathlessURL(r.URL))
proxy.Transport = s.transport proxy.Transport = s.transport
@ -154,12 +195,15 @@ func main() {
"servercrt": "/Volumes/bldisk/server.crt", "servercrt": "/Volumes/bldisk/server.crt",
"port": "8888", "port": "8888",
"whitelist": "192.168.0.86,,bel.house,,minio.gcp.blapointe.com", "whitelist": "192.168.0.86,,bel.house,,minio.gcp.blapointe.com",
"bypass": "plex.tv",
}) })
if !strings.HasPrefix(conf["port"], ":") { if !strings.HasPrefix(conf["port"], ":") {
conf["port"] = ":" + conf["port"] conf["port"] = ":" + conf["port"]
} }
whitelist := strings.Split(conf["whitelist"], ",,")
bypass := strings.Split(conf["bypass"], ",,")
logger.Log(conf) logger.Log(conf)
server, err := NewServer(conf["stunaddr"], conf["clientcrt"], conf["clientkey"], conf["servercrt"], strings.Split(conf["whitelist"], ",,")) server, err := NewServer(conf["stunaddr"], conf["clientcrt"], conf["clientkey"], conf["servercrt"], append(whitelist, bypass...), bypass)
if err != nil { if err != nil {
logger.Fatal(err) logger.Fatal(err)
} }