From b0212beec3eb5343e6f3a728e684257558590af8 Mon Sep 17 00:00:00 2001 From: Pascal Vizeli Date: Tue, 1 May 2018 22:39:30 +0200 Subject: [PATCH] Apparmor hassio (#10) * Delete 0001-Autostart.patch * Update apparmor.mk * Update Config.in * Create hassio-apparmor * Update hassio-apparmor * Update data.conf * Delete etc-apparmor.d-containers.mount * Delete etc-apparmor.d-containers.mount * Delete hassio.conf * Update hassio-apparmor * Update Config.in * Update Config.in * Update hassio.mk * Update hostapp.sh * Update Config.in * Update hassio.mk * Update hassio.mk * Create hassio-supervisor * Update hassio-apparmor * Update hassio-apparmor * Update hassio-apparmor * Update hassio-supervisor * Update hassio-cli * Update hassio-apparmor * Update hassio-apparmor * Create hassio-apparmor.service * Update hassio-apparmor.service * Delete apparmor.service * Update local stuff * Profile for CLI * Update hassio.mk * Update hassio.mk * Update hassio-supervisor * Update hassio-apparmor --- buildroot-external/apparmor/hassio-supervisor | 59 +++++++++++++++++++ buildroot-external/busybox.config | 4 +- buildroot-external/configs/ova_defconfig | 4 +- .../package/apparmor/0001-Autostart.patch | 25 -------- buildroot-external/package/apparmor/Config.in | 2 +- .../package/apparmor/apparmor.mk | 3 +- buildroot-external/package/hassio/Config.in | 17 +++++- .../package/hassio/builder/hostapp.sh | 37 ++++++++++-- buildroot-external/package/hassio/hassio.mk | 20 ++++--- .../system/apparmor.service.d/hassio.conf | 2 - .../etc-apparmor.d-containers.mount | 1 - .../multi-user.target.wants/apparmor.service | 1 - .../hassio-apparmor.service | 1 + .../rootfs-overlay/etc/tmpfiles.d/data.conf | 1 - .../rootfs-overlay/usr/bin/hassio-cli | 2 + .../system/etc-apparmor.d-containers.mount | 14 ----- .../systemd/system/hassio-apparmor.service | 13 ++++ .../rootfs-overlay/usr/sbin/hassio-apparmor | 47 +++++++++++++++ .../rootfs-overlay/usr/sbin/hassio-supervisor | 2 + 19 files changed, 192 insertions(+), 63 deletions(-) create mode 100644 buildroot-external/apparmor/hassio-supervisor delete mode 100644 buildroot-external/package/apparmor/0001-Autostart.patch delete mode 100644 buildroot-external/rootfs-overlay/etc/systemd/system/apparmor.service.d/hassio.conf delete mode 120000 buildroot-external/rootfs-overlay/etc/systemd/system/hassio-bind.target.wants/etc-apparmor.d-containers.mount delete mode 120000 buildroot-external/rootfs-overlay/etc/systemd/system/multi-user.target.wants/apparmor.service create mode 120000 buildroot-external/rootfs-overlay/etc/systemd/system/multi-user.target.wants/hassio-apparmor.service delete mode 100644 buildroot-external/rootfs-overlay/usr/lib/systemd/system/etc-apparmor.d-containers.mount create mode 100644 buildroot-external/rootfs-overlay/usr/lib/systemd/system/hassio-apparmor.service create mode 100755 buildroot-external/rootfs-overlay/usr/sbin/hassio-apparmor diff --git a/buildroot-external/apparmor/hassio-supervisor b/buildroot-external/apparmor/hassio-supervisor new file mode 100644 index 000000000..b3332acae --- /dev/null +++ b/buildroot-external/apparmor/hassio-supervisor @@ -0,0 +1,59 @@ +#include + + +profile hassio-supervisor flags=(attach_disconnected,mediate_deleted) { + #include + #include + + network inet tcp, + + deny network raw, + deny network packet, + + /usr/bin/python3 ix, + /usr/bin/socat cx, + /usr/bin/gdbus cx, + + deny /bin/** wl, + deny /boot/** wl, + deny /dev/** wl, + deny /etc/** wl, + deny /home/** wl, + deny /lib/** wl, + deny /mnt/** wl, + deny /proc/** wl, + deny /root/** wl, + deny /sbin/** wl, + deny /tmp/** wl, + deny /sys/** wl, + deny /usr/** wl, + + /data/** rw, + /var/run/docker.sock rw, + + /proc/** r, + /sys/** r, + + profile /usr/bin/socat { + #include + + network inet udp, + network inet tcp, + + deny network raw, + deny network packet, + + deny /data/** r, + } + + profile /usr/bin/gdbus { + #include + #include + + deny network inet, + + /var/run/dbus/system_bus_socket rw, + + deny /data/** r, + } +} diff --git a/buildroot-external/busybox.config b/buildroot-external/busybox.config index c4a156b3a..61ce69e48 100644 --- a/buildroot-external/busybox.config +++ b/buildroot-external/busybox.config @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit # Busybox version: 1.27.2 -# Sun Apr 29 21:50:21 2018 +# Tue May 1 14:34:48 2018 # CONFIG_HAVE_DOT_CONFIG=y @@ -452,7 +452,7 @@ CONFIG_FEATURE_VI_UNDO_QUEUE_MAX=256 # CONFIG_FEATURE_FIND_CONTEXT is not set # CONFIG_FEATURE_FIND_LINKS is not set CONFIG_GREP=y -CONFIG_EGREP=y +# CONFIG_EGREP is not set # CONFIG_FGREP is not set # CONFIG_FEATURE_GREP_CONTEXT is not set # CONFIG_XARGS is not set diff --git a/buildroot-external/configs/ova_defconfig b/buildroot-external/configs/ova_defconfig index 1e3020268..1f8a4b1dc 100644 --- a/buildroot-external/configs/ova_defconfig +++ b/buildroot-external/configs/ova_defconfig @@ -68,7 +68,9 @@ BR2_PACKAGE_HASSIO=y BR2_PACKAGE_HASSIO_SUPERVISOR="homeassistant/amd64-hassio-supervisor" BR2_PACKAGE_HASSIO_SUPERVISOR_VERSION="0.101" BR2_PACKAGE_HASSIO_SUPERVISOR_ARGS="-e HOMEASSISTANT_REPOSITORY=homeassistant/qemux86-64-homeassistant" +BR2_PACKAGE_HASSIO_SUPERVISOR_PROFILE="hassio-supervisor" BR2_PACKAGE_HASSIO_CLI="homeassistant/amd64-hassio-cli" BR2_PACKAGE_HASSIO_CLI_VERSION="0.1" -BR2_PACKAGE_LIBAPPARMOR=y +BR2_PACKAGE_HASSIO_CLI_PROFILE="docker-default" +BR2_PACKAGE_HASSIO_APPARMOR_DIR="supervisor/apparmor" BR2_PACKAGE_APPARMOR=y diff --git a/buildroot-external/package/apparmor/0001-Autostart.patch b/buildroot-external/package/apparmor/0001-Autostart.patch deleted file mode 100644 index 4b3369084..000000000 --- a/buildroot-external/package/apparmor/0001-Autostart.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 78ceb52ff4e5d4dbe003651b2193979114152763 Mon Sep 17 00:00:00 2001 -From: Pascal Vizeli -Date: Mon, 30 Apr 2018 23:40:27 +0200 -Subject: [PATCH 1/1] Fix permission - ---- - parser/Makefile | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/parser/Makefile b/parser/Makefile -index b18cfe4..7b7b519 100644 ---- a/parser/Makefile -+++ b/parser/Makefile -@@ -383,7 +383,7 @@ install-indep: indep - install-systemd: - install -m 755 -d $(SYSTEMD_UNIT_DIR) - install -m 644 apparmor.service $(SYSTEMD_UNIT_DIR) -- install -m 644 apparmor.systemd $(APPARMOR_BIN_PREFIX) -+ install -m 755 apparmor.systemd $(APPARMOR_BIN_PREFIX) - install -m 755 -d $(DESTDIR)/sbin - install -m 755 aa-teardown $(DESTDIR)/sbin - --- -2.7.4 - diff --git a/buildroot-external/package/apparmor/Config.in b/buildroot-external/package/apparmor/Config.in index 6ba44321a..3703354c5 100644 --- a/buildroot-external/package/apparmor/Config.in +++ b/buildroot-external/package/apparmor/Config.in @@ -1,6 +1,6 @@ config BR2_PACKAGE_APPARMOR bool "apparmor" - depends on BR2_PACKAGE_LIBAPPARMOR + select BR2_PACKAGE_LIBAPPARMOR help AppArmor gives you network application security via mandatory access control for programs, protecting against the exploitation diff --git a/buildroot-external/package/apparmor/apparmor.mk b/buildroot-external/package/apparmor/apparmor.mk index 2d1ddf99d..3ccca7ed5 100644 --- a/buildroot-external/package/apparmor/apparmor.mk +++ b/buildroot-external/package/apparmor/apparmor.mk @@ -16,8 +16,9 @@ endef define APPARMOR_INSTALL_TARGET_CMDS $(TARGET_MAKE_ENV) $(TARGET_CONFIGURE_OPTS) $(MAKE) -C $(@D)/parser DESTDIR=$(TARGET_DIR) USE_SYSTEM=1 PREFIX=/usr install - $(TARGET_MAKE_ENV) $(TARGET_CONFIGURE_OPTS) $(MAKE) -C $(@D)/parser DESTDIR=$(TARGET_DIR) USE_SYSTEM=1 PREFIX=/usr install-systemd $(TARGET_MAKE_ENV) $(TARGET_CONFIGURE_OPTS) $(MAKE) -C $(@D)/profiles DESTDIR=$(TARGET_DIR) PREFIX=/usr install + + rm -rf $(TARGET_DIR)/usr/lib/apparmor endef $(eval $(generic-package)) diff --git a/buildroot-external/package/hassio/Config.in b/buildroot-external/package/hassio/Config.in index 303725a1b..b659ce4c4 100644 --- a/buildroot-external/package/hassio/Config.in +++ b/buildroot-external/package/hassio/Config.in @@ -1,4 +1,4 @@ -config BR2_PACKAGE_HASSIO +menuconfig BR2_PACKAGE_HASSIO bool "hassio-app" help This is the Application layer they build the @@ -23,6 +23,11 @@ config BR2_PACKAGE_HASSIO_SUPERVISOR_ARGS help Extended docker arguments to run the supervisor. +config BR2_PACKAGE_HASSIO_SUPERVISOR_PROFILE + string "AppArmor supervisor profile" + help + AppArmor profile for supervisor. + config BR2_PACKAGE_HASSIO_CLI string "cli docker image" help @@ -38,4 +43,14 @@ config BR2_PACKAGE_HASSIO_CLI_ARGS help Extended docker arguments to run the cli. +config BR2_PACKAGE_HASSIO_CLI_PROFILE + string "AppArmor cli profile" + help + AppArmor profile for cli. + +config BR2_PACKAGE_HASSIO_APPARMOR_DIR + string "AppArmor profiles folder" + help + AppArmor profiles folder for supervisor. + endif diff --git a/buildroot-external/package/hassio/builder/hostapp.sh b/buildroot-external/package/hassio/builder/hostapp.sh index 952406dbe..c226ba394 100755 --- a/buildroot-external/package/hassio/builder/hostapp.sh +++ b/buildroot-external/package/hassio/builder/hostapp.sh @@ -4,9 +4,12 @@ set -e SUPERVISOR="" SUPERVISOR_VERSION="" SUPERVISOR_ARGS="" +SUPERVISOR_PROFILE="" CLI="" CLI_VERSION="" CLI_ARGS="" +CLI_PROFILE="" +APPARMOR="" DATA_IMG="/export/data.ext4" # Parse @@ -25,6 +28,10 @@ while [[ $# -gt 0 ]]; do SUPERVISOR_ARGS=$2 shift ;; + --supervisor-profile) + SUPERVISOR_PROFILE=$2 + shift + ;; --cli) CLI=$2 shift @@ -37,6 +44,14 @@ while [[ $# -gt 0 ]]; do CLI_ARGS=$2 shift ;; + --cli-profile) + CLI_PROFILE=$2 + shift + ;; + --apparmor) + APPARMOR=$2 + shift + ;; *) exit 1 ;; @@ -49,11 +64,12 @@ dd if=/dev/zero of=${DATA_IMG} bs=1G count=1 mkfs.ext4 -L "hassio-data" -E lazy_itable_init=0,lazy_journal_init=0 ${DATA_IMG} # Mount / init file structs -mount -o loop ${DATA_IMG} /mnt -mkdir -p /mnt/docker +mkdir -p /mnt/data/ +mount -o loop ${DATA_IMG} /mnt/data +mkdir -p /mnt/data/docker # Run dockerd -dockerd -s overlay2 -g /mnt/docker & +dockerd -s overlay2 -g /mnt/data/docker & DOCKER_PID=$! DOCKER_COUNT=0 @@ -75,14 +91,23 @@ docker pull "${CLI}:${CLI_VERSION}" docker tag "${CLI}:${CLI_VERSION}" "${CLI}:latest" # Write config -cat > /mnt/hassio.json <<- EOF +cat > /mnt/data/hassio.json <<- EOF { "supervisor": "${SUPERVISOR}", "supervisor_args": "${SUPERVISOR_ARGS}", + "supervisor_apparmor": "${SUPERVISOR_PROFILE}", "cli": "${CLI}", - "cli_args": "${CLI_ARGS}" + "cli_args": "${CLI_ARGS}", + "cli_apparmor": "${CLI_PROFILE}", + "apparmor": "${APPARMOR}" } EOF +# Setup AppArmor +if [ ! -z "${APPARMOR}" ]; then + mkdir -p /mnt/data/${APPARMOR} + cp -f /apparmor/* /mnt/data/${APPARMOR}/ +fi + # Finish -kill -TERM $DOCKER_PID && wait $DOCKER_PID && umount /mnt +kill -TERM $DOCKER_PID && wait $DOCKER_PID && umount /mnt/data diff --git a/buildroot-external/package/hassio/hassio.mk b/buildroot-external/package/hassio/hassio.mk index a41472a86..1d89ab7f8 100644 --- a/buildroot-external/package/hassio/hassio.mk +++ b/buildroot-external/package/hassio/hassio.mk @@ -15,13 +15,19 @@ define HASSIO_BUILD_CMDS endef define HASSIO_INSTALL_TARGET_CMDS - docker run --rm --privileged -v ${BINARIES_DIR}:/export hassio-hostapps \ - --supervisor ${BR2_PACKAGE_HASSIO_SUPERVISOR} \ - --supervisor-version ${BR2_PACKAGE_HASSIO_SUPERVISOR_VERSION} \ - --supervisor-args ${BR2_PACKAGE_HASSIO_SUPERVISOR_ARGS} \ - --cli ${BR2_PACKAGE_HASSIO_CLI} \ - --cli-version ${BR2_PACKAGE_HASSIO_CLI_VERSION} \ - --cli-args ${BR2_PACKAGE_HASSIO_CLI_ARGS} + docker run --rm --privileged \ + -v $(BINARIES_DIR):/export \ + -v $(BR2_EXTERNAL_HASSIO_PATH)/apparmor:/apparmor \ + hassio-hostapps \ + --supervisor $(BR2_PACKAGE_HASSIO_SUPERVISOR) \ + --supervisor-version $(BR2_PACKAGE_HASSIO_SUPERVISOR_VERSION) \ + --supervisor-args $(BR2_PACKAGE_HASSIO_SUPERVISOR_ARGS) \ + --supervisor-profile $(BR2_PACKAGE_HASSIO_SUPERVISOR_PROFILE) \ + --cli $(BR2_PACKAGE_HASSIO_CLI) \ + --cli-version $(BR2_PACKAGE_HASSIO_CLI_VERSION) \ + --cli-args $(BR2_PACKAGE_HASSIO_CLI_ARGS) \ + --cli-profile $(BR2_PACKAGE_HASSIO_CLI_PROFILE) \ + --apparmor $(BR2_PACKAGE_HASSIO_APPARMOR_DIR) endef $(eval $(generic-package)) diff --git a/buildroot-external/rootfs-overlay/etc/systemd/system/apparmor.service.d/hassio.conf b/buildroot-external/rootfs-overlay/etc/systemd/system/apparmor.service.d/hassio.conf deleted file mode 100644 index 13ed578b5..000000000 --- a/buildroot-external/rootfs-overlay/etc/systemd/system/apparmor.service.d/hassio.conf +++ /dev/null @@ -1,2 +0,0 @@ -[Unit] -RequiresMountsFor=/etc/apparmor.d/containers diff --git a/buildroot-external/rootfs-overlay/etc/systemd/system/hassio-bind.target.wants/etc-apparmor.d-containers.mount b/buildroot-external/rootfs-overlay/etc/systemd/system/hassio-bind.target.wants/etc-apparmor.d-containers.mount deleted file mode 120000 index 834306a17..000000000 --- a/buildroot-external/rootfs-overlay/etc/systemd/system/hassio-bind.target.wants/etc-apparmor.d-containers.mount +++ /dev/null @@ -1 +0,0 @@ -/usr/lib/systemd/system/etc-apparmor.d-containers.mount \ No newline at end of file diff --git a/buildroot-external/rootfs-overlay/etc/systemd/system/multi-user.target.wants/apparmor.service b/buildroot-external/rootfs-overlay/etc/systemd/system/multi-user.target.wants/apparmor.service deleted file mode 120000 index f9a498ed8..000000000 --- a/buildroot-external/rootfs-overlay/etc/systemd/system/multi-user.target.wants/apparmor.service +++ /dev/null @@ -1 +0,0 @@ -/usr/lib/systemd/system/apparmor.service \ No newline at end of file diff --git a/buildroot-external/rootfs-overlay/etc/systemd/system/multi-user.target.wants/hassio-apparmor.service b/buildroot-external/rootfs-overlay/etc/systemd/system/multi-user.target.wants/hassio-apparmor.service new file mode 120000 index 000000000..625edb930 --- /dev/null +++ b/buildroot-external/rootfs-overlay/etc/systemd/system/multi-user.target.wants/hassio-apparmor.service @@ -0,0 +1 @@ +/usr/lib/systemd/system/hassio-apparmor.service \ No newline at end of file diff --git a/buildroot-external/rootfs-overlay/etc/tmpfiles.d/data.conf b/buildroot-external/rootfs-overlay/etc/tmpfiles.d/data.conf index 76d1ffe7c..1e8e1e876 100644 --- a/buildroot-external/rootfs-overlay/etc/tmpfiles.d/data.conf +++ b/buildroot-external/rootfs-overlay/etc/tmpfiles.d/data.conf @@ -1,3 +1,2 @@ d /mnt/data/supervisor d /mnt/data/cli -d /mnt/data/apparmor diff --git a/buildroot-external/rootfs-overlay/usr/bin/hassio-cli b/buildroot-external/rootfs-overlay/usr/bin/hassio-cli index 81bf07757..02b682865 100755 --- a/buildroot-external/rootfs-overlay/usr/bin/hassio-cli +++ b/buildroot-external/rootfs-overlay/usr/bin/hassio-cli @@ -5,6 +5,7 @@ CONFIG_FILE=/mnt/data/hassio.json CLI="$(jq --raw-output '.cli' ${CONFIG_FILE})" DOCKER_ARGS="$(jq --raw-output '.cli_args // empty' ${CONFIG_FILE})" +APPARMOR="$(jq --raw-output '.cli_apparmor // "docker-default"' ${CONFIG_FILE})" CLI_DATA=/mnt/data/cli mkdir -p ${CLI_DATA} @@ -12,6 +13,7 @@ mkdir -p ${CLI_DATA} # Run CLI docker run \ --rm -ti --init \ + --security-opt apparmor="${APPARMOR}" \ -v ${CLI_DATA}:/data \ $DOCKER_ARGS \ ${CLI} diff --git a/buildroot-external/rootfs-overlay/usr/lib/systemd/system/etc-apparmor.d-containers.mount b/buildroot-external/rootfs-overlay/usr/lib/systemd/system/etc-apparmor.d-containers.mount deleted file mode 100644 index 4fa1b8b56..000000000 --- a/buildroot-external/rootfs-overlay/usr/lib/systemd/system/etc-apparmor.d-containers.mount +++ /dev/null @@ -1,14 +0,0 @@ -[Unit] -Description=Supervisor persistent apparmor profiles -Requires=mnt-data.mount apparmor.service -After=mnt-data.mount -Before=apparmor.service - -[Mount] -What=/mnt/data/apparmor -Where=/etc/apparmor.d/containers -Type=none -Options=bind - -[Install] -WantedBy=hassio-bind.target diff --git a/buildroot-external/rootfs-overlay/usr/lib/systemd/system/hassio-apparmor.service b/buildroot-external/rootfs-overlay/usr/lib/systemd/system/hassio-apparmor.service new file mode 100644 index 000000000..db8bf42a4 --- /dev/null +++ b/buildroot-external/rootfs-overlay/usr/lib/systemd/system/hassio-apparmor.service @@ -0,0 +1,13 @@ +[Unit] +Description=Hass.io AppArmor +Wants=hassio-supervisor.service +Before=docker.service hassio-supervisor.service +RequiresMountsFor=/mnt/data + +[Service] +Type=oneshot +RemainAfterExit=true +ExecStart=/usr/sbin/hassio-apparmor + +[Install] +WantedBy=multi-user.target diff --git a/buildroot-external/rootfs-overlay/usr/sbin/hassio-apparmor b/buildroot-external/rootfs-overlay/usr/sbin/hassio-apparmor new file mode 100755 index 000000000..bba158658 --- /dev/null +++ b/buildroot-external/rootfs-overlay/usr/sbin/hassio-apparmor @@ -0,0 +1,47 @@ +#!/bin/sh +set -e + +# Load configs +CONFIG_FILE=/mnt/data/hassio.json + +# Read configs +PROFILES_DIR="$(jq --raw-output '.apparmor // empty' ${CONFIG_FILE})" +if [ -z "${PROFILES_DIR}" ]; then + exit 0 +fi + +PROFILES_DIR="/mnt/data/${PROFILES_DIR}" +CACHE_DIR="${PROFILES_DIR}/cache" +REMOVE_DIR="${PROFILES_DIR}/remove" + +# Check folder structure +mkdir -p ${PROFILES_DIR} +mkdir -p ${CACHE_DIR} +mkdir -p ${REMOVE_DIR} + +# Load/Update exists/new profiles +for profile in ${PROFILES_DIR}/*; do + if [ ! -f ${profile} ]; then + continue + fi + + # Load Profile + if ! apparmor_parser -r -W -L ${CACHE_DIR} ${profile}; then + echo "[Error]: Can't load profile ${profile}" + fi +done + +# Cleanup old profiles +for profile in ${REMOVE_DIR}/*; do + if [ ! -f ${profile} ]; then + continue + fi + + # Unload Profile + if apparmor_parser -R -W -L ${CACHE_DIR} ${profile}; then + if rm ${profile}; then + continue + fi + fi + echo "[Error]: Can't remove profile ${profile}" +done diff --git a/buildroot-external/rootfs-overlay/usr/sbin/hassio-supervisor b/buildroot-external/rootfs-overlay/usr/sbin/hassio-supervisor index 727289f4f..726484d87 100755 --- a/buildroot-external/rootfs-overlay/usr/sbin/hassio-supervisor +++ b/buildroot-external/rootfs-overlay/usr/sbin/hassio-supervisor @@ -6,6 +6,7 @@ CONFIG_FILE=/mnt/data/hassio.json SUPERVISOR="$(jq --raw-output '.supervisor' ${CONFIG_FILE})" DOCKER_ARGS="$(jq --raw-output '.supervisor_args // empty' ${CONFIG_FILE})" +APPARMOR="$(jq --raw-output '.supervisor_apparmor // "docker-default"' ${CONFIG_FILE})" # Init supervisor HASSIO_DATA=/mnt/data/supervisor @@ -15,6 +16,7 @@ HASSIO_CONTAINER_ID=$(docker inspect --format='{{.Image}}' hassio_supervisor || runSupervisor() { docker rm --force hassio_supervisor || true docker run --name hassio_supervisor \ + --security-opt apparmor="${APPARMOR}" \ -v /var/run/docker.sock:/var/run/docker.sock \ -v /var/run/dbus:/var/run/dbus \ -v ${HASSIO_DATA}:/data \