Skip to content

Commit c24f275

Browse files
committed
TUN-7065: Remove classic tunnel creation
1 parent d8f2b76 commit c24f275

File tree

9 files changed

+50
-254
lines changed

9 files changed

+50
-254
lines changed

cmd/cloudflared/main.go

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -155,8 +155,6 @@ func action(graceShutdownC chan struct{}) cli.ActionFunc {
155155
if isEmptyInvocation(c) {
156156
return handleServiceMode(c, graceShutdownC)
157157
}
158-
tags := make(map[string]string)
159-
tags["hostname"] = c.String("hostname")
160158
func() {
161159
defer sentry.Recover()
162160
err = tunnel.TunnelCommand(c)

cmd/cloudflared/tunnel/cmd.go

Lines changed: 4 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ var (
100100
routeFailMsg = fmt.Sprintf("failed to provision routing, please create it manually via Cloudflare dashboard or UI; "+
101101
"most likely you already have a conflicting record there. You can also rerun this command with --%s to overwrite "+
102102
"any existing DNS records for this hostname.", overwriteDNSFlag)
103+
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/)")
103104
)
104105

105106
func Flags() []cli.Flag {
@@ -182,17 +183,17 @@ func TunnelCommand(c *cli.Context) error {
182183

183184
// Unauthenticated named tunnel on <random>.<quick-tunnels-service>.com
184185
shouldRunQuickTunnel := c.IsSet("url") || c.IsSet("hello-world")
185-
if !dnsProxyStandAlone(c, nil) && c.String("hostname") == "" && c.String("quick-service") != "" && shouldRunQuickTunnel {
186+
if !dnsProxyStandAlone(c, nil) && c.String("quick-service") != "" && shouldRunQuickTunnel {
186187
return RunQuickTunnel(sc)
187188
}
188189

189190
if ref := config.GetConfiguration().TunnelID; ref != "" {
190191
return fmt.Errorf("Use `cloudflared tunnel run` to start tunnel %s", ref)
191192
}
192193

193-
// Start a classic tunnel if hostname is specified.
194+
// classic tunnel usage is no longer supported
194195
if c.String("hostname") != "" {
195-
return runClassicTunnel(sc)
196+
return deprecatedClassicTunnelErr
196197
}
197198

198199
if c.IsSet("proxy-dns") {
@@ -237,11 +238,6 @@ func runAdhocNamedTunnel(sc *subcommandContext, name, credentialsOutputPath stri
237238
return nil
238239
}
239240

240-
// runClassicTunnel creates a "classic" non-named tunnel
241-
func runClassicTunnel(sc *subcommandContext) error {
242-
return StartServer(sc.c, buildInfo, nil, sc.log)
243-
}
244-
245241
func routeFromFlag(c *cli.Context) (route cfapi.HostnameRoute, ok bool) {
246242
if hostname := c.String("hostname"); hostname != "" {
247243
if lbPool := c.String("lb-pool"); lbPool != "" {
@@ -350,14 +346,6 @@ func StartServer(
350346
return waitToShutdown(&wg, cancel, errC, graceShutdownC, 0, log)
351347
}
352348

353-
url := c.String("url")
354-
hostname := c.String("hostname")
355-
if url == hostname && url != "" && hostname != "" {
356-
errText := "hostname and url shouldn't match. See --help for more information"
357-
log.Error().Msg(errText)
358-
return fmt.Errorf(errText)
359-
}
360-
361349
logTransport := logger.CreateTransportLoggerFromContext(c, logger.EnableTerminalLog)
362350

363351
observer := connection.NewObserver(log, logTransport)

cmd/cloudflared/tunnel/configuration.go

Lines changed: 43 additions & 96 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@ 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"
3635
)
3736

3837
const LogFieldOriginCertPath = "originCertPath"
@@ -43,8 +42,6 @@ var (
4342
serviceUrl = developerPortal + "/reference/service/"
4443
argumentsUrl = developerPortal + "/reference/arguments/"
4544

46-
LogFieldHostname = "hostname"
47-
4845
secretFlags = [2]*altsrc.StringFlag{credentialsContentsFlag, tunnelTokenFlag}
4946
defaultFeatures = []string{supervisor.FeatureAllowRemoteConfig, supervisor.FeatureSerializedHeaders, supervisor.FeatureDatagramV2, supervisor.FeatureQUICSupportEOF}
5047

@@ -127,7 +124,7 @@ func isSecretEnvVar(key string) bool {
127124
}
128125

129126
func dnsProxyStandAlone(c *cli.Context, namedTunnel *connection.NamedTunnelProperties) bool {
130-
return c.IsSet("proxy-dns") && (!c.IsSet("hostname") && !c.IsSet("tag") && !c.IsSet("hello-world") && namedTunnel == nil)
127+
return c.IsSet("proxy-dns") && (!c.IsSet("tag") && !c.IsSet("hello-world") && namedTunnel == nil)
131128
}
132129

133130
func findOriginCert(originCertPath string, log *zerolog.Logger) (string, error) {
@@ -193,37 +190,19 @@ func prepareTunnelConfig(
193190
observer *connection.Observer,
194191
namedTunnel *connection.NamedTunnelProperties,
195192
) (*supervisor.TunnelConfig, *orchestration.Config, error) {
196-
isNamedTunnel := namedTunnel != nil
197-
198-
configHostname := c.String("hostname")
199-
hostname, err := validation.ValidateHostname(configHostname)
193+
clientID, err := uuid.NewRandom()
200194
if err != nil {
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-
}
195+
return nil, nil, errors.Wrap(err, "can't generate connector UUID")
210196
}
211-
197+
log.Info().Msgf("Generated Connector ID: %s", clientID)
212198
tags, err := NewTagSliceFromCLI(c.StringSlice("tag"))
213199
if err != nil {
214200
log.Err(err).Msg("Tag parse failure")
215201
return nil, nil, errors.Wrap(err, "Tag parse failure")
216202
}
217-
218-
tags = append(tags, tunnelpogs.Tag{Name: "ID", Value: clientID})
219-
220-
var (
221-
ingressRules ingress.Ingress
222-
classicTunnel *connection.ClassicTunnelProperties
223-
)
203+
tags = append(tags, tunnelpogs.Tag{Name: "ID", Value: clientID.String()})
224204

225205
transportProtocol := c.String("protocol")
226-
227206
needPQ := c.Bool("post-quantum")
228207
if needPQ {
229208
if FipsEnabled {
@@ -238,79 +217,52 @@ func prepareTunnelConfig(
238217

239218
protocolFetcher := edgediscovery.ProtocolPercentage
240219

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
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+
},
267237
}
238+
return preferQuic, nil
268239
}
269-
log.Info().Msg("Will be fetching remotely managed configuration from Cloudflare API. Defaulting to protocol: quic")
270-
}
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 {
279-
return nil, nil, err
280-
}
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"),
301240
}
241+
log.Info().Msg("Will be fetching remotely managed configuration from Cloudflare API. Defaulting to protocol: quic")
302242
}
303-
304-
// Convert single-origin configuration into multi-origin configuration.
305-
if ingressRules.IsEmpty() {
306-
ingressRules, err = ingress.NewSingleOrigin(c, !isNamedTunnel)
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)
307257
if err != nil {
308258
return nil, nil, err
309259
}
310260
}
261+
if ingressRules.IsEmpty() {
262+
return nil, nil, ingress.ErrNoIngressRules
263+
}
311264

312-
warpRoutingEnabled := isWarpRoutingEnabled(cfg.WarpRouting, isNamedTunnel)
313-
protocolSelector, err := connection.NewProtocolSelector(transportProtocol, warpRoutingEnabled, namedTunnel, protocolFetcher, supervisor.ResolveTTL, log, c.Bool("post-quantum"))
265+
protocolSelector, err := connection.NewProtocolSelector(transportProtocol, cfg.WarpRouting.Enabled, namedTunnel, protocolFetcher, supervisor.ResolveTTL, log, c.Bool("post-quantum"))
314266
if err != nil {
315267
return nil, nil, err
316268
}
@@ -362,7 +314,7 @@ func prepareTunnelConfig(
362314
GracePeriod: gracePeriod,
363315
ReplaceExisting: c.Bool("force"),
364316
OSArch: info.OSArch(),
365-
ClientID: clientID,
317+
ClientID: clientID.String(),
366318
EdgeAddrs: c.StringSlice("edge"),
367319
Region: c.String("region"),
368320
EdgeIPVersion: edgeIPVersion,
@@ -379,7 +331,6 @@ func prepareTunnelConfig(
379331
Retries: uint(c.Int("retries")),
380332
RunFromTerminal: isRunningFromTerminal(),
381333
NamedTunnel: namedTunnel,
382-
ClassicTunnel: classicTunnel,
383334
MuxerConfig: muxerConfig,
384335
ProtocolSelector: protocolSelector,
385336
EdgeTLSConfigs: edgeTLSConfigs,
@@ -421,10 +372,6 @@ func gracePeriod(c *cli.Context) (time.Duration, error) {
421372
return period, nil
422373
}
423374

424-
func isWarpRoutingEnabled(warpConfig config.WarpRoutingConfig, isNamedTunnel bool) bool {
425-
return warpConfig.Enabled && isNamedTunnel
426-
}
427-
428375
func isRunningFromTerminal() bool {
429376
return terminal.IsTerminal(int(os.Stdout.Fd()))
430377
}

component-tests/test_proxy_dns.py

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -12,18 +12,12 @@ class TestProxyDns:
1212
def test_proxy_dns_with_named_tunnel(self, tmp_path, component_tests_config):
1313
run_test_scenario(tmp_path, component_tests_config, CfdModes.NAMED, run_proxy_dns=True)
1414

15-
def test_proxy_dns_with_classic_tunnel(self, tmp_path, component_tests_config):
16-
run_test_scenario(tmp_path, component_tests_config, CfdModes.CLASSIC, run_proxy_dns=True)
17-
1815
def test_proxy_dns_alone(self, tmp_path, component_tests_config):
1916
run_test_scenario(tmp_path, component_tests_config, CfdModes.PROXY_DNS, run_proxy_dns=True)
2017

2118
def test_named_tunnel_alone(self, tmp_path, component_tests_config):
2219
run_test_scenario(tmp_path, component_tests_config, CfdModes.NAMED, run_proxy_dns=False)
2320

24-
def test_classic_tunnel_alone(self, tmp_path, component_tests_config):
25-
run_test_scenario(tmp_path, component_tests_config, CfdModes.CLASSIC, run_proxy_dns=False)
26-
2721

2822
def run_test_scenario(tmp_path, component_tests_config, cfd_mode, run_proxy_dns):
2923
expect_proxy_dns = run_proxy_dns
@@ -33,10 +27,6 @@ def run_test_scenario(tmp_path, component_tests_config, cfd_mode, run_proxy_dns)
3327
expect_tunnel = True
3428
pre_args = ["tunnel"]
3529
args = ["run"]
36-
elif cfd_mode == CfdModes.CLASSIC:
37-
expect_tunnel = True
38-
pre_args = []
39-
args = []
4030
elif cfd_mode == CfdModes.PROXY_DNS:
4131
expect_proxy_dns = True
4232
pre_args = []

component-tests/test_reconnect.py

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -33,13 +33,6 @@ def test_named_reconnect(self, tmp_path, component_tests_config, protocol):
3333
# Repeat the test multiple times because some issues only occur after multiple reconnects
3434
self.assert_reconnect(config, cloudflared, 5)
3535

36-
def test_classic_reconnect(self, tmp_path, component_tests_config):
37-
extra_config = copy.copy(self.extra_config)
38-
extra_config["hello-world"] = True
39-
config = component_tests_config(additional_config=extra_config, cfd_mode=CfdModes.CLASSIC)
40-
with start_cloudflared(tmp_path, config, cfd_args=[], new_process=True, allow_input=True, capture_output=False) as cloudflared:
41-
self.assert_reconnect(config, cloudflared, 1)
42-
4336
def send_reconnect(self, cloudflared, secs):
4437
# Although it is recommended to use the Popen.communicate method, we cannot
4538
# use it because it blocks on reading stdout and stderr until EOF is reached

connection/h2mux.go

Lines changed: 0 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -123,46 +123,6 @@ func (h *h2muxConnection) ServeNamedTunnel(ctx context.Context, namedTunnel *Nam
123123
return err
124124
}
125125

126-
func (h *h2muxConnection) ServeClassicTunnel(ctx context.Context, classicTunnel *ClassicTunnelProperties, credentialManager CredentialManager, registrationOptions *tunnelpogs.RegistrationOptions, connectedFuse ConnectedFuse) error {
127-
errGroup, serveCtx := errgroup.WithContext(ctx)
128-
errGroup.Go(func() error {
129-
return h.serveMuxer(serveCtx)
130-
})
131-
132-
errGroup.Go(func() (err error) {
133-
defer func() {
134-
if err == nil {
135-
connectedFuse.Connected()
136-
}
137-
}()
138-
if classicTunnel.UseReconnectToken && connectedFuse.IsConnected() {
139-
err := h.reconnectTunnel(ctx, credentialManager, classicTunnel, registrationOptions)
140-
if err == nil {
141-
return nil
142-
}
143-
// log errors and proceed to RegisterTunnel
144-
h.observer.log.Err(err).
145-
Uint8(LogFieldConnIndex, h.connIndex).
146-
Msg("Couldn't reconnect connection. Re-registering it instead.")
147-
}
148-
return h.registerTunnel(ctx, credentialManager, classicTunnel, registrationOptions)
149-
})
150-
151-
errGroup.Go(func() error {
152-
h.controlLoop(serveCtx, connectedFuse, false)
153-
return nil
154-
})
155-
156-
err := errGroup.Wait()
157-
if err == errMuxerStopped {
158-
if h.stoppedGracefully {
159-
return nil
160-
}
161-
h.observer.log.Info().Uint8(LogFieldConnIndex, h.connIndex).Msg("Unexpected muxer shutdown")
162-
}
163-
return err
164-
}
165-
166126
func (h *h2muxConnection) serveMuxer(ctx context.Context) error {
167127
// All routines should stop when muxer finish serving. When muxer is shutdown
168128
// gracefully, it doesn't return an error, so we need to return errMuxerShutdown

ingress/ingress.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,9 +71,8 @@ type Ingress struct {
7171
}
7272

7373
// NewSingleOrigin constructs an Ingress set with only one rule, constructed from
74-
// legacy CLI parameters like --url or --no-chunked-encoding.
74+
// CLI parameters for quick tunnels like --url or --no-chunked-encoding.
7575
func NewSingleOrigin(c *cli.Context, allowURLFromArgs bool) (Ingress, error) {
76-
7776
service, err := parseSingleOriginService(c, allowURLFromArgs)
7877
if err != nil {
7978
return Ingress{}, err

0 commit comments

Comments
 (0)