diff --git a/cmd/cloudflared/config/configuration.go b/cmd/cloudflared/config/configuration.go index 87910a9e..cb497dc2 100644 --- a/cmd/cloudflared/config/configuration.go +++ b/cmd/cloudflared/config/configuration.go @@ -63,7 +63,17 @@ func FindDefaultConfigPath() string { return "" } +// ValidateUnixSocket ensures --unix-socket param is used exclusively +// i.e. it fails if a user specifies both --url and --unix-socket +func ValidateUnixSocket(c *cli.Context) (string, error) { + if c.IsSet("unix-socket") && (c.IsSet("url") || c.NArg() > 0) { + return "", errors.New("--unix-socket must be used exclusivly.") + } + return c.String("unix-socket"), nil +} + // ValidateUrl will validate url flag correctness. It can be either from --url or argument +// Notice ValidateUnixSocket, it will enforce --unix-socket is not used with --url or argument func ValidateUrl(c *cli.Context) (string, error) { var url = c.String("url") if c.NArg() > 0 { diff --git a/cmd/cloudflared/tunnel/cmd.go b/cmd/cloudflared/tunnel/cmd.go index f39a3a9b..3953c00d 100644 --- a/cmd/cloudflared/tunnel/cmd.go +++ b/cmd/cloudflared/tunnel/cmd.go @@ -476,6 +476,12 @@ func tunnelFlags(shouldHide bool) []cli.Flag { EnvVars: []string{"TUNNEL_URL"}, Hidden: shouldHide, }), + altsrc.NewStringFlag(&cli.StringFlag{ + Name: "unix-socket", + Usage: "Path to unix socket to use instead of --url", + EnvVars: []string{"TUNNEL_UNIX_SOCKET"}, + Hidden: shouldHide, + }), altsrc.NewStringFlag(&cli.StringFlag{ Name: "hostname", Usage: "Set a hostname on a Cloudflare zone to route traffic through this tunnel.", diff --git a/cmd/cloudflared/tunnel/configuration.go b/cmd/cloudflared/tunnel/configuration.go index 17c15cb7..e39054d5 100644 --- a/cmd/cloudflared/tunnel/configuration.go +++ b/cmd/cloudflared/tunnel/configuration.go @@ -1,6 +1,7 @@ package tunnel import ( + "context" "crypto/tls" "crypto/x509" "encoding/hex" @@ -160,7 +161,6 @@ func prepareTunnelConfig(c *cli.Context, buildInfo *origin.BuildInfo, version st logger.WithError(err).Error("Error validating origin URL") return nil, errors.Wrap(err, "Error validating origin URL") } - logger.Infof("Proxying tunnel requests to %s", originURL) originCert, err := getOriginCert(c) if err != nil { @@ -175,12 +175,7 @@ func prepareTunnelConfig(c *cli.Context, buildInfo *origin.BuildInfo, version st tunnelMetrics := origin.NewTunnelMetrics() httpTransport := &http.Transport{ - Proxy: http.ProxyFromEnvironment, - DialContext: (&net.Dialer{ - Timeout: c.Duration("proxy-connect-timeout"), - KeepAlive: c.Duration("proxy-tcp-keepalive"), - DualStack: !c.Bool("proxy-no-happy-eyeballs"), - }).DialContext, + Proxy: http.ProxyFromEnvironment, MaxIdleConns: c.Int("proxy-keepalive-connections"), IdleConnTimeout: c.Duration("proxy-keepalive-timeout"), TLSHandshakeTimeout: c.Duration("proxy-tls-timeout"), @@ -188,6 +183,29 @@ func prepareTunnelConfig(c *cli.Context, buildInfo *origin.BuildInfo, version st TLSClientConfig: &tls.Config{RootCAs: originCertPool, InsecureSkipVerify: c.IsSet("no-tls-verify")}, } + dialContext := (&net.Dialer{ + Timeout: c.Duration("proxy-connect-timeout"), + KeepAlive: c.Duration("proxy-tcp-keepalive"), + DualStack: !c.Bool("proxy-no-happy-eyeballs"), + }).DialContext + + if c.IsSet("unix-socket") { + unixSocket, err := config.ValidateUnixSocket(c) + if err != nil { + logger.WithError(err).Error("Error validating --unix-socket") + return nil, errors.Wrap(err, "Error validating --unix-socket") + } + + logger.Infof("Proxying tunnel requests to unix:%s", unixSocket) + httpTransport.DialContext = func(ctx context.Context, _, _ string) (net.Conn, error) { + // if --unix-socket specified, enforce network type "unix" + return dialContext(ctx, "unix", unixSocket) + } + } else { + logger.Infof("Proxying tunnel requests to %s", originURL) + httpTransport.DialContext = dialContext + } + if !c.IsSet("hello-world") && c.IsSet("origin-server-name") { httpTransport.TLSClientConfig.ServerName = c.String("origin-server-name") } diff --git a/origin/tunnel.go b/origin/tunnel.go index ea373e0d..a953ae0f 100644 --- a/origin/tunnel.go +++ b/origin/tunnel.go @@ -37,8 +37,10 @@ const ( ) type TunnelConfig struct { + // OriginUrl may not be used if a user specifies a unix socket. + OriginUrl string + EdgeAddrs []string - OriginUrl string Hostname string OriginCert []byte TlsConfig *tls.Config