From ec68b4fe4674f06b404acf2e40642347d22513b2 Mon Sep 17 00:00:00 2001 From: Antoine Martin Date: Sun, 13 Aug 2023 23:34:15 -0400 Subject: [PATCH] qubes-vm-core: initial import from user-aports --- qubes-vm-core/APKBUILD | 169 ++++++++++++++++++ qubes-vm-core/qubes-core-early.openrc | 39 ++++ qubes-vm-core/qubes-core-netvm.openrc | 30 ++++ qubes-vm-core/qubes-core.openrc | 30 ++++ qubes-vm-core/qubes-firewall.openrc | 22 +++ qubes-vm-core/qubes-iptables.openrc | 75 ++++++++ qubes-vm-core/qubes-sysinit.openrc | 18 ++ .../qubes-updates-proxy-forwarder.openrc | 116 ++++++++++++ qubes-vm-core/qubes-updates-proxy.openrc | 124 +++++++++++++ qubes-vm-core/qvm-sync-clock.sh | 6 + 10 files changed, 629 insertions(+) create mode 100644 qubes-vm-core/APKBUILD create mode 100755 qubes-vm-core/qubes-core-early.openrc create mode 100755 qubes-vm-core/qubes-core-netvm.openrc create mode 100755 qubes-vm-core/qubes-core.openrc create mode 100755 qubes-vm-core/qubes-firewall.openrc create mode 100755 qubes-vm-core/qubes-iptables.openrc create mode 100755 qubes-vm-core/qubes-sysinit.openrc create mode 100755 qubes-vm-core/qubes-updates-proxy-forwarder.openrc create mode 100755 qubes-vm-core/qubes-updates-proxy.openrc create mode 100755 qubes-vm-core/qvm-sync-clock.sh diff --git a/qubes-vm-core/APKBUILD b/qubes-vm-core/APKBUILD new file mode 100644 index 0000000..a352a67 --- /dev/null +++ b/qubes-vm-core/APKBUILD @@ -0,0 +1,169 @@ +# Maintainer: Antoine Martin (ayakael) +# Contributor: Antoine Martin (ayakael) + +pkgname=qubes-vm-core +subpackages=" + qubes-vm-networking:networking:noarch + qubes-vm-passwordless-root:root:noarch + $pkgname-openrc + $pkgname-doc + " +pkgver=4.1.39 +pkgrel=1 +_gittag="v$pkgver" +pkgdesc="The Qubes core files for installation inside a Qubes VM." +arch="x86_64" +url="https://github.com/QubesOS/qubes-core-agent-linux" +license="GPL" +options="!check" # No testsuite +depends=" + coreutils + dconf + desktop-file-utils + device-mapper + ethtool + fakeroot + gawk + grep + haveged + icu + imagemagick + librsvg + net-tools + ntpsec + procps + py3-dbus + py3-gobject3 + py3-xdg + python3 + qubes-db-vm + qubes-libvchan-xen + qubes-vm-utils + sed + socat + xdg-utils + zenity + " +makedepends=" + gcc + libx11-dev + linux-pam-dev + make + pandoc + pkgconf + py3-setuptools + python3 + qubes-db-vm + qubes-libvchan-xen + qubes-vm-utils + " +options="suid" +source=" + $pkgname-$_gittag.tar.gz::https://github.com/QubesOS/qubes-core-agent-linux/archive/refs/tags/$_gittag.tar.gz + qubes-core-early.openrc + qubes-core-netvm.openrc + qubes-core.openrc + qubes-firewall.openrc + qubes-iptables.openrc + qubes-sysinit.openrc + qubes-updates-proxy-forwarder.openrc + qubes-updates-proxy.openrc + qvm-sync-clock.sh + " +builddir="$srcdir"/qubes-core-agent-linux-${_gittag/v} + + +build() { + # Fix for network tools paths + sed 's:/sbin/ethtool:ethtool:g' -i network/* + sed 's:/sbin/ip:ip:g' -i network/* + sed 's:/bin/grep:grep:g' -i network/* + + for dir in qubes-rpc misc; do + make -C "$dir" + done + + # replace all shebangs with /bin/sh as qubes expects bash + # shellcheck disable=SC2013 + for i in $(grep '/bin/sh' -Rl .); do + sed -i 's|/bin/sh|/bin/bash|' "$i" + done +} + +#This package provides: +# * qrexec agent +# * qubes rpc scripts +# * core linux tools and scripts +# * core systemd services and drop-ins +# * basic network functionality (setting IP address, DNS, default gateway) +package() { + make install-corevm DESTDIR="$pkgdir" SBINDIR=/sbin LIBDIR=/usr/lib SYSLIBDIR=/lib + make -C app-menu install DESTDIR="$pkgdir" install LIBDIR=/usr/lib SYSLIBDIR=/lib + make -C misc install DESTDIR="$pkgdir" install LIBDIR=/usr/lib SYSLIBDIR=/lib + make -C qubes-rpc DESTDIR="$pkgdir" install + make -C qubes-rpc/kde DESTDIR="$pkgdir" install + make -C qubes-rpc/nautilus DESTDIR="$pkgdir" install + make -C qubes-rpc/thunar DESTDIR="$pkgdir" install + make -C network DESTDIR="$pkgdir" install + install -Dm755 "$builddir"/network/update-proxy-configs "$pkgdir"/usr/lib/qubes/. + install -Dm755 "$srcdir"/qvm-sync-clock.sh "$pkgdir"/etc/qubes/suspend-post.d/. + + for i in $source; do + case $i in + *.openrc) install -Dm755 "$srcdir"/$i \ + "$pkgdir"/etc/init.d/${i%.*};; + *.confd) install -Dm644 "$srcdir"/$i \ + "$pkgdir"/etc/conf.d/${i%.*};; + esac + done + +} + + +#This package provides: +# * proxy service used by TemplateVMs to download updates +# * qubes-firewall service (FirewallVM) +# +#Integration of NetworkManager for Qubes VM: +# * make connections config persistent +# * adjust DNS redirections when needed +# * show/hide NetworkManager applet icon +# +networking() { + pkgdesc="Qubes OS tools allowing to use a Qubes VM as a NetVM/ProxyVM" + depends=" + conntrack-tools + ethtool + iptables + net-tools + networkmanager + nftables + python3 + qubes-db-vm + qubes-vm-core + qubes-vm-utils + tinyproxy + " + cd "$builddir" + install -dm 755 "$subpkgdir"/usr/bin + mv "$pkgdir"/usr/bin/qubes-firewall "$subpkgdir"/usr/bin/. + make install-netvm DESTDIR="$subpkgdir" SBINDIR=/sbin LIBDIR=/usr/lib SYSLIBDIR=/lib +} + +root() { + cd "$builddir" + pkgdesc="Qubes OS Passwordless root access from normal user" + make -C passwordless-root install DESTDIR="$subpkgdir" SBINDIR=/sbin LIBDIR=/usr/lib SYSLIBDIR=/lib +} +sha512sums=" +2ac642946ed6ca12857d7d88ec54bb293ca5f9fe99c79fceffd4717bbcc0265367bc1cfbddd0ec52cd1a0dc714a3f2978aa08c32199e76d761c53910ae1d5908 qubes-vm-core-v4.1.39.tar.gz +95c080a593ca1cd457ffafc0cdd6ee28999c72f67191a3955b6081a4a7d287cae4cd0c626139562e5e1eb55516c25402a174e3599daf7d4cb259d6b4bbdff155 qubes-core-early.openrc +61529413a16b7fa0df691c24adc41b90477c01ea70d572921ecec89df23932e5a2e60c4e73b9a84181dc30424e2e6af4ad1c7dcf6c42689c3cc346a9923d6e07 qubes-core-netvm.openrc +da8e293520f5fce29ce76d7586e8ce1a4164798a1214079fb554c690264da1d774fdad3f45825aac52c2c3a0b0cfd39df73eb33394dedd7c043fe0f2344b90ca qubes-core.openrc +8f1ea1b6bfb4d3089a51cc3e325861ee7b644f743b2652bf61789933adedefdbc743a61567ad980d2a6077647eb61570b68a056125abaab2a67166d249a961b0 qubes-firewall.openrc +437a3dc443c5b0311c5dc8f792739eef89e38b2e854b9a5bb248211dd0eb0f26c1d79588ca2b4b63236b8bed0d735be6b2265d8328885730a8aa5f854301d61f qubes-iptables.openrc +e9096560e4ee4cad836b686e18eb6dbac729227683eda2f0c8b3541c909f64de3489dbb66e3752014deab69cbfae7885bc15b9bb7e3942c02e40328337b9ef30 qubes-sysinit.openrc +b1e8af2335955e52cf1817c56296f94f8c472e68d7a17a28f516fe4f5fa8a8053d4f9333efbb007a82a06f9442a4a6cfe5f9c751de07f337e47ee04cb18b9395 qubes-updates-proxy-forwarder.openrc +29d316b9f48cad15f6e22aaa67b228a5e4893ded86463dbe25b3cc68301b961473e79c01f003b1665e217ad4af2e618625442250d5607c1c16462e3f5eed069c qubes-updates-proxy.openrc +cca9f49422fa25cd5f3942dce8edd3ecff080bf5c407a7a790b438bedea054f39a4a3d8c179b44c4c08fc490b597e14d00dad9b0240861e83957e0af7aa6475d qvm-sync-clock.sh +" diff --git a/qubes-vm-core/qubes-core-early.openrc b/qubes-vm-core/qubes-core-early.openrc new file mode 100755 index 0000000..f0635ee --- /dev/null +++ b/qubes-vm-core/qubes-core-early.openrc @@ -0,0 +1,39 @@ +#!/sbin/openrc-run + +name=$RC_SVCNAME +error_log=/var/log/qubes/$RC_SVCNAME.log + +depend() { + need qubes-sysinit + need qubes-db +} + +start_pre() { + checkpath --directory --owner $command_user:qubes --mode 0775 \ + /var/lib/qubes +} + + +start() +{ + echo "Enabling transparent hugepages" | tee -a "$error_log" + echo "madvise" > /sys/kernel/mm/transparent_hugepage/enabled + + echo "Setting up early config" | tee -a "$error_log" + /usr/lib/qubes/init/qubes-early-vm-config.sh 2>&1 | tee -a "$error_log" + + echo "Adjusting root filesystem size:" | tee -a "$error_log" + /usr/lib/qubes/init/resize-rootfs-if-needed.sh 2>&1 | tee -a "$error_log" + + echo "Setting up Qubes persistent file systems:" 2>&1 | tee -a "$error_log" + /usr/lib/qubes/init/mount-dirs.sh 2>&1 | tee -a "$error_log" + + echo "Executing Qubes random seed scripts:" | tee -a "$error_log" + /usr/lib/qubes/init/qubes-random-seed.sh 2>&1 | tee -a "$error_log" + +} + +stop() +{ + return 0 +} diff --git a/qubes-vm-core/qubes-core-netvm.openrc b/qubes-vm-core/qubes-core-netvm.openrc new file mode 100755 index 0000000..4cb3530 --- /dev/null +++ b/qubes-vm-core/qubes-core-netvm.openrc @@ -0,0 +1,30 @@ +#!/sbin/openrc-run + +name=$RC_SVCNAME +cfgfile="/etc/qubes/$RC_SVCNAME.conf" +command="/usr/lib/qubes/init/network-proxy-setup" +command_args="" +command_user="root" +pidfile="/run/qubes/$RC_SVCNAME.pid" +start_stop_daemon_args="" +command_background="yes" +output_log="/var/log/qubes/$RC_SVCNAME.log" +error_log="/var/log/qubes/$RC_SVCNAME.err" + +# Source Qubes library. +# shellcheck source=init/functions +. /usr/lib/qubes/init/functions + +depend() { + need net +} + +start_pre() { + if is_netvm; then + /usr/lib/qubes/network-manager-prepare-conf-dir + /sbin/service networkmanager start + fi + + checkpath --directory --owner $command_user:qubes --mode 0775 \ + /run/$RC_SVCNAME /var/log/$RC_SVCNAME +} diff --git a/qubes-vm-core/qubes-core.openrc b/qubes-vm-core/qubes-core.openrc new file mode 100755 index 0000000..03c0721 --- /dev/null +++ b/qubes-vm-core/qubes-core.openrc @@ -0,0 +1,30 @@ +#!/sbin/openrc-run + +name=$RC_SVCNAME +error_log=/var/log/qubes/$RC_SVCNAME.log + +depend() { + need qubes-db + need qubes-meminfo-writer + need qubes-core-early +} + +start() +{ + echo "Finagling printer icon:" | tee -a "$error_log" + /usr/lib/qubes/init/control-printer-icon.sh 2>&1 | tee -a "$error_log" + + echo "Executing Qubes misc post scripts:" | tee -a "$error_log" + /usr/lib/qubes/init/misc-post.sh 2>&1 | tee -a "$error_log" + + echo "Setting up IP:" | tee -a "$error_log" + /usr/lib/qubes/setup-ip add eth0 2>&1 | tee -a "$error_log" + + echo "Syncing clock" | tee -a "$error_log" + /usr/bin/qvm-sync-clock | tee -a "$error_log" +} + +stop() +{ + /usr/lib/qubes/init/misc-post-stop.sh +} diff --git a/qubes-vm-core/qubes-firewall.openrc b/qubes-vm-core/qubes-firewall.openrc new file mode 100755 index 0000000..6cc4b38 --- /dev/null +++ b/qubes-vm-core/qubes-firewall.openrc @@ -0,0 +1,22 @@ +#!/sbin/openrc-run + +name=$RC_SVCNAME +cfgfile="/etc/qubes/$RC_SVCNAME.conf" +command="/usr/bin/qubes-firewall" +command_args="" +command_user="root" +pidfile="/run/qubes/$RC_SVCNAME.pid" +start_stop_daemon_args="" +command_background="yes" +output_log="/var/log/qubes/$RC_SVCNAME.log" +error_log="/var/log/qubes/$RC_SVCNAME.err" + +depend() { + need qubes-db +} + +start_pre() { + /sbin/ethtool -K "$(get_qubes_managed_iface)" sg off + checkpath --directory --owner $command_user:qubes --mode 0775 \ + /run/$RC_SVCNAME /var/log/qubes +} diff --git a/qubes-vm-core/qubes-iptables.openrc b/qubes-vm-core/qubes-iptables.openrc new file mode 100755 index 0000000..6daa9ac --- /dev/null +++ b/qubes-vm-core/qubes-iptables.openrc @@ -0,0 +1,75 @@ +#!/bin/bash +# +# qubes-iptables Start Qubes base iptables firewall +# +# chkconfig: 2345 08 92 +# description: Loads iptables firewall +# +# config: /etc/qubes/iptables.rules +# config: /etc/qubes/ip6tables.rules +# +### BEGIN INIT INFO +# Provides: iptables +# Required-Start: +# Required-Stop: +# Default-Start: 2 3 4 5 +# Default-Stop: 0 1 6 +# Short-Description: Loads Qubes base iptables firewall +# Description: Loads Qubes base iptables firewall +### END INIT INFO + +IPTABLES=iptables +IPTABLES_DATA_DIR=/etc/qubes + +if [ ! -x /sbin/$IPTABLES ]; then + echo $"${IPTABLES}: /sbin/$IPTABLES does not exist." + exit 5 +fi + +start() { + ipt=$1 + IPTABLES_DATA=$IPTABLES_DATA_DIR/${ipt}.rules + ipv6_enabled= + if qubesdb-read /qubes-ip6 >/dev/null 2>&1 || \ + qubesdb-read /qubes-netvm-gateway6 >/dev/null 2>&1; then + ipv6_enabled=true + fi + # if IPv6 is enabled, load alternative rules file + if [ "$ipt" = "ip6tables" ] && [ -n "$ipv6_enabled" ]; then + IPTABLES_DATA=$IPTABLES_DATA_DIR/${ipt}-enabled.rules + fi + CMD=$ipt + # Do not start if there is no config file. + [ ! -f "$IPTABLES_DATA" ] && return 6 + + CMD_ARGS= + if "$CMD-restore" --help 2>&1 | grep -q wait=; then + # 'wait' must be last on command line if secs not specified + CMD_ARGS=--wait + fi + + echo -n $"${CMD}: Applying firewall rules: " + + "$CMD-restore" "$IPTABLES_DATA" $CMD_ARGS + ret="$?" + if [ "$ret" -eq 0 ]; then + echo OK + else + echo FAIL; return 1 + fi + + return $ret +} + +case "$1" in + start) + start iptables && start ip6tables + RETVAL=$? + ;; + *) + echo $"Usage: ${IPTABLES} start" + RETVAL=2 + ;; +esac + +exit $RETVAL diff --git a/qubes-vm-core/qubes-sysinit.openrc b/qubes-vm-core/qubes-sysinit.openrc new file mode 100755 index 0000000..186e0fd --- /dev/null +++ b/qubes-vm-core/qubes-sysinit.openrc @@ -0,0 +1,18 @@ +#!/sbin/openrc-run + +name=$RC_SVCNAME +error_log="/var/log/qubes/$RC_SVCNAME.log" +depend() { + need qubes-db +} + +start() +{ + echo "Executing Qubes system initialization scripts:" + /usr/lib/qubes/init/qubes-sysinit.sh 2>&1 | tee -a $error_log +} + +stop() +{ + return 0 +} diff --git a/qubes-vm-core/qubes-updates-proxy-forwarder.openrc b/qubes-vm-core/qubes-updates-proxy-forwarder.openrc new file mode 100755 index 0000000..52e53f8 --- /dev/null +++ b/qubes-vm-core/qubes-updates-proxy-forwarder.openrc @@ -0,0 +1,116 @@ +#!/bin/bash +# +# Updates proxy forwarder Startup script for the updates proxy forwarder +# +# chkconfig: 345 85 15 +# description: forwards connection to updates proxy over Qubes RPC +# +# processname: ncat +# pidfile: /var/run/qubes-updates-proxy-forwarder.pid +# + +# Source function library. +# shellcheck disable=SC1091 +. /etc/init.d/functions.sh + +# Source Qubes library. +# shellcheck source=init/functions +. /usr/lib/qubes/init/functions + +# Check that networking is up. +[ "$NETWORKING" = "no" ] && exit 0 + +exec="/usr/bin/ncat" +prog=$(basename $exec) +pidfile="/var/run/qubes-updates-proxy-forwarder.pid" + +# shellcheck disable=SC1091 +[ -e /etc/sysconfig/qubes-updates-proxy-forwarder ] && . /etc/sysconfig/qubes-updates-proxy-forwarder + +lockfile=/var/lock/subsys/qubes-updates-proxy-forwarder + +start() { + have_qubesdb || return + + if ! qsvc updates-proxy-setup ; then + # updates proxy configuration disabled + exit 0 + fi + + if qsvc qubes-updates-proxy ; then + # updates proxy running here too, avoid looping traffic back to itself + exit 0 + fi + + [ -x $exec ] || exit 5 + + echo -n $"Starting $prog (as Qubes updates proxy forwarder): " + # shellcheck disable=SC2016 + start-stop-daemon \ + --exec $exec \ + --pidfile "$pidfile" \ + --make-pidfile \ + --background \ + --start \ + -- \ + -k -l -e 'qrexec-client-vm $default qubes.UpdatesProxy' + retval=$? + echo + [ $retval -eq 0 ] && touch $lockfile + return $retval +} + +stop() { + echo -n $"Stopping $prog: " + killproc -p $pidfile "$prog" + retval=$? + echo + [ $retval -eq 0 ] && rm -f $lockfile + return $retval +} + +restart() { + stop + start +} + +force_reload() { + restart +} + +rh_status() { + status "$prog" +} + +rh_status_q() { + rh_status >/dev/null 2>&1 +} + +case "$1" in + start) + rh_status_q && exit 0 + $1 + ;; + stop) + rh_status_q || exit 0 + $1 + ;; + restart) + $1 + ;; + force-reload) + force_reload + ;; + status) + rh_status + ;; + condrestart|try-restart) + rh_status_q || exit 0 + restart + ;; + *) + echo $"Usage: $0 {start|stop|status|restart|condrestart|try-restart|force-reload}" + exit 2 +esac +exit $? + diff --git a/qubes-vm-core/qubes-updates-proxy.openrc b/qubes-vm-core/qubes-updates-proxy.openrc new file mode 100755 index 0000000..884aeb3 --- /dev/null +++ b/qubes-vm-core/qubes-updates-proxy.openrc @@ -0,0 +1,124 @@ +#!/bin/bash +# +# tinyproxy Startup script for the tinyproxy server as Qubes updates proxy +# +# chkconfig: 345 85 15 +# description: small, efficient HTTP/SSL proxy daemon +# +# processname: tinyproxy +# config: /etc/tinyproxy/tinyproxy-updates.conf +# config: /etc/sysconfig/tinyproxy-updates +# pidfile: /var/run/tinyproxy/tinyproxy-updates.pid +# +# Note: pidfile is created by tinyproxy in its config +# see PidFile in the configuration file. + +# Source function library. +# shellcheck disable=SC1091 +. /etc/init.d/functions.sh + +# Source Qubes library. +# shellcheck source=init/functions +. /usr/lib/qubes/init/functions + +# Check that networking is up. +[ "$NETWORKING" = "no" ] && exit 0 + +exec="$(command -v tinyproxy)" +prog=$(basename "$exec") +config="/etc/tinyproxy/tinyproxy-updates.conf" +pidfile="/var/run/tinyproxy-updates/tinyproxy.pid" + +# shellcheck disable=SC1091 +[ -e /etc/sysconfig/tinyproxy-updates ] && . /etc/sysconfig/tinyproxy-updates + +lockfile=/var/lock/subsys/tinyproxy-updates + +start() { + have_qubesdb || return + + if qsvc qubes-updates-proxy ; then + # Yum proxy disabled + exit 0 + fi + + [ -x "$exec" ] || exit 5 + [ -f $config ] || exit 6 + # setup network redirection + /sbin/iptables -I INPUT -i vif+ -p tcp --dport 8082 -j ACCEPT + /sbin/iptables -t nat -A PR-QBS-SERVICES -i vif+ -d 10.137.255.254 -p tcp --dport 8082 -j REDIRECT + + echo -n $"Starting $prog (as Qubes updates proxy): " + daemon "$exec" -c $config + retval=$? + echo + [ $retval -eq 0 ] && touch $lockfile + return $retval +} + +stop() { + echo -n $"Stopping $prog: " + killproc -p $pidfile "$prog" + retval=$? + echo + /sbin/iptables -t nat -D PR-QBS-SERVICES -i vif+ -d 10.137.255.254 -p tcp --dport 8082 -j REDIRECT + /sbin/iptables -D INPUT -i vif+ -p tcp --dport 8082 -j ACCEPT + [ $retval -eq 0 ] && rm -f "$lockfile" + return $retval +} + +restart() { + stop + start +} + +reload() { + echo -n $"Reloading $prog: " + killproc -p $pidfile "$prog" -HUP + echo +} + +force_reload() { + restart +} + +rh_status() { + status "$prog" +} + +rh_status_q() { + rh_status >/dev/null 2>&1 +} + +case "$1" in + start) + rh_status_q && exit 0 + $1 + ;; + stop) + rh_status_q || exit 0 + $1 + ;; + restart) + $1 + ;; + reload) + rh_status_q || exit 7 + $1 + ;; + force-reload) + force_reload + ;; + status) + rh_status + ;; + condrestart|try-restart) + rh_status_q || exit 0 + restart + ;; + *) + echo $"Usage: $0 {start|stop|status|restart|condrestart|try-restart|reload|force-reload}" + exit 2 +esac +exit $? + diff --git a/qubes-vm-core/qvm-sync-clock.sh b/qubes-vm-core/qvm-sync-clock.sh new file mode 100755 index 0000000..bd616f6 --- /dev/null +++ b/qubes-vm-core/qvm-sync-clock.sh @@ -0,0 +1,6 @@ +#!/bin/sh + +if [ ! -f /var/run/qubes-service/clocksync ]; then + # https://github.com/QubesOS/qubes-issues/issues/7265 + /usr/bin/qvm-sync-clock +fi