go-tunnel/cmd/server/main.go

103 lines
2.6 KiB
Go
Raw Normal View History

2020-10-21 18:00:15 +02:00
package main
import (
"context"
2020-10-26 19:42:07 +01:00
"flag"
2020-10-21 18:00:15 +02:00
"net/http"
"strings"
"cdr.dev/slog"
"forge.cadoles.com/wpetit/go-tunnel"
"github.com/pkg/errors"
"gitlab.com/wpetit/goweb/logger"
)
const salt = "go-tunnel"
var registry = NewRegistry()
func main() {
2020-10-26 19:42:07 +01:00
var (
serverAddr = ":36543"
httpAddr = ":3003"
sharedKey = "go-tunnel"
targetURL = "https://arcad.games"
)
flag.StringVar(&serverAddr, "server-addr", serverAddr, "server address")
flag.StringVar(&targetURL, "target-url", targetURL, "target url")
flag.StringVar(&httpAddr, "http-addr", httpAddr, "http server address")
flag.StringVar(&sharedKey, "shared-key", sharedKey, "shared key")
flag.Parse()
2020-10-21 18:00:15 +02:00
ctx := context.Background()
logger.SetLevel(slog.LevelDebug)
server := tunnel.NewServer(
2020-10-26 19:42:07 +01:00
tunnel.WithServerAddress(serverAddr),
2020-10-21 18:00:15 +02:00
tunnel.WithServerOnClientAuth(registry.OnClientAuth),
tunnel.WithServerOnClientDisconnect(registry.OnClientDisconnect),
2020-10-26 19:42:07 +01:00
tunnel.WithServerOnClientAuth(func(ctx context.Context, remoteClient *tunnel.RemoteClient, credentials interface{}) (bool, error) {
remoteAddr := remoteClient.RemoteAddr().String()
ctx = logger.With(ctx, logger.F("remoteAddr", remoteAddr))
logger.Debug(ctx, "new client auth")
clientID, ok := credentials.(string)
if !ok {
logger.Debug(ctx, "client auth failed")
return false, nil
}
registry.Add(clientID, remoteAddr, remoteClient)
logger.Debug(ctx, "client auth success")
return true, nil
}),
tunnel.WithServerOnClientDisconnect(func(ctx context.Context, remoteClient *tunnel.RemoteClient) error {
remoteAddr := remoteClient.RemoteAddr().String()
ctx = logger.With(ctx, logger.F("remoteAddr", remoteAddr))
logger.Debug(ctx, "client disconnected")
registry.RemoveByRemoteAddr(remoteAddr)
return nil
}),
2020-10-21 18:00:15 +02:00
)
go func() {
if err := server.Listen(ctx); err != nil {
logger.Fatal(ctx, "error while listening", logger.E(err))
}
}()
2020-10-26 19:42:07 +01:00
handler, err := createProxyHandler(targetURL)
if err != nil {
logger.Fatal(ctx, "could not create proxy handler", logger.E(errors.WithStack(err)))
2020-10-21 18:00:15 +02:00
}
2020-10-26 19:42:07 +01:00
if err := http.ListenAndServe(httpAddr, handler); err != nil {
logger.Fatal(ctx, "error while listening", logger.E(err))
2020-10-21 18:00:15 +02:00
}
2020-10-26 19:42:07 +01:00
}
2020-10-21 18:00:15 +02:00
2020-10-26 19:42:07 +01:00
func createProxyHandler(targetURL string) (http.Handler, error) {
return tunnel.ProxyHandler(targetURL, func(w http.ResponseWriter, r *http.Request) (*tunnel.RemoteClient, error) {
subdomains := strings.SplitN(r.Host, ".", 2)
2020-10-21 18:00:15 +02:00
2020-10-26 19:42:07 +01:00
if len(subdomains) < 2 {
http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
2020-10-21 18:00:15 +02:00
2020-10-26 19:42:07 +01:00
return nil, tunnel.ErrAbortProxy
}
2020-10-21 18:00:15 +02:00
2020-10-26 19:42:07 +01:00
clientID := subdomains[0]
2020-10-21 18:00:15 +02:00
2020-10-26 19:42:07 +01:00
return registry.Get(clientID), nil
})
2020-10-21 18:00:15 +02:00
}