From 8cf89245f5b5f9abb066f599cb69bfe0202bae5d Mon Sep 17 00:00:00 2001 From: Jessica Frazelle Date: Tue, 13 Oct 2015 17:37:54 -0700 Subject: [PATCH 1/4] change default docker-engine profile to a template based on apparmor_parser version Signed-off-by: Jessica Frazelle --- contrib/apparmor/main.go | 85 +++++++++++++++++++ .../apparmor/{docker-engine => template.go} | 22 ++++- 2 files changed, 105 insertions(+), 2 deletions(-) create mode 100644 contrib/apparmor/main.go rename contrib/apparmor/{docker-engine => template.go} (89%) diff --git a/contrib/apparmor/main.go b/contrib/apparmor/main.go new file mode 100644 index 0000000000..f70d5bb4ff --- /dev/null +++ b/contrib/apparmor/main.go @@ -0,0 +1,85 @@ +package main + +import ( + "fmt" + "log" + "os" + "os/exec" + "path" + "strconv" + "strings" + "text/template" +) + +type profileData struct { + MajorVersion int + MinorVersion int +} + +func main() { + if len(os.Args) < 2 { + log.Fatal("pass a filename to save the profile in.") + } + + // parse the arg + apparmorProfilePath := os.Args[1] + + // get the apparmor_version version + cmd := exec.Command("/sbin/apparmor_parser", "--version") + + output, err := cmd.CombinedOutput() + if err != nil { + log.Fatalf("getting apparmor_parser version failed: %s (%s)", err, output) + } + + // parse the version from the output + // output is in the form of the following: + // AppArmor parser version 2.9.1 + // Copyright (C) 1999-2008 Novell Inc. + // Copyright 2009-2012 Canonical Ltd. + lines := strings.SplitN(string(output), "\n", 2) + words := strings.Split(lines[0], " ") + version := words[len(words)-1] + // split by major minor version + v := strings.Split(version, ".") + if len(v) < 2 { + log.Fatalf("parsing major minor version failed for %q", version) + } + + majorVersion, err := strconv.Atoi(v[0]) + if err != nil { + log.Fatal(err) + } + minorVersion, err := strconv.Atoi(v[1]) + if err != nil { + log.Fatal(err) + } + data := profileData{ + MajorVersion: majorVersion, + MinorVersion: minorVersion, + } + fmt.Printf("apparmor_parser is of version %+v\n", data) + + // parse the template + compiled, err := template.New("apparmor_profile").Parse(dockerProfileTemplate) + if err != nil { + log.Fatalf("parsing template failed: %v", err) + } + + // make sure /etc/apparmor.d exists + if err := os.MkdirAll(path.Dir(apparmorProfilePath), 0755); err != nil { + log.Fatal(err) + } + + f, err := os.OpenFile(apparmorProfilePath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0644) + if err != nil { + log.Fatal(err) + } + defer f.Close() + + if err := compiled.Execute(f, data); err != nil { + log.Fatalf("executing template failed: %v", err) + } + + fmt.Printf("created apparmor profile for version %+v at %q\n", data, apparmorProfilePath) +} diff --git a/contrib/apparmor/docker-engine b/contrib/apparmor/template.go similarity index 89% rename from contrib/apparmor/docker-engine rename to contrib/apparmor/template.go index 23ac5d6f05..9b9cfe4e80 100644 --- a/contrib/apparmor/docker-engine +++ b/contrib/apparmor/template.go @@ -1,4 +1,6 @@ -@{DOCKER_GRAPH_PATH}=/var/lib/docker +package main + +const dockerProfileTemplate = `@{DOCKER_GRAPH_PATH}=/var/lib/docker profile /usr/bin/docker (attach_disconnected, complain) { # Prevent following links to these files during container setup. @@ -15,9 +17,11 @@ profile /usr/bin/docker (attach_disconnected, complain) { umount, pivot_root, +{{if ge .MajorVersion 2}}{{if ge .MinorVersion 9}} signal (receive) peer=@{profile_name}, signal (receive) peer=unconfined, signal (send), +{{end}}{{end}} ipc rw, network, capability, @@ -34,10 +38,12 @@ profile /usr/bin/docker (attach_disconnected, complain) { /etc/localtime r, /etc/ld.so.cache r, +{{if ge .MajorVersion 2}}{{if ge .MinorVersion 9}} ptrace peer=@{profile_name}, ptrace (read) peer=docker-default, deny ptrace (trace) peer=docker-default, deny ptrace peer=/usr/bin/docker///bin/ps, +{{end}}{{end}} /usr/lib/** rm, /lib/** rm, @@ -57,9 +63,11 @@ profile /usr/bin/docker (attach_disconnected, complain) { /sbin/zfs rCx, /sbin/apparmor_parser rCx, +{{if ge .MajorVersion 2}}{{if ge .MinorVersion 9}} # Transitions change_profile -> docker-*, change_profile -> unconfined, +{{end}}{{end}} profile /bin/cat (complain) { /etc/ld.so.cache r, @@ -81,8 +89,10 @@ profile /usr/bin/docker (attach_disconnected, complain) { /dev/null rw, /bin/ps mr, +{{if ge .MajorVersion 2}}{{if ge .MinorVersion 9}} # We don't need ptrace so we'll deny and ignore the error. deny ptrace (read, trace), +{{end}}{{end}} # Quiet dac_override denials deny capability dac_override, @@ -100,11 +110,15 @@ profile /usr/bin/docker (attach_disconnected, complain) { /proc/tty/drivers r, } profile /sbin/iptables (complain) { +{{if ge .MajorVersion 2}}{{if ge .MinorVersion 9}} signal (receive) peer=/usr/bin/docker, +{{end}}{{end}} capability net_admin, } profile /sbin/auplink flags=(attach_disconnected, complain) { +{{if ge .MajorVersion 2}}{{if ge .MinorVersion 9}} signal (receive) peer=/usr/bin/docker, +{{end}}{{end}} capability sys_admin, capability dac_override, @@ -123,7 +137,9 @@ profile /usr/bin/docker (attach_disconnected, complain) { /proc/[0-9]*/mounts rw, } profile /sbin/modprobe /bin/kmod (complain) { +{{if ge .MajorVersion 2}}{{if ge .MinorVersion 9}} signal (receive) peer=/usr/bin/docker, +{{end}}{{end}} capability sys_module, /etc/ld.so.cache r, /lib/** rm, @@ -137,7 +153,9 @@ profile /usr/bin/docker (attach_disconnected, complain) { } # xz works via pipes, so we do not need access to the filesystem. profile /usr/bin/xz (complain) { +{{if ge .MajorVersion 2}}{{if ge .MinorVersion 9}} signal (receive) peer=/usr/bin/docker, +{{end}}{{end}} /etc/ld.so.cache r, /lib/** rm, /usr/bin/xz rm, @@ -238,4 +256,4 @@ profile /usr/bin/docker (attach_disconnected, complain) { capability mac_admin, } -} +}` From c39689ca70193f9fdc60a3ae3dbfd0ef979966ba Mon Sep 17 00:00:00 2001 From: Jessica Frazelle Date: Tue, 13 Oct 2015 17:42:43 -0700 Subject: [PATCH 2/4] add dh-apparmor & apparmor to deb builder dockerfiles Signed-off-by: Jessica Frazelle --- contrib/builder/deb/debian-jessie/Dockerfile | 2 +- contrib/builder/deb/debian-stretch/Dockerfile | 2 +- contrib/builder/deb/debian-wheezy/Dockerfile | 2 +- contrib/builder/deb/generate.sh | 2 ++ contrib/builder/deb/ubuntu-precise/Dockerfile | 2 +- contrib/builder/deb/ubuntu-trusty/Dockerfile | 2 +- contrib/builder/deb/ubuntu-vivid/Dockerfile | 2 +- contrib/builder/deb/ubuntu-wily/Dockerfile | 2 +- 8 files changed, 9 insertions(+), 7 deletions(-) diff --git a/contrib/builder/deb/debian-jessie/Dockerfile b/contrib/builder/deb/debian-jessie/Dockerfile index 6733ffe2ab..ab1c113171 100644 --- a/contrib/builder/deb/debian-jessie/Dockerfile +++ b/contrib/builder/deb/debian-jessie/Dockerfile @@ -4,7 +4,7 @@ FROM debian:jessie -RUN apt-get update && apt-get install -y bash-completion btrfs-tools build-essential curl ca-certificates debhelper dh-systemd git libapparmor-dev libdevmapper-dev libsqlite3-dev libsystemd-journal-dev --no-install-recommends && rm -rf /var/lib/apt/lists/* +RUN apt-get update && apt-get install -y apparmor bash-completion btrfs-tools build-essential curl ca-certificates debhelper dh-apparmor dh-systemd git libapparmor-dev libdevmapper-dev libsqlite3-dev libsystemd-journal-dev --no-install-recommends && rm -rf /var/lib/apt/lists/* ENV GO_VERSION 1.4.3 RUN curl -fSL "https://storage.googleapis.com/golang/go${GO_VERSION}.linux-amd64.tar.gz" | tar xzC /usr/local diff --git a/contrib/builder/deb/debian-stretch/Dockerfile b/contrib/builder/deb/debian-stretch/Dockerfile index 0b0072f069..db14ef0ed5 100644 --- a/contrib/builder/deb/debian-stretch/Dockerfile +++ b/contrib/builder/deb/debian-stretch/Dockerfile @@ -4,7 +4,7 @@ FROM debian:stretch -RUN apt-get update && apt-get install -y bash-completion btrfs-tools build-essential curl ca-certificates debhelper dh-systemd git libapparmor-dev libdevmapper-dev libsqlite3-dev libsystemd-dev --no-install-recommends && rm -rf /var/lib/apt/lists/* +RUN apt-get update && apt-get install -y apparmor bash-completion btrfs-tools build-essential curl ca-certificates debhelper dh-apparmor dh-systemd git libapparmor-dev libdevmapper-dev libsqlite3-dev libsystemd-dev --no-install-recommends && rm -rf /var/lib/apt/lists/* ENV GO_VERSION 1.4.3 RUN curl -fSL "https://storage.googleapis.com/golang/go${GO_VERSION}.linux-amd64.tar.gz" | tar xzC /usr/local diff --git a/contrib/builder/deb/debian-wheezy/Dockerfile b/contrib/builder/deb/debian-wheezy/Dockerfile index f224ed9b7d..73ebf954be 100644 --- a/contrib/builder/deb/debian-wheezy/Dockerfile +++ b/contrib/builder/deb/debian-wheezy/Dockerfile @@ -4,7 +4,7 @@ FROM debian:wheezy-backports -RUN apt-get update && apt-get install -y bash-completion btrfs-tools/wheezy-backports build-essential curl ca-certificates debhelper dh-systemd git libapparmor-dev libdevmapper-dev libsqlite3-dev libsystemd-journal-dev --no-install-recommends && rm -rf /var/lib/apt/lists/* +RUN apt-get update && apt-get install -y apparmor bash-completion btrfs-tools/wheezy-backports build-essential curl ca-certificates debhelper dh-apparmor dh-systemd git libapparmor-dev libdevmapper-dev libsqlite3-dev libsystemd-journal-dev --no-install-recommends && rm -rf /var/lib/apt/lists/* ENV GO_VERSION 1.4.3 RUN curl -fSL "https://storage.googleapis.com/golang/go${GO_VERSION}.linux-amd64.tar.gz" | tar xzC /usr/local diff --git a/contrib/builder/deb/generate.sh b/contrib/builder/deb/generate.sh index bfdace6be9..9e836dacc7 100755 --- a/contrib/builder/deb/generate.sh +++ b/contrib/builder/deb/generate.sh @@ -45,11 +45,13 @@ for version in "${versions[@]}"; do # this list is sorted alphabetically; please keep it that way packages=( + apparmor # for apparmor_parser for testing the profile bash-completion # for bash-completion debhelper integration btrfs-tools # for "btrfs/ioctl.h" (and "version.h" if possible) build-essential # "essential for building Debian packages" curl ca-certificates # for downloading Go debhelper # for easy ".deb" building + dh-apparmor # for apparmor debhelper dh-systemd # for systemd debhelper integration git # for "git commit" info in "docker -v" libapparmor-dev # for "sys/apparmor.h" diff --git a/contrib/builder/deb/ubuntu-precise/Dockerfile b/contrib/builder/deb/ubuntu-precise/Dockerfile index 04d554291d..834f022385 100644 --- a/contrib/builder/deb/ubuntu-precise/Dockerfile +++ b/contrib/builder/deb/ubuntu-precise/Dockerfile @@ -4,7 +4,7 @@ FROM ubuntu:precise -RUN apt-get update && apt-get install -y bash-completion build-essential curl ca-certificates debhelper git libapparmor-dev libsqlite3-dev --no-install-recommends && rm -rf /var/lib/apt/lists/* +RUN apt-get update && apt-get install -y apparmor bash-completion build-essential curl ca-certificates debhelper dh-apparmor git libapparmor-dev libsqlite3-dev --no-install-recommends && rm -rf /var/lib/apt/lists/* ENV GO_VERSION 1.4.3 RUN curl -fSL "https://storage.googleapis.com/golang/go${GO_VERSION}.linux-amd64.tar.gz" | tar xzC /usr/local diff --git a/contrib/builder/deb/ubuntu-trusty/Dockerfile b/contrib/builder/deb/ubuntu-trusty/Dockerfile index d9c85e2dfa..f932d7f23c 100644 --- a/contrib/builder/deb/ubuntu-trusty/Dockerfile +++ b/contrib/builder/deb/ubuntu-trusty/Dockerfile @@ -4,7 +4,7 @@ FROM ubuntu:trusty -RUN apt-get update && apt-get install -y bash-completion btrfs-tools build-essential curl ca-certificates debhelper dh-systemd git libapparmor-dev libdevmapper-dev libsqlite3-dev libsystemd-journal-dev --no-install-recommends && rm -rf /var/lib/apt/lists/* +RUN apt-get update && apt-get install -y apparmor bash-completion btrfs-tools build-essential curl ca-certificates debhelper dh-apparmor dh-systemd git libapparmor-dev libdevmapper-dev libsqlite3-dev libsystemd-journal-dev --no-install-recommends && rm -rf /var/lib/apt/lists/* ENV GO_VERSION 1.4.3 RUN curl -fSL "https://storage.googleapis.com/golang/go${GO_VERSION}.linux-amd64.tar.gz" | tar xzC /usr/local diff --git a/contrib/builder/deb/ubuntu-vivid/Dockerfile b/contrib/builder/deb/ubuntu-vivid/Dockerfile index c47270430b..524ae3e130 100644 --- a/contrib/builder/deb/ubuntu-vivid/Dockerfile +++ b/contrib/builder/deb/ubuntu-vivid/Dockerfile @@ -4,7 +4,7 @@ FROM ubuntu:vivid -RUN apt-get update && apt-get install -y bash-completion btrfs-tools build-essential curl ca-certificates debhelper dh-systemd git libapparmor-dev libdevmapper-dev libsqlite3-dev libsystemd-journal-dev --no-install-recommends && rm -rf /var/lib/apt/lists/* +RUN apt-get update && apt-get install -y apparmor bash-completion btrfs-tools build-essential curl ca-certificates debhelper dh-apparmor dh-systemd git libapparmor-dev libdevmapper-dev libsqlite3-dev libsystemd-journal-dev --no-install-recommends && rm -rf /var/lib/apt/lists/* ENV GO_VERSION 1.4.3 RUN curl -fSL "https://storage.googleapis.com/golang/go${GO_VERSION}.linux-amd64.tar.gz" | tar xzC /usr/local diff --git a/contrib/builder/deb/ubuntu-wily/Dockerfile b/contrib/builder/deb/ubuntu-wily/Dockerfile index 2d5555f7e0..401f37906f 100644 --- a/contrib/builder/deb/ubuntu-wily/Dockerfile +++ b/contrib/builder/deb/ubuntu-wily/Dockerfile @@ -4,7 +4,7 @@ FROM ubuntu:wily -RUN apt-get update && apt-get install -y bash-completion btrfs-tools build-essential curl ca-certificates debhelper dh-systemd git libapparmor-dev libdevmapper-dev libsqlite3-dev libsystemd-dev --no-install-recommends && rm -rf /var/lib/apt/lists/* +RUN apt-get update && apt-get install -y apparmor bash-completion btrfs-tools build-essential curl ca-certificates debhelper dh-apparmor dh-systemd git libapparmor-dev libdevmapper-dev libsqlite3-dev libsystemd-dev --no-install-recommends && rm -rf /var/lib/apt/lists/* ENV GO_VERSION 1.4.3 RUN curl -fSL "https://storage.googleapis.com/golang/go${GO_VERSION}.linux-amd64.tar.gz" | tar xzC /usr/local From 8369f00d30cc1d7823723dec6147f0419e67ad46 Mon Sep 17 00:00:00 2001 From: Jessica Frazelle Date: Tue, 13 Oct 2015 17:52:18 -0700 Subject: [PATCH 3/4] add generate aa profile to deb install Signed-off-by: Jessica Frazelle --- hack/make/.build-deb/docker-engine.install | 1 + hack/make/.build-deb/rules | 4 ++++ hack/make/build-deb | 2 ++ 3 files changed, 7 insertions(+) diff --git a/hack/make/.build-deb/docker-engine.install b/hack/make/.build-deb/docker-engine.install index a8857a96dc..0ee579350a 100644 --- a/hack/make/.build-deb/docker-engine.install +++ b/hack/make/.build-deb/docker-engine.install @@ -9,3 +9,4 @@ contrib/init/systemd/docker.socket lib/systemd/system/ contrib/mk* usr/share/docker-engine/contrib/ contrib/nuke-graph-directory.sh usr/share/docker-engine/contrib/ contrib/syntax/nano/Dockerfile.nanorc usr/share/nano/ +contrib/apparmor/docker-engine etc/apparmor.d/ diff --git a/hack/make/.build-deb/rules b/hack/make/.build-deb/rules index b4c8e2b4c7..be45676c1d 100755 --- a/hack/make/.build-deb/rules +++ b/hack/make/.build-deb/rules @@ -32,5 +32,9 @@ override_dh_installudev: # match our existing priority dh_installudev --priority=z80 +override_dh_install: + dh_install + dh_apparmor --profile-name=docker-engine -pdocker-engine + %: dh $@ --with=bash-completion $(shell command -v dh_systemd_enable > /dev/null 2>&1 && echo --with=systemd) diff --git a/hack/make/build-deb b/hack/make/build-deb index deab30c238..418d9a1947 100644 --- a/hack/make/build-deb +++ b/hack/make/build-deb @@ -57,6 +57,8 @@ set -e echo 'ENV DOCKER_EXPERIMENTAL 1' >> "$DEST/$version/Dockerfile.build" fi cat >> "$DEST/$version/Dockerfile.build" <<-EOF + RUN go build -o aagen contrib/apparmor/*.go \ + && ./aagen contrib/apparmor/docker-engine RUN ln -sfv hack/make/.build-deb debian RUN { echo '$debSource (${debVersion}-0~${suite}) $suite; urgency=low'; echo; echo ' * Version: $VERSION'; echo; echo " -- $debMaintainer $debDate"; } > debian/changelog && cat >&2 debian/changelog RUN dpkg-buildpackage -uc -us From 14e85c8c556bae67584e71f5c4bb6322c77a3ef5 Mon Sep 17 00:00:00 2001 From: Jessica Frazelle Date: Thu, 15 Oct 2015 11:55:17 -0700 Subject: [PATCH 4/4] add test script for built debs Signed-off-by: Jessica Frazelle --- hack/make/test-deb-install | 57 +++++++++++++++++++++++++++++++++++ hack/make/test-install-script | 2 ++ 2 files changed, 59 insertions(+) create mode 100755 hack/make/test-deb-install diff --git a/hack/make/test-deb-install b/hack/make/test-deb-install new file mode 100755 index 0000000000..f0e84d7f20 --- /dev/null +++ b/hack/make/test-deb-install @@ -0,0 +1,57 @@ +#!/bin/bash +# This script is used for testing install.sh and that it works for +# each of component of our apt and yum repos +set -e + +: ${DEB_DIR:="$(pwd)/bundles/$(cat VERSION)/build-deb"} + +if [[ ! -d "${DEB_DIR}" ]]; then + echo "you must first run `make deb` or hack/make/build-deb" + exit 1 +fi + +test_deb_install(){ + # test for each Dockerfile in contrib/builder + for dir in contrib/builder/deb/*/; do + local from="$(awk 'toupper($1) == "FROM" { print $2; exit }' "$dir/Dockerfile")" + local dir=$(basename "$dir") + + if [[ ! -d "${DEB_DIR}/${dir}" ]]; then + echo "No deb found for ${dir}" + exit 1 + fi + + local script=$(mktemp /tmp/install-XXXXXXXXXX.sh) + cat <<-EOF > "${script}" + #!/bin/bash + set -e + set -x + + apt-get update && apt-get install -y apparmor + + dpkg -i /root/debs/*.deb || true + + apt-get install -yf + + /etc/init.d/apparmor start + + # this will do everything _except_ load the profile into the kernel + ( + cd /etc/apparmor.d + /sbin/apparmor_parser --skip-kernel-load docker-engine + ) + EOF + + chmod +x "${script}" + + echo "testing deb install for ${from}" + docker run --rm -i --privileged \ + -v ${DEB_DIR}/${dir}:/root/debs \ + -v ${script}:/install.sh \ + ${from} /install.sh + + rm -f ${script} + done +} + +test_deb_install diff --git a/hack/make/test-install-script b/hack/make/test-install-script index a5ea41693e..4782cbea88 100755 --- a/hack/make/test-install-script +++ b/hack/make/test-install-script @@ -23,6 +23,8 @@ test_install_script(){ echo "running install.sh for ${component} with ${from}" docker run --rm -i -v ${script}:/install.sh ${from} /install.sh done + + rm -f ${script} done }