Implement qrexec-based connection to updates proxy

Configure package manager to use 127.0.0.1:8082 as proxy instead of
"magic" IP intercepted later. The listen on this port and whenever
new connection arrives, spawn qubes.UpdatesProxy service call (to
default target domain - subject to configuration in dom0) and connect
its stdin/out to the local TCP connection. This part use systemd.socket
unit in case of systemd, and ncat --exec otherwise.

On the other end - in target domain - simply pass stdin/out to updates
proxy (tinyproxy) running locally.

It's important to _not_ configure the same VM to both be updates proxy and
use it. In practice such configuration makes little sense - if VM can
access network (which is required to run updates proxy), package manager
can use it directly. Even if this network access is through some
VPN/Tor. If a single VM would be configured as both proxy provider and
proxy user, connection would loop back to itself. Because of this, proxy
connection redirection (to qrexec service) is disabled when the same VM
also run updates proxy.

Fixes QubesOS/qubes-issues#1854
This commit is contained in:
Marek Marczykowski-Górecki 2017-05-26 03:07:47 +02:00
parent f9d6ff89bc
commit b49ae50ad5
No known key found for this signature in database
GPG Key ID: 063938BA42CFA724
9 changed files with 152 additions and 2 deletions

View File

@ -119,6 +119,7 @@ install-systemd: install-init
install -d $(DESTDIR)$(SYSLIBDIR)/systemd/system{,-preset} $(DESTDIR)$(LIBDIR)/qubes/init $(DESTDIR)$(SYSLIBDIR)/modules-load.d install -d $(DESTDIR)$(SYSLIBDIR)/systemd/system{,-preset} $(DESTDIR)$(LIBDIR)/qubes/init $(DESTDIR)$(SYSLIBDIR)/modules-load.d
install -m 0644 vm-systemd/qubes-*.service $(DESTDIR)$(SYSLIBDIR)/systemd/system/ install -m 0644 vm-systemd/qubes-*.service $(DESTDIR)$(SYSLIBDIR)/systemd/system/
install -m 0644 vm-systemd/qubes-*.timer $(DESTDIR)$(SYSLIBDIR)/systemd/system/ install -m 0644 vm-systemd/qubes-*.timer $(DESTDIR)$(SYSLIBDIR)/systemd/system/
install -m 0644 vm-systemd/qubes-*.socket $(DESTDIR)$(SYSLIBDIR)/systemd/system/
install -m 0644 vm-systemd/75-qubes-vm.preset $(DESTDIR)$(SYSLIBDIR)/systemd/system-preset/ install -m 0644 vm-systemd/75-qubes-vm.preset $(DESTDIR)$(SYSLIBDIR)/systemd/system-preset/
install -m 0644 vm-systemd/qubes-core.conf $(DESTDIR)$(SYSLIBDIR)/modules-load.d/ install -m 0644 vm-systemd/qubes-core.conf $(DESTDIR)$(SYSLIBDIR)/modules-load.d/
install -m 0644 vm-systemd/qubes-misc.conf $(DESTDIR)$(SYSLIBDIR)/modules-load.d/ install -m 0644 vm-systemd/qubes-misc.conf $(DESTDIR)$(SYSLIBDIR)/modules-load.d/
@ -136,6 +137,7 @@ install-sysvinit: install-init
install vm-init.d/qubes-qrexec-agent $(DESTDIR)/etc/init.d/ install vm-init.d/qubes-qrexec-agent $(DESTDIR)/etc/init.d/
install vm-init.d/qubes-updates-proxy $(DESTDIR)/etc/init.d/ install vm-init.d/qubes-updates-proxy $(DESTDIR)/etc/init.d/
install vm-init.d/qubes-dvm $(DESTDIR)/etc/init.d/ install vm-init.d/qubes-dvm $(DESTDIR)/etc/init.d/
install vm-init.d/qubes-updates-proxy-forwarder $(DESTDIR)/etc/init.d/
install -D vm-init.d/qubes-core.modules $(DESTDIR)/etc/sysconfig/modules/qubes-core.modules install -D vm-init.d/qubes-core.modules $(DESTDIR)/etc/sysconfig/modules/qubes-core.modules
install -D vm-init.d/qubes-misc.modules $(DESTDIR)/etc/sysconfig/modules/qubes-misc.modules install -D vm-init.d/qubes-misc.modules $(DESTDIR)/etc/sysconfig/modules/qubes-misc.modules
install network/qubes-iptables $(DESTDIR)/etc/init.d/ install network/qubes-iptables $(DESTDIR)/etc/init.d/
@ -268,6 +270,7 @@ install-common:
install -m 0755 qubes-rpc/qubes.InstallUpdatesGUI $(DESTDIR)/etc/qubes-rpc install -m 0755 qubes-rpc/qubes.InstallUpdatesGUI $(DESTDIR)/etc/qubes-rpc
install -m 0755 qubes-rpc/qubes.ResizeDisk $(DESTDIR)/etc/qubes-rpc install -m 0755 qubes-rpc/qubes.ResizeDisk $(DESTDIR)/etc/qubes-rpc
install -m 0755 qubes-rpc/qubes.StartApp $(DESTDIR)/etc/qubes-rpc install -m 0755 qubes-rpc/qubes.StartApp $(DESTDIR)/etc/qubes-rpc
install -m 0755 qubes-rpc/qubes.UpdatesProxy $(DESTDIR)/etc/qubes-rpc
install -d $(DESTDIR)/etc/qubes/suspend-pre.d install -d $(DESTDIR)/etc/qubes/suspend-pre.d
install -m 0644 qubes-rpc/suspend-pre.README $(DESTDIR)/etc/qubes/suspend-pre.d/README install -m 0644 qubes-rpc/suspend-pre.README $(DESTDIR)/etc/qubes/suspend-pre.d/README

View File

@ -30,6 +30,7 @@ etc/qubes-rpc/qubes.SuspendPostAll
etc/qubes-rpc/qubes.SuspendPre etc/qubes-rpc/qubes.SuspendPre
etc/qubes-rpc/qubes.SuspendPreAll etc/qubes-rpc/qubes.SuspendPreAll
etc/qubes-rpc/qubes.SyncNtpClock etc/qubes-rpc/qubes.SyncNtpClock
etc/qubes-rpc/qubes.UpdatesProxy
etc/qubes-rpc/qubes.VMShell etc/qubes-rpc/qubes.VMShell
etc/qubes-rpc/qubes.WaitForSession etc/qubes-rpc/qubes.WaitForSession
etc/qubes-suspend-module-blacklist etc/qubes-suspend-module-blacklist
@ -83,6 +84,8 @@ lib/systemd/system/qubes-sysinit.service
lib/systemd/system/qubes-update-check.service lib/systemd/system/qubes-update-check.service
lib/systemd/system/qubes-update-check.timer lib/systemd/system/qubes-update-check.timer
lib/systemd/system/qubes-updates-proxy.service lib/systemd/system/qubes-updates-proxy.service
lib/systemd/system/qubes-updates-proxy-forwarder@.service
lib/systemd/system/qubes-updates-proxy-forwarder.socket
lib/systemd/system/systemd-random-seed.service.d/30_qubes.conf lib/systemd/system/systemd-random-seed.service.d/30_qubes.conf
lib/systemd/system/tinyproxy.service.d/30_not_needed_in_qubes_by_default.conf lib/systemd/system/tinyproxy.service.d/30_not_needed_in_qubes_by_default.conf
lib/systemd/system/tmp.mount.d/30_qubes.conf lib/systemd/system/tmp.mount.d/30_qubes.conf

View File

@ -75,7 +75,7 @@ EOF
# Determine whether the proxy should be used # Determine whether the proxy should be used
if qsvc yum-proxy-setup || qsvc updates-proxy-setup ; then if qsvc yum-proxy-setup || qsvc updates-proxy-setup ; then
PROXY_ADDR="http://10.137.255.254:8082/" PROXY_ADDR="http://127.0.0.1:8082/"
PROXY_CONF_ENTRY="proxy=$PROXY_ADDR" PROXY_CONF_ENTRY="proxy=$PROXY_ADDR"
else else
PROXY_ADDR="" PROXY_ADDR=""

2
qubes-rpc/qubes.UpdatesProxy Executable file
View File

@ -0,0 +1,2 @@
#!/bin/sh
exec nc localhost 8082

View File

@ -20,7 +20,7 @@
# #
# #
%define qubes_services qubes-core qubes-core-netvm qubes-core-early qubes-firewall qubes-iptables qubes-updates-proxy qubes-qrexec-agent qubes-dvm %define qubes_services qubes-core qubes-core-netvm qubes-core-early qubes-firewall qubes-iptables qubes-updates-proxy qubes-qrexec-agent qubes-dvm qubes-updates-proxy-forwarder
%define qubes_preset_file 75-qubes-vm.preset %define qubes_preset_file 75-qubes-vm.preset
%{!?version: %define version %(cat version)} %{!?version: %define version %(cat version)}
@ -124,6 +124,7 @@ Conflicts: firewalld
Requires: xdg-utils Requires: xdg-utils
Requires: ethtool Requires: ethtool
Requires: tinyproxy Requires: tinyproxy
Requires: nmap-ncat
Requires: ntpdate Requires: ntpdate
Requires: net-tools Requires: net-tools
Requires: qubes-utils >= 3.1.3 Requires: qubes-utils >= 3.1.3
@ -440,6 +441,7 @@ rm -f %{name}-%{version}
%config(noreplace) /etc/qubes-rpc/qubes.InstallUpdatesGUI %config(noreplace) /etc/qubes-rpc/qubes.InstallUpdatesGUI
%config(noreplace) /etc/qubes-rpc/qubes.ResizeDisk %config(noreplace) /etc/qubes-rpc/qubes.ResizeDisk
%config(noreplace) /etc/qubes-rpc/qubes.StartApp %config(noreplace) /etc/qubes-rpc/qubes.StartApp
%config(noreplace) /etc/qubes-rpc/qubes.UpdatesProxy
%dir /etc/qubes/autostart %dir /etc/qubes/autostart
/etc/qubes/autostart/README.txt /etc/qubes/autostart/README.txt
%config /etc/qubes/autostart/*.desktop.d/30_qubes.conf %config /etc/qubes/autostart/*.desktop.d/30_qubes.conf
@ -576,6 +578,7 @@ The Qubes core startup configuration for SysV init (or upstart).
/etc/init.d/qubes-iptables /etc/init.d/qubes-iptables
/etc/init.d/qubes-updates-proxy /etc/init.d/qubes-updates-proxy
/etc/init.d/qubes-qrexec-agent /etc/init.d/qubes-qrexec-agent
/etc/init.d/qubes-updates-proxy-forwarder
/etc/sysconfig/modules/qubes-core.modules /etc/sysconfig/modules/qubes-core.modules
/etc/sysconfig/modules/qubes-misc.modules /etc/sysconfig/modules/qubes-misc.modules
@ -650,6 +653,8 @@ The Qubes core startup configuration for SystemD init.
/lib/systemd/system/qubes-update-check.timer /lib/systemd/system/qubes-update-check.timer
/lib/systemd/system/qubes-updates-proxy.service /lib/systemd/system/qubes-updates-proxy.service
/lib/systemd/system/qubes-qrexec-agent.service /lib/systemd/system/qubes-qrexec-agent.service
/lib/systemd/system/qubes-updates-proxy-forwarder@.service
/lib/systemd/system/qubes-updates-proxy-forwarder.socket
/lib/systemd/system-preset/%qubes_preset_file /lib/systemd/system-preset/%qubes_preset_file
/lib/modules-load.d/qubes-core.conf /lib/modules-load.d/qubes-core.conf
/lib/modules-load.d/qubes-misc.conf /lib/modules-load.d/qubes-misc.conf

View File

@ -0,0 +1,115 @@
#!/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.
. /etc/rc.d/init.d/functions
# Source Qubes library.
. /usr/lib/qubes/init/functions
# Source networking configuration.
. /etc/sysconfig/network
# Check that networking is up.
[ "$NETWORKING" = "no" ] && exit 0
exec="/usr/bin/ncat"
prog=$(basename $exec)
pidfile="/var/run/qubes-updates-proxy-forwarder.pid"
[ -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): "
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 $?

View File

@ -90,6 +90,7 @@ enable qubes-mount-dirs.service
enable qubes-firewall.service enable qubes-firewall.service
enable qubes-meminfo-writer.service enable qubes-meminfo-writer.service
enable qubes-iptables.service enable qubes-iptables.service
enable qubes-updates-proxy-forwarder.socket
enable haveged.service enable haveged.service
enable chronyd.service enable chronyd.service
enable xendriverdomain.service enable xendriverdomain.service

View File

@ -0,0 +1,14 @@
[Unit]
Description=Forward connection to updates proxy over Qubes RPC
ConditionPathExists=/var/run/qubes-service/updates-proxy-setup
# don't start the forwarder when updates proxy itself is also enabled here,
# otherwise it would most likely loop back to itself
ConditionPathExists=!/var/run/qubes-service/qubes-updates-proxy
[Socket]
ListenStream=127.0.0.1:8082
BindToDevice=lo
Accept=true
[Install]
WantedBy=multi-user.target

View File

@ -0,0 +1,7 @@
[Unit]
Description=Forward connection to updates proxy over Qubes RPC
[Service]
ExecStart=/usr/bin/qrexec-client-vm '' qubes.UpdatesProxy
StandardInput=socket
StandardOutput=inherit