Requesting interfaces for tailscale-snap

We’re working on a snap for tailscale:

Requesting autoconnect for:

  • firewall-control: required for setting firewall rules. If this interface is not present, tailscaled will crash.
  • network-control: required for configuring the network and access to /dev/net/tun. Tailscaled needs this to set up networking rules for the wiregard config and such (routing, attaching networks, etc.).

Also requesting approval for sys-devices-virtual-info: a custom system-files read-only interface for files tailscaled needs to determine the platform it’s running on. The requested definition is:

plugs:
  sys-devices-virtual-info:
    interface: system-files
    read:
      # tailscale uses this to figure out if running in VM and if so, which Public Cloud
      # https://github.com/tailscale/tailscale/blob/65fe0ba7b50928eff53e2750ff2d583e4a33eb7e/util/cloudenv/cloudenv.go#L115-L126
      - /sys/class/dmi/id/bios_vendor
      - /sys/class/dmi/id/sys_vendor
      - /sys/class/dmi/id/product_name
      # the above paths appear to be symlinks to the below
      - /sys/devices/virtual/dmi/id/bios_vendor
      - /sys/devices/virtual/dmi/id/product_name
      - /sys/devices/virtual/dmi/id/sys_vendor

Thanks.

+1 from me for auto-connect of both firewall-control and network-control as a VPN application these are both entirely expected and appropriate.

Regarding the system-files instance - AppArmor only deals with the underlying files, not the symlinks to them, so you can remove the symlinks and just leave it with:

      - /sys/devices/virtual/dmi/id/bios_vendor
      - /sys/devices/virtual/dmi/id/product_name
      - /sys/devices/virtual/dmi/id/sys_vendor

Also I think a better name would be sys-devices-virtual-dmi-ids for this interface.

I also wonder if these should be added to the existing system-observe or hardware-observe interfaces?

Finally, I also notice that interfaces like audio-playback include at least sys_vendor and bios_vendor so these are not privileged pieces of information.

Either way, +1 from me for auto-connect of a system-files instance named sys-devices-virtual-dmi-ids for read access to

  - /sys/devices/virtual/dmi/id/bios_vendor
  - /sys/devices/virtual/dmi/id/product_name
  - /sys/devices/virtual/dmi/id/sys_vendor

Thanks @alexmurray

AppArmor only deals with the underlying files, not the symlinks to them, so you can remove the symlinks and just leave it with:

Ah nice, I was wondering about that. I’m curious about the internals of this, since I would imagine there would be an initial read request sent to the /sys/class/* path.

I also wonder if these should be added to the existing system-observe or hardware-observe interfaces?

Hmm looking at https://snapcraft.io/docs/hardware-observe-interface , it appears that /sys/devices/** is already there - although I guess in this case it makes more sense to have a smaller scoped interface, since it’s only those three files (afaik) that tailscale needs to read.

Hmm actually, I was double checking, and found that the corresponding files under /sys/class/ aren’t necessarily symlinks - for example, this is in an LXD VM, Ubuntu Jammy:

root@tailscale-2:~# stat /sys/class/dmi/id/bios_vendor
  File: /sys/class/dmi/id/bios_vendor
  Size: 4096            Blocks: 0          IO Block: 4096   regular file
Device: 14h/20d Inode: 571         Links: 1
Access: (0444/-r--r--r--)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2024-11-24 22:30:57.197224916 +0000
Modify: 2024-11-24 22:30:57.197224916 +0000
Change: 2024-11-24 22:30:57.197224916 +0000
 Birth: -
root@tailscale-2:~# stat /sys/devices/virtual/dmi/id/bios_vendor
  File: /sys/devices/virtual/dmi/id/bios_vendor
  Size: 4096            Blocks: 0          IO Block: 4096   regular file
Device: 14h/20d Inode: 571         Links: 1
Access: (0444/-r--r--r--)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2024-11-24 22:30:57.197224916 +0000
Modify: 2024-11-24 22:30:57.197224916 +0000
Change: 2024-11-24 22:30:57.197224916 +0000
 Birth: -
root@tailscale-2:~# cat /sys/devices/virtual/dmi/id/bios_vendor
EDK II
root@tailscale-2:~# cat /sys/class/dmi/id/bios_vendor
EDK II
root@tailscale-2:~# file /sys/class/dmi/id/bios_vendor
/sys/class/dmi/id/bios_vendor: ASCII text
root@tailscale-2:~# lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 22.04.5 LTS
Release:        22.04
Codename:       jammy

So it may be safer to include all the paths, to cover cases where they aren’t symlinks. What do you think?

The underlying file there is real but I am pretty sure one of the directories earlier in the path is a symlink - what does realpath show in that case?

$ realpath /sys/class/dmi/id/board_serial 
/sys/devices/virtual/dmi/id/board_serial

Ah of course, my bad. :+1:

$ stat /sys/class/dmi/id
  File: /sys/class/dmi/id -> ../../devices/virtual/dmi/id
...

@alexmurray , I’ve implemented your recommendations here. (see tailscale-snap/snap/snapcraft.yaml at main · canonical/tailscale-snap · GitHub )

Thanks. :slight_smile:

@reviewers can anyone else chime in on this one?