From 2a15863ccb7b2931d5a248d9db97907ec8a38886 Mon Sep 17 00:00:00 2001 From: qubesuser Date: Sun, 30 Aug 2015 16:27:14 +0200 Subject: [PATCH] network: add vif-route-qubes-nat for IP address anonymization --- Makefile | 2 + network/vif-qubes-nat.sh | 79 ++++++++++++++++++++++++++++++++ network/vif-route-qubes-nat | 91 +++++++++++++++++++++++++++++++++++++ rpm_spec/core-vm.spec | 2 + 4 files changed, 174 insertions(+) create mode 100755 network/vif-qubes-nat.sh create mode 100755 network/vif-route-qubes-nat diff --git a/Makefile b/Makefile index 1af2899..81d7a26 100644 --- a/Makefile +++ b/Makefile @@ -156,6 +156,8 @@ install-common: install -d $(DESTDIR)/etc/NetworkManager/dispatcher.d/ install network/{qubes-nmhook,30-qubes-external-ip} $(DESTDIR)/etc/NetworkManager/dispatcher.d/ install -D network/vif-route-qubes $(DESTDIR)/etc/xen/scripts/vif-route-qubes + install -D network/vif-route-qubes-nat $(DESTDIR)/etc/xen/scripts/vif-route-qubes-nat + install -D network/vif-qubes-nat.sh $(DESTDIR)/etc/xen/scripts/vif-qubes-nat.sh install -m 0644 -D network/tinyproxy-updates.conf $(DESTDIR)/etc/tinyproxy/tinyproxy-updates.conf install -m 0644 -D network/filter-updates $(DESTDIR)/etc/tinyproxy/filter-updates install -m 0755 -D network/iptables-updates-proxy $(DESTDIR)$(LIBDIR)/qubes/iptables-updates-proxy diff --git a/network/vif-qubes-nat.sh b/network/vif-qubes-nat.sh new file mode 100755 index 0000000..9e26845 --- /dev/null +++ b/network/vif-qubes-nat.sh @@ -0,0 +1,79 @@ +#!/bin/bash +#set -x + +netvm_subnet=/24 +undetectable_netvm_ips=1 + +netns="${vif}-nat" +netvm_if="${vif}" +netns_netvm_if="${vif}-p" +netns_appvm_if="${vif}" + +function run +{ + #echo "$@" >> /var/log/qubes-nat.log + "$@" +} + +function netns +{ + run ip netns exec "$netns" "$@" +} + + + +run ip addr flush dev "$netns_appvm_if" +run ip netns delete "$netns" || : + +if test "$command" == online; then + run ip netns add "$netns" + run ip link set "$netns_appvm_if" netns "$netns" + + run ip link add "$netns_netvm_if" type veth peer name "$netvm_if" + run ip link set "$netns_netvm_if" netns "$netns" + + + netns ip6tables -t raw -I PREROUTING -j DROP + netns ip6tables -P INPUT DROP + netns ip6tables -P FORWARD DROP + netns ip6tables -P OUTPUT DROP + + netns sh -c 'echo 1 > /proc/sys/net/ipv4/ip_forward' + + netns iptables -t raw -I PREROUTING -i "$netns_appvm_if" ! -s "$appvm_ip" -j DROP + + if test -n "$undetectable_netvm_ips"; then + # prevent an AppVM connecting to its own ProxyVM IP because that makes the internal IPs detectable even with no firewall rules + netns iptables -t raw -I PREROUTING -i "$netns_appvm_if" -d "$netvm_ip" -j DROP + + # same for the gateway/DNS IPs + netns iptables -t raw -I PREROUTING -i "$netns_appvm_if" -d "$netvm_gw_ip" -j DROP + netns iptables -t raw -I PREROUTING -i "$netns_appvm_if" -d "$netvm_dns2_ip" -j DROP + fi + + netns iptables -t nat -I PREROUTING -i "$netns_netvm_if" -j DNAT --to-destination "$appvm_ip" + netns iptables -t nat -I POSTROUTING -o "$netns_netvm_if" -j SNAT --to-source "$netvm_ip" + + netns iptables -t nat -I PREROUTING -i "$netns_appvm_if" -d "$appvm_gw_ip" -j DNAT --to-destination "$netvm_gw_ip" + netns iptables -t nat -I POSTROUTING -o "$netns_appvm_if" -s "$netvm_gw_ip" -j SNAT --to-source "$appvm_gw_ip" + + if test -n "$appvm_dns2_ip"; then + netns iptables -t nat -I PREROUTING -i "$netns_appvm_if" -d "$appvm_dns2_ip" -j DNAT --to-destination "$netvm_dns2_ip" + netns iptables -t nat -I POSTROUTING -o "$netns_appvm_if" -s "$netvm_dns2_ip" -j SNAT --to-source "$appvm_dns2_ip" + fi + + netns ip addr add "$netvm_ip$netvm_subnet" dev "$netns_netvm_if" + netns ip addr add "$appvm_gw_ip" dev "$netns_appvm_if" + + netns ip link set "$netns_netvm_if" up + netns ip link set "$netns_appvm_if" up + + netns ip route add "$appvm_ip" dev "$netns_appvm_if" src "$appvm_gw_ip" + netns ip route add default via "$netvm_gw_ip" dev "$netns_netvm_if" src "$netvm_ip" + + + #run ip addr add "$netvm_gw_ip" dev "$netvm_if" + #run ip link set "$netvm_if" up + #run ip route add "$netvm_ip" dev "$netvm_if" src "$netvm_gw_ip" +fi + diff --git a/network/vif-route-qubes-nat b/network/vif-route-qubes-nat new file mode 100755 index 0000000..4a232bc --- /dev/null +++ b/network/vif-route-qubes-nat @@ -0,0 +1,91 @@ +#!/bin/bash +#============================================================================ +# /etc/xen/vif-route-qubes-nat +# +# Script for configuring a vif in routed mode. +# The hotplugging system will call this script if it is specified either in +# the device configuration given to Xend, or the default Xend configuration +# in /etc/xen/xend-config.sxp. If the script is specified in neither of those +# places, then vif-bridge is the default. +# +# Usage: +# vif-route (add|remove|online|offline) +# +# Environment vars: +# vif vif interface name (required). +# XENBUS_PATH path to this device's details in the XenStore (required). +# +# Read from the store: +# ip list of IP networks for the vif, space-separated (default given in +# this script). +#============================================================================ + +appvm_gw_ip="$1" +netvm_ip="$2" +shift 2 + +dir=$(dirname "$0") +. "$dir/vif-common.sh" + +if [ "${ip}" ]; then + appvm_ip="$ip" + netvm_gw_ip=`qubesdb-read /qubes-netvm-gateway` + netvm_dns2_ip=`qubesdb-read /qubes-netvm-secondary-dns` + + ip="$netvm_ip" + back_ip="$netvm_gw_ip" +fi + +#echo "$appvm_ip $appvm_gw_ip $netvm_ip $netvm_gw_ip" >> /var/log/qubes-nat.log + +#main_ip=$(dom0_ip) +lockfile=/var/run/xen-hotplug/vif-lock + +if [ "${ip}" ]; then + if test "$command" == online; then + echo 1 >/proc/sys/net/ipv4/conf/${vif}/proxy_arp + fi + + . "$dir/vif-qubes-nat.sh" +fi + +case "$command" in + online) + ifconfig ${vif} up + echo 1 >/proc/sys/net/ipv4/conf/${vif}/proxy_arp + ipcmd='add' + iptables_cmd='-I PREROUTING 1' + cmdprefix='' + ;; + offline) + do_without_error ifdown ${vif} + ipcmd='del' + iptables_cmd='-D PREROUTING' + cmdprefix='do_without_error' + ;; +esac + +domid=${vif/vif/} +domid=${domid/.*/} +# metric must be possitive, but prefer later interface +# 32752 is max XID aka domid +metric=$[ 32752 - $domid ] + +if [ "${ip}" ] ; then + # If we've been given a list of IP addresses, then add routes from dom0 to + # the guest using those addresses. + for addr in ${ip} ; do + ${cmdprefix} ip route ${ipcmd} ${addr} dev ${vif} metric $metric + done + echo -e "*raw\n$iptables_cmd -i ${vif} ! -s ${ip} -j DROP\nCOMMIT" | \ + ${cmdprefix} flock $lockfile iptables-restore --noflush + ${cmdprefix} ip addr ${ipcmd} ${back_ip}/32 dev ${vif} +fi + +log debug "Successful vif-route-qubes-nat $command for $vif." +if [ "$command" = "online" ] +then + # disable tx checksumming offload, apparently it doesn't work with our ancient qemu in stubdom + do_without_error ethtool -K $vif tx off + success +fi diff --git a/rpm_spec/core-vm.spec b/rpm_spec/core-vm.spec index 21a968f..bc6106e 100644 --- a/rpm_spec/core-vm.spec +++ b/rpm_spec/core-vm.spec @@ -367,6 +367,8 @@ rm -f %{name}-%{version} %config(noreplace) /etc/udev/rules.d/99-qubes-network.rules /etc/xdg/autostart/00-qubes-show-hide-nm-applet.desktop /etc/xen/scripts/vif-route-qubes +/etc/xen/scripts/vif-route-qubes-nat +/etc/xen/scripts/vif-qubes-nat.sh %config(noreplace) /etc/yum.conf.d/qubes-proxy.conf %config(noreplace) /etc/yum.repos.d/qubes-r3.repo /etc/yum/pluginconf.d/yum-qubes-hooks.conf