gitee.com/mysnapcore/mysnapd@v0.1.0/interfaces/builtin/multipass_support.go (about)

     1  // -*- Mode: Go; indent-tabs-mode: t -*-
     2  
     3  /*
     4   * Copyright (C) 2019 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  /*
    23   * Multipass is a tool to create and manage Virtual Machines and their images.
    24   * Each VM runs as a separate "qemu" process (on Linux). VM images are automatically
    25   * downloaded, but need conversion using "qemu-img". Networking is provided by
    26   * configuring a TUN/TAP network on the host, with DHCP provided by a shared
    27   * "dnsmasq" process. File sharing between the VM and the host is provided by a
    28   * "sshfs_server" utility. All these utilities are shipped in the snap.
    29   *
    30   * Each of these utilities have a different purpose, and an attempt
    31   * to confine them all in a single profile would result in an extremely broad AppArmor
    32   * profile.
    33   *
    34   * Instead we defer to Multipass the responsibility of generating custom AppArmor
    35   * profiles for each of these utilities, and trust it launches each utility with
    36   * all possible security mechanisms enabled. The Multipass daemon itself will run
    37   * under this restricted policy.
    38   */
    39  
    40  const multipassSupportSummary = `allows operating as the Multipass service`
    41  
    42  const multipassSupportBaseDeclarationPlugs = `
    43    multipass-support:
    44      allow-installation: false
    45      deny-auto-connection: true
    46  `
    47  
    48  const multipassSupportBaseDeclarationSlots = `
    49    multipass-support:
    50      allow-installation:
    51        slot-snap-type:
    52          - core
    53      deny-auto-connection: true
    54  `
    55  
    56  const multipassSupportConnectedPlugAppArmor = `
    57  # Description: this policy intentionally allows the Multipass daemon to configure AppArmor
    58  # as Multipass generates AppArmor profiles for the utility processes it spawns.
    59  /{,usr/}sbin/apparmor_parser ixr,
    60  /etc/apparmor{,.d}/{,**} r,
    61  /sys/kernel/security/apparmor/{,**} r,
    62  /sys/kernel/security/apparmor/.remove w,
    63  /sys/kernel/security/apparmor/.replace w,
    64  
    65  # Allow running utility processes under the specialized AppArmor profiles.
    66  # These profiles will prevent utility processes escaping confinement.
    67  capability mac_admin,
    68  
    69  # Multipass has a server/client design, using a socket for IPC. The daemon runs
    70  # as root, but makes the socket accessible to anyone in the sudo group.
    71  capability chown,
    72  
    73  # Multipass will also use privilege separation when running utility processes
    74  capability setuid,
    75  capability setgid,
    76  
    77  # Some utility process (e.g. dnsmasq) will drop root privileges after startup and
    78  # change to another user. The Multipass daemon needs ability to stop them.
    79  capability kill,
    80  
    81  # Profiles Multipass generates have a naming scheme, restrict any profile changes to
    82  # those matching that scheme. Need unsafe to prevent env scrubbing.
    83  change_profile unsafe /var/snap/{@{SNAP_NAME},@{SNAP_INSTANCE_NAME}}/usr/bin/* -> multipass.*,
    84  signal (send) peer=multipass.*,
    85  ptrace (read, trace) peer=multipass.*,
    86  `
    87  
    88  const multipassSupportConnectedPlugSecComp = `
    89  # Description: allow operating as the Multipass daemon, and enable its various utilites
    90  # (qemu, qemu-img, dnsmasq, sshfs_server)
    91  
    92  # Note that this profile necessarily contains the union of all the syscalls each of the
    93  # utilities requires. We rely on Multipass to generate specific AppArmor profiles
    94  # for each child process, to further restrict their abilities.
    95  
    96  # dnsmasq fails unless it can drop supplementary groups
    97  setgroups 0 -
    98  setgroups32 0 -
    99  
   100  # Multipassd will have a child process - sshfs_server - which allows mounting a
   101  # user-specified directory on the host into the VM. Here we permit typical filesytem
   102  # syscalls with the knowledge that Multipass will generate a specific AppArmor
   103  # profile for sshfs_server, restricting any filesystem access to just the
   104  # user-specified directory.
   105  
   106  # More filesystem syscalls sshfs_server will need, as it allows user to change
   107  # file owner/group arbitrarily.
   108  chown
   109  chown32
   110  fchown
   111  fchown32
   112  fchownat
   113  lchown
   114  lchownat
   115  `
   116  
   117  func init() {
   118  	registerIface(&commonInterface{
   119  		name:                  "multipass-support",
   120  		summary:               multipassSupportSummary,
   121  		implicitOnCore:        true,
   122  		implicitOnClassic:     true,
   123  		baseDeclarationSlots:  multipassSupportBaseDeclarationSlots,
   124  		baseDeclarationPlugs:  multipassSupportBaseDeclarationPlugs,
   125  		connectedPlugAppArmor: multipassSupportConnectedPlugAppArmor,
   126  		connectedPlugSecComp:  multipassSupportConnectedPlugSecComp,
   127  	})
   128  }