1
0
mirror of https://github.com/fumiama/terasu-cloudflared.git synced 2026-06-08 12:00:36 +08:00

AUTH-1188: UX Review and Changes for CLI SSH Access

This commit is contained in:
Austin Cherry
2018-10-19 15:44:35 -05:00
committed by Areg Harutyunyan
parent 6acc95f756
commit 80a75e91d2
10 changed files with 409 additions and 70 deletions

View File

@@ -1,38 +0,0 @@
package tunnel
import (
"net/url"
"github.com/cloudflare/cloudflared/carrier"
"github.com/cloudflare/cloudflared/validation"
"github.com/pkg/errors"
cli "gopkg.in/urfave/cli.v2"
)
// ssh will start a WS proxy server for server mode
// or copy from stdin/stdout for client mode
// useful for proxying other protocols (like ssh) over websockets
// (which you can put Access in front of)
func ssh(c *cli.Context) error {
hostname, err := validation.ValidateHostname(c.String("hostname"))
if err != nil {
logger.WithError(err).Error("Invalid hostname")
return errors.Wrap(err, "invalid hostname")
}
if c.NArg() > 0 || c.IsSet("url") {
localForwarder, err := validateUrl(c)
if err != nil {
logger.WithError(err).Error("Error validating origin URL")
return errors.Wrap(err, "error validating origin URL")
}
forwarder, err := url.Parse(localForwarder)
if err != nil {
logger.WithError(err).Error("Error validating origin URL")
return errors.Wrap(err, "error validating origin URL")
}
return carrier.StartServer(logger, forwarder.Host, "https://"+hostname, shutdownC)
}
return carrier.StartClient(logger, "https://"+hostname, &carrier.StdinoutStream{})
}

View File

@@ -4,6 +4,7 @@ import (
"fmt"
"io/ioutil"
"net"
"net/url"
"os"
"runtime/trace"
"sync"
@@ -139,21 +140,6 @@ func Commands() []*cli.Command {
},
Hidden: true,
},
{
Name: "ssh",
Action: ssh,
Usage: `ssh -o ProxyCommand="cloudflared tunnel ssh --hostname %h" ssh.warptunnels.org`,
ArgsUsage: "[origin-url]",
Description: `The ssh subcommand wraps sends data over a WebSocket proxy to the Cloudflare edge.`,
Flags: []cli.Flag{
&cli.StringFlag{
Name: "hostname",
},
&cli.StringFlag{
Name: "url",
},
},
},
}
var subcommands []*cli.Command
@@ -325,7 +311,11 @@ func StartServer(c *cli.Context, version string, shutdownC, graceShutdownC chan
c.Set("url", "https://"+helloListener.Addr().String())
}
if c.IsSet("ws-proxy-server") {
if uri, _ := url.Parse(c.String("url")); uri.Scheme == "ssh" {
host := uri.Host
if uri.Port() == "" { // default to 22
host = uri.Hostname() + ":22"
}
listener, err := net.Listen("tcp", "127.0.0.1:")
if err != nil {
logger.WithError(err).Error("Cannot start Websocket Proxy Server")
@@ -334,7 +324,7 @@ func StartServer(c *cli.Context, version string, shutdownC, graceShutdownC chan
wg.Add(1)
go func() {
defer wg.Done()
errC <- websocket.StartProxyServer(logger, listener, c.String("remote"), shutdownC)
errC <- websocket.StartProxyServer(logger, listener, host, shutdownC)
}()
c.Set("url", "http://"+listener.Addr().String())
}
@@ -355,19 +345,19 @@ func StartServer(c *cli.Context, version string, shutdownC, graceShutdownC chan
func Before(c *cli.Context) error {
if c.String("config") == "" {
logger.Warnf("Cannot determine default configuration path. No file %v in %v", config.DefaultConfigFiles, config.DefaultConfigDirs)
logger.Debugf("Cannot determine default configuration path. No file %v in %v", config.DefaultConfigFiles, config.DefaultConfigDirs)
}
inputSource, err := config.FindInputSourceContext(c)
if err != nil {
logger.WithError(err).Infof("Cannot load configuration from %s", c.String("config"))
logger.WithError(err).Debugf("Cannot load configuration from %s", c.String("config"))
return err
} else if inputSource != nil {
err := altsrc.ApplyInputSourceValues(c, inputSource, c.App.Flags)
if err != nil {
logger.WithError(err).Infof("Cannot apply configuration from %s", c.String("config"))
logger.WithError(err).Debugf("Cannot apply configuration from %s", c.String("config"))
return err
}
logger.Infof("Applied configuration from %s", c.String("config"))
logger.Debugf("Applied configuration from %s", c.String("config"))
}
return nil
}
@@ -478,13 +468,6 @@ func tunnelFlags(shouldHide bool) []cli.Flag {
EnvVars: []string{"TUNNEL_URL"},
Hidden: shouldHide,
}),
altsrc.NewStringFlag(&cli.StringFlag{
Name: "remote",
Value: "localhost:22",
Usage: "Connect to the local server over tcp at `remote`.",
EnvVars: []string{"TUNNEL_REMOTE"},
Hidden: shouldHide,
}),
altsrc.NewStringFlag(&cli.StringFlag{
Name: "hostname",
Usage: "Set a hostname on a Cloudflare zone to route traffic through this tunnel.",
@@ -587,13 +570,6 @@ func tunnelFlags(shouldHide bool) []cli.Flag {
EnvVars: []string{"TUNNEL_HELLO_WORLD"},
Hidden: shouldHide,
}),
altsrc.NewBoolFlag(&cli.BoolFlag{
Name: "ws-proxy-server",
Value: false,
Usage: "Run WS proxy Server",
EnvVars: []string{"TUNNEL_WS_PROXY"},
Hidden: shouldHide,
}),
altsrc.NewStringFlag(&cli.StringFlag{
Name: "pidfile",
Usage: "Write the application's PID to this file after first successful connection.",

View File

@@ -64,19 +64,6 @@ func handleDeprecatedOptions(c *cli.Context) error {
return nil
}
// validate url. It can be either from --url or argument
func validateUrl(c *cli.Context) (string, error) {
var url = c.String("url")
if c.NArg() > 0 {
if c.IsSet("url") {
return "", errors.New("Specified origin urls using both --url and argument. Decide which one you want, I can only support one.")
}
url = c.Args().Get(0)
}
validUrl, err := validation.ValidateUrl(url)
return validUrl, err
}
func logClientOptions(c *cli.Context) {
flags := make(map[string]interface{})
for _, flag := range c.LocalFlagNames() {
@@ -168,7 +155,7 @@ func prepareTunnelConfig(c *cli.Context, buildInfo *origin.BuildInfo, version st
tags = append(tags, tunnelpogs.Tag{Name: "ID", Value: clientID})
originURL, err := validateUrl(c)
originURL, err := config.ValidateUrl(c)
if err != nil {
logger.WithError(err).Error("Error validating origin URL")
return nil, errors.Wrap(err, "Error validating origin URL")