vm: qubes-yum-proxy service (#568)

Introduce proxy service, which allow only http(s) traffic to yum repos. The
filter rules are based on URL regexp, so it isn't full-featured content
inspection and can be easy bypassed, but should be enough to prevent some
erroneus user actions (like clicking on invalid link).

It is set up to intercept connections to 10.137.255.254:8082, so VM can connect
to this IP regardless of VM in which proxy is running. By default it is
started in every NetVM, but this can be changed using qvm-service or
qubes-manager (as always).
This commit is contained in:
Marek Marczykowski 2012-05-31 02:24:49 +02:00
parent 181426c19d
commit 81806796ca
6 changed files with 183 additions and 2 deletions

6
network/filter-qubes-yum Normal file
View File

@ -0,0 +1,6 @@
.*/repodata/[A-Za-z0-9-]*\(primary\|filelist\|comps\(-[a-z0-9]*\)\?\|other\|prestodelta\)\.\(sqlite\|xml\)\(\.bz2\|\.gz\)\?$
.*/repodata/repomd\.xml$
.*\.rpm$
.*\.drpm$
mirrors.fedoraproject.org:443
^http://mirrors\..*/mirrorlist

View File

@ -0,0 +1,30 @@
User tinyproxy
Group tinyproxy
Port 8082
Timeout 60
DefaultErrorFile "/usr/share/tinyproxy/default.html"
#StatHost "tinyproxy.stats"
StatFile "/usr/share/tinyproxy/stats.html"
Syslog On
LogLevel Notice
PidFile "/var/run/tinyproxy/tinyproxy-qubes-yum.pid"
MaxClients 50
MinSpareServers 2
MaxSpareServers 10
StartServers 2
MaxRequestsPerChild 0
ViaProxyName "tinyproxy"
Allow 127.0.0.1
Allow 10.137.0.0/16
Filter "/etc/tinyproxy/filter-qubes-yum"
FilterURLs On
#FilterExtended On
#FilterCaseSensitive On
FilterDefaultDeny Yes
ConnectPort 443

View File

@ -37,6 +37,7 @@ Requires: yum-plugin-post-transaction-actions
Requires: NetworkManager >= 0.8.1-1
Requires: /usr/bin/mimeopen
Requires: /sbin/ethtool
Requires: tinyproxy
Provides: qubes-core-vm
Obsoletes: qubes-core-commonvm
Obsoletes: qubes-core-appvm
@ -127,6 +128,8 @@ install -d $RPM_BUILD_ROOT/etc/NetworkManager/dispatcher.d/
install network/{qubes_nmhook,30-qubes_external_ip} $RPM_BUILD_ROOT/etc/NetworkManager/dispatcher.d/
install -D network/vif-route-qubes $RPM_BUILD_ROOT/etc/xen/scripts/vif-route-qubes
install -m 0644 -D network/iptables $RPM_BUILD_ROOT/etc/sysconfig/iptables
install -m 0644 -D network/tinyproxy-qubes-yum.conf $RPM_BUILD_ROOT/etc/tinyproxy/tinyproxy-qubes-yum.conf
install -m 0644 -D network/filter-qubes-yum $RPM_BUILD_ROOT/etc/tinyproxy/filter-qubes-yum
install -d $RPM_BUILD_ROOT/usr/sbin
install network/qubes_firewall $RPM_BUILD_ROOT/usr/sbin/
@ -334,6 +337,8 @@ rm -rf $RPM_BUILD_ROOT
/etc/sudoers.d/qubes
/etc/sysconfig/iptables
/etc/sysconfig/modules/qubes_core.modules
/etc/tinyproxy/filter-qubes-yum
/etc/tinyproxy/tinyproxy-qubes-yum.conf
/etc/udev/rules.d/50-qubes_memory.rules
/etc/udev/rules.d/99-qubes_block.rules
/etc/udev/rules.d/99-qubes_network.rules
@ -422,6 +427,7 @@ The Qubes core startup configuration for SysV init (or upstart).
/etc/init.d/qubes_core_netvm
/etc/init.d/qubes-firewall
/etc/init.d/qubes-netwatcher
/etc/init.d/qubes-yum-proxy
%post sysvinit
@ -454,6 +460,8 @@ chkconfig --add qubes_firewall || echo "WARNING: Cannot add service qubes_core!"
chkconfig qubes_firewall on || echo "WARNING: Cannot enable service qubes_core!"
chkconfig --add qubes-netwatcher || echo "WARNING: Cannot add service qubes_core!"
chkconfig qubes-netwatcher on || echo "WARNING: Cannot enable service qubes_core!"
chkconfig --add qubes-yum-proxy || echo "WARNING: Cannot add service qubes-yum-proxy!"
chkconfig qubes-yum-proxy on || echo "WARNING: Cannot enable service qubes-yum-proxy!"
# TODO: make this not display the silly message about security context...
sed -i s/^id:.:initdefault:/id:3:initdefault:/ /etc/inittab
@ -466,6 +474,7 @@ if [ "$1" = 0 ] ; then
chkconfig qubes_core_appvm off
chkconfig qubes-firewall off
chkconfig qubes-netwatcher off
chkconfig qubes-yum-proxy off
fi
%package systemd
@ -495,6 +504,7 @@ The Qubes core startup configuration for SystemD init.
/lib/systemd/system/qubes-sysinit.service
/lib/systemd/system/qubes-update-check.service
/lib/systemd/system/qubes-update-check.timer
/lib/systemd/system/qubes-yum-proxy.service
%dir /usr/lib/qubes/init
/usr/lib/qubes/init/prepare-dvm.sh
/usr/lib/qubes/init/network-proxy-setup.sh
@ -509,7 +519,7 @@ The Qubes core startup configuration for SystemD init.
%post systemd
for srv in qubes-dvm qubes-meminfo-writer qubes-qrexec-agent qubes-sysinit qubes-misc-post qubes-netwatcher qubes-network qubes-firewall; do
for srv in qubes-dvm qubes-meminfo-writer qubes-qrexec-agent qubes-sysinit qubes-misc-post qubes-netwatcher qubes-network qubes-firewall qubes-yum-proxy; do
/bin/systemctl enable $srv.service 2> /dev/null
done

121
vm-init.d/qubes-yum-proxy Executable file
View File

@ -0,0 +1,121 @@
#!/bin/sh
#
# tinyproxy Startup script for the tinyproxy server as Qubes yum proxy
#
# chkconfig: - 85 15
# description: small, efficient HTTP/SSL proxy daemon
#
# processname: tinyproxy
# config: /etc/tinyproxy/tinyproxy-qubes-yum.conf
# config: /etc/sysconfig/tinyproxy-qubes-yum
# pidfile: /var/run/tinyproxy/tinyproxy-qubes-yum.pid
#
# Note: pidfile is created by tinyproxy in its config
# see PidFile in the configuration file.
# Source function library.
. /etc/rc.d/init.d/functions
# Source networking configuration.
. /etc/sysconfig/network
# Check that networking is up.
[ "$NETWORKING" = "no" ] && exit 0
exec="/usr/sbin/tinyproxy"
prog=$(basename $exec)
config="/etc/tinyproxy/tinyproxy-qubes-yum.conf"
pidfile="/var/run/tinyproxy/tinyproxy-qubes-yum.pid"
[ -e /etc/sysconfig/tinyproxy-qubes-yum ] && . /etc/sysconfig/tinyproxy-qubes-yum
lockfile=/var/lock/subsys/tinyproxy-qubes-yum
start() {
type=`/usr/bin/xenstore-read qubes_vm_type`
start_yum_proxy=`/usr/bin/xenstore-read qubes-service/qubes-yum-proxy 2>/dev/null`
if [ -z "$start_yum_proxy" ] && [ "$type" != "NetVM" ] || [ "$start_yum_proxy" != "1" ]; 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 yum 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 $?

View File

@ -1,7 +1,7 @@
#!/bin/sh
# List of services enabled by default (in case of absence of xenstore entry)
DEFAULT_ENABLED_NETVM="network-manager qubes-network qubes-update-check"
DEFAULT_ENABLED_NETVM="network-manager qubes-network qubes-update-check qubes-yum-proxy"
DEFAULT_ENABLED_PROXYVM="meminfo-writer qubes-network qubes-firewall qubes-netwatcher qubes-update-check"
DEFAULT_ENABLED_APPVM="meminfo-writer cups qubes-update-check"
DEFAULT_ENABLED_TEMPLATEVM=$DEFAULT_ENABLED_APPVM

View File

@ -0,0 +1,14 @@
[Unit]
Description=Qubes yum proxy (tinyproxy)
ConditionPathExists=/var/run/qubes-service/qubes-yum-proxy
After=iptables.service
[Service]
ExecStartPre=/sbin/iptables -I INPUT -i vif+ -p tcp --dport 8082 -j ACCEPT
ExecStartPre=/sbin/iptables -t nat -A PR-QBS-SERVICES -i vif+ -d 10.137.255.254 -p tcp --dport 8082 -j REDIRECT
ExecStart=/usr/sbin/tinyproxy -d -c /etc/tinyproxy/tinyproxy-qubes-yum.conf
ExecStopPost=/sbin/iptables -t nat -D PR-QBS-SERVICES -i vif+ -d 10.137.255.254 -p tcp --dport 8082 -j REDIRECT
ExecStopPost=/sbin/iptables -D INPUT -i vif+ -p tcp --dport 8082 -j ACCEPT
[Install]
WantedBy=multi-user.target