cloudflare/cloudflared
Publicmirrored from https://github.com/cloudflare/cloudflaredAvailable
cmd/cloudflared/proxydns/cmd.go
114lines · modecode
| 1 | package proxydns |
| 2 | |
| 3 | import ( |
| 4 | "net" |
| 5 | "os" |
| 6 | "os/signal" |
| 7 | "syscall" |
| 8 | |
| 9 | "github.com/urfave/cli/v2" |
| 10 | |
| 11 | "github.com/cloudflare/cloudflared/cmd/cloudflared/cliutil" |
| 12 | "github.com/cloudflare/cloudflared/logger" |
| 13 | "github.com/cloudflare/cloudflared/metrics" |
| 14 | "github.com/cloudflare/cloudflared/tunneldns" |
| 15 | ) |
| 16 | |
| 17 | func Command(hidden bool) *cli.Command { |
| 18 | return &cli.Command{ |
| 19 | Name: "proxy-dns", |
| 20 | Action: cliutil.ConfiguredAction(Run), |
| 21 | |
| 22 | Usage: "Run a DNS over HTTPS proxy server.", |
| 23 | Flags: []cli.Flag{ |
| 24 | &cli.StringFlag{ |
| 25 | Name: "metrics", |
| 26 | Value: "localhost:", |
| 27 | Usage: "Listen address for metrics reporting.", |
| 28 | EnvVars: []string{"TUNNEL_METRICS"}, |
| 29 | }, |
| 30 | &cli.StringFlag{ |
| 31 | Name: "address", |
| 32 | Usage: "Listen address for the DNS over HTTPS proxy server.", |
| 33 | Value: "localhost", |
| 34 | EnvVars: []string{"TUNNEL_DNS_ADDRESS"}, |
| 35 | }, |
| 36 | // Note TUN-3758 , we use Int because UInt is not supported with altsrc |
| 37 | &cli.IntFlag{ |
| 38 | Name: "port", |
| 39 | Usage: "Listen on given port for the DNS over HTTPS proxy server.", |
| 40 | Value: 53, |
| 41 | EnvVars: []string{"TUNNEL_DNS_PORT"}, |
| 42 | }, |
| 43 | &cli.StringSliceFlag{ |
| 44 | Name: "upstream", |
| 45 | Usage: "Upstream endpoint URL, you can specify multiple endpoints for redundancy.", |
| 46 | Value: cli.NewStringSlice("https://1.1.1.1/dns-query", "https://1.0.0.1/dns-query"), |
| 47 | EnvVars: []string{"TUNNEL_DNS_UPSTREAM"}, |
| 48 | }, |
| 49 | &cli.StringSliceFlag{ |
| 50 | Name: "bootstrap", |
| 51 | Usage: "bootstrap endpoint URL, you can specify multiple endpoints for redundancy.", |
| 52 | 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"), |
| 53 | EnvVars: []string{"TUNNEL_DNS_BOOTSTRAP"}, |
| 54 | }, |
| 55 | &cli.IntFlag{ |
| 56 | Name: "max-upstream-conns", |
| 57 | Usage: "Maximum concurrent connections to upstream. Setting to 0 means unlimited.", |
| 58 | Value: tunneldns.MaxUpstreamConnsDefault, |
| 59 | EnvVars: []string{"TUNNEL_DNS_MAX_UPSTREAM_CONNS"}, |
| 60 | }, |
| 61 | }, |
| 62 | ArgsUsage: " ", // can't be the empty string or we get the default output |
| 63 | Hidden: hidden, |
| 64 | } |
| 65 | } |
| 66 | |
| 67 | // Run implements a foreground runner |
| 68 | func Run(c *cli.Context) error { |
| 69 | log := logger.CreateLoggerFromContext(c, logger.EnableTerminalLog) |
| 70 | |
| 71 | metricsListener, err := net.Listen("tcp", c.String("metrics")) |
| 72 | if err != nil { |
| 73 | log.Fatal().Err(err).Msg("Failed to open the metrics listener") |
| 74 | } |
| 75 | |
| 76 | go metrics.ServeMetrics(metricsListener, nil, nil, "", log) |
| 77 | |
| 78 | listener, err := tunneldns.CreateListener( |
| 79 | c.String("address"), |
| 80 | // Note TUN-3758 , we use Int because UInt is not supported with altsrc |
| 81 | uint16(c.Int("port")), |
| 82 | c.StringSlice("upstream"), |
| 83 | c.StringSlice("bootstrap"), |
| 84 | c.Int("max-upstream-conns"), |
| 85 | log, |
| 86 | ) |
| 87 | |
| 88 | if err != nil { |
| 89 | log.Err(err).Msg("Failed to create the listeners") |
| 90 | return err |
| 91 | } |
| 92 | |
| 93 | // Try to start the server |
| 94 | readySignal := make(chan struct{}) |
| 95 | err = listener.Start(readySignal) |
| 96 | if err != nil { |
| 97 | log.Err(err).Msg("Failed to start the listeners") |
| 98 | return listener.Stop() |
| 99 | } |
| 100 | <-readySignal |
| 101 | |
| 102 | // Wait for signal |
| 103 | signals := make(chan os.Signal, 10) |
| 104 | signal.Notify(signals, syscall.SIGTERM, syscall.SIGINT) |
| 105 | defer signal.Stop(signals) |
| 106 | <-signals |
| 107 | |
| 108 | // Shut down server |
| 109 | err = listener.Stop() |
| 110 | if err != nil { |
| 111 | log.Err(err).Msg("failed to stop") |
| 112 | } |
| 113 | return err |
| 114 | } |
| 115 | |