Skip to content

Commit 36479ef

Browse files
authored
Merge pull request #478 from echtish/secret-flag
Add flag to 'tunnel create' subcommand to specify a base64-encoded secret
2 parents 5853861 + 1239006 commit 36479ef

File tree

3 files changed

+27
-7
lines changed

3 files changed

+27
-7
lines changed

cmd/cloudflared/tunnel/cmd.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,8 @@ func Init(ver string, gracefulShutdown chan struct{}) {
181181
func runAdhocNamedTunnel(sc *subcommandContext, name, credentialsOutputPath string) error {
182182
tunnel, ok, err := sc.tunnelActive(name)
183183
if err != nil || !ok {
184-
tunnel, err = sc.create(name, credentialsOutputPath)
184+
// pass empty string as secret to generate one
185+
tunnel, err = sc.create(name, credentialsOutputPath, "")
185186
if err != nil {
186187
return errors.Wrap(err, "failed to create tunnel")
187188
}

cmd/cloudflared/tunnel/subcommand_context.go

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package tunnel
22

33
import (
4+
"encoding/base64"
45
"encoding/json"
56
"fmt"
67
"os"
@@ -148,15 +149,27 @@ func (sc *subcommandContext) readTunnelCredentials(credFinder CredFinder) (conne
148149
return credentials, nil
149150
}
150151

151-
func (sc *subcommandContext) create(name string, credentialsFilePath string) (*tunnelstore.Tunnel, error) {
152+
func (sc *subcommandContext) create(name string, credentialsFilePath string, secret string) (*tunnelstore.Tunnel, error) {
152153
client, err := sc.client()
153154
if err != nil {
154155
return nil, errors.Wrap(err, "couldn't create client to talk to Cloudflare Tunnel backend")
155156
}
156157

157-
tunnelSecret, err := generateTunnelSecret()
158-
if err != nil {
159-
return nil, errors.Wrap(err, "couldn't generate the secret for your new tunnel")
158+
var tunnelSecret []byte
159+
if secret == "" {
160+
tunnelSecret, err = generateTunnelSecret()
161+
if err != nil {
162+
return nil, errors.Wrap(err, "couldn't generate the secret for your new tunnel")
163+
}
164+
} else {
165+
decodedSecret, err := base64.StdEncoding.DecodeString(secret)
166+
if err != nil {
167+
return nil, errors.Wrap(err, "Couldn't decode tunnel secret from base64")
168+
}
169+
tunnelSecret = []byte(decodedSecret)
170+
if len(tunnelSecret) < 32 {
171+
return nil, errors.New("Decoded tunnel secret must be at least 32 bytes long")
172+
}
160173
}
161174

162175
tunnel, err := client.CreateTunnel(name, tunnelSecret)

cmd/cloudflared/tunnel/subcommands.go

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,12 @@ var (
156156
Usage: `Overwrites existing DNS records with this hostname`,
157157
EnvVars: []string{"TUNNEL_FORCE_PROVISIONING_DNS"},
158158
}
159+
createSecretFlag = &cli.StringFlag{
160+
Name: "secret",
161+
Aliases: []string{"s"},
162+
Usage: "Base64 encoded secret to set for the tunnel. The decoded secret must be at least 32 bytes long. If not specified, a random 32-byte secret will be generated.",
163+
EnvVars: []string{"TUNNEL_CREATE_SECRET"},
164+
}
159165
)
160166

161167
func buildCreateCommand() *cli.Command {
@@ -170,7 +176,7 @@ func buildCreateCommand() *cli.Command {
170176
For example, to create a tunnel named 'my-tunnel' run:
171177
172178
$ cloudflared tunnel create my-tunnel`,
173-
Flags: []cli.Flag{outputFormatFlag, credentialsFileFlagCLIOnly},
179+
Flags: []cli.Flag{outputFormatFlag, credentialsFileFlagCLIOnly, createSecretFlag},
174180
CustomHelpTemplate: commandHelpTemplate(),
175181
}
176182
}
@@ -196,7 +202,7 @@ func createCommand(c *cli.Context) error {
196202
warningChecker := updater.StartWarningCheck(c)
197203
defer warningChecker.LogWarningIfAny(sc.log)
198204

199-
_, err = sc.create(name, c.String(CredFileFlag))
205+
_, err = sc.create(name, c.String(CredFileFlag), c.String(createSecretFlag.Name))
200206
return errors.Wrap(err, "failed to create tunnel")
201207
}
202208

0 commit comments

Comments
 (0)