github.com/kubiko/snapd@v0.0.0-20201013125620-d4f3094d9ddf/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  
    70  # Allow protocols except those that we blacklist in
    71  # /etc/modprobe.d/blacklist-rare-network.conf
    72  network appletalk,
    73  network bridge,
    74  network inet,
    75  network inet6,
    76  network ipx,
    77  network packet,
    78  network pppox,
    79  network sna,
    80  
    81  @{PROC}/@{pid}/net/ r,
    82  @{PROC}/@{pid}/net/** r,
    83  
    84  # used by sysctl, et al
    85  @{PROC}/sys/ r,
    86  @{PROC}/sys/net/ r,
    87  @{PROC}/sys/net/core/ r,
    88  @{PROC}/sys/net/core/** rw,
    89  @{PROC}/sys/net/ipv{4,6}/ r,
    90  @{PROC}/sys/net/ipv{4,6}/** rw,
    91  @{PROC}/sys/net/netfilter/ r,
    92  @{PROC}/sys/net/netfilter/** rw,
    93  @{PROC}/sys/net/nf_conntrack_max rw,
    94  
    95  # For advanced wireless configuration
    96  /sys/kernel/debug/ieee80211/ r,
    97  /sys/kernel/debug/ieee80211/** rw,
    98  
    99  # read netfilter module parameters
   100  /sys/module/nf_*/                r,
   101  /sys/module/nf_*/parameters/{,*} r,
   102  
   103  # networking tools
   104  /{,usr/}{,s}bin/arp ixr,
   105  /{,usr/}{,s}bin/arpd ixr,
   106  /{,usr/}{,s}bin/bridge ixr,
   107  /{,usr/}{,s}bin/dhclient Pxr,             # use ixr instead if want to limit to snap dirs
   108  /{,usr/}{,s}bin/dhclient-script ixr,
   109  /{,usr/}{,s}bin/ifconfig ixr,
   110  /{,usr/}{,s}bin/ifdown ixr,
   111  /{,usr/}{,s}bin/ifquery ixr,
   112  /{,usr/}{,s}bin/ifup ixr,
   113  /{,usr/}{,s}bin/ip ixr,
   114  /{,usr/}{,s}bin/ipmaddr ixr,
   115  /{,usr/}{,s}bin/iptunnel ixr,
   116  /{,usr/}{,s}bin/iw ixr,
   117  /{,usr/}{,s}bin/nameif ixr,
   118  /{,usr/}{,s}bin/netstat ixr,              # -p not supported
   119  /{,usr/}{,s}bin/nstat ixr,
   120  /{,usr/}{,s}bin/ping ixr,
   121  /{,usr/}{,s}bin/ping6 ixr,
   122  /{,usr/}{,s}bin/pppd ixr,
   123  /{,usr/}{,s}bin/pppdump ixr,
   124  /{,usr/}{,s}bin/pppoe-discovery ixr,
   125  #/{,usr/}{,s}bin/pppstats ixr,            # needs sys_module
   126  /{,usr/}{,s}bin/route ixr,
   127  /{,usr/}{,s}bin/routef ixr,
   128  /{,usr/}{,s}bin/routel ixr,
   129  /{,usr/}{,s}bin/rtacct ixr,
   130  /{,usr/}{,s}bin/rtmon ixr,
   131  /{,usr/}{,s}bin/ss ixr,
   132  /{,usr/}{,s}bin/sysctl ixr,
   133  /{,usr/}{,s}bin/tc ixr,
   134  /{,usr/}{,s}bin/wpa_action ixr,
   135  /{,usr/}{,s}bin/wpa_cli ixr,
   136  /{,usr/}{,s}bin/wpa_passphrase ixr,
   137  /{,usr/}{,s}bin/wpa_supplicant ixr,
   138  
   139  /dev/rfkill rw,
   140  /sys/class/rfkill/ r,
   141  /sys/devices/{pci[0-9a-f]*,platform,virtual}/**/rfkill[0-9]*/{,**} r,
   142  /sys/devices/{pci[0-9a-f]*,platform,virtual}/**/rfkill[0-9]*/state w,
   143  
   144  # arp
   145  network netlink dgram,
   146  
   147  # ip, et al
   148  /etc/iproute2/{,**} r,
   149  /etc/iproute2/rt_{protos,realms,scopes,tables} w,
   150  /etc/iproute2/rt_{protos,tables}.d/* w,
   151  
   152  # ping - child profile would be nice but seccomp causes problems with that
   153  /{,usr/}{,s}bin/ping ixr,
   154  /{,usr/}{,s}bin/ping6 ixr,
   155  network inet raw,
   156  network inet6 raw,
   157  
   158  # pppd
   159  capability setuid,
   160  @{PROC}/@{pid}/loginuid r,
   161  @{PROC}/@{pid}/mounts r,
   162  
   163  # static host tables
   164  /etc/hosts w,
   165  
   166  # resolvconf
   167  /sbin/resolvconf ixr,
   168  /run/resolvconf/{,**} rk,
   169  /run/resolvconf/** w,
   170  /etc/resolvconf/{,**} r,
   171  /lib/resolvconf/* ix,
   172  # Required by resolvconf
   173  /bin/run-parts ixr,
   174  /etc/resolvconf/update.d/* ix,
   175  
   176  # wpa_suplicant
   177  /{,var/}run/wpa_supplicant/ w,
   178  /{,var/}run/wpa_supplicant/** rw,
   179  /etc/wpa_supplicant/{,**} ixr,
   180  
   181  #ifup,ifdown, dhclient
   182  /{,var/}run/dhclient.*.pid rw,
   183  /var/lib/dhcp/ r,
   184  /var/lib/dhcp/** rw,
   185  
   186  /run/network/ifstate* rw,
   187  /run/network/.ifstate* rw,
   188  /run/network/ifup-* rw,
   189  /run/network/ifdown-* rw,
   190  
   191  # route
   192  /etc/networks r,
   193  /etc/ethers r,
   194  
   195  /etc/rpc r,
   196  
   197  # TUN/TAP - https://www.kernel.org/doc/Documentation/networking/tuntap.txt
   198  #
   199  # We only need to tag /dev/net/tun since the tap[0-9]* and tun[0-9]* devices
   200  # are virtual and don't show up in /dev
   201  /dev/net/tun rw,
   202  
   203  # access to bridge sysfs interfaces for bridge settings
   204  /sys/devices/virtual/net/*/bridge/* rw,
   205  
   206  # Network namespaces via 'ip netns'. In order to create network namespaces
   207  # that persist outside of the process and be entered (eg, via
   208  # 'ip netns exec ...') the ip command uses mount namespaces such that
   209  # applications can open the /run/netns/NAME object and use it with setns(2).
   210  # For 'ip netns exec' it will also create a mount namespace and bind mount
   211  # network configuration files into /etc in that namespace. See man ip-netns(8)
   212  # for details.
   213  
   214  capability sys_admin, # for setns()
   215  network netlink raw,
   216  
   217  / r,
   218  /run/netns/ r,     # only 'r' since snap-confine will create this for us
   219  /run/netns/* rw,
   220  mount options=(rw, rshared) -> /run/netns/,
   221  mount options=(rw, bind) /run/netns/ -> /run/netns/,
   222  mount options=(rw, bind) / -> /run/netns/*,
   223  umount /,
   224  
   225  # 'ip netns identify <pid>' and 'ip netns pids foo'. Intenionally omit 'ptrace
   226  # (trace)' here since ip netns doesn't actually need to trace other processes.
   227  capability sys_ptrace,
   228  
   229  # 'ip netns exec foo /bin/sh'
   230  mount options=(rw, rslave) /,
   231  mount options=(rw, rslave), # LP: #1648245
   232  umount /sys/,
   233  
   234  # Eg, nsenter --net=/run/netns/... <command>
   235  /{,usr/}{,s}bin/nsenter ixr,
   236  `
   237  
   238  const networkControlConnectedPlugSecComp = `
   239  # Description: Can configure networking and network namespaces via the standard
   240  # 'ip netns' command (man ip-netns(8)). This interface is restricted because it
   241  # gives wide, privileged access to networking and should only be used with
   242  # trusted apps.
   243  
   244  # for ping and ping6
   245  capset
   246  
   247  # Network namespaces via 'ip netns'. In order to create network namespaces
   248  # that persist outside of the process and be entered (eg, via
   249  # 'ip netns exec ...') the ip command uses mount namespaces such that
   250  # applications can open the /run/netns/NAME object and use it with setns(2).
   251  # For 'ip netns exec' it will also create a mount namespace and bind mount
   252  # network configuration files into /etc in that namespace. See man ip-netns(8)
   253  # for details.
   254  bind
   255  
   256  mount
   257  umount
   258  umount2
   259  
   260  unshare
   261  setns - CLONE_NEWNET
   262  
   263  # For various network related netlink sockets
   264  socket AF_NETLINK - NETLINK_ROUTE
   265  socket AF_NETLINK - NETLINK_FIB_LOOKUP
   266  socket AF_NETLINK - NETLINK_INET_DIAG
   267  socket AF_NETLINK - NETLINK_XFRM
   268  socket AF_NETLINK - NETLINK_DNRTMSG
   269  socket AF_NETLINK - NETLINK_ISCSI
   270  socket AF_NETLINK - NETLINK_RDMA
   271  socket AF_NETLINK - NETLINK_GENERIC
   272  
   273  # for receiving kobject_uevent() net messages from the kernel
   274  socket AF_NETLINK - NETLINK_KOBJECT_UEVENT
   275  `
   276  
   277  /* https://www.kernel.org/doc/Documentation/networking/tuntap.txt
   278   *
   279   * We only need to tag /dev/net/tun since the tap[0-9]* and tun[0-9]* devices
   280   * are virtual and don't show up in /dev
   281   */
   282  var networkControlConnectedPlugUDev = []string{
   283  	`KERNEL=="rfkill"`,
   284  	`KERNEL=="tun"`,
   285  }
   286  
   287  var networkControlConnectedPlugMount = []osutil.MountEntry{{
   288  	Name:    "/var/lib/snapd/hostfs/var/lib/dhcp",
   289  	Dir:     "/var/lib/dhcp",
   290  	Options: []string{"bind", "rw", osutil.XSnapdIgnoreMissing()},
   291  }}
   292  
   293  // TODO: Add a layer that derives this sort of data from mount entry, like the
   294  // one above, into a set of apparmor rules for snap-update-ns, like the ones
   295  // below.
   296  //
   297  // When setting up a mount entry, we also need corresponding
   298  // snap-updates-ns rules. Eg, if have:
   299  // []osutil.MountEntry{{
   300  //	Name:    "/foo/bar",
   301  //	Dir:     "/bar",
   302  //	Options: []string{"rw", "bind"},
   303  // }}
   304  // Then you can expect to need:
   305  // /foo/ r,
   306  // /foo/bar/ r,
   307  // mount options=(rw bind) /foo/bar/ -> /bar/,
   308  // umount /bar/,
   309  // ...
   310  // You'll need 'r' rules for all the directories that need to be traversed,
   311  // starting from the root directory all the way down to the directory being
   312  // mounted. This is required by the safe bind mounting trick employed by
   313  // snap-update-ns.
   314  //
   315  // You'll need 'rw' rules to support cases when snap-update-ns is expected to
   316  // create the missing directory, before performing the bind mount. Note that
   317  // there are two sides, one side is the host visible through
   318  // /var/lib/snapd/hostfs and the other side is everything else. To support
   319  // writes to the host side you need to coordinate with the trespassing rules
   320  // implemented in snap-update-ns/system.go.
   321  var networkControlConnectedPlugUpdateNSAppArmor = `
   322  /var/ r,
   323  /var/lib/ r,
   324  /var/lib/snapd/ r,
   325  /var/lib/snapd/hostfs/ r,
   326  /var/lib/snapd/hostfs/var/ r,
   327  /var/lib/snapd/hostfs/var/lib/ r,
   328  /var/lib/snapd/hostfs/var/lib/dhcp/ r,
   329  /var/lib/dhcp/ r,
   330  mount options=(rw bind) /var/lib/snapd/hostfs/var/lib/dhcp/ -> /var/lib/dhcp/,
   331  umount /var/lib/dhcp/,
   332  `
   333  
   334  func init() {
   335  	registerIface(&commonInterface{
   336  		name:                  "network-control",
   337  		summary:               networkControlSummary,
   338  		implicitOnCore:        true,
   339  		implicitOnClassic:     true,
   340  		baseDeclarationSlots:  networkControlBaseDeclarationSlots,
   341  		connectedPlugAppArmor: networkControlConnectedPlugAppArmor,
   342  		connectedPlugSecComp:  networkControlConnectedPlugSecComp,
   343  		connectedPlugUDev:     networkControlConnectedPlugUDev,
   344  
   345  		connectedPlugMount:            networkControlConnectedPlugMount,
   346  		connectedPlugUpdateNSAppArmor: networkControlConnectedPlugUpdateNSAppArmor,
   347  
   348  		suppressPtraceTrace: true,
   349  	})
   350  
   351  }