From 85a5004cc7510c1fc1a00b6a4e4a76016a4bf69f Mon Sep 17 00:00:00 2001 From: Anders Pitman Date: Tue, 20 Oct 2020 19:14:04 -0600 Subject: [PATCH] Implement raw TCP tunnels Just needed to add an option to allow external connections to the ports from the server, then set the proper values in the authorized_keys file and on the client. --- api.go | 13 ++++++++----- client.go | 6 +++++- database.go | 1 + tunnel_manager.go | 14 ++++++++++---- webui/index.tmpl | 6 +++++- 5 files changed, 29 insertions(+), 11 deletions(-) diff --git a/api.go b/api.go index e6c79f5..dec7648 100644 --- a/api.go +++ b/api.go @@ -77,12 +77,15 @@ func (a *Api) CreateTunnel(tokenData TokenData, params url.Values) (*Tunnel, err clientAddr = "127.0.0.1" } + allowExternalTcp := params.Get("allow-external-tcp") == "on" + request := Tunnel{ - Domain: domain, - Owner: tokenData.Owner, - ClientName: clientName, - ClientPort: clientPort, - ClientAddress: clientAddr, + Domain: domain, + Owner: tokenData.Owner, + ClientName: clientName, + ClientPort: clientPort, + ClientAddress: clientAddr, + AllowExternalTcp: allowExternalTcp, } tunnel, err := a.tunMan.RequestCreateTunnel(request) diff --git a/client.go b/client.go index 63ce54f..63127d6 100644 --- a/client.go +++ b/client.go @@ -163,7 +163,11 @@ func (c *BoringProxyClient) BoreTunnel(tunnel Tunnel) context.CancelFunc { } //defer client.Close() - tunnelAddr := fmt.Sprintf("127.0.0.1:%d", tunnel.TunnelPort) + bindAddr := "127.0.0.1" + if tunnel.AllowExternalTcp { + bindAddr = "0.0.0.0" + } + tunnelAddr := fmt.Sprintf("%s:%d", bindAddr, tunnel.TunnelPort) listener, err := client.Listen("tcp", tunnelAddr) if err != nil { log.Fatal("unable to register tcp forward: ", err) diff --git a/database.go b/database.go index 63507fd..9b3ec19 100644 --- a/database.go +++ b/database.go @@ -35,6 +35,7 @@ type Tunnel struct { ClientName string `json:"client_name"` ClientAddress string `json:"client_address"` ClientPort int `json:"client_port"` + AllowExternalTcp bool `json:"allow_external_tcp"` CssId string `json:"css_id"` } diff --git a/tunnel_manager.go b/tunnel_manager.go index e67a4bb..429e1e9 100644 --- a/tunnel_manager.go +++ b/tunnel_manager.go @@ -77,7 +77,7 @@ func (m *TunnelManager) RequestCreateTunnel(tunReq Tunnel) (Tunnel, error) { return Tunnel{}, err } - privKey, err := m.addToAuthorizedKeys(tunReq.Domain, port) + privKey, err := m.addToAuthorizedKeys(tunReq.Domain, port, tunReq.AllowExternalTcp) if err != nil { return Tunnel{}, err } @@ -88,12 +88,13 @@ func (m *TunnelManager) RequestCreateTunnel(tunReq Tunnel) (Tunnel, error) { ServerAddress: m.config.WebUiDomain, ServerPort: 22, ServerPublicKey: "", + Username: m.user.Username, TunnelPort: port, TunnelPrivateKey: privKey, ClientName: tunReq.ClientName, ClientPort: tunReq.ClientPort, ClientAddress: tunReq.ClientAddress, - Username: m.user.Username, + AllowExternalTcp: tunReq.AllowExternalTcp, } m.db.SetTunnel(tunReq.Domain, tunnel) @@ -155,7 +156,7 @@ func (m *TunnelManager) GetPort(domain string) (int, error) { return tunnel.TunnelPort, nil } -func (m *TunnelManager) addToAuthorizedKeys(domain string, port int) (string, error) { +func (m *TunnelManager) addToAuthorizedKeys(domain string, port int, allowExternalTcp bool) (string, error) { authKeysPath := fmt.Sprintf("%s/.ssh/authorized_keys", m.user.HomeDir) @@ -171,7 +172,12 @@ func (m *TunnelManager) addToAuthorizedKeys(domain string, port int) (string, er return "", err } - options := fmt.Sprintf(`command="echo This key permits tunnels only",permitopen="fakehost:1",permitlisten="127.0.0.1:%d"`, port) + bindAddr := "127.0.0.1" + if allowExternalTcp { + bindAddr = "0.0.0.0" + } + + options := fmt.Sprintf(`command="echo This key permits tunnels only",permitopen="fakehost:1",permitlisten="%s:%d"`, bindAddr, port) tunnelId := fmt.Sprintf("boringproxy-%s-%d", domain, port) diff --git a/webui/index.tmpl b/webui/index.tmpl index 8d5ae09..67f46d1 100644 --- a/webui/index.tmpl +++ b/webui/index.tmpl @@ -66,12 +66,16 @@
- +
+
+ + +