Skip to content

Commit

Permalink
posture: add network hardware addresses to posture identity
Browse files Browse the repository at this point in the history
If an optional `hwaddrs` URL parameter is present, add network interface
hardware addresses to the posture identity response.

Just like with serial numbers, this requires client opt-in via MDM or
`tailscale set --posture-checking=true`
(https://tailscale.com/kb/1326/device-identity)

Updates tailscale/corp#21371

Signed-off-by: Anton Tolchanov <anton@tailscale.com>
  • Loading branch information
knyar committed Jul 10, 2024
1 parent b546a6e commit 874972b
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 5 deletions.
13 changes: 11 additions & 2 deletions ipn/ipnlocal/c2n.go
Original file line number Diff line number Diff line change
Expand Up @@ -318,7 +318,7 @@ func handleC2NPostureIdentityGet(b *LocalBackend, w http.ResponseWriter, r *http

res := tailcfg.C2NPostureIdentityResponse{}

// Only collect serial numbers if enabled on the client,
// Only collect posture identity if enabled on the client,
// this will first check syspolicy, MDM settings like Registry
// on Windows or defaults on macOS. If they are not set, it falls
// back to the cli-flag, `--posture-checking`.
Expand All @@ -337,8 +337,17 @@ func handleC2NPostureIdentityGet(b *LocalBackend, w http.ResponseWriter, r *http
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}

res.SerialNumbers = sns

// TODO(tailscale/corp#21371, 2024-07-10): once this has landed in a stable release
// and looks good in client metrics, remove this parameter and always report MAC
// addresses.
if r.FormValue("hwaddrs") == "true" {
res.IfaceHardwareAddrs, err = posture.GetHardwareAddrs()
if err != nil {
b.logf("c2n: GetHardwareAddrs returned error: %v", err)
}
}
} else {
res.PostureDisabled = true
}
Expand Down
26 changes: 26 additions & 0 deletions posture/hwaddr.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// Copyright (c) Tailscale Inc & AUTHORS
// SPDX-License-Identifier: BSD-3-Clause

package posture

import (
"net/netip"
"slices"

"tailscale.com/net/netmon"
)

// GetHardwareAddrs returns the hardware addresses of all non-loopback
// network interfaces.
func GetHardwareAddrs() (hwaddrs []string, err error) {
err = netmon.ForeachInterface(func(i netmon.Interface, _ []netip.Prefix) {
if i.IsLoopback() {
return
}
if a := i.HardwareAddr.String(); a != "" {
hwaddrs = append(hwaddrs, a)
}
})
slices.Sort(hwaddrs)
return
}
10 changes: 7 additions & 3 deletions tailcfg/c2ntypes.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,13 +55,17 @@ type C2NUpdateResponse struct {
Started bool
}

// C2NPostureIdentityResponse contains either a set of identifying serial number
// from the client or a boolean indicating that the machine has opted out of
// posture collection.
// C2NPostureIdentityResponse contains either a set of identifying serial
// numbers and hardware addresses from the client, or a boolean flag
// indicating that the machine has opted out of posture collection.
type C2NPostureIdentityResponse struct {
// SerialNumbers is a list of serial numbers of the client machine.
SerialNumbers []string `json:",omitempty"`

// IfaceHardwareAddrs is a list of hardware addresses (MAC addresses)
// of the client machine's network interfaces.
IfaceHardwareAddrs []string `json:",omitempty"`

// PostureDisabled indicates if the machine has opted out of
// device posture collection.
PostureDisabled bool `json:",omitempty"`
Expand Down

0 comments on commit 874972b

Please sign in to comment.