This commit is contained in:
Jonathan Leibiusky @xetorthio
2017-06-19 11:03:31 -03:00
parent 1ee90c43d1
commit cd6d172cfa
6 changed files with 173 additions and 33 deletions

32
api.go
View File

@@ -1,7 +1,6 @@
package main package main
import ( import (
"fmt"
"log" "log"
"net/http" "net/http"
"os" "os"
@@ -9,7 +8,6 @@ import (
gh "github.com/gorilla/handlers" gh "github.com/gorilla/handlers"
"github.com/gorilla/mux" "github.com/gorilla/mux"
"github.com/miekg/dns"
"github.com/play-with-docker/play-with-docker/config" "github.com/play-with-docker/play-with-docker/config"
"github.com/play-with-docker/play-with-docker/handlers" "github.com/play-with-docker/play-with-docker/handlers"
"github.com/play-with-docker/play-with-docker/templates" "github.com/play-with-docker/play-with-docker/templates"
@@ -18,29 +16,11 @@ import (
) )
func main() { func main() {
config.ParseFlags() config.ParseFlags()
handlers.Bootstrap() handlers.Bootstrap()
bypassCaptcha := len(os.Getenv("GOOGLE_RECAPTCHA_DISABLED")) > 0 bypassCaptcha := len(os.Getenv("GOOGLE_RECAPTCHA_DISABLED")) > 0
// Start the DNS server
dns.HandleFunc(".", handlers.DnsRequest)
udpDnsServer := &dns.Server{Addr: ":53", Net: "udp"}
go func() {
err := udpDnsServer.ListenAndServe()
if err != nil {
log.Fatal(err)
}
}()
tcpDnsServer := &dns.Server{Addr: ":53", Net: "tcp"}
go func() {
err := tcpDnsServer.ListenAndServe()
if err != nil {
log.Fatal(err)
}
}()
server := handlers.Broadcast.GetHandler() server := handlers.Broadcast.GetHandler()
r := mux.NewRouter() r := mux.NewRouter()
@@ -55,10 +35,6 @@ func main() {
corsHandler := gh.CORS(gh.AllowCredentials(), gh.AllowedHeaders([]string{"x-requested-with", "content-type"}), gh.AllowedOrigins([]string{"*"})) corsHandler := gh.CORS(gh.AllowCredentials(), gh.AllowedHeaders([]string{"x-requested-with", "content-type"}), gh.AllowedOrigins([]string{"*"}))
// Specific routes // Specific routes
r.Host(fmt.Sprintf("{subdomain:.*}pwd{node:%s}-{port:%s}.{tld:.*}", config.PWDHostnameRegex, config.PortRegex)).Handler(tcpHandler)
r.Host(fmt.Sprintf("{subdomain:.*}pwd{node:%s}.{tld:.*}", config.PWDHostnameRegex)).Handler(tcpHandler)
r.Host(fmt.Sprintf("pwd{alias:%s}-{session:%s}-{port:%s}.{tld:.*}", config.AliasnameRegex, config.AliasSessionRegex, config.PortRegex)).Handler(tcpHandler)
r.Host(fmt.Sprintf("pwd{alias:%s}-{session:%s}.{tld:.*}", config.AliasnameRegex, config.AliasSessionRegex)).Handler(tcpHandler)
r.HandleFunc("/ping", handlers.Ping).Methods("GET") r.HandleFunc("/ping", handlers.Ping).Methods("GET")
corsRouter.HandleFunc("/instances/images", handlers.GetInstanceImages).Methods("GET") corsRouter.HandleFunc("/instances/images", handlers.GetInstanceImages).Methods("GET")
corsRouter.HandleFunc("/sessions/{sessionId}", handlers.GetSession).Methods("GET") corsRouter.HandleFunc("/sessions/{sessionId}", handlers.GetSession).Methods("GET")
@@ -106,13 +82,11 @@ func main() {
ReadHeaderTimeout: 5 * time.Second, ReadHeaderTimeout: 5 * time.Second,
} }
go func() {
log.Println("Listening on port " + config.PortNumber)
log.Fatal(httpServer.ListenAndServe())
}()
go handlers.ListenSSHProxy("0.0.0.0:1022") go handlers.ListenSSHProxy("0.0.0.0:1022")
// Now listen for TLS connections that need to be proxied // Now listen for TLS connections that need to be proxied
handlers.StartTLSProxy(config.SSLPortNumber) handlers.StartTLSProxy(config.SSLPortNumber)
log.Println("Listening on port " + config.PortNumber)
log.Fatal(httpServer.ListenAndServe())
} }

View File

@@ -1,4 +1,4 @@
package handlers package dns
import ( import (
"fmt" "fmt"

117
router/router.go Normal file
View File

@@ -0,0 +1,117 @@
package router
import (
"fmt"
"io"
"log"
"net"
vhost "github.com/inconshreveable/go-vhost"
)
type Director func(host string) (*net.TCPAddr, error)
type proxyRouter struct {
director Director
}
func (r *proxyRouter) Listen(laddr string) {
l, err := net.Listen("tcp", laddr)
defer l.Close()
if err != nil {
log.Fatal(err)
}
for {
conn, err := l.Accept()
if err != nil {
log.Println(err)
continue
}
go r.handleConnection(conn)
}
}
func (r *proxyRouter) handleConnection(c net.Conn) {
defer c.Close()
// first try tls
vhostConn, err := vhost.TLS(c)
if err != nil {
log.Printf("Incoming TLS connection produced an error. Error: %s", err)
return
}
defer vhostConn.Close()
host := vhostConn.ClientHelloMsg.ServerName
c.LocalAddr()
dstHost, err := r.director(fmt.Sprintf("%s:%d", host, 12))
if err != nil {
log.Printf("Error directing request: %v\n", err)
return
}
d, err := net.Dial("tcp", dstHost.String())
if err != nil {
log.Printf("Error dialing backend %s: %v\n", dstHost.String(), err)
return
}
errc := make(chan error, 2)
cp := func(dst io.Writer, src io.Reader) {
_, err := io.Copy(dst, src)
errc <- err
}
go cp(d, vhostConn)
go cp(vhostConn, d)
<-errc
/*
req, err := http.ReadRequest(bufio.NewReader(c))
if err != nil {
log.Println(err)
return
}
log.Println(req.Header)
*/
}
func NewRouter(director Director) *proxyRouter {
return &proxyRouter{director: director}
}
/*
// Start the DNS server
dns.HandleFunc(".", routerDns.DnsRequest)
udpDnsServer := &dns.Server{Addr: ":53", Net: "udp"}
go func() {
err := udpDnsServer.ListenAndServe()
if err != nil {
log.Fatal(err)
}
}()
tcpDnsServer := &dns.Server{Addr: ":53", Net: "tcp"}
go func() {
err := tcpDnsServer.ListenAndServe()
if err != nil {
log.Fatal(err)
}
}()
r := mux.NewRouter()
tcpHandler := handlers.NewTCPProxy()
r.Host(fmt.Sprintf("{subdomain:.*}pwd{node:%s}-{port:%s}.{tld:.*}", config.PWDHostnameRegex, config.PortRegex)).Handler(tcpHandler)
r.Host(fmt.Sprintf("{subdomain:.*}pwd{node:%s}.{tld:.*}", config.PWDHostnameRegex)).Handler(tcpHandler)
r.Host(fmt.Sprintf("pwd{alias:%s}-{session:%s}-{port:%s}.{tld:.*}", config.AliasnameRegex, config.AliasSessionRegex, config.PortRegex)).Handler(tcpHandler)
r.Host(fmt.Sprintf("pwd{alias:%s}-{session:%s}.{tld:.*}", config.AliasnameRegex, config.AliasSessionRegex)).Handler(tcpHandler)
r.HandleFunc("/ping", handlers.Ping).Methods("GET")
n := negroni.Classic()
n.UseHandler(r)
httpServer := http.Server{
Addr: "0.0.0.0:" + config.PortNumber,
Handler: n,
IdleTimeout: 30 * time.Second,
ReadHeaderTimeout: 5 * time.Second,
}
// Now listen for TLS connections that need to be proxied
tls.StartTLSProxy(config.SSLPortNumber)
http.ListenAndServe()
*/

49
router/router_test.go Normal file
View File

@@ -0,0 +1,49 @@
package router
import (
"crypto/tls"
"fmt"
"io/ioutil"
"net"
"net/http"
"net/http/httptest"
"net/url"
"testing"
"github.com/stretchr/testify/assert"
)
func TestProxy_TLS(t *testing.T) {
tr := &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
}
client := &http.Client{Transport: tr}
const msg = "It works!"
var receivedHost string
ts := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
fmt.Fprint(w, msg)
}))
defer ts.Close()
r := NewRouter(func(host string) (*net.TCPAddr, error) {
receivedHost = host
u, _ := url.Parse(ts.URL)
a, _ := net.ResolveTCPAddr("tcp", u.Host)
return a, nil
})
go r.Listen(":8080")
req, err := http.NewRequest("GET", "https://localhost:8080", nil)
assert.Nil(t, err)
resp, err := client.Do(req)
assert.Nil(t, err)
body, err := ioutil.ReadAll(resp.Body)
assert.Nil(t, err)
assert.Equal(t, msg, string(body))
assert.Equal(t, "localhost:8080", receivedHost)
}

View File

@@ -1,4 +1,4 @@
package handlers package tcp
import ( import (
"crypto/tls" "crypto/tls"
@@ -9,8 +9,8 @@ import (
"net/http" "net/http"
"strings" "strings"
"github.com/franela/pwd.old/config"
"github.com/gorilla/mux" "github.com/gorilla/mux"
"github.com/play-with-docker/play-with-docker/config"
) )
func getTargetInfo(vars map[string]string, req *http.Request) (string, string) { func getTargetInfo(vars map[string]string, req *http.Request) (string, string) {

View File

@@ -1,4 +1,4 @@
package handlers package tls
import ( import (
"fmt" "fmt"