mirror of
https://github.com/tailscale/tailscale.git
synced 2025-02-21 12:28:39 +00:00
cmd/tailscale,ipn: minor fixes to tailscale lock commands
* Fix broken add/remove key commands * Make lock status display whether the node is signed Signed-off-by: Tom DNetto <tom@tailscale.com>
This commit is contained in:
parent
c60e444696
commit
4c31183781
@ -82,11 +82,46 @@ func runNetworkLockStatus(ctx context.Context, args []string) error {
|
|||||||
} else {
|
} else {
|
||||||
fmt.Println("Network-lock is NOT enabled.")
|
fmt.Println("Network-lock is NOT enabled.")
|
||||||
}
|
}
|
||||||
|
fmt.Println()
|
||||||
|
|
||||||
|
if st.Enabled && st.NodeKey != nil {
|
||||||
|
if st.NodeKeySigned {
|
||||||
|
fmt.Println("This node is trusted by network-lock.")
|
||||||
|
} else {
|
||||||
|
fmt.Println("This node IS NOT trusted by network-lock, and action is required to establish connectivity.")
|
||||||
|
fmt.Printf("Run the following command on a node with a network-lock key:\n\ttailscale lock sign %v\n", st.NodeKey)
|
||||||
|
}
|
||||||
|
fmt.Println()
|
||||||
|
}
|
||||||
|
|
||||||
p, err := st.PublicKey.MarshalText()
|
p, err := st.PublicKey.MarshalText()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
fmt.Printf("our public-key: %s\n", p)
|
fmt.Printf("This node's public-key: %s\n", p)
|
||||||
|
fmt.Println()
|
||||||
|
|
||||||
|
if st.Enabled && len(st.TrustedKeys) > 0 {
|
||||||
|
fmt.Println("Keys trusted to make changes to network-lock:")
|
||||||
|
for _, k := range st.TrustedKeys {
|
||||||
|
key, err := k.Key.MarshalText()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
var line strings.Builder
|
||||||
|
line.WriteString("\t")
|
||||||
|
line.WriteString(string(key))
|
||||||
|
line.WriteString("\t")
|
||||||
|
line.WriteString(fmt.Sprint(k.Votes))
|
||||||
|
line.WriteString("\t")
|
||||||
|
if k.Key == st.PublicKey {
|
||||||
|
line.WriteString("(us)")
|
||||||
|
}
|
||||||
|
fmt.Println(line.String())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -143,8 +178,8 @@ func runNetworkLockModify(ctx context.Context, addArgs, removeArgs []string) err
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return fixTailscaledConnectError(err)
|
return fixTailscaledConnectError(err)
|
||||||
}
|
}
|
||||||
if st.Enabled {
|
if !st.Enabled {
|
||||||
return errors.New("network-lock is already enabled")
|
return errors.New("network-lock is not enabled")
|
||||||
}
|
}
|
||||||
|
|
||||||
addKeys, err := parseNLKeyArgs(addArgs)
|
addKeys, err := parseNLKeyArgs(addArgs)
|
||||||
|
@ -329,10 +329,17 @@ func (b *LocalBackend) NetworkLockStatus() *ipnstate.NetworkLockStatus {
|
|||||||
b.mu.Lock()
|
b.mu.Lock()
|
||||||
defer b.mu.Unlock()
|
defer b.mu.Unlock()
|
||||||
|
|
||||||
|
var nodeKey *key.NodePublic
|
||||||
|
if p := b.pm.CurrentPrefs(); p.Valid() {
|
||||||
|
nkp := p.Persist().PublicNodeKey()
|
||||||
|
nodeKey = &nkp
|
||||||
|
}
|
||||||
|
|
||||||
if b.tka == nil {
|
if b.tka == nil {
|
||||||
return &ipnstate.NetworkLockStatus{
|
return &ipnstate.NetworkLockStatus{
|
||||||
Enabled: false,
|
Enabled: false,
|
||||||
PublicKey: b.nlPrivKey.Public(),
|
PublicKey: b.nlPrivKey.Public(),
|
||||||
|
NodeKey: nodeKey,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -340,10 +347,28 @@ func (b *LocalBackend) NetworkLockStatus() *ipnstate.NetworkLockStatus {
|
|||||||
h := b.tka.authority.Head()
|
h := b.tka.authority.Head()
|
||||||
copy(head[:], h[:])
|
copy(head[:], h[:])
|
||||||
|
|
||||||
|
var selfAuthorized bool
|
||||||
|
if b.netMap != nil {
|
||||||
|
selfAuthorized = b.tka.authority.NodeKeyAuthorized(b.netMap.SelfNode.Key, b.netMap.SelfNode.KeySignature) == nil
|
||||||
|
}
|
||||||
|
|
||||||
|
keys := b.tka.authority.Keys()
|
||||||
|
outKeys := make([]ipnstate.TKAKey, len(keys))
|
||||||
|
for i, k := range keys {
|
||||||
|
outKeys[i] = ipnstate.TKAKey{
|
||||||
|
Key: key.NLPublicFromEd25519Unsafe(k.Public),
|
||||||
|
Metadata: k.Meta,
|
||||||
|
Votes: k.Votes,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return &ipnstate.NetworkLockStatus{
|
return &ipnstate.NetworkLockStatus{
|
||||||
Enabled: true,
|
Enabled: true,
|
||||||
Head: &head,
|
Head: &head,
|
||||||
PublicKey: b.nlPrivKey.Public(),
|
PublicKey: b.nlPrivKey.Public(),
|
||||||
|
NodeKey: nodeKey,
|
||||||
|
NodeKeySigned: selfAuthorized,
|
||||||
|
TrustedKeys: outKeys,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -67,6 +67,13 @@ type Status struct {
|
|||||||
User map[tailcfg.UserID]tailcfg.UserProfile
|
User map[tailcfg.UserID]tailcfg.UserProfile
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TKAKey describes a key trusted by network lock.
|
||||||
|
type TKAKey struct {
|
||||||
|
Key key.NLPublic
|
||||||
|
Metadata map[string]string
|
||||||
|
Votes uint
|
||||||
|
}
|
||||||
|
|
||||||
// NetworkLockStatus represents whether network-lock is enabled,
|
// NetworkLockStatus represents whether network-lock is enabled,
|
||||||
// along with details about the locally-known state of the tailnet
|
// along with details about the locally-known state of the tailnet
|
||||||
// key authority.
|
// key authority.
|
||||||
@ -78,8 +85,19 @@ type NetworkLockStatus struct {
|
|||||||
// if network lock is not enabled.
|
// if network lock is not enabled.
|
||||||
Head *[32]byte
|
Head *[32]byte
|
||||||
|
|
||||||
// PublicKey describes the nodes' network-lock public key.
|
// PublicKey describes the node's network-lock public key.
|
||||||
PublicKey key.NLPublic
|
PublicKey key.NLPublic
|
||||||
|
|
||||||
|
// NodeKey describes the node's current node-key. This field is not
|
||||||
|
// populated if the node is not operating (i.e. waiting for a login).
|
||||||
|
NodeKey *key.NodePublic
|
||||||
|
|
||||||
|
// NodeKeySigned is true if our node is authorized by network-lock.
|
||||||
|
NodeKeySigned bool
|
||||||
|
|
||||||
|
// TrustedKeys describes the keys currently trusted to make changes
|
||||||
|
// to network-lock.
|
||||||
|
TrustedKeys []TKAKey
|
||||||
}
|
}
|
||||||
|
|
||||||
// TailnetStatus is information about a Tailscale network ("tailnet").
|
// TailnetStatus is information about a Tailscale network ("tailnet").
|
||||||
|
11
tka/key.go
11
tka/key.go
@ -85,6 +85,17 @@ func (k Key) ID() tkatype.KeyID {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Ed25519 returns the ed25519 public key encoded by Key. An error is
|
||||||
|
// returned for keys which do not represent ed25519 public keys.
|
||||||
|
func (k Key) Ed25519() (ed25519.PublicKey, error) {
|
||||||
|
switch k.Kind {
|
||||||
|
case Key25519:
|
||||||
|
return ed25519.PublicKey(k.Public), nil
|
||||||
|
default:
|
||||||
|
return nil, fmt.Errorf("key is of type %v, not ed25519", k.Kind)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const maxMetaBytes = 512
|
const maxMetaBytes = 512
|
||||||
|
|
||||||
func (k Key) StaticValidate() error {
|
func (k Key) StaticValidate() error {
|
||||||
|
@ -705,3 +705,12 @@ func (a *Authority) KeyTrusted(keyID tkatype.KeyID) bool {
|
|||||||
_, err := a.state.GetKey(keyID)
|
_, err := a.state.GetKey(keyID)
|
||||||
return err == nil
|
return err == nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Keys returns the set of keys trusted by the tailnet key authority.
|
||||||
|
func (a *Authority) Keys() []Key {
|
||||||
|
out := make([]Key, len(a.state.Keys))
|
||||||
|
for i := range a.state.Keys {
|
||||||
|
out[i] = a.state.Keys[i].Clone()
|
||||||
|
}
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
@ -100,6 +100,17 @@ type NLPublic struct {
|
|||||||
k [ed25519.PublicKeySize]byte
|
k [ed25519.PublicKeySize]byte
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NLPublicFromEd25519Unsafe converts an ed25519 public key into
|
||||||
|
// a type of NLPublic.
|
||||||
|
//
|
||||||
|
// New uses of this function should be avoided, as its possible to
|
||||||
|
// accidentally construct an NLPublic from a non network-lock key.
|
||||||
|
func NLPublicFromEd25519Unsafe(public ed25519.PublicKey) NLPublic {
|
||||||
|
var out NLPublic
|
||||||
|
copy(out.k[:], public)
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
// MarshalText implements encoding.TextUnmarshaler.
|
// MarshalText implements encoding.TextUnmarshaler.
|
||||||
func (k *NLPublic) UnmarshalText(b []byte) error {
|
func (k *NLPublic) UnmarshalText(b []byte) error {
|
||||||
return parseHex(k.k[:], mem.B(b), mem.S(nlPublicHexPrefix))
|
return parseHex(k.k[:], mem.B(b), mem.S(nlPublicHexPrefix))
|
||||||
|
Loading…
x
Reference in New Issue
Block a user