@@ -32,6 +32,7 @@ import (
3232 "github.com/cloudflare/cloudflared/supervisor"
3333 "github.com/cloudflare/cloudflared/tlsconfig"
3434 tunnelpogs "github.com/cloudflare/cloudflared/tunnelrpc/pogs"
35+ "github.com/cloudflare/cloudflared/validation"
3536)
3637
3738const LogFieldOriginCertPath = "originCertPath"
4243 serviceUrl = developerPortal + "/reference/service/"
4344 argumentsUrl = developerPortal + "/reference/arguments/"
4445
46+ LogFieldHostname = "hostname"
47+
4548 secretFlags = [2 ]* altsrc.StringFlag {credentialsContentsFlag , tunnelTokenFlag }
4649 defaultFeatures = []string {supervisor .FeatureAllowRemoteConfig , supervisor .FeatureSerializedHeaders , supervisor .FeatureDatagramV2 , supervisor .FeatureQUICSupportEOF }
4750
@@ -124,7 +127,7 @@ func isSecretEnvVar(key string) bool {
124127}
125128
126129func dnsProxyStandAlone (c * cli.Context , namedTunnel * connection.NamedTunnelProperties ) bool {
127- return c .IsSet ("proxy-dns" ) && (! c .IsSet ("tag" ) && ! c .IsSet ("hello-world" ) && namedTunnel == nil )
130+ return c .IsSet ("proxy-dns" ) && (! c .IsSet ("hostname" ) && ! c . IsSet ( " tag" ) && ! c .IsSet ("hello-world" ) && namedTunnel == nil )
128131}
129132
130133func findOriginCert (originCertPath string , log * zerolog.Logger ) (string , error ) {
@@ -190,19 +193,37 @@ func prepareTunnelConfig(
190193 observer * connection.Observer ,
191194 namedTunnel * connection.NamedTunnelProperties ,
192195) (* supervisor.TunnelConfig , * orchestration.Config , error ) {
193- clientID , err := uuid .NewRandom ()
196+ isNamedTunnel := namedTunnel != nil
197+
198+ configHostname := c .String ("hostname" )
199+ hostname , err := validation .ValidateHostname (configHostname )
194200 if err != nil {
195- return nil , nil , errors .Wrap (err , "can't generate connector UUID" )
201+ log .Err (err ).Str (LogFieldHostname , configHostname ).Msg ("Invalid hostname" )
202+ return nil , nil , errors .Wrap (err , "Invalid hostname" )
203+ }
204+ clientID := c .String ("id" )
205+ if ! c .IsSet ("id" ) {
206+ clientID , err = generateRandomClientID (log )
207+ if err != nil {
208+ return nil , nil , err
209+ }
196210 }
197- log . Info (). Msgf ( "Generated Connector ID: %s" , clientID )
211+
198212 tags , err := NewTagSliceFromCLI (c .StringSlice ("tag" ))
199213 if err != nil {
200214 log .Err (err ).Msg ("Tag parse failure" )
201215 return nil , nil , errors .Wrap (err , "Tag parse failure" )
202216 }
203- tags = append (tags , tunnelpogs.Tag {Name : "ID" , Value : clientID .String ()})
217+
218+ tags = append (tags , tunnelpogs.Tag {Name : "ID" , Value : clientID })
219+
220+ var (
221+ ingressRules ingress.Ingress
222+ classicTunnel * connection.ClassicTunnelProperties
223+ )
204224
205225 transportProtocol := c .String ("protocol" )
226+
206227 needPQ := c .Bool ("post-quantum" )
207228 if needPQ {
208229 if FipsEnabled {
@@ -217,52 +238,79 @@ func prepareTunnelConfig(
217238
218239 protocolFetcher := edgediscovery .ProtocolPercentage
219240
220- features := append (c .StringSlice ("features" ), defaultFeatures ... )
221- if needPQ {
222- features = append (features , supervisor .FeaturePostQuantum )
223- }
224- if c .IsSet (TunnelTokenFlag ) {
225- if transportProtocol == connection .AutoSelectFlag {
226- protocolFetcher = func () (edgediscovery.ProtocolPercents , error ) {
227- // If the Tunnel is remotely managed and no protocol is set, we prefer QUIC, but still allow fall-back.
228- preferQuic := []edgediscovery.ProtocolPercent {
229- {
230- Protocol : connection .QUIC .String (),
231- Percentage : 100 ,
232- },
233- {
234- Protocol : connection .HTTP2 .String (),
235- Percentage : 100 ,
236- },
241+ cfg := config .GetConfiguration ()
242+ if isNamedTunnel {
243+ clientUUID , err := uuid .NewRandom ()
244+ if err != nil {
245+ return nil , nil , errors .Wrap (err , "can't generate connector UUID" )
246+ }
247+ log .Info ().Msgf ("Generated Connector ID: %s" , clientUUID )
248+ features := append (c .StringSlice ("features" ), defaultFeatures ... )
249+ if needPQ {
250+ features = append (features , supervisor .FeaturePostQuantum )
251+ }
252+ if c .IsSet (TunnelTokenFlag ) {
253+ if transportProtocol == connection .AutoSelectFlag {
254+ protocolFetcher = func () (edgediscovery.ProtocolPercents , error ) {
255+ // If the Tunnel is remotely managed and no protocol is set, we prefer QUIC, but still allow fall-back.
256+ preferQuic := []edgediscovery.ProtocolPercent {
257+ {
258+ Protocol : connection .QUIC .String (),
259+ Percentage : 100 ,
260+ },
261+ {
262+ Protocol : connection .HTTP2 .String (),
263+ Percentage : 100 ,
264+ },
265+ }
266+ return preferQuic , nil
237267 }
238- return preferQuic , nil
239268 }
269+ log .Info ().Msg ("Will be fetching remotely managed configuration from Cloudflare API. Defaulting to protocol: quic" )
240270 }
241- log .Info ().Msg ("Will be fetching remotely managed configuration from Cloudflare API. Defaulting to protocol: quic" )
242- }
243- namedTunnel .Client = tunnelpogs.ClientInfo {
244- ClientID : clientID [:],
245- Features : dedup (features ),
246- Version : info .Version (),
247- Arch : info .OSArch (),
248- }
249- cfg := config .GetConfiguration ()
250- ingressRules , err := ingress .ParseIngress (cfg )
251- if err != nil && err != ingress .ErrNoIngressRules {
252- return nil , nil , err
253- }
254- // Only for quick tunnels will we attempt to parse the --url flag for a tunnel ingress rule
255- if ingressRules .IsEmpty () && c .IsSet ("url" ) && namedTunnel .QuickTunnelUrl != "" {
256- ingressRules , err = ingress .NewSingleOrigin (c , true )
257- if err != nil {
271+ namedTunnel .Client = tunnelpogs.ClientInfo {
272+ ClientID : clientUUID [:],
273+ Features : dedup (features ),
274+ Version : info .Version (),
275+ Arch : info .OSArch (),
276+ }
277+ ingressRules , err = ingress .ParseIngress (cfg )
278+ if err != nil && err != ingress .ErrNoIngressRules {
258279 return nil , nil , err
259280 }
281+ if ! ingressRules .IsEmpty () && c .IsSet ("url" ) {
282+ return nil , nil , ingress .ErrURLIncompatibleWithIngress
283+ }
284+ } else {
285+
286+ originCertPath := c .String ("origincert" )
287+ originCertLog := log .With ().
288+ Str (LogFieldOriginCertPath , originCertPath ).
289+ Logger ()
290+
291+ originCert , err := getOriginCert (originCertPath , & originCertLog )
292+ if err != nil {
293+ return nil , nil , errors .Wrap (err , "Error getting origin cert" )
294+ }
295+
296+ classicTunnel = & connection.ClassicTunnelProperties {
297+ Hostname : hostname ,
298+ OriginCert : originCert ,
299+ // turn off use of reconnect token and auth refresh when using named tunnels
300+ UseReconnectToken : ! isNamedTunnel && c .Bool ("use-reconnect-token" ),
301+ }
260302 }
303+
304+ // Convert single-origin configuration into multi-origin configuration.
261305 if ingressRules .IsEmpty () {
262- return nil , nil , ingress .ErrNoIngressRules
306+ ingressRules , err = ingress .NewSingleOrigin (c , ! isNamedTunnel )
307+ if err != nil {
308+ return nil , nil , err
309+ }
263310 }
264311
265- protocolSelector , err := connection .NewProtocolSelector (transportProtocol , cfg .WarpRouting .Enabled , namedTunnel , protocolFetcher , supervisor .ResolveTTL , log , c .Bool ("post-quantum" ))
312+ warpRoutingEnabled := isWarpRoutingEnabled (cfg .WarpRouting , isNamedTunnel )
313+ protocolSelector , err := connection .NewProtocolSelector (transportProtocol , warpRoutingEnabled , namedTunnel , protocolFetcher , supervisor .ResolveTTL , log , c .Bool ("post-quantum" ))
266314 if err != nil {
267315 return nil , nil , err
268316 }
@@ -314,7 +362,7 @@ func prepareTunnelConfig(
314362 GracePeriod : gracePeriod ,
315363 ReplaceExisting : c .Bool ("force" ),
316364 OSArch : info .OSArch (),
317- ClientID : clientID . String () ,
365+ ClientID : clientID ,
318366 EdgeAddrs : c .StringSlice ("edge" ),
319367 Region : c .String ("region" ),
320368 EdgeIPVersion : edgeIPVersion ,
@@ -331,6 +379,7 @@ func prepareTunnelConfig(
331379 Retries : uint (c .Int ("retries" )),
332380 RunFromTerminal : isRunningFromTerminal (),
333381 NamedTunnel : namedTunnel ,
382+ ClassicTunnel : classicTunnel ,
334383 MuxerConfig : muxerConfig ,
335384 ProtocolSelector : protocolSelector ,
336385 EdgeTLSConfigs : edgeTLSConfigs ,
@@ -372,6 +421,10 @@ func gracePeriod(c *cli.Context) (time.Duration, error) {
372421 return period , nil
373422}
374423
424+ func isWarpRoutingEnabled (warpConfig config.WarpRoutingConfig , isNamedTunnel bool ) bool {
425+ return warpConfig .Enabled && isNamedTunnel
426+ }
427+
375428func isRunningFromTerminal () bool {
376429 return terminal .IsTerminal (int (os .Stdout .Fd ()))
377430}
0 commit comments