From 692571a7f871485d00d2d6aa8e98e86483a4886b Mon Sep 17 00:00:00 2001 From: Disassembler Date: Wed, 18 Mar 2020 22:09:18 +0100 Subject: [PATCH] Add custom LXC with fixed -g/-u for lxc-execute/attach --- apk/lxc/APKBUILD | 176 ++++++++++++++++++ .../cgroups-initialize-cpuset-properly.patch | 33 ++++ apk/lxc/execute-attach-user-group.patch | 53 ++++++ apk/lxc/lxc.confd | 10 + apk/lxc/lxc.initd | 157 ++++++++++++++++ ...tore-ability-to-move-nl80211-devices.patch | 91 +++++++++ build/build-all.sh | 4 + vm.sh | 2 +- 8 files changed, 525 insertions(+), 1 deletion(-) create mode 100644 apk/lxc/APKBUILD create mode 100644 apk/lxc/cgroups-initialize-cpuset-properly.patch create mode 100644 apk/lxc/execute-attach-user-group.patch create mode 100644 apk/lxc/lxc.confd create mode 100644 apk/lxc/lxc.initd create mode 100644 apk/lxc/network-restore-ability-to-move-nl80211-devices.patch diff --git a/apk/lxc/APKBUILD b/apk/lxc/APKBUILD new file mode 100644 index 0000000..6ebb843 --- /dev/null +++ b/apk/lxc/APKBUILD @@ -0,0 +1,176 @@ +# Contributor: Ɓukasz Jendrysik +# Contributor: Jakub Jirutka +# Maintainer: Natanael Copa +pkgname=lxc +pkgver=3.2.1 +_pkgver=${pkgver/_rc/.rc} +pkgrel=2 +pkgdesc="Userspace interface for the Linux kernel containment features" +url="https://linuxcontainers.org/lxc/" +arch="all" +license="GPL-2.0-only" +makedepends=" + libcap-dev + libcap-static + libseccomp-dev + linux-pam-dev + linux-headers + bsd-compat-headers + docbook2x + + automake + autoconf + libtool + " + +options="suid" +subpackages=" + $pkgname-dev + $pkgname-doc + $pkgname-openrc + $pkgname-lvm::noarch + $pkgname-libs + $pkgname-bridge::noarch + $pkgname-bash-completion:bashcomp:noarch + $pkgname-pam + $pkgname-download:_download:noarch + $pkgname-templates-oci:templates_oci:noarch + $pkgname-templates::noarch + " + +source="https://linuxcontainers.org/downloads/lxc/lxc-$_pkgver.tar.gz + cgroups-initialize-cpuset-properly.patch + network-restore-ability-to-move-nl80211-devices.patch + execute-attach-user-group.patch + lxc.initd + lxc.confd + " + +# secfixes: +# 3.1.0-r1: +# - CVE-2019-5736 +# 2.1.1-r9: +# - CVE-2018-6556 +# + +_tmpldir="usr/share/lxc/templates" + +build() { + ./configure \ + --build=$CBUILD \ + --host=$CHOST \ + --prefix=/usr \ + --sysconfdir=/etc \ + --localstatedir=/var \ + --disable-apparmor \ + --enable-pam \ + --with-distro=alpine \ + --disable-werror \ + --enable-doc + make +} + +check() { + make check +} + +package() { + make DESTDIR="$pkgdir" install + + install -Dm755 "$srcdir"/lxc.initd "$pkgdir"/etc/init.d/lxc + install -Dm644 "$srcdir"/lxc.confd "$pkgdir"/etc/conf.d/lxc + install -d "$pkgdir"/var/lib/lxc + + # Remove useless config for SysVinit. + rm -r "$pkgdir"/etc/default +} + +lvm() { + pkgdesc="LVM support for LXC" + depends="$pkgname=$pkgver-r$pkgrel lvm2 util-linux" + install_if="$pkgname=$pkgver-r$pkgrel lvm2" + mkdir "$subpkgdir" +} + +_py3() { + pkgdesc="Python3 module for LXC" + depends="python3" + mkdir -p "$subpkgdir"/usr/lib + mv "$pkgdir"/usr/lib/python3.* "$subpkgdir"/usr/lib +} + +_download() { + pkgdesc="LXC container image downloader template" + depends="$pkgname gnupg1 tar wget" + + mkdir -p "$subpkgdir"/$_tmpldir + mv "$pkgdir"/$_tmpldir/lxc-download "$subpkgdir"/$_tmpldir/ +} + +templates() { + pkgdesc="Templates for LXC (except alpine and download)" + depends="tar" + mkdir -p "$subpkgdir"/$_tmpldir + mv "$pkgdir"/$_tmpldir/* "$subpkgdir"/$_tmpldir/ +} + +templates_oci() { + pkgdesc="OCI Template for LXC" + depends="bash jq" + mkdir -p "$subpkgdir"/usr/share/lxc/templates + mv "$pkgdir"/usr/share/lxc/templates/lxc-oci \ + "$subpkgdir"/usr/share/lxc/templates/ +} + +pam() { + pkgdesc="PAM module for LXC" + mkdir -p "$subpkgdir"/lib/security + mv "$pkgdir"/lib/security/pam_cgfs.so "$subpkgdir"/lib/security/ +} + +dev() { + default_dev + # fix abuild smartness + mv "$subpkgdir"/usr/bin/lxc-config "$pkgdir"/usr/bin/ + mv "$subpkgdir"/usr/bin/lxc-update-config "$pkgdir"/usr/bin/ +} + +bridge() { + depends="dnsmasq" + pkgdesc="Bridge interface for LXC with dhcp" + mkdir -p "$subpkgdir"/etc/conf.d \ + "$subpkgdir"/etc/init.d \ + "$subpkgdir"/etc/lxc + + ln -s dnsmasq "$subpkgdir"/etc/init.d/dnsmasq.lxcbr0 + cat >>"$subpkgdir"/etc/conf.d/dnsmasq.lxcbr0 <<- EOF + rc_before="lxc" + BRIDGE_ADDR="10.0.3.1" + BRIDGE_NETMASK="255.255.255.0" + BRIDGE_NETWORK="10.0.3.0/24" + BRIDGE_DHCP_RANGE="10.0.3.2,10.0.3.254" + BRIDGE_DHCP_MAX="253" + BRIDGE_MAC="00:16:3e:00:00:00" + DNSMASQ_CONFFILE="/etc/lxc/dnsmasq.conf" + EOF + cat >>"$subpkgdir"/etc/lxc/dnsmasq.conf <<- EOF + #dhcp-host=somehost,10.0.3.3 + #dhcp-host=otherhost,10.0.3.4 + EOF +} + +bashcomp() { + depends="" + pkgdesc="Bash completions for $pkgname" + install_if="$pkgname=$pkgver-r$pkgrel bash-completion" + mkdir -p "$subpkgdir"/usr/share/bash-completion/completions + mv "$pkgdir"/etc/bash_completion.d/$pkgname "$subpkgdir"/usr/share/bash-completion/completions + rmdir "$pkgdir"/etc/bash_completion.d +} + +sha512sums="4b3046fc6c4aa497fb26bd45839e60de503184af86d3966e796d14e619203536b9a9ed67bdcd8a108cf1a548f8d095fb46dff53094a08abd8d268c866db685c0 lxc-3.2.1.tar.gz +2bebe6cc24987354b6e7dc9003c3a4df450ca10263e6dc0e9313977fdfc2eb57c0d68560da4d1071c8de2f8e3e394ed3ca17af445bea524daa5f8ae8955b3ba6 cgroups-initialize-cpuset-properly.patch +d302b7296918680901d034dc12ae0687dbbc65766800a9f7256e661f638d3dcad66bcc737aec2c6de8c27d3b9c08833e00420c2064f356d6d73efda9ae9bd707 network-restore-ability-to-move-nl80211-devices.patch +a26cd718760e73309a686242b03c5de5ceff17ab9c348438cd19d2d875696e5c788f0e04d66dd01e08449754c14ce2b7cc1dfc1bac2a64429ccf4462f8aa93a5 execute-attach-user-group.patch +b74ffe7c3e8f193265a90ffeb6e5743b1212bc1416b898e5a7e59ddd7f06fc77dc34e2dcbb3614038ac6222a95e2b9beb9f03ab734c991837203ab626b1b091f lxc.initd +91de43db5369a9e10102933514d674e9c875218a1ff2910dd882e5b9c308f9e430deacb13d1d7e0b2ed1ef682d0bb035aa6f8a6738f54fa2ca3a05acce04e467 lxc.confd" diff --git a/apk/lxc/cgroups-initialize-cpuset-properly.patch b/apk/lxc/cgroups-initialize-cpuset-properly.patch new file mode 100644 index 0000000..4096ba4 --- /dev/null +++ b/apk/lxc/cgroups-initialize-cpuset-properly.patch @@ -0,0 +1,33 @@ +From b31d62b847a3ee013613795094cce4acc12345ef Mon Sep 17 00:00:00 2001 +From: Christian Brauner +Date: Sun, 28 Jul 2019 23:13:26 +0200 +Subject: [PATCH] cgroups: initialize cpuset properly + +Closes #3108. +Signed-off-by: Christian Brauner +--- + src/lxc/cgroups/cgfsng.c | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +diff --git a/src/lxc/cgroups/cgfsng.c b/src/lxc/cgroups/cgfsng.c +index 7b8fe6736f..c29c0958e9 100644 +--- a/src/lxc/cgroups/cgfsng.c ++++ b/src/lxc/cgroups/cgfsng.c +@@ -496,12 +496,12 @@ static bool cg_legacy_filter_and_set_cpus(char *path, bool am_initialized) + } + + if (!flipped_bit) { +- DEBUG("No isolated or offline cpus present in cpuset"); +- return true; ++ cpulist = lxc_cpumask_to_cpulist(possmask, maxposs); ++ TRACE("No isolated or offline cpus present in cpuset"); ++ } else { ++ cpulist = move_ptr(posscpus); ++ TRACE("Removed isolated or offline cpus from cpuset"); + } +- DEBUG("Removed isolated or offline cpus from cpuset"); +- +- cpulist = lxc_cpumask_to_cpulist(possmask, maxposs); + if (!cpulist) { + ERROR("Failed to create cpu list"); + return false; diff --git a/apk/lxc/execute-attach-user-group.patch b/apk/lxc/execute-attach-user-group.patch new file mode 100644 index 0000000..a0dd700 --- /dev/null +++ b/apk/lxc/execute-attach-user-group.patch @@ -0,0 +1,53 @@ +--- a/src/lxc/tools/lxc_attach.c ++++ b/src/lxc/tools/lxc_attach.c +@@ -153,6 +153,8 @@ + .checker = NULL, + .log_priority = "ERROR", + .log_file = "none", ++ .uid = LXC_INVALID_UID, ++ .gid = LXC_INVALID_GID, + }; + + static int my_parser(struct lxc_arguments *args, int c, char *arg) +@@ -366,10 +368,10 @@ + goto out; + } + +- if (my_args.uid) ++ if (my_args.uid != LXC_INVALID_UID) + attach_options.uid = my_args.uid; + +- if (my_args.gid) ++ if (my_args.gid != LXC_INVALID_GID) + attach_options.gid = my_args.gid; + + if (command.program) { +--- a/src/lxc/tools/lxc_execute.c ++++ b/src/lxc/tools/lxc_execute.c +@@ -84,6 +84,8 @@ + .log_priority = "ERROR", + .log_file = "none", + .daemonize = 0, ++ .uid = LXC_INVALID_UID, ++ .gid = LXC_INVALID_GID, + }; + + static int my_parser(struct lxc_arguments *args, int c, char *arg) +@@ -211,7 +213,7 @@ + if (!bret) + goto out; + +- if (my_args.uid) { ++ if (my_args.uid != LXC_INVALID_UID) { + char buf[256]; + + ret = snprintf(buf, 256, "%d", my_args.uid); +@@ -223,7 +225,7 @@ + goto out; + } + +- if (my_args.gid) { ++ if (my_args.gid != LXC_INVALID_GID) { + char buf[256]; + + ret = snprintf(buf, 256, "%d", my_args.gid); diff --git a/apk/lxc/lxc.confd b/apk/lxc/lxc.confd new file mode 100644 index 0000000..1badcf8 --- /dev/null +++ b/apk/lxc/lxc.confd @@ -0,0 +1,10 @@ +# Configuration for /etc/init.d/lxc[.*] + +# Enable cgroup for systemd-based containers. +#systemd_container=no + +# autostart groups (comma separated) +#lxc_group="onboot" + +# Directory for containers' logs (used for symlinked runscripts lxc.*). +#logdir="/var/log/lxc" diff --git a/apk/lxc/lxc.initd b/apk/lxc/lxc.initd new file mode 100644 index 0000000..aab7147 --- /dev/null +++ b/apk/lxc/lxc.initd @@ -0,0 +1,157 @@ +#!/sbin/openrc-run +# Copyright 1999-2012 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 +# $Header: /var/cvsroot/gentoo-x86/app-emulation/lxc/files/lxc.initd.2,v 1.5 2012/07/21 05:07:15 flameeyes Exp $ + +extra_started_commands="reboot" + +description="Linux Containers (LXC)" +description_reboot="Reboot containers" + +CONTAINER=${SVCNAME#*.} +: ${lxc_group:=$LXC_GROUP} +: ${systemd_container:=no} +: ${logdir:=/var/log/lxc} + +command="/usr/bin/lxc-start" +pidfile="/var/run/lxc/$CONTAINER.pid" + +depend() { + need localmount sysfs cgroups + after firewall net +} + +lxc_get_configfile() { + local i + for i in /var/lib/lxc/${CONTAINER}/config \ + /etc/lxc/${CONTAINER}.conf \ + /etc/lxc/${CONTAINER}/config; do + if [ -f "$i" ]; then + echo "$i" + return 0 + fi + done + eerror "Unable to find a suitable configuration file." + eerror "If you set up the container in a non-standard" + eerror "location, please set the CONFIGFILE variable." + return 1 +} + +lxc_get_var() { + awk 'BEGIN { FS="[ \t]*=[ \t]*" } $1 == "'$1'" { print $2; exit }' ${CONFIGFILE} | cut -d: -f2 +} + +checkconfig() { + if [ ${CONTAINER} = ${SVCNAME} ]; then + CONTAINER= + return 0 + fi + CONFIGFILE=${CONFIGFILE:-$(lxc_get_configfile)} + + # no need to output anything, the function takes care of that. + [ -z "${CONFIGFILE}" ] && return 1 + + utsname=$(lxc_get_var lxc.uts.name) + if [ "${CONTAINER}" != "${utsname}" ]; then + eerror "You should use the same name for the service and the" + eerror "lxc.uts.name : Right now the lxc.uts.name is set to : ${utsname}" + return 1 + fi +} + +systemd_ctr() { + local cmd="$1" + # Required for lxc-console and services inside systemd containers. + local cgroup=/sys/fs/cgroup/systemd + local mnt_opts='rw,nosuid,nodev,noexec,relatime,none,name=systemd' + + case "$cmd" in + mount) + checkpath -d $cgroup + if ! mount | grep $cgroup >/dev/null; then + mount -t cgroup -o $mnt_opts cgroup $cgroup + fi + ;; + unmount) + if mount | grep $cgroup >/dev/null; then + umount $cgroup + fi + ;; + esac +} + +_autostart() { + ebegin "$1 LXC containers" + shift + lxc-autostart --group "$lxc_group" "$@" + eend $? +} + +start() { + checkconfig || return 1 + if yesno "$systemd_container"; then + systemd_ctr mount + fi + if [ -z "$CONTAINER" ]; then + _autostart "Starting" + return + fi + + rm -f "$logdir"/${CONTAINER}.log + + rootpath=$(lxc_get_var lxc.rootfs.path) + # verify that container is not on tmpfs + dev=$(df -P "${rootpath}" | awk '{d=$1}; END {print d}') + type=$(awk -v dev="$dev" '$1 == dev {m=$3}; END {print m}' /proc/mounts) + if [ "$type" = tmpfs ] && ! yesno "$ALLOW_TMPFS"; then + eerror "${rootpath} is on tmpfs and ALLOW_TMPFS is not set" + return 1 + fi + + checkpath -d -m 750 -o root:wheel $logdir + + checkpath -d ${pidfile%/*} + ebegin "Starting container ${CONTAINER}" + start-stop-daemon --start $command \ + --pidfile $pidfile \ + -- \ + --daemon \ + --pidfile $pidfile \ + --name ${CONTAINER} \ + --rcfile ${CONFIGFILE} \ + --logpriority WARN \ + --logfile $logdir/${CONTAINER}.log \ + || eend $? || return $? + lxc-wait -n ${CONTAINER} -t 5 -s RUNNING + eend $? +} + +stop() { + checkconfig || return 1 + systemd_ctr unmount + + if [ -z "$CONTAINER" ]; then + _autostart "Stopping" --shutdown --timeout ${LXC_TIMEOUT:-30} + return + fi + + ebegin "Stopping container ${CONTAINER}" + start-stop-daemon --stop --pidfile ${pidfile} \ + --retry ${POWEROFF_SIGNAL:-SIGUSR2}/${TIMEOUT:-30} \ + --progress + eend $? +} + +reboot() { + checkconfig || return 1 + if [ -z "$CONTAINER" ]; then + _autostart "Rebooting" --reboot + return + fi + + ebegin "Sending reboot signal to container $CONTAINER" + start-stop-daemon --signal ${RESTART_SIG:-SIGTERM} \ + --pidfile ${pidfile} + eend $? +} + diff --git a/apk/lxc/network-restore-ability-to-move-nl80211-devices.patch b/apk/lxc/network-restore-ability-to-move-nl80211-devices.patch new file mode 100644 index 0000000..965ef89 --- /dev/null +++ b/apk/lxc/network-restore-ability-to-move-nl80211-devices.patch @@ -0,0 +1,91 @@ +From 3dd7829433f63b2ec1323a1f237efa7d67ea6e2b Mon Sep 17 00:00:00 2001 +From: Christian Brauner +Date: Fri, 26 Jul 2019 08:20:02 +0200 +Subject: [PATCH] network: restore ability to move nl80211 devices + +Closes #3105. +Signed-off-by: Christian Brauner +--- + src/lxc/network.c | 31 +++++++++++++++++-------------- + 1 file changed, 17 insertions(+), 14 deletions(-) + +diff --git a/src/lxc/network.c b/src/lxc/network.c +index 9755116ba1..7684f95918 100644 +--- a/src/lxc/network.c ++++ b/src/lxc/network.c +@@ -1248,22 +1248,21 @@ static int lxc_netdev_rename_by_name_in_netns(pid_t pid, const char *old, + static int lxc_netdev_move_wlan(char *physname, const char *ifname, pid_t pid, + const char *newname) + { +- char *cmd; ++ __do_free char *cmd = NULL; + pid_t fpid; +- int err = -1; + + /* Move phyN into the container. TODO - do this using netlink. + * However, IIUC this involves a bit more complicated work to talk to + * the 80211 module, so for now just call out to iw. + */ + cmd = on_path("iw", NULL); +- if (!cmd) +- goto out1; +- free(cmd); ++ if (!cmd) { ++ return -1; ++ } + + fpid = fork(); + if (fpid < 0) +- goto out1; ++ return -1; + + if (fpid == 0) { + char pidstr[30]; +@@ -1274,21 +1273,18 @@ static int lxc_netdev_move_wlan(char *physname, const char *ifname, pid_t pid, + } + + if (wait_for_pid(fpid)) +- goto out1; ++ return -1; + +- err = 0; + if (newname) +- err = lxc_netdev_rename_by_name_in_netns(pid, ifname, newname); ++ return lxc_netdev_rename_by_name_in_netns(pid, ifname, newname); + +-out1: +- free(physname); +- return err; ++ return 0; + } + + int lxc_netdev_move_by_name(const char *ifname, pid_t pid, const char* newname) + { ++ __do_free char *physname = NULL; + int index; +- char *physname; + + if (!ifname) + return -EINVAL; +@@ -3279,13 +3275,20 @@ int lxc_network_move_created_netdev_priv(struct lxc_handler *handler) + return 0; + + lxc_list_for_each(iterator, network) { ++ __do_free char *physname = NULL; + int ret; + struct lxc_netdev *netdev = iterator->elem; + + if (!netdev->ifindex) + continue; + +- ret = lxc_netdev_move_by_index(netdev->ifindex, pid, NULL); ++ if (netdev->type == LXC_NET_PHYS) ++ physname = is_wlan(netdev->link); ++ ++ if (physname) ++ ret = lxc_netdev_move_wlan(physname, netdev->link, pid, NULL); ++ else ++ ret = lxc_netdev_move_by_index(netdev->ifindex, pid, NULL); + if (ret) { + errno = -ret; + SYSERROR("Failed to move network device \"%s\" with ifindex %d to network namespace %d", diff --git a/build/build-all.sh b/build/build-all.sh index fec66a0..2482e55 100755 --- a/build/build-all.sh +++ b/build/build-all.sh @@ -12,6 +12,10 @@ cd ${ROOT}/vm tar czpf /srv/build/vm.tar.gz * # Build native apps +cd ${ROOT}/apk/lxc +apk add -U autoconf automake bsd-compat-headers docbook2x libcap-dev libcap-static libseccomp-dev libtool linux-headers linux-pam-dev +abuild -F + cd ${ROOT}/apk/rabbitmq-server apk add -U elixir erlang-compiler erlang-dev erlang-edoc erlang-eldap erlang-erl-docgen erlang-mnesia erlang-os-mon erlang-runtime-tools erlang-tools erlang-eunit erlang-xmerl gawk grep libxslt py3-simplejson python3 rsync socat xmlto zip abuild -F diff --git a/vm.sh b/vm.sh index 4fb8e52..e1a31a6 100755 --- a/vm.sh +++ b/vm.sh @@ -89,7 +89,7 @@ apk --no-cache add apache2-utils gettext wget https://repo.spotter.cz/vm.tar.gz -O - | tar xzf - -C /mnt envsubst /mnt/boot/extlinux.conf.new mv /mnt/boot/extlinux.conf.new /mnt/boot/extlinux.conf -chroot /mnt apk --no-cache add bridge ca-certificates curl e2fsprogs-extra gettext iptables kbd-misc logrotate postfix nginx openssh-server openssh-sftp-server util-linux wireguard-virt wireguard-tools-wg spoc@vm vmmgr@vm +chroot /mnt apk --no-cache add bridge ca-certificates curl e2fsprogs-extra gettext iptables kbd-misc logrotate postfix nginx openssh-server openssh-sftp-server util-linux wireguard-virt wireguard-tools-wg lxc@vm spoc@vm vmmgr@vm chroot /mnt newaliases for SERVICE in cgroups consolefont crond iptables networking nginx ntpd postfix spoc swap urandom vmmgr; do ln -s /etc/init.d/${SERVICE} /mnt/etc/runlevels/boot