2018-10-08 19:20:28 +00:00
package tunnel
import (
2020-03-27 14:39:59 +00:00
"bufio"
2019-06-17 21:18:47 +00:00
"context"
2018-10-08 19:20:28 +00:00
"fmt"
"io/ioutil"
2018-10-19 20:44:35 +00:00
"net/url"
2018-10-08 19:20:28 +00:00
"os"
"runtime/trace"
2020-04-30 05:02:08 +00:00
"strings"
2018-10-08 19:20:28 +00:00
"sync"
"time"
2021-03-23 14:30:43 +00:00
"github.com/coreos/go-systemd/daemon"
"github.com/facebookgo/grace/gracenet"
2022-12-25 04:44:15 +00:00
"github.com/getsentry/sentry-go"
2022-06-08 06:09:26 +00:00
"github.com/google/uuid"
2021-03-23 14:30:43 +00:00
homedir "github.com/mitchellh/go-homedir"
"github.com/pkg/errors"
"github.com/rs/zerolog"
"github.com/urfave/cli/v2"
"github.com/urfave/cli/v2/altsrc"
2021-12-27 14:56:50 +00:00
"github.com/cloudflare/cloudflared/cfapi"
2020-05-18 18:24:17 +00:00
"github.com/cloudflare/cloudflared/cmd/cloudflared/cliutil"
2021-03-08 16:46:23 +00:00
"github.com/cloudflare/cloudflared/cmd/cloudflared/proxydns"
2018-10-08 19:20:28 +00:00
"github.com/cloudflare/cloudflared/cmd/cloudflared/updater"
2021-03-08 16:46:23 +00:00
"github.com/cloudflare/cloudflared/config"
2020-10-08 10:12:26 +00:00
"github.com/cloudflare/cloudflared/connection"
2020-10-15 21:41:03 +00:00
"github.com/cloudflare/cloudflared/ingress"
2020-04-29 20:51:32 +00:00
"github.com/cloudflare/cloudflared/logger"
2023-03-21 18:42:25 +00:00
"github.com/cloudflare/cloudflared/management"
2018-10-08 19:20:28 +00:00
"github.com/cloudflare/cloudflared/metrics"
2022-02-11 10:49:06 +00:00
"github.com/cloudflare/cloudflared/orchestration"
2019-03-04 19:48:56 +00:00
"github.com/cloudflare/cloudflared/signal"
2022-02-07 09:42:07 +00:00
"github.com/cloudflare/cloudflared/supervisor"
2019-05-28 20:53:35 +00:00
"github.com/cloudflare/cloudflared/tlsconfig"
2018-10-08 19:20:28 +00:00
"github.com/cloudflare/cloudflared/tunneldns"
2023-02-06 17:13:05 +00:00
"github.com/cloudflare/cloudflared/validation"
2018-10-08 19:20:28 +00:00
)
2019-08-28 15:48:30 +00:00
const (
2019-08-26 20:56:17 +00:00
sentryDSN = "https://56a9c9fa5c364ab28f34b14f35ea0f1b:3e8827f6f9f740738eb11138f7bebb68@sentry.io/189878"
2023-03-13 10:20:58 +00:00
// ha-Connections specifies how many connections to make to the edge
haConnectionsFlag = "ha-connections"
2019-08-28 15:48:30 +00:00
// sshPortFlag is the port on localhost the cloudflared ssh server will run on
2019-08-26 20:56:17 +00:00
sshPortFlag = "local-ssh-port"
2019-08-28 15:48:30 +00:00
// sshIdleTimeoutFlag defines the duration a SSH session can remain idle before being closed
sshIdleTimeoutFlag = "ssh-idle-timeout"
// sshMaxTimeoutFlag defines the max duration a SSH session can remain open for
2019-08-26 20:56:17 +00:00
sshMaxTimeoutFlag = "ssh-max-timeout"
// bucketNameFlag is the bucket name to use for the SSH log uploader
bucketNameFlag = "bucket-name"
// regionNameFlag is the AWS region name to use for the SSH log uploader
regionNameFlag = "region-name"
// secretIDFlag is the Secret id of SSH log uploader
secretIDFlag = "secret-id"
// accessKeyIDFlag is the Access key id of SSH log uploader
accessKeyIDFlag = "access-key-id"
// sessionTokenIDFlag is the Session token of SSH log uploader
sessionTokenIDFlag = "session-token"
// s3URLFlag is the S3 URL of SSH log uploader (e.g. don't use AWS s3 and use google storage bucket instead)
s3URLFlag = "s3-url-host"
2019-09-04 16:14:27 +00:00
2019-10-17 21:23:06 +00:00
// hostKeyPath is the path of the dir to save SSH host keys too
hostKeyPath = "host-key-path"
2020-09-01 16:06:00 +00:00
// uiFlag is to enable launching cloudflared in interactive UI mode
uiFlag = "ui"
2021-03-12 14:29:07 +00:00
debugLevelWarning = "At debug level cloudflared will log request URL, method, protocol, content length, as well as, all request and response headers. " +
"This can expose sensitive information in your logs."
2020-12-28 18:10:01 +00:00
LogFieldCommand = "command"
LogFieldExpandedPath = "expandedPath"
LogFieldPIDPathname = "pidPathname"
LogFieldTmpTraceFilename = "tmpTraceFilename"
LogFieldTraceOutputFilepath = "traceOutputFilepath"
2022-12-07 16:13:21 +00:00
2023-02-28 16:11:42 +00:00
tunnelCmdErrorMessage = ` You did not specify any valid additional argument to the cloudflared tunnel command .
2022-12-07 16:13:21 +00:00
2023-02-28 16:11:42 +00:00
If you are trying to run a Quick Tunnel then you need to explicitly pass the -- url flag .
Eg . cloudflared tunnel -- url localhost : 8080 / .
2022-12-07 16:13:21 +00:00
2023-02-28 16:11:42 +00:00
Please note that Quick Tunnels are meant to be ephemeral and should only be used for testing purposes .
2022-12-07 16:13:21 +00:00
For production usage , we recommend creating Named Tunnels . ( https : //developers.cloudflare.com/cloudflare-one/connections/connect-apps/install-and-setup/tunnel-guide/)
`
2019-08-28 15:48:30 +00:00
)
2018-10-08 19:20:28 +00:00
var (
graceShutdownC chan struct { }
2021-12-27 19:05:14 +00:00
buildInfo * cliutil . BuildInfo
2021-05-19 17:38:09 +00:00
routeFailMsg = fmt . Sprintf ( "failed to provision routing, please create it manually via Cloudflare dashboard or UI; " +
"most likely you already have a conflicting record there. You can also rerun this command with --%s to overwrite " +
"any existing DNS records for this hostname." , overwriteDNSFlag )
2023-02-06 17:13:05 +00:00
deprecatedClassicTunnelErr = fmt . Errorf ( "Classic tunnels have been deprecated, please use Named Tunnels. (https://developers.cloudflare.com/cloudflare-one/connections/connect-apps/install-and-setup/tunnel-guide/)" )
2018-10-08 19:20:28 +00:00
)
func Flags ( ) [ ] cli . Flag {
return tunnelFlags ( true )
}
func Commands ( ) [ ] * cli . Command {
2020-10-09 17:07:08 +00:00
subcommands := [ ] * cli . Command {
buildLoginSubcommand ( false ) ,
buildCreateCommand ( ) ,
buildRouteCommand ( ) ,
2022-01-21 10:23:09 +00:00
buildVirtualNetworkSubcommand ( false ) ,
2020-10-09 17:07:08 +00:00
buildRunCommand ( ) ,
buildListCommand ( ) ,
2021-03-15 18:30:17 +00:00
buildInfoCommand ( ) ,
2020-10-09 17:07:08 +00:00
buildIngressSubcommand ( ) ,
buildDeleteCommand ( ) ,
buildCleanupCommand ( ) ,
2022-03-22 12:46:07 +00:00
buildTokenCommand ( ) ,
2020-10-09 17:07:08 +00:00
// for compatibility, allow following as tunnel subcommands
2021-03-08 16:46:23 +00:00
proxydns . Command ( true ) ,
2021-02-16 22:09:27 +00:00
cliutil . RemovedCommand ( "db-connect" ) ,
2018-10-08 19:20:28 +00:00
}
2020-10-12 17:54:15 +00:00
return [ ] * cli . Command {
2020-10-09 17:07:08 +00:00
buildTunnelCommand ( subcommands ) ,
// for compatibility, allow following as top-level subcommands
buildLoginSubcommand ( true ) ,
2021-02-16 22:09:27 +00:00
cliutil . RemovedCommand ( "db-connect" ) ,
2018-10-08 19:20:28 +00:00
}
2020-09-16 12:15:49 +00:00
}
func buildTunnelCommand ( subcommands [ ] * cli . Command ) * cli . Command {
return & cli . Command {
2018-10-08 19:20:28 +00:00
Name : "tunnel" ,
2021-03-16 22:36:46 +00:00
Action : cliutil . ConfiguredAction ( TunnelCommand ) ,
2018-10-08 19:20:28 +00:00
Category : "Tunnel" ,
2022-03-22 11:22:18 +00:00
Usage : "Use Cloudflare Tunnel to expose private services to the Internet or to Cloudflare connected private users." ,
2020-05-21 20:36:49 +00:00
ArgsUsage : " " ,
2022-03-22 11:22:18 +00:00
Description : ` Cloudflare Tunnel allows to expose private services without opening any ingress port on this machine . It can expose :
A ) Locally reachable HTTP - based private services to the Internet on DNS with Cloudflare as authority ( which you can
then protect with Cloudflare Access ) .
B ) Locally reachable TCP / UDP - based private services to Cloudflare connected private users in the same account , e . g . ,
those enrolled to a Zero Trust WARP Client .
2018-10-08 19:20:28 +00:00
2022-03-22 11:22:18 +00:00
You can manage your Tunnels via dash . teams . cloudflare . com . This approach will only require you to run a single command
later in each machine where you wish to run a Tunnel .
2018-10-08 19:20:28 +00:00
2022-03-22 11:22:18 +00:00
Alternatively , you can manage your Tunnels via the command line . Begin by obtaining a certificate to be able to do so :
2018-10-08 19:20:28 +00:00
2022-03-22 11:22:18 +00:00
$ cloudflared tunnel login
2018-10-08 19:20:28 +00:00
2022-03-22 11:22:18 +00:00
With your certificate installed you can then get started with Tunnels :
2018-10-08 19:20:28 +00:00
2022-03-22 11:22:18 +00:00
$ cloudflared tunnel create my - first - tunnel
$ cloudflared tunnel route dns my - first - tunnel my - first - tunnel . mydomain . com
$ cloudflared tunnel run -- hello - world my - first - tunnel
2018-10-08 19:20:28 +00:00
2022-03-22 11:22:18 +00:00
You can now access my - first - tunnel . mydomain . com and be served an example page by your local cloudflared process .
For exposing local TCP / UDP services by IP to your privately connected users , check out :
$ cloudflared tunnel route ip -- help
See https : //developers.cloudflare.com/cloudflare-one/connections/connect-apps/install-and-setup/tunnel-guide/ for more info.`,
2018-10-08 19:20:28 +00:00
Subcommands : subcommands ,
Flags : tunnelFlags ( false ) ,
2020-09-16 12:15:49 +00:00
}
2018-10-08 19:20:28 +00:00
}
2020-07-30 17:00:57 +00:00
func TunnelCommand ( c * cli . Context ) error {
2020-10-15 20:08:57 +00:00
sc , err := newSubcommandContext ( c )
if err != nil {
return err
}
2022-12-07 16:13:21 +00:00
2023-02-06 17:13:05 +00:00
// Run a adhoc named tunnel
// Allows for the creation, routing (optional), and startup of a tunnel in one command
// --name required
// --url or --hello-world required
// --hostname optional
if name := c . String ( "name" ) ; name != "" {
hostname , err := validation . ValidateHostname ( c . String ( "hostname" ) )
if err != nil {
return errors . Wrap ( err , "Invalid hostname provided" )
}
url := c . String ( "url" )
if url == hostname && url != "" && hostname != "" {
return fmt . Errorf ( "hostname and url shouldn't match. See --help for more information" )
}
2021-02-04 17:57:50 +00:00
return runAdhocNamedTunnel ( sc , name , c . String ( CredFileFlag ) )
2020-07-30 17:00:57 +00:00
}
2022-12-07 16:13:21 +00:00
2023-02-06 17:13:05 +00:00
// Run a quick tunnel
// A unauthenticated named tunnel hosted on <random>.<quick-tunnels-service>.com
// We don't support running proxy-dns and a quick tunnel at the same time as the same process
2023-03-06 23:19:10 +00:00
shouldRunQuickTunnel := c . IsSet ( "url" ) || c . IsSet ( ingress . HelloWorldFlag )
2023-02-06 17:13:05 +00:00
if ! c . IsSet ( "proxy-dns" ) && c . String ( "quick-service" ) != "" && shouldRunQuickTunnel {
2022-12-07 16:13:21 +00:00
return RunQuickTunnel ( sc )
}
2023-02-06 17:13:05 +00:00
// If user provides a config, check to see if they meant to use `tunnel run` instead
2020-10-19 22:33:40 +00:00
if ref := config . GetConfiguration ( ) . TunnelID ; ref != "" {
return fmt . Errorf ( "Use `cloudflared tunnel run` to start tunnel %s" , ref )
2020-10-15 20:08:57 +00:00
}
2023-02-06 17:13:05 +00:00
// Classic tunnel usage is no longer supported
2022-12-07 16:13:21 +00:00
if c . String ( "hostname" ) != "" {
2023-02-06 17:13:05 +00:00
return deprecatedClassicTunnelErr
2021-06-22 00:31:24 +00:00
}
2023-01-22 16:59:09 +00:00
if c . IsSet ( "proxy-dns" ) {
2023-03-06 23:19:10 +00:00
if shouldRunQuickTunnel {
return fmt . Errorf ( "running a quick tunnel with `proxy-dns` is not supported" )
}
2022-12-20 11:26:27 +00:00
// NamedTunnelProperties are nil since proxy dns server does not need it.
// This is supported for legacy reasons: dns proxy server is not a tunnel and ideally should
// not run as part of cloudflared tunnel.
return StartServer ( sc . c , buildInfo , nil , sc . log )
}
2022-12-07 16:13:21 +00:00
return errors . New ( tunnelCmdErrorMessage )
2018-10-08 19:20:28 +00:00
}
2021-12-27 19:05:14 +00:00
func Init ( info * cliutil . BuildInfo , gracefulShutdown chan struct { } ) {
buildInfo , graceShutdownC = info , gracefulShutdown
2018-10-08 19:20:28 +00:00
}
2020-10-15 20:08:57 +00:00
// runAdhocNamedTunnel create, route and run a named tunnel in one command
2021-02-04 17:57:50 +00:00
func runAdhocNamedTunnel ( sc * subcommandContext , name , credentialsOutputPath string ) error {
2020-07-30 17:00:57 +00:00
tunnel , ok , err := sc . tunnelActive ( name )
if err != nil || ! ok {
2021-09-29 23:56:38 +00:00
// pass empty string as secret to generate one
tunnel , err = sc . create ( name , credentialsOutputPath , "" )
2020-07-30 17:00:57 +00:00
if err != nil {
return errors . Wrap ( err , "failed to create tunnel" )
}
} else {
2020-12-28 18:10:01 +00:00
sc . log . Info ( ) . Str ( LogFieldTunnelID , tunnel . ID . String ( ) ) . Msg ( "Reusing existing tunnel with this name" )
2020-07-30 17:00:57 +00:00
}
2020-10-15 20:08:57 +00:00
if r , ok := routeFromFlag ( sc . c ) ; ok {
2020-09-17 20:19:47 +00:00
if res , err := sc . route ( tunnel . ID , r ) ; err != nil {
2021-05-19 17:38:09 +00:00
sc . log . Err ( err ) . Str ( "route" , r . String ( ) ) . Msg ( routeFailMsg )
2020-07-30 17:00:57 +00:00
} else {
2020-12-28 18:10:01 +00:00
sc . log . Info ( ) . Msg ( res . SuccessSummary ( ) )
2020-07-30 17:00:57 +00:00
}
}
if err := sc . run ( tunnel . ID ) ; err != nil {
return errors . Wrap ( err , "error running tunnel" )
}
return nil
}
2021-12-27 14:56:50 +00:00
func routeFromFlag ( c * cli . Context ) ( route cfapi . HostnameRoute , ok bool ) {
2020-07-30 17:00:57 +00:00
if hostname := c . String ( "hostname" ) ; hostname != "" {
if lbPool := c . String ( "lb-pool" ) ; lbPool != "" {
2021-12-27 14:56:50 +00:00
return cfapi . NewLBRoute ( hostname , lbPool ) , true
2020-07-30 17:00:57 +00:00
}
2021-12-27 14:56:50 +00:00
return cfapi . NewDNSRoute ( hostname , c . Bool ( overwriteDNSFlagName ) ) , true
2020-07-30 17:00:57 +00:00
}
return nil , false
}
2020-09-01 16:06:00 +00:00
func StartServer (
c * cli . Context ,
2021-12-27 19:05:14 +00:00
info * cliutil . BuildInfo ,
2022-02-07 09:42:07 +00:00
namedTunnel * connection . NamedTunnelProperties ,
2020-11-25 06:55:13 +00:00
log * zerolog . Logger ,
2020-09-01 16:06:00 +00:00
) error {
2022-12-25 04:44:15 +00:00
err := sentry . Init ( sentry . ClientOptions {
Dsn : sentryDSN ,
Release : c . App . Version ,
} )
if err != nil {
return err
}
2018-10-08 19:20:28 +00:00
var wg sync . WaitGroup
listeners := gracenet . Net { }
errC := make ( chan error )
2022-12-13 11:03:00 +00:00
// Only log for locally configured tunnels (Token is blank).
if config . GetConfiguration ( ) . Source ( ) == "" && c . String ( TunnelTokenFlag ) == "" {
2020-11-25 06:55:13 +00:00
log . Info ( ) . Msg ( config . ErrNoConfigFile . Error ( ) )
2018-10-08 19:20:28 +00:00
}
if c . IsSet ( "trace-output" ) {
tmpTraceFile , err := ioutil . TempFile ( "" , "trace" )
if err != nil {
2020-12-28 18:10:01 +00:00
log . Err ( err ) . Msg ( "Failed to create new temporary file to save trace output" )
2018-10-08 19:20:28 +00:00
}
2020-12-28 18:10:01 +00:00
traceLog := log . With ( ) . Str ( LogFieldTmpTraceFilename , tmpTraceFile . Name ( ) ) . Logger ( )
2018-10-08 19:20:28 +00:00
defer func ( ) {
if err := tmpTraceFile . Close ( ) ; err != nil {
2020-12-28 18:10:01 +00:00
traceLog . Err ( err ) . Msg ( "Failed to close temporary trace output file" )
2018-10-08 19:20:28 +00:00
}
2020-12-28 18:10:01 +00:00
traceOutputFilepath := c . String ( "trace-output" )
if err := os . Rename ( tmpTraceFile . Name ( ) , traceOutputFilepath ) ; err != nil {
traceLog .
Err ( err ) .
Str ( LogFieldTraceOutputFilepath , traceOutputFilepath ) .
Msg ( "Failed to rename temporary trace output file" )
2018-10-08 19:20:28 +00:00
} else {
2019-01-07 20:30:22 +00:00
err := os . Remove ( tmpTraceFile . Name ( ) )
if err != nil {
2020-12-28 18:10:01 +00:00
traceLog . Err ( err ) . Msg ( "Failed to remove the temporary trace file" )
2019-01-07 20:30:22 +00:00
}
2018-10-08 19:20:28 +00:00
}
} ( )
if err := trace . Start ( tmpTraceFile ) ; err != nil {
2020-12-28 18:10:01 +00:00
traceLog . Err ( err ) . Msg ( "Failed to start trace" )
2018-10-08 19:20:28 +00:00
return errors . Wrap ( err , "Error starting tracing" )
}
defer trace . Stop ( )
}
2021-12-27 19:05:14 +00:00
info . Log ( log )
2020-11-25 06:55:13 +00:00
logClientOptions ( c , log )
2018-10-08 19:20:28 +00:00
2021-01-25 21:51:58 +00:00
// this context drives the server, when it's cancelled tunnel and all other components (origins, dns, etc...) should stop
ctx , cancel := context . WithCancel ( context . Background ( ) )
defer cancel ( )
go waitForSignal ( graceShutdownC , log )
2018-10-08 19:20:28 +00:00
if c . IsSet ( "proxy-dns" ) {
2021-01-25 21:51:58 +00:00
dnsReadySignal := make ( chan struct { } )
2018-10-08 19:20:28 +00:00
wg . Add ( 1 )
go func ( ) {
defer wg . Done ( )
2021-01-25 21:51:58 +00:00
errC <- runDNSProxyServer ( c , dnsReadySignal , ctx . Done ( ) , log )
2018-10-08 19:20:28 +00:00
} ( )
2021-01-25 21:51:58 +00:00
// Wait for proxy-dns to come up (if used)
<- dnsReadySignal
2018-10-08 19:20:28 +00:00
}
2021-01-25 21:51:58 +00:00
connectedSignal := signal . New ( make ( chan struct { } ) )
2018-10-08 19:20:28 +00:00
go notifySystemd ( connectedSignal )
if c . IsSet ( "pidfile" ) {
2020-11-25 06:55:13 +00:00
go writePidFile ( connectedSignal , c . String ( "pidfile" ) , log )
2018-10-08 19:20:28 +00:00
}
2019-06-18 16:47:29 +00:00
// update needs to be after DNS proxy is up to resolve equinox server address
2021-02-28 23:24:38 +00:00
wg . Add ( 1 )
go func ( ) {
defer wg . Done ( )
autoupdater := updater . NewAutoUpdater (
c . Bool ( "no-autoupdate" ) , c . Duration ( "autoupdate-freq" ) , & listeners , log ,
)
errC <- autoupdater . Run ( ctx )
} ( )
2019-06-18 16:47:29 +00:00
2023-02-06 17:13:05 +00:00
// Serve DNS proxy stand-alone if no tunnel type (quick, adhoc, named) is going to run
2021-04-05 10:09:38 +00:00
if dnsProxyStandAlone ( c , namedTunnel ) {
2019-03-04 19:48:56 +00:00
connectedSignal . Notify ( )
2018-10-08 19:20:28 +00:00
// no grace period, handle SIGINT/SIGTERM immediately
2021-01-25 21:51:58 +00:00
return waitToShutdown ( & wg , cancel , errC , graceShutdownC , 0 , log )
2018-10-08 19:20:28 +00:00
}
2022-07-20 23:17:29 +00:00
logTransport := logger . CreateTransportLoggerFromContext ( c , logger . EnableTerminalLog )
2020-04-29 20:51:32 +00:00
2022-07-20 23:17:29 +00:00
observer := connection . NewObserver ( log , logTransport )
2021-01-14 22:33:36 +00:00
2021-07-09 17:52:41 +00:00
// Send Quick Tunnel URL to UI if applicable
var quickTunnelURL string
if namedTunnel != nil {
quickTunnelURL = namedTunnel . QuickTunnelUrl
}
if quickTunnelURL != "" {
observer . SendURL ( quickTunnelURL )
}
2022-04-27 10:51:06 +00:00
tunnelConfig , orchestratorConfig , err := prepareTunnelConfig ( c , info , log , logTransport , observer , namedTunnel )
2018-10-08 19:20:28 +00:00
if err != nil {
2020-12-28 18:10:01 +00:00
log . Err ( err ) . Msg ( "Couldn't start tunnel" )
2018-10-08 19:20:28 +00:00
return err
}
2022-06-08 06:09:26 +00:00
var clientID uuid . UUID
if tunnelConfig . NamedTunnel != nil {
clientID , err = uuid . FromBytes ( tunnelConfig . NamedTunnel . Client . ClientID )
if err != nil {
// set to nil for classic tunnels
clientID = uuid . Nil
}
}
2018-10-08 19:20:28 +00:00
2023-03-21 18:42:25 +00:00
mgmt := management . New ( c . String ( "management-hostname" ) )
localRules := [ ] ingress . Rule { ingress . NewManagementRule ( mgmt ) }
orchestrator , err := orchestration . NewOrchestrator ( ctx , orchestratorConfig , tunnelConfig . Tags , localRules , tunnelConfig . Log )
2022-03-14 17:51:10 +00:00
if err != nil {
return err
}
2020-11-30 20:05:37 +00:00
metricsListener , err := listeners . Listen ( "tcp" , c . String ( "metrics" ) )
if err != nil {
2020-12-28 18:10:01 +00:00
log . Err ( err ) . Msg ( "Error opening metrics server listener" )
2020-11-30 20:05:37 +00:00
return errors . Wrap ( err , "Error opening metrics server listener" )
}
defer metricsListener . Close ( )
wg . Add ( 1 )
go func ( ) {
defer wg . Done ( )
2022-06-08 06:09:26 +00:00
readinessServer := metrics . NewReadyServer ( log , clientID )
2021-01-14 22:33:36 +00:00
observer . RegisterSink ( readinessServer )
2022-11-22 11:30:28 +00:00
metricsConfig := metrics . Config {
ReadyServer : readinessServer ,
QuickTunnelHostname : quickTunnelURL ,
Orchestrator : orchestrator ,
}
errC <- metrics . ServeMetrics ( metricsListener , ctx , metricsConfig , log )
2020-11-30 20:05:37 +00:00
} ( )
2023-03-13 10:20:58 +00:00
reconnectCh := make ( chan supervisor . ReconnectSignal , c . Int ( haConnectionsFlag ) )
2020-03-27 14:39:59 +00:00
if c . IsSet ( "stdin-control" ) {
2020-11-25 06:55:13 +00:00
log . Info ( ) . Msg ( "Enabling control through stdin" )
go stdinControl ( reconnectCh , log )
2020-03-27 14:39:59 +00:00
}
2020-03-19 15:38:28 +00:00
2018-10-08 19:20:28 +00:00
wg . Add ( 1 )
go func ( ) {
2021-01-25 21:51:58 +00:00
defer func ( ) {
wg . Done ( )
log . Info ( ) . Msg ( "Tunnel server stopped" )
} ( )
2022-02-11 10:49:06 +00:00
errC <- supervisor . StartTunnelDaemon ( ctx , tunnelConfig , orchestrator , connectedSignal , reconnectCh , graceShutdownC )
2018-10-08 19:20:28 +00:00
} ( )
2020-04-29 20:51:32 +00:00
2021-09-21 10:02:59 +00:00
gracePeriod , err := gracePeriod ( c )
if err != nil {
return err
}
return waitToShutdown ( & wg , cancel , errC , graceShutdownC , gracePeriod , log )
2020-06-25 18:25:39 +00:00
}
2018-10-08 19:20:28 +00:00
func waitToShutdown ( wg * sync . WaitGroup ,
2021-01-25 21:51:58 +00:00
cancelServerContext func ( ) ,
errC <- chan error ,
graceShutdownC <- chan struct { } ,
2018-10-08 19:20:28 +00:00
gracePeriod time . Duration ,
2020-11-25 06:55:13 +00:00
log * zerolog . Logger ,
2018-10-08 19:20:28 +00:00
) error {
var err error
2021-01-25 21:51:58 +00:00
select {
case err = <- errC :
log . Error ( ) . Err ( err ) . Msg ( "Initiating shutdown" )
case <- graceShutdownC :
log . Debug ( ) . Msg ( "Graceful shutdown signalled" )
if gracePeriod > 0 {
// wait for either grace period or service termination
select {
case <- time . Tick ( gracePeriod ) :
case <- errC :
}
}
2018-10-08 19:20:28 +00:00
}
2021-01-25 21:51:58 +00:00
// stop server context
cancelServerContext ( )
// Wait for clean exit, discarding all errors while we wait
stopDiscarding := make ( chan struct { } )
2018-10-08 19:20:28 +00:00
go func ( ) {
2021-01-25 21:51:58 +00:00
for {
select {
case <- errC : // ignore
case <- stopDiscarding :
return
}
2018-10-08 19:20:28 +00:00
}
} ( )
wg . Wait ( )
2021-01-25 21:51:58 +00:00
close ( stopDiscarding )
2018-10-08 19:20:28 +00:00
return err
}
2019-03-04 19:48:56 +00:00
func notifySystemd ( waitForSignal * signal . Signal ) {
<- waitForSignal . Wait ( )
2018-10-08 19:20:28 +00:00
daemon . SdNotify ( false , "READY=1" )
}
2020-12-28 18:10:01 +00:00
func writePidFile ( waitForSignal * signal . Signal , pidPathname string , log * zerolog . Logger ) {
2019-03-04 19:48:56 +00:00
<- waitForSignal . Wait ( )
2020-12-28 18:10:01 +00:00
expandedPath , err := homedir . Expand ( pidPathname )
2020-04-28 00:55:27 +00:00
if err != nil {
2020-12-28 18:10:01 +00:00
log . Err ( err ) . Str ( LogFieldPIDPathname , pidPathname ) . Msg ( "Unable to expand the path, try to use absolute path in --pidfile" )
2020-04-28 00:55:27 +00:00
return
}
file , err := os . Create ( expandedPath )
2018-10-08 19:20:28 +00:00
if err != nil {
2020-12-28 18:10:01 +00:00
log . Err ( err ) . Str ( LogFieldExpandedPath , expandedPath ) . Msg ( "Unable to write pid" )
2020-04-28 00:55:27 +00:00
return
2018-10-08 19:20:28 +00:00
}
defer file . Close ( )
fmt . Fprintf ( file , "%d" , os . Getpid ( ) )
}
2019-02-01 22:43:59 +00:00
func hostnameFromURI ( uri string ) string {
u , err := url . Parse ( uri )
if err != nil {
return ""
}
switch u . Scheme {
case "ssh" :
return addPortIfMissing ( u , 22 )
case "rdp" :
return addPortIfMissing ( u , 3389 )
2020-05-13 18:53:31 +00:00
case "smb" :
return addPortIfMissing ( u , 445 )
2020-03-23 15:22:58 +00:00
case "tcp" :
return addPortIfMissing ( u , 7864 ) // just a random port since there isn't a default in this case
2019-02-01 22:43:59 +00:00
}
return ""
}
func addPortIfMissing ( uri * url . URL , port int ) string {
if uri . Port ( ) != "" {
return uri . Host
}
return fmt . Sprintf ( "%s:%d" , uri . Hostname ( ) , port )
}
2018-10-08 19:20:28 +00:00
func tunnelFlags ( shouldHide bool ) [ ] cli . Flag {
2020-09-29 09:47:50 +00:00
flags := configureCloudflaredFlags ( shouldHide )
flags = append ( flags , configureProxyFlags ( shouldHide ) ... )
flags = append ( flags , configureLoggingFlags ( shouldHide ) ... )
flags = append ( flags , configureProxyDNSFlags ( shouldHide ) ... )
flags = append ( flags , [ ] cli . Flag {
2021-02-04 17:57:50 +00:00
credentialsFileFlag ,
2018-10-08 19:20:28 +00:00
altsrc . NewBoolFlag ( & cli . BoolFlag {
Name : "is-autoupdated" ,
2021-09-28 07:39:40 +00:00
Usage : "Signal the new process that Cloudflare Tunnel connector has been autoupdated" ,
2018-10-08 19:20:28 +00:00
Value : false ,
Hidden : true ,
} ) ,
altsrc . NewStringSliceFlag ( & cli . StringSliceFlag {
Name : "edge" ,
2020-02-19 22:16:13 +00:00
Usage : "Address of the Cloudflare tunnel server. Only works in Cloudflare's internal testing environment." ,
2018-10-08 19:20:28 +00:00
EnvVars : [ ] string { "TUNNEL_EDGE" } ,
Hidden : true ,
} ) ,
2021-08-28 15:39:00 +00:00
altsrc . NewStringFlag ( & cli . StringFlag {
Name : "region" ,
Usage : "Cloudflare Edge region to connect to. Omit or set to empty to connect to the global region." ,
EnvVars : [ ] string { "TUNNEL_REGION" } ,
} ) ,
2022-06-02 17:57:37 +00:00
altsrc . NewStringFlag ( & cli . StringFlag {
Name : "edge-ip-version" ,
2023-02-28 16:11:42 +00:00
Usage : "Cloudflare Edge IP address version to connect with. {4, 6, auto}" ,
2022-06-02 17:57:37 +00:00
EnvVars : [ ] string { "TUNNEL_EDGE_IP_VERSION" } ,
2022-06-03 03:12:15 +00:00
Value : "4" ,
2022-07-06 11:58:33 +00:00
Hidden : false ,
2022-06-02 17:57:37 +00:00
} ) ,
2023-02-28 16:11:42 +00:00
altsrc . NewStringFlag ( & cli . StringFlag {
Name : "edge-bind-address" ,
Usage : "Bind to IP address for outgoing connections to Cloudflare Edge." ,
EnvVars : [ ] string { "TUNNEL_EDGE_BIND_ADDRESS" } ,
Hidden : false ,
} ) ,
2018-10-08 19:20:28 +00:00
altsrc . NewStringFlag ( & cli . StringFlag {
2019-05-28 20:53:35 +00:00
Name : tlsconfig . CaCertFlag ,
2018-11-15 15:43:50 +00:00
Usage : "Certificate Authority authenticating connections with Cloudflare's edge network." ,
2018-10-08 19:20:28 +00:00
EnvVars : [ ] string { "TUNNEL_CACERT" } ,
Hidden : true ,
} ) ,
altsrc . NewStringFlag ( & cli . StringFlag {
Name : "hostname" ,
Usage : "Set a hostname on a Cloudflare zone to route traffic through this tunnel." ,
EnvVars : [ ] string { "TUNNEL_HOSTNAME" } ,
Hidden : shouldHide ,
} ) ,
altsrc . NewStringFlag ( & cli . StringFlag {
Name : "id" ,
Usage : "A unique identifier used to tie connections to this tunnel instance." ,
EnvVars : [ ] string { "TUNNEL_ID" } ,
Hidden : true ,
} ) ,
altsrc . NewStringFlag ( & cli . StringFlag {
Name : "lb-pool" ,
Usage : "The name of a (new/existing) load balancing pool to add this origin to." ,
EnvVars : [ ] string { "TUNNEL_LB_POOL" } ,
Hidden : shouldHide ,
} ) ,
altsrc . NewStringFlag ( & cli . StringFlag {
Name : "api-key" ,
Usage : "This parameter has been deprecated since version 2017.10.1." ,
EnvVars : [ ] string { "TUNNEL_API_KEY" } ,
Hidden : true ,
} ) ,
altsrc . NewStringFlag ( & cli . StringFlag {
Name : "api-email" ,
Usage : "This parameter has been deprecated since version 2017.10.1." ,
EnvVars : [ ] string { "TUNNEL_API_EMAIL" } ,
Hidden : true ,
} ) ,
altsrc . NewStringFlag ( & cli . StringFlag {
Name : "api-ca-key" ,
Usage : "This parameter has been deprecated since version 2017.10.1." ,
EnvVars : [ ] string { "TUNNEL_API_CA_KEY" } ,
Hidden : true ,
} ) ,
2020-05-21 20:36:49 +00:00
altsrc . NewStringFlag ( & cli . StringFlag {
Name : "api-url" ,
Usage : "Base URL for Cloudflare API v4" ,
EnvVars : [ ] string { "TUNNEL_API_URL" } ,
Value : "https://api.cloudflare.com/client/v4" ,
Hidden : true ,
} ) ,
2018-10-08 19:20:28 +00:00
altsrc . NewDurationFlag ( & cli . DurationFlag {
Name : "metrics-update-freq" ,
Usage : "Frequency to update tunnel metrics" ,
Value : time . Second * 5 ,
EnvVars : [ ] string { "TUNNEL_METRICS_UPDATE_FREQ" } ,
Hidden : shouldHide ,
} ) ,
altsrc . NewStringSliceFlag ( & cli . StringSliceFlag {
Name : "tag" ,
Usage : "Custom tags used to identify this tunnel, in format `KEY=VALUE`. Multiple tags may be specified" ,
EnvVars : [ ] string { "TUNNEL_TAG" } ,
Hidden : shouldHide ,
} ) ,
altsrc . NewDurationFlag ( & cli . DurationFlag {
Name : "heartbeat-interval" ,
Usage : "Minimum idle time before sending a heartbeat." ,
Value : time . Second * 5 ,
Hidden : true ,
} ) ,
2021-01-14 13:08:55 +00:00
// Note TUN-3758 , we use Int because UInt is not supported with altsrc
altsrc . NewIntFlag ( & cli . IntFlag {
2018-10-08 19:20:28 +00:00
Name : "heartbeat-count" ,
Usage : "Minimum number of unacked heartbeats to send before closing the connection." ,
Value : 5 ,
Hidden : true ,
} ) ,
2022-12-14 11:43:52 +00:00
altsrc . NewIntFlag ( & cli . IntFlag {
Name : "max-edge-addr-retries" ,
Usage : "Maximum number of times to retry on edge addrs before falling back to a lower protocol" ,
Value : 8 ,
Hidden : true ,
} ) ,
2021-01-14 13:08:55 +00:00
// Note TUN-3758 , we use Int because UInt is not supported with altsrc
altsrc . NewIntFlag ( & cli . IntFlag {
2018-10-08 19:20:28 +00:00
Name : "retries" ,
Value : 5 ,
Usage : "Maximum number of retries for connection/protocol errors." ,
EnvVars : [ ] string { "TUNNEL_RETRIES" } ,
Hidden : shouldHide ,
} ) ,
2020-09-29 09:47:50 +00:00
altsrc . NewIntFlag ( & cli . IntFlag {
2023-03-13 10:20:58 +00:00
Name : haConnectionsFlag ,
2020-09-29 09:47:50 +00:00
Value : 4 ,
Hidden : true ,
} ) ,
altsrc . NewDurationFlag ( & cli . DurationFlag {
Name : "grace-period" ,
2021-03-29 21:04:00 +00:00
Usage : "When cloudflared receives SIGINT/SIGTERM it will stop accepting new requests, wait for in-progress requests to terminate, then shutdown. Waiting for in-progress requests will timeout after this grace period, or when a second SIGTERM/SIGINT is received." ,
2020-09-29 09:47:50 +00:00
Value : time . Second * 30 ,
EnvVars : [ ] string { "TUNNEL_GRACE_PERIOD" } ,
2021-03-29 21:04:00 +00:00
Hidden : shouldHide ,
2020-09-29 09:47:50 +00:00
} ) ,
2021-01-14 13:08:55 +00:00
// Note TUN-3758 , we use Int because UInt is not supported with altsrc
altsrc . NewIntFlag ( & cli . IntFlag {
2020-09-29 09:47:50 +00:00
Name : "compression-quality" ,
Value : 0 ,
Usage : "(beta) Use cross-stream compression instead HTTP compression. 0-off, 1-low, 2-medium, >=3-high." ,
EnvVars : [ ] string { "TUNNEL_COMPRESSION_LEVEL" } ,
2018-10-08 19:20:28 +00:00
Hidden : shouldHide ,
} ) ,
2020-09-29 09:47:50 +00:00
altsrc . NewBoolFlag ( & cli . BoolFlag {
Name : "use-reconnect-token" ,
Usage : "Test reestablishing connections with the new 'reconnect token' flow." ,
Value : true ,
EnvVars : [ ] string { "TUNNEL_USE_RECONNECT_TOKEN" } ,
Hidden : true ,
} ) ,
altsrc . NewDurationFlag ( & cli . DurationFlag {
Name : "dial-edge-timeout" ,
Usage : "Maximum wait time to set up a connection with the edge" ,
Value : time . Second * 15 ,
EnvVars : [ ] string { "DIAL_EDGE_TIMEOUT" } ,
Hidden : true ,
} ) ,
altsrc . NewBoolFlag ( & cli . BoolFlag {
Name : "stdin-control" ,
Usage : "Control the process using commands sent through stdin" ,
2021-04-09 15:43:01 +00:00
EnvVars : [ ] string { "STDIN_CONTROL" } ,
2020-09-29 09:47:50 +00:00
Hidden : true ,
Value : false ,
} ) ,
2020-06-16 15:33:03 +00:00
altsrc . NewStringFlag ( & cli . StringFlag {
2020-09-29 09:47:50 +00:00
Name : "name" ,
Aliases : [ ] string { "n" } ,
EnvVars : [ ] string { "TUNNEL_NAME" } ,
Usage : "Stable name to identify the tunnel. Using this flag will create, route and run a tunnel. For production usage, execute each command separately" ,
2021-02-05 01:44:03 +00:00
Hidden : shouldHide ,
2020-09-29 09:47:50 +00:00
} ) ,
altsrc . NewBoolFlag ( & cli . BoolFlag {
Name : uiFlag ,
2022-07-20 23:17:29 +00:00
Usage : "(depreciated) Launch tunnel UI. Tunnel logs are scrollable via 'j', 'k', or arrow keys." ,
2020-09-29 09:47:50 +00:00
Value : false ,
2022-07-20 23:17:29 +00:00
Hidden : true ,
2020-09-29 09:47:50 +00:00
} ) ,
2021-06-22 00:31:24 +00:00
altsrc . NewStringFlag ( & cli . StringFlag {
Name : "quick-service" ,
Usage : "URL for a service which manages unauthenticated 'quick' tunnels." ,
2021-07-09 17:52:41 +00:00
Value : "https://api.trycloudflare.com" ,
2021-06-22 00:31:24 +00:00
Hidden : true ,
} ) ,
2021-10-19 14:01:23 +00:00
altsrc . NewIntFlag ( & cli . IntFlag {
2021-10-18 09:32:33 +00:00
Name : "max-fetch-size" ,
Usage : ` The maximum number of results that cloudflared can fetch from Cloudflare API for any listing operations needed ` ,
EnvVars : [ ] string { "TUNNEL_MAX_FETCH_SIZE" } ,
Hidden : true ,
2021-10-19 14:01:23 +00:00
} ) ,
2022-10-04 23:33:17 +00:00
altsrc . NewBoolFlag ( & cli . BoolFlag {
Name : "post-quantum" ,
Usage : "When given creates an experimental post-quantum secure tunnel" ,
Aliases : [ ] string { "pq" } ,
EnvVars : [ ] string { "TUNNEL_POST_QUANTUM" } ,
Hidden : FipsEnabled ,
} ) ,
2020-10-08 09:48:10 +00:00
selectProtocolFlag ,
2021-05-19 17:38:09 +00:00
overwriteDNSFlag ,
2020-09-29 09:47:50 +00:00
} ... )
return flags
}
// Flags in tunnel command that is relevant to run subcommand
func configureCloudflaredFlags ( shouldHide bool ) [ ] cli . Flag {
return [ ] cli . Flag {
& cli . StringFlag {
Name : "config" ,
Usage : "Specifies a config file in YAML format." ,
Value : config . FindDefaultConfigPath ( ) ,
Hidden : shouldHide ,
} ,
altsrc . NewStringFlag ( & cli . StringFlag {
Name : "origincert" ,
Usage : "Path to the certificate generated for your origin when you run cloudflared login." ,
EnvVars : [ ] string { "TUNNEL_ORIGIN_CERT" } ,
Value : findDefaultOriginCertPath ( ) ,
Hidden : shouldHide ,
} ) ,
altsrc . NewDurationFlag ( & cli . DurationFlag {
Name : "autoupdate-freq" ,
Usage : fmt . Sprintf ( "Autoupdate frequency. Default is %v." , updater . DefaultCheckUpdateFreq ) ,
Value : updater . DefaultCheckUpdateFreq ,
Hidden : shouldHide ,
} ) ,
altsrc . NewBoolFlag ( & cli . BoolFlag {
Name : "no-autoupdate" ,
Usage : "Disable periodic check for updates, restarting the server with the new version." ,
EnvVars : [ ] string { "NO_AUTOUPDATE" } ,
Value : false ,
2020-06-16 15:33:03 +00:00
Hidden : shouldHide ,
} ) ,
2018-10-08 19:20:28 +00:00
altsrc . NewStringFlag ( & cli . StringFlag {
2020-09-29 09:47:50 +00:00
Name : "metrics" ,
Value : "localhost:" ,
Usage : "Listen address for metrics reporting." ,
EnvVars : [ ] string { "TUNNEL_METRICS" } ,
2018-10-08 19:20:28 +00:00
Hidden : shouldHide ,
} ) ,
2020-09-29 09:47:50 +00:00
altsrc . NewStringFlag ( & cli . StringFlag {
Name : "pidfile" ,
Usage : "Write the application's PID to this file after first successful connection." ,
EnvVars : [ ] string { "TUNNEL_PIDFILE" } ,
Hidden : shouldHide ,
2018-10-08 19:20:28 +00:00
} ) ,
2020-09-29 09:47:50 +00:00
}
}
func configureProxyFlags ( shouldHide bool ) [ ] cli . Flag {
flags := [ ] cli . Flag {
2020-09-25 02:33:12 +00:00
altsrc . NewStringFlag ( & cli . StringFlag {
2020-09-29 09:47:50 +00:00
Name : "url" ,
Value : "http://localhost:8080" ,
Usage : "Connect to the local webserver at `URL`." ,
EnvVars : [ ] string { "TUNNEL_URL" } ,
2020-09-25 02:33:12 +00:00
Hidden : shouldHide ,
} ) ,
2020-09-29 09:47:50 +00:00
altsrc . NewBoolFlag ( & cli . BoolFlag {
2023-03-06 23:19:10 +00:00
Name : ingress . HelloWorldFlag ,
2020-09-29 09:47:50 +00:00
Value : false ,
Usage : "Run Hello World Server" ,
EnvVars : [ ] string { "TUNNEL_HELLO_WORLD" } ,
Hidden : shouldHide ,
} ) ,
altsrc . NewBoolFlag ( & cli . BoolFlag {
2020-10-15 21:41:03 +00:00
Name : ingress . Socks5Flag ,
2022-02-28 10:57:08 +00:00
Usage : legacyTunnelFlag ( "specify if this tunnel is running as a SOCK5 Server" ) ,
2020-09-29 09:47:50 +00:00
EnvVars : [ ] string { "TUNNEL_SOCKS" } ,
Value : false ,
2020-09-25 02:33:12 +00:00
Hidden : shouldHide ,
} ) ,
2018-10-08 19:20:28 +00:00
altsrc . NewDurationFlag ( & cli . DurationFlag {
2020-10-15 21:41:03 +00:00
Name : ingress . ProxyConnectTimeoutFlag ,
2022-02-28 10:57:08 +00:00
Usage : legacyTunnelFlag ( "HTTP proxy timeout for establishing a new connection" ) ,
2018-10-08 19:20:28 +00:00
Value : time . Second * 30 ,
Hidden : shouldHide ,
} ) ,
altsrc . NewDurationFlag ( & cli . DurationFlag {
2020-10-15 21:41:03 +00:00
Name : ingress . ProxyTLSTimeoutFlag ,
2022-02-28 10:57:08 +00:00
Usage : legacyTunnelFlag ( "HTTP proxy timeout for completing a TLS handshake" ) ,
2018-10-08 19:20:28 +00:00
Value : time . Second * 10 ,
Hidden : shouldHide ,
} ) ,
altsrc . NewDurationFlag ( & cli . DurationFlag {
2021-05-06 20:10:47 +00:00
Name : ingress . ProxyTCPKeepAliveFlag ,
2022-02-28 10:57:08 +00:00
Usage : legacyTunnelFlag ( "HTTP proxy TCP keepalive duration" ) ,
2018-10-08 19:20:28 +00:00
Value : time . Second * 30 ,
Hidden : shouldHide ,
} ) ,
altsrc . NewBoolFlag ( & cli . BoolFlag {
2020-10-15 21:41:03 +00:00
Name : ingress . ProxyNoHappyEyeballsFlag ,
2022-02-28 10:57:08 +00:00
Usage : legacyTunnelFlag ( "HTTP proxy should disable \"happy eyeballs\" for IPv4/v6 fallback" ) ,
2018-10-08 19:20:28 +00:00
Hidden : shouldHide ,
} ) ,
altsrc . NewIntFlag ( & cli . IntFlag {
2020-10-15 21:41:03 +00:00
Name : ingress . ProxyKeepAliveConnectionsFlag ,
2022-02-28 10:57:08 +00:00
Usage : legacyTunnelFlag ( "HTTP proxy maximum keepalive connection pool size" ) ,
2018-10-08 19:20:28 +00:00
Value : 100 ,
Hidden : shouldHide ,
} ) ,
altsrc . NewDurationFlag ( & cli . DurationFlag {
2020-10-15 21:41:03 +00:00
Name : ingress . ProxyKeepAliveTimeoutFlag ,
2022-02-28 10:57:08 +00:00
Usage : legacyTunnelFlag ( "HTTP proxy timeout for closing an idle connection" ) ,
2018-10-08 19:20:28 +00:00
Value : time . Second * 90 ,
Hidden : shouldHide ,
} ) ,
2019-06-18 16:47:29 +00:00
altsrc . NewDurationFlag ( & cli . DurationFlag {
Name : "proxy-connection-timeout" ,
2020-10-15 21:41:03 +00:00
Usage : "DEPRECATED. No longer has any effect." ,
2019-06-18 16:47:29 +00:00
Value : time . Second * 90 ,
Hidden : shouldHide ,
} ) ,
altsrc . NewDurationFlag ( & cli . DurationFlag {
Name : "proxy-expect-continue-timeout" ,
2020-10-15 21:41:03 +00:00
Usage : "DEPRECATED. No longer has any effect." ,
2019-06-18 16:47:29 +00:00
Value : time . Second * 90 ,
Hidden : shouldHide ,
} ) ,
2020-09-29 09:47:50 +00:00
altsrc . NewStringFlag ( & cli . StringFlag {
2020-10-15 21:41:03 +00:00
Name : ingress . HTTPHostHeaderFlag ,
2022-02-28 10:57:08 +00:00
Usage : legacyTunnelFlag ( "Sets the HTTP Host header for the local webserver." ) ,
2020-09-29 09:47:50 +00:00
EnvVars : [ ] string { "TUNNEL_HTTP_HOST_HEADER" } ,
2018-10-08 19:20:28 +00:00
Hidden : shouldHide ,
} ) ,
altsrc . NewStringFlag ( & cli . StringFlag {
2020-10-15 21:41:03 +00:00
Name : ingress . OriginServerNameFlag ,
2022-02-28 10:57:08 +00:00
Usage : legacyTunnelFlag ( "Hostname on the origin server certificate." ) ,
2020-09-29 09:47:50 +00:00
EnvVars : [ ] string { "TUNNEL_ORIGIN_SERVER_NAME" } ,
2018-10-08 19:20:28 +00:00
Hidden : shouldHide ,
} ) ,
2020-09-29 09:47:50 +00:00
altsrc . NewStringFlag ( & cli . StringFlag {
Name : "unix-socket" ,
Usage : "Path to unix socket to use instead of --url" ,
EnvVars : [ ] string { "TUNNEL_UNIX_SOCKET" } ,
2018-10-08 19:20:28 +00:00
Hidden : shouldHide ,
} ) ,
2020-09-29 09:47:50 +00:00
altsrc . NewStringFlag ( & cli . StringFlag {
Name : tlsconfig . OriginCAPoolFlag ,
2022-02-28 10:57:08 +00:00
Usage : legacyTunnelFlag ( "Path to the CA for the certificate of your origin. This option should be used only if your certificate is not signed by Cloudflare." ) ,
2020-09-29 09:47:50 +00:00
EnvVars : [ ] string { "TUNNEL_ORIGIN_CA_POOL" } ,
2020-04-04 20:49:36 +00:00
Hidden : shouldHide ,
} ) ,
2020-09-29 09:47:50 +00:00
altsrc . NewBoolFlag ( & cli . BoolFlag {
2020-10-15 21:41:03 +00:00
Name : ingress . NoTLSVerifyFlag ,
2022-02-28 10:57:08 +00:00
Usage : legacyTunnelFlag ( "Disables TLS verification of the certificate presented by your origin. Will allow any certificate from the origin to be accepted. Note: The connection from your machine to Cloudflare's Edge is still encrypted." ) ,
2020-09-29 09:47:50 +00:00
EnvVars : [ ] string { "NO_TLS_VERIFY" } ,
2018-10-08 19:20:28 +00:00
Hidden : shouldHide ,
} ) ,
altsrc . NewBoolFlag ( & cli . BoolFlag {
2020-10-15 21:41:03 +00:00
Name : ingress . NoChunkedEncodingFlag ,
2022-02-28 10:57:08 +00:00
Usage : legacyTunnelFlag ( "Disables chunked transfer encoding; useful if you are running a WSGI server." ) ,
2018-10-08 19:20:28 +00:00
EnvVars : [ ] string { "TUNNEL_NO_CHUNKED_ENCODING" } ,
Hidden : shouldHide ,
} ) ,
2022-06-01 00:51:59 +00:00
altsrc . NewBoolFlag ( & cli . BoolFlag {
Name : ingress . Http2OriginFlag ,
Usage : "Enables HTTP/2 origin servers." ,
EnvVars : [ ] string { "TUNNEL_ORIGIN_ENABLE_HTTP2" } ,
Hidden : shouldHide ,
Value : false ,
} ) ,
2023-03-21 18:42:25 +00:00
altsrc . NewStringFlag ( & cli . StringFlag {
Name : "management-hostname" ,
Usage : "Management hostname to signify incoming management requests" ,
EnvVars : [ ] string { "TUNNEL_MANAGEMENT_HOSTNAME" } ,
Hidden : true ,
Value : "management.argotunnel.com" ,
} ) ,
2020-09-16 12:15:49 +00:00
}
return append ( flags , sshFlags ( shouldHide ) ... )
}
2022-02-28 10:57:08 +00:00
func legacyTunnelFlag ( msg string ) string {
return fmt . Sprintf (
"%s This flag only takes effect if you define your origin with `--url` and if you do not use ingress rules." +
" The recommended way is to rely on ingress rules and define this property under `originRequest` as per" +
" https://developers.cloudflare.com/cloudflare-one/connections/connect-apps/configuration/configuration-file/ingress" ,
msg ,
)
}
2020-09-16 12:15:49 +00:00
func sshFlags ( shouldHide bool ) [ ] cli . Flag {
return [ ] cli . Flag {
2019-07-18 21:29:16 +00:00
altsrc . NewStringFlag ( & cli . StringFlag {
2019-08-28 15:48:30 +00:00
Name : sshPortFlag ,
2019-07-18 21:29:16 +00:00
Usage : "Localhost port that cloudflared SSH server will run on" ,
2019-09-04 15:37:53 +00:00
Value : "2222" ,
2019-07-18 21:29:16 +00:00
EnvVars : [ ] string { "LOCAL_SSH_PORT" } ,
Hidden : true ,
} ) ,
2019-08-28 15:48:30 +00:00
altsrc . NewDurationFlag ( & cli . DurationFlag {
Name : sshIdleTimeoutFlag ,
Usage : "Connection timeout after no activity" ,
EnvVars : [ ] string { "SSH_IDLE_TIMEOUT" } ,
Hidden : true ,
} ) ,
altsrc . NewDurationFlag ( & cli . DurationFlag {
Name : sshMaxTimeoutFlag ,
Usage : "Absolute connection timeout" ,
EnvVars : [ ] string { "SSH_MAX_TIMEOUT" } ,
Hidden : true ,
} ) ,
2019-08-26 20:56:17 +00:00
altsrc . NewStringFlag ( & cli . StringFlag {
Name : bucketNameFlag ,
Usage : "Bucket name of where to upload SSH logs" ,
EnvVars : [ ] string { "BUCKET_ID" } ,
Hidden : true ,
} ) ,
altsrc . NewStringFlag ( & cli . StringFlag {
Name : regionNameFlag ,
Usage : "Region name of where to upload SSH logs" ,
EnvVars : [ ] string { "REGION_ID" } ,
Hidden : true ,
} ) ,
altsrc . NewStringFlag ( & cli . StringFlag {
Name : secretIDFlag ,
Usage : "Secret ID of where to upload SSH logs" ,
EnvVars : [ ] string { "SECRET_ID" } ,
Hidden : true ,
} ) ,
2020-09-16 12:15:49 +00:00
altsrc . NewStringFlag ( & cli . StringFlag {
Name : accessKeyIDFlag ,
Usage : "Access Key ID of where to upload SSH logs" ,
EnvVars : [ ] string { "ACCESS_CLIENT_ID" } ,
Hidden : true ,
} ) ,
2019-08-26 20:56:17 +00:00
altsrc . NewStringFlag ( & cli . StringFlag {
Name : sessionTokenIDFlag ,
Usage : "Session Token to use in the configuration of SSH logs uploading" ,
EnvVars : [ ] string { "SESSION_TOKEN_ID" } ,
Hidden : true ,
} ) ,
altsrc . NewStringFlag ( & cli . StringFlag {
Name : s3URLFlag ,
Usage : "S3 url of where to upload SSH logs" ,
EnvVars : [ ] string { "S3_URL" } ,
Hidden : true ,
} ) ,
2019-10-17 21:23:06 +00:00
altsrc . NewPathFlag ( & cli . PathFlag {
Name : hostKeyPath ,
Usage : "Absolute path of directory to save SSH host keys in" ,
EnvVars : [ ] string { "HOST_KEY_PATH" } ,
Hidden : true ,
} ) ,
2020-03-27 14:39:59 +00:00
altsrc . NewBoolFlag ( & cli . BoolFlag {
2020-10-15 21:41:03 +00:00
Name : ingress . SSHServerFlag ,
2020-03-31 14:56:22 +00:00
Value : false ,
2020-09-16 12:15:49 +00:00
Usage : "Run an SSH Server" ,
EnvVars : [ ] string { "TUNNEL_SSH_SERVER" } ,
Hidden : true , // TODO: remove when feature is complete
2020-05-04 20:15:17 +00:00
} ) ,
altsrc . NewBoolFlag ( & cli . BoolFlag {
2020-10-15 21:41:03 +00:00
Name : config . BastionFlag ,
2020-05-04 20:15:17 +00:00
Value : false ,
Usage : "Runs as jump host" ,
EnvVars : [ ] string { "TUNNEL_BASTION" } ,
Hidden : shouldHide ,
2020-03-31 14:56:22 +00:00
} ) ,
2020-09-29 09:47:50 +00:00
altsrc . NewStringFlag ( & cli . StringFlag {
2020-10-15 21:41:03 +00:00
Name : ingress . ProxyAddressFlag ,
2020-09-29 09:47:50 +00:00
Usage : "Listen address for the proxy." ,
Value : "127.0.0.1" ,
EnvVars : [ ] string { "TUNNEL_PROXY_ADDRESS" } ,
Hidden : shouldHide ,
} ) ,
2021-01-14 13:08:55 +00:00
// Note TUN-3758 , we use Int because UInt is not supported with altsrc
2020-09-29 09:47:50 +00:00
altsrc . NewIntFlag ( & cli . IntFlag {
2020-10-15 21:41:03 +00:00
Name : ingress . ProxyPortFlag ,
2020-09-29 09:47:50 +00:00
Usage : "Listen port for the proxy." ,
Value : 0 ,
EnvVars : [ ] string { "TUNNEL_PROXY_PORT" } ,
Hidden : shouldHide ,
} ) ,
2020-03-27 14:39:59 +00:00
}
}
2020-09-29 09:47:50 +00:00
func configureLoggingFlags ( shouldHide bool ) [ ] cli . Flag {
return [ ] cli . Flag {
altsrc . NewStringFlag ( & cli . StringFlag {
2020-11-15 01:49:44 +00:00
Name : logger . LogLevelFlag ,
2020-09-29 09:47:50 +00:00
Value : "info" ,
2021-03-12 14:29:07 +00:00
Usage : "Application logging level {debug, info, warn, error, fatal}. " + debugLevelWarning ,
2020-09-29 09:47:50 +00:00
EnvVars : [ ] string { "TUNNEL_LOGLEVEL" } ,
Hidden : shouldHide ,
} ) ,
altsrc . NewStringFlag ( & cli . StringFlag {
2020-11-15 01:49:44 +00:00
Name : logger . LogTransportLevelFlag ,
2020-09-29 09:47:50 +00:00
Aliases : [ ] string { "proto-loglevel" } , // This flag used to be called proto-loglevel
2020-10-08 10:12:26 +00:00
Value : "info" ,
2021-03-12 14:29:07 +00:00
Usage : "Transport logging level(previously called protocol logging level) {debug, info, warn, error, fatal}" ,
2020-09-29 09:47:50 +00:00
EnvVars : [ ] string { "TUNNEL_PROTO_LOGLEVEL" , "TUNNEL_TRANSPORT_LOGLEVEL" } ,
Hidden : shouldHide ,
} ) ,
altsrc . NewStringFlag ( & cli . StringFlag {
2020-11-15 01:49:44 +00:00
Name : logger . LogFileFlag ,
2020-09-29 09:47:50 +00:00
Usage : "Save application log to this file for reporting issues." ,
EnvVars : [ ] string { "TUNNEL_LOGFILE" } ,
Hidden : shouldHide ,
} ) ,
altsrc . NewStringFlag ( & cli . StringFlag {
2020-11-15 01:49:44 +00:00
Name : logger . LogDirectoryFlag ,
2020-09-29 09:47:50 +00:00
Usage : "Save application log to this directory for reporting issues." ,
EnvVars : [ ] string { "TUNNEL_LOGDIRECTORY" } ,
Hidden : shouldHide ,
} ) ,
altsrc . NewStringFlag ( & cli . StringFlag {
Name : "trace-output" ,
Usage : "Name of trace output file, generated when cloudflared stops." ,
EnvVars : [ ] string { "TUNNEL_TRACE_OUTPUT" } ,
Hidden : shouldHide ,
} ) ,
}
}
func configureProxyDNSFlags ( shouldHide bool ) [ ] cli . Flag {
return [ ] cli . Flag {
altsrc . NewBoolFlag ( & cli . BoolFlag {
Name : "proxy-dns" ,
Usage : "Run a DNS over HTTPS proxy server." ,
EnvVars : [ ] string { "TUNNEL_DNS" } ,
Hidden : shouldHide ,
} ) ,
altsrc . NewIntFlag ( & cli . IntFlag {
Name : "proxy-dns-port" ,
Value : 53 ,
Usage : "Listen on given port for the DNS over HTTPS proxy server." ,
EnvVars : [ ] string { "TUNNEL_DNS_PORT" } ,
Hidden : shouldHide ,
} ) ,
altsrc . NewStringFlag ( & cli . StringFlag {
Name : "proxy-dns-address" ,
Usage : "Listen address for the DNS over HTTPS proxy server." ,
Value : "localhost" ,
EnvVars : [ ] string { "TUNNEL_DNS_ADDRESS" } ,
Hidden : shouldHide ,
} ) ,
altsrc . NewStringSliceFlag ( & cli . StringSliceFlag {
Name : "proxy-dns-upstream" ,
Usage : "Upstream endpoint URL, you can specify multiple endpoints for redundancy." ,
Value : cli . NewStringSlice ( "https://1.1.1.1/dns-query" , "https://1.0.0.1/dns-query" ) ,
EnvVars : [ ] string { "TUNNEL_DNS_UPSTREAM" } ,
Hidden : shouldHide ,
} ) ,
2021-02-12 17:32:29 +00:00
altsrc . NewIntFlag ( & cli . IntFlag {
Name : "proxy-dns-max-upstream-conns" ,
Usage : "Maximum concurrent connections to upstream. Setting to 0 means unlimited." ,
Value : tunneldns . MaxUpstreamConnsDefault ,
Hidden : shouldHide ,
EnvVars : [ ] string { "TUNNEL_DNS_MAX_UPSTREAM_CONNS" } ,
} ) ,
2020-09-29 09:47:50 +00:00
altsrc . NewStringSliceFlag ( & cli . StringSliceFlag {
2020-12-28 18:10:01 +00:00
Name : "proxy-dns-bootstrap" ,
Usage : "bootstrap endpoint URL, you can specify multiple endpoints for redundancy." ,
Value : cli . NewStringSlice (
"https://162.159.36.1/dns-query" ,
"https://162.159.46.1/dns-query" ,
"https://[2606:4700:4700::1111]/dns-query" ,
"https://[2606:4700:4700::1001]/dns-query" ,
) ,
2020-09-29 09:47:50 +00:00
EnvVars : [ ] string { "TUNNEL_DNS_BOOTSTRAP" } ,
Hidden : shouldHide ,
} ) ,
}
2020-09-16 12:15:49 +00:00
}
2022-02-07 09:42:07 +00:00
func stdinControl ( reconnectCh chan supervisor . ReconnectSignal , log * zerolog . Logger ) {
2020-03-27 14:39:59 +00:00
for {
scanner := bufio . NewScanner ( os . Stdin )
for scanner . Scan ( ) {
command := scanner . Text ( )
2020-04-30 05:02:08 +00:00
parts := strings . SplitN ( command , " " , 2 )
2020-03-27 14:39:59 +00:00
2020-04-30 05:02:08 +00:00
switch parts [ 0 ] {
case "" :
break
2020-03-27 14:39:59 +00:00
case "reconnect" :
2022-02-07 09:42:07 +00:00
var reconnect supervisor . ReconnectSignal
2020-04-30 05:02:08 +00:00
if len ( parts ) > 1 {
var err error
if reconnect . Delay , err = time . ParseDuration ( parts [ 1 ] ) ; err != nil {
2020-11-25 06:55:13 +00:00
log . Error ( ) . Msg ( err . Error ( ) )
2020-04-30 05:02:08 +00:00
continue
}
}
2021-01-20 19:41:09 +00:00
log . Info ( ) . Msgf ( "Sending %+v" , reconnect )
2020-04-30 05:02:08 +00:00
reconnectCh <- reconnect
2020-03-27 14:39:59 +00:00
default :
2020-12-28 18:10:01 +00:00
log . Info ( ) . Str ( LogFieldCommand , command ) . Msg ( "Unknown command" )
2020-04-30 05:02:08 +00:00
fallthrough
case "help" :
2020-11-25 06:55:13 +00:00
log . Info ( ) . Msg ( ` Supported command :
2020-06-16 22:43:22 +00:00
reconnect [ delay ]
2020-04-30 05:02:08 +00:00
- restarts one randomly chosen connection with optional delay before reconnect ` )
2020-03-27 14:39:59 +00:00
}
}
2018-10-08 19:20:28 +00:00
}
2019-12-04 17:22:08 +00:00
}