@@ -17,6 +17,7 @@ import (
1717 "github.com/mitchellh/go-homedir"
1818 "github.com/pkg/errors"
1919 "github.com/urfave/cli/v2"
20+ "golang.org/x/net/idna"
2021 "gopkg.in/yaml.v2"
2122
2223 "github.com/cloudflare/cloudflared/cmd/cloudflared/cliutil"
@@ -377,7 +378,7 @@ func dnsRouteFromArg(c *cli.Context) (tunnelstore.Route, error) {
377378 userHostname := c .Args ().Get (userHostnameIndex )
378379 if userHostname == "" {
379380 return nil , cliutil .UsageError ("The third argument should be the hostname" )
380- } else if ! validateName (userHostname ) {
381+ } else if ! validateHostname (userHostname ) {
381382 return nil , errors .Errorf ("%s is not a valid hostname" , userHostname )
382383 }
383384 return tunnelstore .NewDNSRoute (userHostname ), nil
@@ -395,7 +396,7 @@ func lbRouteFromArg(c *cli.Context) (tunnelstore.Route, error) {
395396 lbName := c .Args ().Get (lbNameIndex )
396397 if lbName == "" {
397398 return nil , cliutil .UsageError ("The third argument should be the load balancer name" )
398- } else if ! validateName (lbName ) {
399+ } else if ! validateHostname (lbName ) {
399400 return nil , errors .Errorf ("%s is not a valid load balancer name" , lbName )
400401 }
401402
@@ -415,6 +416,16 @@ func validateName(s string) bool {
415416 return nameRegex .MatchString (s )
416417}
417418
419+ func validateHostname (s string ) bool {
420+ // Slightly stricter than PunyCodeProfile
421+ idnaProfile := idna .New (
422+ idna .ValidateLabels (true ),
423+ idna .VerifyDNSLength (true ))
424+
425+ puny , err := idnaProfile .ToASCII (s )
426+ return err == nil && validateName (puny )
427+ }
428+
418429func routeCommand (c * cli.Context ) error {
419430 if c .NArg () < 2 {
420431 return cliutil .UsageError (`"cloudflared tunnel route" requires the first argument to be the route type(dns or lb), followed by the ID or name of the tunnel` )
0 commit comments