cloudflare/cloudflared

Public

mirrored from https://github.com/cloudflare/cloudflaredAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
2020.6.2

Branches

Tags

  • No tags available.
0Branches0Tags
Go to file
Add file
Code

Clone

HTTPS

Download ZIP

dbconnect/cmd.go

165lines · modeblame

759cd019Ashcon Partovi6 years ago1package dbconnect
2
3import (
4"context"
5"log"
6"net"
7"strconv"
8
9"gopkg.in/urfave/cli.v2"
10"gopkg.in/urfave/cli.v2/altsrc"
11)
12
13// Cmd is the entrypoint command for dbconnect.
14//
15// The tunnel package is responsible for appending this to tunnel.Commands().
16func Cmd() *cli.Command {
17return &cli.Command{
df3ad2b2Dalton6 years ago18Category: "Database Connect (ALPHA) - Deprecated",
759cd019Ashcon Partovi6 years ago19Name: "db-connect",
df3ad2b2Dalton6 years ago20Usage: "deprecated: Access your SQL database from Cloudflare Workers or the browser",
759cd019Ashcon Partovi6 years ago21ArgsUsage: " ",
22Description: `
df3ad2b2Dalton6 years ago23This feature has been deprecated.
24Please see:
25
26cloudflared access tcp --help
27
28for setting up database connections to the cloudflare edge.
29
30
759cd019Ashcon Partovi6 years ago31Creates a connection between your database and the Cloudflare edge.
32Now you can execute SQL commands anywhere you can send HTTPS requests.
33
34Connect your database with any of the following commands, you can also try the "playground" without a database:
35
36cloudflared db-connect --hostname sql.mysite.com --url postgres://user:pass@localhost?sslmode=disable \
37--auth-domain mysite.cloudflareaccess.com --application-aud my-access-policy-tag
38cloudflared db-connect --hostname sql-dev.mysite.com --url mysql://localhost --insecure
39cloudflared db-connect --playground
40
41Requests should be authenticated using Cloudflare Access, learn more about how to enable it here:
42
43https://developers.cloudflare.com/access/service-auth/service-token/
44`,
45Flags: []cli.Flag{
46altsrc.NewStringFlag(&cli.StringFlag{
47Name: "url",
48Usage: "URL to the database (eg. postgres://user:pass@localhost?sslmode=disable)",
49EnvVars: []string{"TUNNEL_URL"},
50}),
51altsrc.NewStringFlag(&cli.StringFlag{
52Name: "hostname",
53Usage: "Hostname to accept commands over HTTPS (eg. sql.mysite.com)",
54EnvVars: []string{"TUNNEL_HOSTNAME"},
55}),
56altsrc.NewStringFlag(&cli.StringFlag{
57Name: "auth-domain",
58Usage: "Cloudflare Access authentication domain for your account (eg. mysite.cloudflareaccess.com)",
59EnvVars: []string{"TUNNEL_ACCESS_AUTH_DOMAIN"},
60}),
61altsrc.NewStringFlag(&cli.StringFlag{
62Name: "application-aud",
63Usage: "Cloudflare Access application \"AUD\" to verify JWTs from requests",
64EnvVars: []string{"TUNNEL_ACCESS_APPLICATION_AUD"},
65}),
66altsrc.NewBoolFlag(&cli.BoolFlag{
67Name: "insecure",
68Usage: "Disable authentication, the database will be open to the Internet",
69Value: false,
70EnvVars: []string{"TUNNEL_ACCESS_INSECURE"},
71}),
72altsrc.NewBoolFlag(&cli.BoolFlag{
73Name: "playground",
74Usage: "Run a temporary, in-memory SQLite3 database for testing",
75Value: false,
76EnvVars: []string{"TUNNEL_HELLO_WORLD"},
77}),
78altsrc.NewStringFlag(&cli.StringFlag{
79Name: "loglevel",
80Value: "debug", // Make it more verbose than the tunnel default 'info'.
81EnvVars: []string{"TUNNEL_LOGLEVEL"},
82Hidden: true,
83}),
84},
85Before: CmdBefore,
86Action: CmdAction,
87Hidden: true,
88}
89}
90
91// CmdBefore runs some validation checks before running the command.
92func CmdBefore(c *cli.Context) error {
93// Show the help text is no flags are specified.
94if c.NumFlags() == 0 {
95return cli.ShowSubcommandHelp(c)
96}
97
98// Hello-world and playground are synonymous with each other,
99// unset hello-world to prevent tunnel from initializing the hello package.
100if c.IsSet("hello-world") {
101c.Set("playground", "true")
102c.Set("hello-world", "false")
103}
104
105// Unix-socket database urls are supported, but the logic is the same as url.
106if c.IsSet("unix-socket") {
107c.Set("url", c.String("unix-socket"))
108c.Set("unix-socket", "")
109}
110
111// When playground mode is enabled, run with an in-memory database.
112if c.IsSet("playground") {
113c.Set("url", "sqlite3::memory:?cache=shared")
114c.Set("insecure", strconv.FormatBool(!c.IsSet("auth-domain") && !c.IsSet("application-aud")))
115}
116
117// At this point, insecure configurations are valid.
118if c.Bool("insecure") {
119return nil
120}
121
122// Ensure that secure configurations specify a hostname, domain, and tag for JWT validation.
123if !c.IsSet("hostname") || !c.IsSet("auth-domain") || !c.IsSet("application-aud") {
124log.Fatal("must specify --hostname, --auth-domain, and --application-aud unless you want to run in --insecure mode")
125}
126
127return nil
128}
129
130// CmdAction starts the Proxy and sets the url in cli.Context to point to the Proxy address.
131func CmdAction(c *cli.Context) error {
132// STOR-612: sync with context in tunnel daemon.
133ctx := context.Background()
134
135var proxy *Proxy
136var err error
137if c.Bool("insecure") {
138proxy, err = NewInsecureProxy(ctx, c.String("url"))
139} else {
140proxy, err = NewSecureProxy(ctx, c.String("url"), c.String("auth-domain"), c.String("application-aud"))
141}
142
143if err != nil {
144log.Fatal(err)
145return err
146}
147
148listenerC := make(chan net.Listener)
149defer close(listenerC)
150
151// Since the Proxy should only talk to the tunnel daemon, find the next available
152// localhost port and start to listen to requests.
153go func() {
154err := proxy.Start(ctx, "127.0.0.1:", listenerC)
155if err != nil {
156log.Fatal(err)
157}
158}()
159
160// Block until the the Proxy is online, retreive its address, and change the url to point to it.
161// This is effectively "handing over" control to the tunnel package so it can run the tunnel daemon.
162c.Set("url", "https://"+(<-listenerC).Addr().String())
163
164return nil
165}