gopkg.in/ubuntu-core/snappy.v0@v0.0.0-20210902073436-25a8614f10a6/interfaces/builtin/network_control.go (about)

     1  // -*- Mode: Go; indent-tabs-mode: t -*-
     2  
     3  /*
     4   * Copyright (C) 2016-2017 Canonical Ltd
     5   *
     6   * This program is free software: you can redistribute it and/or modify
     7   * it under the terms of the GNU General Public License version 3 as
     8   * published by the Free Software Foundation.
     9   *
    10   * This program is distributed in the hope that it will be useful,
    11   * but WITHOUT ANY WARRANTY; without even the implied warranty of
    12   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    13   * GNU General Public License for more details.
    14   *
    15   * You should have received a copy of the GNU General Public License
    16   * along with this program.  If not, see <http://www.gnu.org/licenses/>.
    17   *
    18   */
    19  
    20  package builtin
    21  
    22  import (
    23  	"github.com/snapcore/snapd/osutil"
    24  )
    25  
    26  const networkControlSummary = `allows configuring networking and network namespaces`
    27  
    28  const networkControlBaseDeclarationSlots = `
    29    network-control:
    30      allow-installation:
    31        slot-snap-type:
    32          - core
    33      deny-auto-connection: true
    34  `
    35  
    36  const networkControlConnectedPlugAppArmor = `
    37  # Description: Can configure networking and network namespaces via the standard
    38  # 'ip netns' command (man ip-netns(8)). This interface is restricted because it
    39  # gives wide, privileged access to networking and should only be used with
    40  # trusted apps.
    41  
    42  #include <abstractions/nameservice>
    43  /run/systemd/resolve/stub-resolv.conf rk,
    44  
    45  # systemd-resolved (not yet included in nameservice abstraction)
    46  #
    47  # Allow access to the safe members of the systemd-resolved D-Bus API:
    48  #
    49  #   https://www.freedesktop.org/wiki/Software/systemd/resolved/
    50  #
    51  # This API may be used directly over the D-Bus system bus or it may be used
    52  # indirectly via the nss-resolve plugin:
    53  #
    54  #   https://www.freedesktop.org/software/systemd/man/nss-resolve.html
    55  #
    56  #include <abstractions/dbus-strict>
    57  dbus send
    58       bus=system
    59       path="/org/freedesktop/resolve1"
    60       interface="org.freedesktop.resolve1.Manager"
    61       member="Resolve{Address,Hostname,Record,Service}"
    62       peer=(name="org.freedesktop.resolve1"),
    63  
    64  #include <abstractions/ssl_certs>
    65  
    66  capability net_admin,
    67  capability net_raw,
    68  capability setuid, # ping
    69  capability net_broadcast, # openvswitchd
    70  
    71  # Allow protocols except those that we blacklist in
    72  # /etc/modprobe.d/blacklist-rare-network.conf
    73  network appletalk,
    74  network bridge,
    75  network inet,
    76  network inet6,
    77  network ipx,
    78  network packet,
    79  network pppox,
    80  network sna,
    81  
    82  @{PROC}/@{pid}/net/ r,
    83  @{PROC}/@{pid}/net/** r,
    84  
    85  # used by sysctl, et al
    86  @{PROC}/sys/ r,
    87  @{PROC}/sys/net/ r,
    88  @{PROC}/sys/net/core/ r,
    89  @{PROC}/sys/net/core/** rw,
    90  @{PROC}/sys/net/ipv{4,6}/ r,
    91  @{PROC}/sys/net/ipv{4,6}/** rw,
    92  @{PROC}/sys/net/netfilter/ r,
    93  @{PROC}/sys/net/netfilter/** rw,
    94  @{PROC}/sys/net/nf_conntrack_max rw,
    95  
    96  # For advanced wireless configuration
    97  /sys/kernel/debug/ieee80211/ r,
    98  /sys/kernel/debug/ieee80211/** rw,
    99  
   100  # read netfilter module parameters
   101  /sys/module/nf_*/                r,
   102  /sys/module/nf_*/parameters/{,*} r,
   103  
   104  # networking tools
   105  /{,usr/}{,s}bin/arp ixr,
   106  /{,usr/}{,s}bin/arpd ixr,
   107  /{,usr/}{,s}bin/bridge ixr,
   108  /{,usr/}{,s}bin/dhclient Pxr,             # use ixr instead if want to limit to snap dirs
   109  /{,usr/}{,s}bin/dhclient-script ixr,
   110  /{,usr/}{,s}bin/ifconfig ixr,
   111  /{,usr/}{,s}bin/ifdown ixr,
   112  /{,usr/}{,s}bin/ifquery ixr,
   113  /{,usr/}{,s}bin/ifup ixr,
   114  /{,usr/}{,s}bin/ip ixr,
   115  /{,usr/}{,s}bin/ipmaddr ixr,
   116  /{,usr/}{,s}bin/iptunnel ixr,
   117  /{,usr/}{,s}bin/iw ixr,
   118  /{,usr/}{,s}bin/nameif ixr,
   119  /{,usr/}{,s}bin/netstat ixr,              # -p not supported
   120  /{,usr/}{,s}bin/nstat ixr,
   121  /{,usr/}{,s}bin/ping ixr,
   122  /{,usr/}{,s}bin/ping6 ixr,
   123  /{,usr/}{,s}bin/pppd ixr,
   124  /{,usr/}{,s}bin/pppdump ixr,
   125  /{,usr/}{,s}bin/pppoe-discovery ixr,
   126  #/{,usr/}{,s}bin/pppstats ixr,            # needs sys_module
   127  /{,usr/}{,s}bin/route ixr,
   128  /{,usr/}{,s}bin/routef ixr,
   129  /{,usr/}{,s}bin/routel ixr,
   130  /{,usr/}{,s}bin/rtacct ixr,
   131  /{,usr/}{,s}bin/rtmon ixr,
   132  /{,usr/}{,s}bin/ss ixr,
   133  /{,usr/}{,s}bin/sysctl ixr,
   134  /{,usr/}{,s}bin/tc ixr,
   135  /{,usr/}{,s}bin/wpa_action ixr,
   136  /{,usr/}{,s}bin/wpa_cli ixr,
   137  /{,usr/}{,s}bin/wpa_passphrase ixr,
   138  /{,usr/}{,s}bin/wpa_supplicant ixr,
   139  
   140  /dev/rfkill rw,
   141  /sys/class/rfkill/ r,
   142  /sys/devices/{pci[0-9a-f]*,platform,virtual}/**/rfkill[0-9]*/{,**} r,
   143  /sys/devices/{pci[0-9a-f]*,platform,virtual}/**/rfkill[0-9]*/state w,
   144  
   145  # arp
   146  network netlink dgram,
   147  
   148  # ip, et al
   149  /etc/iproute2/{,**} r,
   150  /etc/iproute2/rt_{protos,realms,scopes,tables} w,
   151  /etc/iproute2/rt_{protos,tables}.d/* w,
   152  
   153  # ping - child profile would be nice but seccomp causes problems with that
   154  /{,usr/}{,s}bin/ping ixr,
   155  /{,usr/}{,s}bin/ping6 ixr,
   156  network inet raw,
   157  network inet6 raw,
   158  
   159  # pppd
   160  capability setuid,
   161  @{PROC}/@{pid}/loginuid r,
   162  @{PROC}/@{pid}/mounts r,
   163  
   164  # static host tables
   165  /etc/hosts w,
   166  
   167  # resolvconf
   168  /{,usr/}sbin/resolvconf ixr,
   169  /run/resolvconf/{,**} rk,
   170  /run/resolvconf/** w,
   171  /etc/resolvconf/{,**} r,
   172  /{,usr/}lib/resolvconf/* ix,
   173  # Required by resolvconf
   174  /{,usr/}bin/run-parts ixr,
   175  /etc/resolvconf/update.d/* ix,
   176  
   177  # wpa_suplicant
   178  /{,var/}run/wpa_supplicant/ w,
   179  /{,var/}run/wpa_supplicant/** rw,
   180  /etc/wpa_supplicant/{,**} ixr,
   181  
   182  #ifup,ifdown, dhclient
   183  /{,var/}run/dhclient.*.pid rw,
   184  /var/lib/dhcp/ r,
   185  /var/lib/dhcp/** rw,
   186  
   187  /run/network/ifstate* rw,
   188  /run/network/.ifstate* rw,
   189  /run/network/ifup-* rw,
   190  /run/network/ifdown-* rw,
   191  
   192  # route
   193  /etc/networks r,
   194  /etc/ethers r,
   195  
   196  /etc/rpc r,
   197  
   198  # TUN/TAP - https://www.kernel.org/doc/Documentation/networking/tuntap.txt
   199  #
   200  # We only need to tag /dev/net/tun since the tap[0-9]* and tun[0-9]* devices
   201  # are virtual and don't show up in /dev
   202  /dev/net/tun rw,
   203  
   204  # Access to sysfs interfaces for tun/tap device settings.
   205  /sys/devices/virtual/net/tap*/** rw,
   206  
   207  # access to bridge sysfs interfaces for bridge settings
   208  /sys/devices/virtual/net/*/bridge/* rw,
   209  
   210  # Network namespaces via 'ip netns'. In order to create network namespaces
   211  # that persist outside of the process and be entered (eg, via
   212  # 'ip netns exec ...') the ip command uses mount namespaces such that
   213  # applications can open the /run/netns/NAME object and use it with setns(2).
   214  # For 'ip netns exec' it will also create a mount namespace and bind mount
   215  # network configuration files into /etc in that namespace. See man ip-netns(8)
   216  # for details.
   217  
   218  capability sys_admin, # for setns()
   219  network netlink raw,
   220  
   221  / r,
   222  /run/netns/ r,     # only 'r' since snap-confine will create this for us
   223  /run/netns/* rw,
   224  mount options=(rw, rshared) -> /run/netns/,
   225  mount options=(rw, bind) /run/netns/ -> /run/netns/,
   226  mount options=(rw, bind) / -> /run/netns/*,
   227  umount /,
   228  
   229  # 'ip netns identify <pid>' and 'ip netns pids foo'. Intenionally omit 'ptrace
   230  # (trace)' here since ip netns doesn't actually need to trace other processes.
   231  capability sys_ptrace,
   232  
   233  # 'ip netns exec foo /bin/sh'
   234  mount options=(rw, rslave) /,
   235  mount options=(rw, rslave), # LP: #1648245
   236  umount /sys/,
   237  
   238  # Eg, nsenter --net=/run/netns/... <command>
   239  /{,usr/}{,s}bin/nsenter ixr,
   240  `
   241  
   242  const networkControlConnectedPlugSecComp = `
   243  # Description: Can configure networking and network namespaces via the standard
   244  # 'ip netns' command (man ip-netns(8)). This interface is restricted because it
   245  # gives wide, privileged access to networking and should only be used with
   246  # trusted apps.
   247  
   248  # for ping and ping6
   249  capset
   250  
   251  # Network namespaces via 'ip netns'. In order to create network namespaces
   252  # that persist outside of the process and be entered (eg, via
   253  # 'ip netns exec ...') the ip command uses mount namespaces such that
   254  # applications can open the /run/netns/NAME object and use it with setns(2).
   255  # For 'ip netns exec' it will also create a mount namespace and bind mount
   256  # network configuration files into /etc in that namespace. See man ip-netns(8)
   257  # for details.
   258  bind
   259  
   260  mount
   261  umount
   262  umount2
   263  
   264  unshare
   265  setns - CLONE_NEWNET
   266  
   267  # For various network related netlink sockets
   268  socket AF_NETLINK - NETLINK_ROUTE
   269  socket AF_NETLINK - NETLINK_FIB_LOOKUP
   270  socket AF_NETLINK - NETLINK_INET_DIAG
   271  socket AF_NETLINK - NETLINK_XFRM
   272  socket AF_NETLINK - NETLINK_DNRTMSG
   273  socket AF_NETLINK - NETLINK_ISCSI
   274  socket AF_NETLINK - NETLINK_RDMA
   275  socket AF_NETLINK - NETLINK_GENERIC
   276  
   277  # for receiving kobject_uevent() net messages from the kernel
   278  socket AF_NETLINK - NETLINK_KOBJECT_UEVENT
   279  `
   280  
   281  /* https://www.kernel.org/doc/Documentation/networking/tuntap.txt
   282   *
   283   * We only need to tag /dev/net/tun since the tap[0-9]* and tun[0-9]* devices
   284   * are virtual and don't show up in /dev
   285   */
   286  var networkControlConnectedPlugUDev = []string{
   287  	`KERNEL=="rfkill"`,
   288  	`KERNEL=="tun"`,
   289  }
   290  
   291  var networkControlConnectedPlugMount = []osutil.MountEntry{{
   292  	Name:    "/var/lib/snapd/hostfs/var/lib/dhcp",
   293  	Dir:     "/var/lib/dhcp",
   294  	Options: []string{"bind", "rw", osutil.XSnapdIgnoreMissing()},
   295  }}
   296  
   297  // TODO: Add a layer that derives this sort of data from mount entry, like the
   298  // one above, into a set of apparmor rules for snap-update-ns, like the ones
   299  // below.
   300  //
   301  // When setting up a mount entry, we also need corresponding
   302  // snap-updates-ns rules. Eg, if have:
   303  // []osutil.MountEntry{{
   304  //	Name:    "/foo/bar",
   305  //	Dir:     "/bar",
   306  //	Options: []string{"rw", "bind"},
   307  // }}
   308  // Then you can expect to need:
   309  // /foo/ r,
   310  // /foo/bar/ r,
   311  // mount options=(rw bind) /foo/bar/ -> /bar/,
   312  // umount /bar/,
   313  // ...
   314  // You'll need 'r' rules for all the directories that need to be traversed,
   315  // starting from the root directory all the way down to the directory being
   316  // mounted. This is required by the safe bind mounting trick employed by
   317  // snap-update-ns.
   318  //
   319  // You'll need 'rw' rules to support cases when snap-update-ns is expected to
   320  // create the missing directory, before performing the bind mount. Note that
   321  // there are two sides, one side is the host visible through
   322  // /var/lib/snapd/hostfs and the other side is everything else. To support
   323  // writes to the host side you need to coordinate with the trespassing rules
   324  // implemented in snap-update-ns/system.go.
   325  var networkControlConnectedPlugUpdateNSAppArmor = `
   326  /var/ r,
   327  /var/lib/ r,
   328  /var/lib/snapd/ r,
   329  /var/lib/snapd/hostfs/ r,
   330  /var/lib/snapd/hostfs/var/ r,
   331  /var/lib/snapd/hostfs/var/lib/ r,
   332  /var/lib/snapd/hostfs/var/lib/dhcp/ r,
   333  /var/lib/dhcp/ r,
   334  mount options=(rw bind) /var/lib/snapd/hostfs/var/lib/dhcp/ -> /var/lib/dhcp/,
   335  umount /var/lib/dhcp/,
   336  `
   337  
   338  func init() {
   339  	registerIface(&commonInterface{
   340  		name:                  "network-control",
   341  		summary:               networkControlSummary,
   342  		implicitOnCore:        true,
   343  		implicitOnClassic:     true,
   344  		baseDeclarationSlots:  networkControlBaseDeclarationSlots,
   345  		connectedPlugAppArmor: networkControlConnectedPlugAppArmor,
   346  		connectedPlugSecComp:  networkControlConnectedPlugSecComp,
   347  		connectedPlugUDev:     networkControlConnectedPlugUDev,
   348  
   349  		connectedPlugMount:            networkControlConnectedPlugMount,
   350  		connectedPlugUpdateNSAppArmor: networkControlConnectedPlugUpdateNSAppArmor,
   351  
   352  		suppressPtraceTrace: true,
   353  
   354  		// affects the plug snap because of mount backend
   355  		affectsPlugOnRefresh: true,
   356  	})
   357  }