Jelajahi Sumber

Merge pull request #17002 from jfrazelle/apparmor-check-version-on-deb-install

apparmor check version on deb install
Sebastiaan van Stijn 9 tahun lalu
induk
melakukan
9312a738d8

+ 85 - 0
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)
+}

+ 20 - 2
contrib/apparmor/docker-engine → 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,
   }
-}
+}`

+ 1 - 1
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

+ 1 - 1
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

+ 1 - 1
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

+ 2 - 0
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"

+ 1 - 1
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

+ 1 - 1
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

+ 1 - 1
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

+ 1 - 1
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

+ 1 - 0
hack/make/.build-deb/docker-engine.install

@@ -10,3 +10,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/

+ 4 - 0
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)

+ 2 - 0
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

+ 57 - 0
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

+ 2 - 0
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
 }