AppArmor

Revision 89 as of 2018-03-12 23:22:31

Clear message

Dependents/Clients

  • dbus
  • snapd
  • lxd
  • lxc
  • libvirt/libvirt-lxc
  • docker.io
  • click-apparmor (Ubuntu 17.10 and older releases only)
  • apparmor-easyprof-ubuntu (Ubuntu 17.10 and older releases only)
  • ubuntu-app-launch (uses apparmor kernel interface via upstart)
  • libusermetrics (uses libapparmor; Ubuntu 17.10 and older releases only)

Test Plan

autopkgtests

  1. Run autopkgtests for important rdepends. Do they all exit with status '0':
    • click-apparmor:
      1. make sure the schroot is up to date (eg, autopkgtest-trusty-amd64)

      2. download the new AppArmor binaries to ../binary

      3. run the tests

        $ adt-run -B ../binary/*.deb --apt-source click-apparmor --log-file /tmp/click-apparmor-adt.out --- adt-virt-schroot autopkgtest-trusty-amd64 || echo "** AUTOPKGTESTS FAILED"
    • apparmor-easyprof-ubuntu:
      1. make sure the schroot is up to date (eg, autopkgtest-trusty-amd64)

      2. download the new AppArmor binaries to ../binary

      3. run the tests

        $ adt-run -B ../binary/*.deb --apt-source apparmor-easyprof-ubuntu --log-file /tmp/apparmor-easyprof-ubuntu-adt.out --- adt-virt-schroot autopkgtest-trusty-amd64 || echo "** AUTOPKGTESTS FAILED"
    • OPTIONAL: lxc (requires autopkgtest VM. Note: runs before promotion to -proposed, but there are manual tests below that should be performed before upload)

      1. Create a pristine VM for testing:

        $ adt-buildvm-ubuntu-cloud -v
      2. Run the lxc autopkgtests after enabling a PPA and updating and dist-upgrading:

        $ adt-run --setup-commands='add-apt-repository -ys ppa:apparmor-dev/apparmor-devel' -U --apt-source lxc --log-file /tmp/lxc-adt.out --- adt-virt-qemu adt-xenial-amd64-cloud.img || echo "** AUTOPKGTESTS FAILED"

Common tests

  1. Install image on phone/emulator (x86) and have an up to date Ubuntu Desktop and/or Server VM
  2. Install freshly built packages that are needed for landing and reboot
    • Eg:
      • devel: copy_sppa_to_repos --arch=i386,amd64,armhf --include-devel --ppa=ci-train-ppa-service/landing-NNN apparmor

      • rtm: copy_sppa_to_repos --include-devel -a amd64,i386,armhf --ppa=ci-train-ppa-service/landing-002 --distribution=ubuntu-rtm -r 14.09 apparmor

  3. Verify the system comes up and has networking (dhclient profile)
  4. Verify the output of aa-status. It should report:

    1. many profiles loaded (eg, 20 or more)
    2. many profiles in enforce mode (eg, 20 or more)
    3. 0 profiles in complain mode (unless apparmor-profiles or some other special package is installed)
    4. some process should have a profile defined
    5. some process should be in enforce mode (the same number as '4', above)
    6. 0 processes in complain mode (unless libreoffice-common, apparmor-profiles, or some other special package is installed)
    7. 0 processes are unconfined but have a profile defined (the only exception is /usr/bin/lxc-start on Ubuntu Touch)
  5. Verify cache files have no errors:

    $ for i in /etc/apparmor.d/cache /var/cache/apparmor ; do echo "= $i =" ; for j in $i/* ; do echo -n "$j: " ; sudo apparmor_parser -B -r $j && echo pass || echo FAIL ; done ; done | grep FAIL

Desktop only

Note: some of these can also be run on server if preferred.

  1. Verify Ubuntu Desktop and/or Server works by performing basic login testing - eg, verify networking, verify browser launches, verify apt-get works
  2. Run QRT/scripts/test-apparmor.py on Ubuntu Desktop/Server (not Ubuntu Touch, needs extensive read/write permissions. Note: in the exceptional case when there are temporary new expected failures, be sure to update test-apparmor.py for these to not block kernel team processes):

    $ git clone https://git.launchpad.net/qa-regression-testing
    $ cd qa-regression-testing
    $ ./scripts/make-test-tarball ./scripts/test-apparmor.py
    # To run, copy /tmp/qrt-test-apparmor.tar.gz to the target system, then do:
    $ tar -zxf qrt-test-apparmor.tar.gz
    $ cd ./qrt-test-apparmor
    $ sudo ./install-packages test-apparmor.py
    $ sudo ./test-apparmor.py -v
  3. Run QRT/scripts/test-dbus.py on Ubuntu Desktop:

    $ ./scripts/make-test-tarball ./scripts/test-apparmor.py
    # To run, copy /tmp/qrt-test-dbus.tar.gz to the target system, then log in through a graphical session and do:
    $ tar -zxf qrt-test-dbus.tar.gz
    $ cd ./qrt-test-dbus
    $ sudo ./install-packages test-dbus.py
    $ sudo ./test-dbus.py -v
  4. Run image tests on Ubuntu Desktop/Server:
    • Desktop:

      $ git clone https://git.launchpad.net/qa-regression-testing
      $ cd qa-regression-testing
      $ scp -r ./tests username@vm:/tmp/tests
      $ ssh -tt root@vm /tmp/tests/image/privileged/check-apparmor
      $ ssh -tt root@vm apt-get install click-apparmor apparmor-easyprof-ubuntu click packagekit-tools ubuntu-app-launch ubuntu-sdk-libs

      At this point you'll need to login to Ubuntu Desktop and open a terminal and run (if someone knows how to run this over ssh, please tell :):

      $ /tmp/tests/image/unprivileged/click-apparmor
      $ /tmp/tests/image/unprivileged/apparmor-easyprof-ubuntu
  5. Verify lxc container starts with new AppArmor on Ubuntu Desktop/Server:

    ~$ sudo apt-get install lxc
    # optionally adjust MIRROR in /etc/default/lxc
    ~$ sudo lxc-create -t ubuntu -n CN
    ~$ sudo lxc-start -n CN # later versions (eg 15.04)  may not start in a console
    ...
    Ubuntu Trusty Tahr (development branch) CN console
    
    CN login: ubuntu
    Password:
    ...

    Run a few external commands:

    $ sudo lxc-ls
    CN
    $ sudo lxc-info --name CN
    Name:           CN
    State:          RUNNING
    PID:            24354
    IP:             10.0.3.153
    CPU use:        1.80 seconds
    BlkIO use:      12.18 MiB
    Memory use:     20.58 MiB
    KMem use:       0 bytes
    Link:           vethYD8QMX
     TX bytes:      2.90 KiB
     RX bytes:      6.77 KiB
     Total bytes:   9.67 KiB
    $ sudo lxc-console --name CN
    Connected to tty 1
    Type <Ctrl+a q> to exit the console, <Ctrl+a Ctrl+a> to enter Ctrl+a itself
    
    Ubuntu Utopic Unicorn (development branch) CN tty1
    
    CN login:
    ...
    $ sudo lxc-attach --name CN uptime
     22:29:49 up  1:10,  1 user,  load average: 0.06, 0.31, 0.58

    When done, shut it down with (outside the container (tests lxc-start still works to control the container)):

    $ sudo lxc-stop -k -n CN

    And, finally, destroy it:

    $ sudo lxc-destroy -n CN
  6. Verify lxd container starts with new AppArmor on Ubuntu Desktop/Server:

    • deb:

      $ sudo apt-get install lxd
      $ newgrp lxd
    • snap:

      $ sudo apt-get remove lxd lxc
      $ sudo addgroup lxd
      $ sudo adduser `id -un` lxd
      $ newgrp lxd
      $ sudo snap install lxd
      $ sudo lxd init

      adjust ~/.bashrc to have alias lxc="lxd.lxc" and run . ~/.bashrc

    Once lxd is installed:

    $ lxc remote add images images.linuxcontainers.org # this may already be done for you
    
    $ lxc image list images:
    ...
    |                                 | 0d4bfe75bd0d | yes    | Ubuntu trusty (amd64) (20160321_03:49)    | x86_64  | 75.60MB  | Mar 21, 2016 at 4:19am (UTC)  |
    ...
    
    $ lxc launch ubuntu: ubuntu-64
    ...
    Creating ubuntu-64
    Retrieving image: 100%
    Starting ubuntu-64
    
    $ lxc list
    +-----------+---------+-------------------+------+------------+-----------+
    |   NAME    |  STATE  |       IPV4        | IPV6 |    TYPE    | SNAPSHOTS |
    +-----------+---------+-------------------+------+------------+-----------+
    | ubuntu-64 | RUNNING | 10.0.3.181 (eth0) |      | PERSISTENT | 0         |
    +-----------+---------+-------------------+------+------------+-----------+
    
    $ lxc info ubuntu-64
    Name: ubuntu-64
    Architecture: i686
    Created: 2016/03/22 17:55 UTC
    Status: Running
    Type: persistent
    Profiles: default
    Pid: 2612
    Processes: 8
    Ips:
      eth0: inet    10.0.3.181      vethIKDBKR
      eth0: inet6   fe80::216:3eff:fe88:59b7        vethIKDBKR
      lo:   inet    127.0.0.1
      lo:   inet6   ::1
    
    $ lxc exec ubuntu-64 /bin/bash
    root@ubuntu-64:~# ls
    root@ubuntu-64:~# uptime
     17:58:40 up 3 min,  0 users,  load average: 0.01, 0.06, 0.05
    root@ubuntu-64:~# exit
    
    $ lxc exec ubuntu-64 ps
      PID TTY          TIME CMD
     1552 ?        00:00:00 ps
    
    # pull/push files
    $ lxc file pull ubuntu-64/etc/hostname .
    $ lxc file push hostname ubuntu-64/tmp/hostname
    $ lxc exec ubuntu-64 -- cat /tmp/hostname
    ubuntu-64
    
    $ lxc stop ubuntu-64  # the lxd snap may show an error here, but should've have stopped the container
    $ lxc delete ubuntu-64
  7. Install libvirt and ensure that the libvirtd group is part of the current session:

    $ sudo apt-get install libvirt-bin
    $ newgrp libvirtd
  8. Follow setup instructions in $QRT/notes_testing/libvirt/README
  9. Verify qemu/kvm libvirt VMs start under confinement (verify with sudo aa-status) with new AppArmor on Ubuntu Desktop/Server by using QRT/scripts/test-libvirt.py (note: there are some failures unrelated to apparmor, so do a baseline run before upgrading to compare)

  10. Verify libvirt-lxc VMs start with new AppArmor on Ubuntu Desktop/Server by following SergeHallyn_libvirtlxc

    • IMPORTANT: The instructions linked to above will not work until bug #1445611 is fixed.

  11. Verify docker.io (need at least 1.2) containers with new AppArmor on Ubuntu Desktop/Server:

    $ sudo apt-get install docker.io # should not have libvirt or lxc co-installed
    $ sudo docker pull ubuntu:trusty
    ...
    809ed259f845: Download complete
    
    $ sudo docker images
    REPOSITORY          TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
    ubuntu              trusty              96864a7d2df3        9 hours ago         205.1 MB
    
    $ sudo docker run ubuntu:trusty uptime
     20:31:21 up 1 min,  0 users,  load average: 0.09, 0.06, 0.03
    ...
    
    $ sudo docker run -i -t ubuntu:trusty /bin/sh
    # ps
      PID TTY          TIME CMD
        1 ?        00:00:00 sh
        7 ?        00:00:00 ps

    At this point, an interactive shell is running in the terminal. In another, try a couple of operations:

    $ sudo aa-status|grep docker
       docker-default
       docker-default (2209)
    
    $ sudo docker ps
    CONTAINER ID        IMAGE               COMMAND             CREATED              STATUS              PORTS               NAMES
    e0f6f329ad29        ubuntu:trusty       "/bin/sh"           About a minute ago   Up About a minute                       cocky_davinci
    
    $ ps -Z 2209
    LABEL                             PID TTY      STAT   TIME COMMAND
    docker-default                   2209 pts/1    Ss+    0:00 /bin/sh
    
    $ sudo docker inspect e0f6f329ad29
    [{
        "Args": [],
        "Config": {
            "AttachStderr": true,
            "AttachStdin": true,
            "AttachStdout": true,
            "Cmd": [
                "/bin/sh"
            ],
    ...

    In the terminal running 'sh', now exit:

    # exit
    
    $ sudo docker ps
    CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
  12. Verify lightdm guest session works correctly (there will be apparmor denials, but this is expected)
    • IMPORTANT: Open a shell from inside the guest session and ensure the following command indicates that new processes inside the guest session are confined:

      $ cat /proc/self/attr/current
      /usr/lib/lightdm/lightdm-guest-session (enforce)
    • Verify that the browser and libreoffice work as expected
  13. Verify snappy works ok:

    $ sudo apt-get install ubuntu-snappy
    $ sudo snap install ubuntu-core
    $ sudo snap install hello-world
    $ su - `id -un` # to update your PATH to include /snaps/bin
    $ hello-world.evil 
    Hello Evil World!
    This example demonstrates the app confinement
    You should see a permission denied error next
    /snaps/hello-world.canonical/6.0/bin/evil: 9: /snaps/hello-world.canonical/6.0/bin/evil: cannot create /var/tmp/myevil.txt: Permission denied
    $ hello-world.sh
    Launching a shell inside the default app confinement. Navigate to your
    app-specific directories with:
    
      $ cd $SNAP
      $ cd $SNAP_DATA
      $ cd $SNAP_USER_DATA
    
    bash-4.3$ 
    cat /etc/fstab
    cat: /etc/fstab: Permission denied
    bash-4.3$ exit
    $ sudo aa-status | grep hello-world # verify profiles are loaded

Additional information

While not usually necessary, it might be useful to be able to test AppArmor policy using a binary under some arbitrary Ubuntu Touch confinement policy.

  1. grab the binary from QRT (eg, armhf/confined-basic)

  2. adb push ./confined-basic /tmp

  3. run it on the device under phablet-shell:

    $ aa-exec-click -p <profile to test> -- /tmp/confined-basic -r /path/to/read-only/file
    $ aa-exec-click -p <profile to test> -- /tmp/confined-basic -w /path/to/write-only/file
    $ aa-exec-click -p <profile to test> -- /tmp/confined-basic -W /path/to/readwrite/file