all: implement preauth-key support with tailnet lock

Signed-off-by: Tom DNetto <tom@tailscale.com>
This commit is contained in:
Tom DNetto
2023-03-02 13:24:26 -08:00
committed by Tom
parent f4f8ed98d9
commit ce99474317
7 changed files with 251 additions and 3 deletions

View File

@@ -15,6 +15,7 @@ import (
"os"
"strconv"
"strings"
"time"
"github.com/mattn/go-colorable"
"github.com/mattn/go-isatty"
@@ -39,6 +40,7 @@ var netlockCmd = &ffcli.Command{
nlDisablementKDFCmd,
nlLogCmd,
nlLocalDisableCmd,
nlTskeyWrapCmd,
},
Exec: runNetworkLockStatus,
}
@@ -622,3 +624,60 @@ func runNetworkLockLog(ctx context.Context, args []string) error {
}
return nil
}
var nlTskeyWrapCmd = &ffcli.Command{
Name: "tskey-wrap",
ShortUsage: "tskey-wrap <tailscale pre-auth key>",
ShortHelp: "Modifies a pre-auth key from the admin panel to work with tailnet lock",
LongHelp: "Modifies a pre-auth key from the admin panel to work with tailnet lock",
Exec: runTskeyWrapCmd,
}
func runTskeyWrapCmd(ctx context.Context, args []string) error {
if len(args) != 1 {
return errors.New("usage: lock tskey-wrap <tailscale pre-auth key>")
}
if strings.Contains(args[0], "--TL") {
return errors.New("Error: provided key was already wrapped")
}
st, err := localClient.StatusWithoutPeers(ctx)
if err != nil {
return fixTailscaledConnectError(err)
}
// Generate a separate tailnet-lock key just for the credential signature.
// We use the free-form meta strings to mark a little bit of metadata about this
// key.
priv := key.NewNLPrivate()
m := map[string]string{
"purpose": "pre-auth key",
"wrapper_stableid": string(st.Self.ID),
"wrapper_createtime": fmt.Sprint(time.Now().Unix()),
}
if strings.HasPrefix(args[0], "tskey-auth-") && strings.Index(args[0][len("tskey-auth-"):], "-") > 0 {
// We don't want to accidentally embed the nonce part of the authkey in
// the event the format changes. As such, we make sure its in the format we
// expect (tskey-auth-<stableID, inc CNTRL suffix>-nonce) before we parse
// out and embed the stableID.
s := strings.TrimPrefix(args[0], "tskey-auth-")
m["authkey_stableid"] = s[:strings.Index(s, "-")]
}
k := tka.Key{
Kind: tka.Key25519,
Public: priv.Public().Verifier(),
Votes: 1,
Meta: m,
}
wrapped, err := localClient.NetworkLockWrapPreauthKey(ctx, args[0], priv)
if err != nil {
return fmt.Errorf("wrapping failed: %w", err)
}
if err := localClient.NetworkLockModify(ctx, []tka.Key{k}, nil); err != nil {
return fmt.Errorf("add key failed: %w", err)
}
fmt.Println(wrapped)
return nil
}

View File

@@ -86,10 +86,9 @@ func TestQnapAuthnURL(t *testing.T) {
},
{
name: "err != nil",
in: "http://192.168.0.%31/",
in: "http://192.168.0.%31/",
want: "http://localhost/cgi-bin/authLogin.cgi?qtoken=token",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {