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.
This commit is contained in:
Anders Pitman 2020-10-20 19:14:04 -06:00
parent 9882017d5a
commit 85a5004cc7
5 changed files with 29 additions and 11 deletions

13
api.go
View File

@ -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)

View File

@ -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)

View File

@ -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"`
}

View File

@ -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)

View File

@ -66,12 +66,16 @@
</div>
<div class='input'>
<label for="client-addr">Client Address:</label>
<input type="text" id="client-addr" name="client-addr" value='127.0.0.1' required>
<input type="text" id="client-addr" name="client-addr" value='127.0.0.1'>
</div>
<div class='input'>
<label for="client-port">Client Port:</label>
<input type="text" id="client-port" name="client-port" required>
</div>
<div class='input'>
<label for="allow-external-tcp">Allow External TCP:</label>
<input type="checkbox" id="allow-external-tcp" name="allow-external-tcp">
</div>
<button class='button' type="submit">Submit</button>
</form>
</div>