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"
2019-11-12 18:50:41 +00:00
"reflect"
2018-10-08 19:20:28 +00:00
"runtime/trace"
2020-04-30 05:02:08 +00:00
"strings"
2018-10-08 19:20:28 +00:00
"sync"
"time"
2019-06-17 21:18:47 +00:00
"github.com/cloudflare/cloudflared/cmd/cloudflared/buildinfo"
2020-05-18 18:24:17 +00:00
"github.com/cloudflare/cloudflared/cmd/cloudflared/cliutil"
2018-10-08 19:20:28 +00:00
"github.com/cloudflare/cloudflared/cmd/cloudflared/config"
2020-07-29 22:48:27 +00:00
"github.com/cloudflare/cloudflared/cmd/cloudflared/ui"
2018-10-08 19:20:28 +00:00
"github.com/cloudflare/cloudflared/cmd/cloudflared/updater"
2020-10-08 10:12:26 +00:00
"github.com/cloudflare/cloudflared/connection"
2019-11-12 18:50:41 +00:00
"github.com/cloudflare/cloudflared/dbconnect"
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"
2018-10-08 19:20:28 +00:00
"github.com/cloudflare/cloudflared/metrics"
"github.com/cloudflare/cloudflared/origin"
2019-03-04 19:48:56 +00:00
"github.com/cloudflare/cloudflared/signal"
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"
2020-07-30 17:00:57 +00:00
"github.com/cloudflare/cloudflared/tunnelstore"
2019-07-18 21:29:16 +00:00
2018-10-08 19:20:28 +00:00
"github.com/coreos/go-systemd/daemon"
"github.com/facebookgo/grace/gracenet"
2019-07-18 21:29:16 +00:00
"github.com/getsentry/raven-go"
2020-04-28 00:55:27 +00:00
"github.com/mitchellh/go-homedir"
2018-10-08 19:20:28 +00:00
"github.com/pkg/errors"
2020-11-25 06:55:13 +00:00
"github.com/rs/zerolog"
2020-08-05 10:49:53 +00:00
"github.com/urfave/cli/v2"
"github.com/urfave/cli/v2/altsrc"
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"
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"
2020-04-29 20:51:32 +00:00
debugLevelWarning = "At debug level, request URL, method, protocol, content legnth and header will be logged. " +
"Response status, content length and header will also be logged in debug level."
2020-12-28 18:10:01 +00:00
LogFieldCommand = "command"
LogFieldExpandedPath = "expandedPath"
LogFieldPIDPathname = "pidPathname"
LogFieldTmpTraceFilename = "tmpTraceFilename"
LogFieldTraceOutputFilepath = "traceOutputFilepath"
2019-08-28 15:48:30 +00:00
)
2018-10-08 19:20:28 +00:00
var (
graceShutdownC chan struct { }
version string
)
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 ( ) ,
buildRunCommand ( ) ,
buildListCommand ( ) ,
buildIngressSubcommand ( ) ,
buildDeleteCommand ( ) ,
buildCleanupCommand ( ) ,
// for compatibility, allow following as tunnel subcommands
tunneldns . Command ( true ) ,
2019-11-12 18:50:41 +00:00
dbConnectCmd ( ) ,
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 ) ,
dbConnectCmd ( ) ,
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" ,
2020-07-30 17:00:57 +00:00
Action : cliutil . ErrorHandler ( TunnelCommand ) ,
2020-10-09 17:07:08 +00:00
Before : SetFlagsFromConfigFile ,
2018-10-08 19:20:28 +00:00
Category : "Tunnel" ,
Usage : "Make a locally-running web service accessible over the internet using Argo Tunnel." ,
2020-05-21 20:36:49 +00:00
ArgsUsage : " " ,
2018-10-08 19:20:28 +00:00
Description : ` Argo Tunnel asks you to specify a hostname on a Cloudflare - powered
domain you control and a local address . Traffic from that hostname is routed
( optionally via a Cloudflare Load Balancer ) to this machine and appears on the
specified port where it can be served .
This feature requires your Cloudflare account be subscribed to the Argo Smart Routing feature .
To use , begin by calling login to download a certificate :
2020-09-16 12:15:49 +00:00
$ cloudflared tunnel login
2018-10-08 19:20:28 +00:00
With your certificate installed you can then launch your first tunnel ,
replacing my . site . com with a subdomain of your site :
2020-09-16 12:15:49 +00:00
$ cloudflared tunnel -- hostname my . site . com -- url http : //localhost:8080
2018-10-08 19:20:28 +00:00
If you have a web server running on port 8080 ( in this example ) , it will be available on
the internet ! ` ,
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
}
2020-09-01 16:06:00 +00:00
if name := c . String ( "name" ) ; name != "" { // Start a named tunnel
2020-10-15 20:08:57 +00:00
return runAdhocNamedTunnel ( sc , name )
2020-07-30 17:00:57 +00:00
}
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
}
// Start a classic tunnel
return runClassicTunnel ( sc )
2018-10-08 19:20:28 +00:00
}
2021-01-25 21:51:58 +00:00
func Init ( ver string , gracefulShutdown chan struct { } ) {
version , graceShutdownC = ver , 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
func runAdhocNamedTunnel ( sc * subcommandContext , name string ) error {
2020-07-30 17:00:57 +00:00
tunnel , ok , err := sc . tunnelActive ( name )
if err != nil || ! ok {
tunnel , err = sc . create ( name )
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 {
2020-12-28 18:10:01 +00:00
sc . log . Err ( err ) . Msg ( "failed to create route, please create it manually" )
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
}
2020-10-15 20:08:57 +00:00
// runClassicTunnel creates a "classic" non-named tunnel
func runClassicTunnel ( sc * subcommandContext ) error {
2021-01-20 19:41:09 +00:00
return StartServer ( sc . c , version , nil , sc . log , sc . isUIEnabled )
2020-09-01 16:06:00 +00:00
}
func routeFromFlag ( c * cli . Context ) ( tunnelstore . Route , bool ) {
2020-07-30 17:00:57 +00:00
if hostname := c . String ( "hostname" ) ; hostname != "" {
if lbPool := c . String ( "lb-pool" ) ; lbPool != "" {
return tunnelstore . NewLBRoute ( hostname , lbPool ) , true
}
return tunnelstore . NewDNSRoute ( hostname ) , true
}
return nil , false
}
2020-09-01 16:06:00 +00:00
func StartServer (
c * cli . Context ,
version string ,
2020-10-08 10:12:26 +00:00
namedTunnel * connection . NamedTunnelConfig ,
2020-11-25 06:55:13 +00:00
log * zerolog . Logger ,
2020-09-01 16:06:00 +00:00
isUIEnabled bool ,
) error {
2019-01-07 20:30:22 +00:00
_ = raven . SetDSN ( sentryDSN )
2018-10-08 19:20:28 +00:00
var wg sync . WaitGroup
listeners := gracenet . Net { }
errC := make ( chan error )
2020-10-19 22:33:40 +00:00
if config . GetConfiguration ( ) . Source ( ) == "" {
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 ( )
}
2019-06-17 21:18:47 +00:00
buildInfo := buildinfo . GetBuildInfo ( version )
2020-11-25 06:55:13 +00:00
buildInfo . Log ( log )
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
2020-11-25 06:55:13 +00:00
if updater . IsAutoupdateEnabled ( c , log ) {
2020-12-28 18:10:01 +00:00
autoupdateFreq := c . Duration ( "autoupdate-freq" )
log . Info ( ) . Dur ( "autoupdateFreq" , autoupdateFreq ) . Msg ( "Autoupdate frequency is set" )
2019-06-18 16:47:29 +00:00
wg . Add ( 1 )
go func ( ) {
defer wg . Done ( )
2020-11-25 06:55:13 +00:00
autoupdater := updater . NewAutoUpdater ( c . Duration ( "autoupdate-freq" ) , & listeners , log )
2019-06-18 16:47:29 +00:00
errC <- autoupdater . Run ( ctx )
} ( )
}
2018-10-08 19:20:28 +00:00
// Serve DNS proxy stand-alone if no hostname or tag or app is going to run
if dnsProxyStandAlone ( c ) {
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
}
2020-06-05 20:10:09 +00:00
url := c . String ( "url" )
hostname := c . String ( "hostname" )
if url == hostname && url != "" && hostname != "" {
errText := "hostname and url shouldn't match. See --help for more information"
2020-11-25 06:55:13 +00:00
log . Error ( ) . Msg ( errText )
2020-06-05 20:10:09 +00:00
return fmt . Errorf ( errText )
}
2020-11-25 06:55:13 +00:00
transportLog := logger . CreateTransportLoggerFromContext ( c , isUIEnabled )
2020-04-29 20:51:32 +00:00
2021-01-14 22:33:36 +00:00
observer := connection . NewObserver ( log , isUIEnabled )
tunnelConfig , ingressRules , err := prepareTunnelConfig ( c , buildInfo , version , log , 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
}
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 ( )
2021-01-14 22:33:36 +00:00
readinessServer := metrics . NewReadyServer ( log )
observer . RegisterSink ( readinessServer )
2021-01-25 21:51:58 +00:00
errC <- metrics . ServeMetrics ( metricsListener , ctx . Done ( ) , readinessServer , log )
2020-11-30 20:05:37 +00:00
} ( )
2021-01-25 21:51:58 +00:00
if err := ingressRules . StartOrigins ( & wg , log , ctx . Done ( ) , errC ) ; err != nil {
2020-12-30 19:48:19 +00:00
return err
}
2020-10-15 21:41:03 +00:00
2020-04-30 05:02:08 +00:00
reconnectCh := make ( chan origin . ReconnectSignal , 1 )
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" )
} ( )
2021-01-20 19:41:09 +00:00
errC <- origin . StartTunnelDaemon ( ctx , tunnelConfig , connectedSignal , reconnectCh , graceShutdownC )
2018-10-08 19:20:28 +00:00
} ( )
2020-04-29 20:51:32 +00:00
2020-09-01 16:06:00 +00:00
if isUIEnabled {
2021-01-14 22:33:36 +00:00
tunnelUI := ui . NewUIModel (
2020-09-01 16:06:00 +00:00
version ,
hostname ,
metricsListener . Addr ( ) . String ( ) ,
2020-11-02 11:21:34 +00:00
& ingressRules ,
2020-09-01 16:06:00 +00:00
tunnelConfig . HAConnections ,
)
2021-01-14 22:33:36 +00:00
app := tunnelUI . Launch ( ctx , log , transportLog )
observer . RegisterSink ( app )
2020-07-24 22:17:17 +00:00
}
2021-01-25 21:51:58 +00:00
return waitToShutdown ( & wg , cancel , errC , graceShutdownC , c . Duration ( "grace-period" ) , log )
2020-06-25 18:25:39 +00:00
}
2020-10-09 17:07:08 +00:00
func SetFlagsFromConfigFile ( c * cli . Context ) error {
2020-10-21 10:11:35 +00:00
const exitCode = 1
2020-11-25 06:55:13 +00:00
log := logger . CreateLoggerFromContext ( c , logger . EnableTerminalLog )
2020-10-19 22:33:40 +00:00
inputSource , err := config . ReadConfigFile ( c , log )
2018-10-08 19:20:28 +00:00
if err != nil {
2020-10-15 20:08:57 +00:00
if err == config . ErrNoConfigFile {
return nil
}
2020-10-21 10:11:35 +00:00
return cli . Exit ( err , exitCode )
2020-10-09 17:07:08 +00:00
}
2020-10-15 20:08:57 +00:00
targetFlags := c . Command . Flags
if c . Command . Name == "" {
targetFlags = c . App . Flags
}
if err := altsrc . ApplyInputSourceValues ( c , inputSource , targetFlags ) ; err != nil {
2020-10-21 10:11:35 +00:00
return cli . Exit ( err , exitCode )
2018-10-08 19:20:28 +00:00
}
return nil
}
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 )
}
2019-11-12 18:50:41 +00:00
func dbConnectCmd ( ) * cli . Command {
cmd := dbconnect . Cmd ( )
// Append the tunnel commands so users can customize the daemon settings.
cmd . Flags = appendFlags ( Flags ( ) , cmd . Flags ... )
// Override before to run tunnel validation before dbconnect validation.
cmd . Before = func ( c * cli . Context ) error {
2020-10-09 17:07:08 +00:00
err := SetFlagsFromConfigFile ( c )
2019-11-12 18:50:41 +00:00
if err == nil {
err = dbconnect . CmdBefore ( c )
}
return err
}
// Override action to setup the Proxy, then if successful, start the tunnel daemon.
2020-05-18 18:24:17 +00:00
cmd . Action = cliutil . ErrorHandler ( func ( c * cli . Context ) error {
2019-11-12 18:50:41 +00:00
err := dbconnect . CmdAction ( c )
if err == nil {
2020-07-30 17:00:57 +00:00
err = TunnelCommand ( c )
2019-11-12 18:50:41 +00:00
}
return err
2020-05-18 18:24:17 +00:00
} )
2019-11-12 18:50:41 +00:00
return cmd
}
// appendFlags will append extra flags to a slice of flags.
//
// The cli package will panic if two flags exist with the same name,
// so if extraFlags contains a flag that was already defined, modify the
// original flags to use the extra version.
func appendFlags ( flags [ ] cli . Flag , extraFlags ... cli . Flag ) [ ] cli . Flag {
for _ , extra := range extraFlags {
var found bool
// Check if an extra flag overrides an existing flag.
for i , flag := range flags {
if reflect . DeepEqual ( extra . Names ( ) , flag . Names ( ) ) {
flags [ i ] = extra
found = true
break
}
}
// Append the extra flag if it has nothing to override.
if ! found {
flags = append ( flags , extra )
}
}
return flags
}
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 {
2018-10-08 19:20:28 +00:00
altsrc . NewBoolFlag ( & cli . BoolFlag {
Name : "is-autoupdated" ,
Usage : "Signal the new process that Argo Tunnel client has been autoupdated" ,
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 ,
} ) ,
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 ,
} ) ,
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 {
Name : "ha-connections" ,
Value : 4 ,
Hidden : true ,
} ) ,
altsrc . NewDurationFlag ( & cli . DurationFlag {
Name : "grace-period" ,
Usage : "Duration to accept new requests after cloudflared receives first SIGINT/SIGTERM. A second SIGINT/SIGTERM will force cloudflared to shutdown immediately." ,
Value : time . Second * 30 ,
EnvVars : [ ] string { "TUNNEL_GRACE_PERIOD" } ,
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 {
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" ,
EnvVars : [ ] string { "STDIN-CONTROL" } ,
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" ,
} ) ,
altsrc . NewBoolFlag ( & cli . BoolFlag {
Name : uiFlag ,
Usage : "Launch tunnel UI. Tunnel logs are scrollable via 'j', 'k', or arrow keys." ,
Value : false ,
Hidden : shouldHide ,
} ) ,
2020-10-08 09:48:10 +00:00
selectProtocolFlag ,
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 {
Name : "hello-world" ,
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 ,
2020-09-29 09:47:50 +00:00
Usage : "specify if this tunnel is running as a SOCK5 Server" ,
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 ,
2018-10-08 19:20:28 +00:00
Usage : "HTTP proxy timeout for establishing a new connection" ,
Value : time . Second * 30 ,
Hidden : shouldHide ,
} ) ,
altsrc . NewDurationFlag ( & cli . DurationFlag {
2020-10-15 21:41:03 +00:00
Name : ingress . ProxyTLSTimeoutFlag ,
2018-10-08 19:20:28 +00:00
Usage : "HTTP proxy timeout for completing a TLS handshake" ,
Value : time . Second * 10 ,
Hidden : shouldHide ,
} ) ,
altsrc . NewDurationFlag ( & cli . DurationFlag {
2020-10-15 21:41:03 +00:00
Name : ingress . ProxyTCPKeepAlive ,
2018-10-08 19:20:28 +00:00
Usage : "HTTP proxy TCP keepalive duration" ,
Value : time . Second * 30 ,
Hidden : shouldHide ,
} ) ,
altsrc . NewBoolFlag ( & cli . BoolFlag {
2020-10-15 21:41:03 +00:00
Name : ingress . ProxyNoHappyEyeballsFlag ,
2018-10-08 19:20:28 +00:00
Usage : "HTTP proxy should disable \"happy eyeballs\" for IPv4/v6 fallback" ,
Hidden : shouldHide ,
} ) ,
altsrc . NewIntFlag ( & cli . IntFlag {
2020-10-15 21:41:03 +00:00
Name : ingress . ProxyKeepAliveConnectionsFlag ,
2018-10-08 19:20:28 +00:00
Usage : "HTTP proxy maximum keepalive connection pool size" ,
Value : 100 ,
Hidden : shouldHide ,
} ) ,
altsrc . NewDurationFlag ( & cli . DurationFlag {
2020-10-15 21:41:03 +00:00
Name : ingress . ProxyKeepAliveTimeoutFlag ,
2018-10-08 19:20:28 +00:00
Usage : "HTTP proxy timeout for closing an idle connection" ,
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 ,
2020-09-29 09:47:50 +00:00
Usage : "Sets the HTTP Host header for the local webserver." ,
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 ,
2020-09-29 09:47:50 +00:00
Usage : "Hostname on the origin server certificate." ,
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 ,
Usage : "Path to the CA for the certificate of your origin. This option should be used only if your certificate is not signed by Cloudflare." ,
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 ,
2020-09-29 09:47:50 +00:00
Usage : "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." ,
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 ,
2018-10-08 19:20:28 +00:00
Usage : "Disables chunked transfer encoding; useful if you are running a WSGI server." ,
EnvVars : [ ] string { "TUNNEL_NO_CHUNKED_ENCODING" } ,
Hidden : shouldHide ,
} ) ,
2020-09-16 12:15:49 +00:00
}
return append ( flags , sshFlags ( shouldHide ) ... )
}
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" ,
Usage : "Application logging level {fatal, error, info, debug}. " + debugLevelWarning ,
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" ,
2020-09-29 09:47:50 +00:00
Usage : "Transport logging level(previously called protocol logging level) {fatal, error, info, debug}" ,
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 ,
} ) ,
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
}
2020-11-25 06:55:13 +00:00
func stdinControl ( reconnectCh chan origin . 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" :
2020-04-30 05:02:08 +00:00
var reconnect origin . ReconnectSignal
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
}