network: configure IPv6 when enabled

If dom0 expose IPv6 address settings, configure it on the interface.
Both backend and frontend side. If no IPv6 configuration is provided,
block IPv6 as it was before.

Fixes QubesOS/qubes-issues#718
This commit is contained in:
Marek Marczykowski-Górecki 2017-12-03 03:27:45 +01:00
parent aab5a28fbe
commit 44f8cceb38
No known key found for this signature in database
GPG Key ID: 063938BA42CFA724
2 changed files with 77 additions and 15 deletions

View File

@ -7,9 +7,11 @@
have_qubesdb || exit 0 have_qubesdb || exit 0
ip=$(/usr/bin/qubesdb-read /qubes-ip 2> /dev/null) ip=$(/usr/bin/qubesdb-read /qubes-ip 2> /dev/null)
ip6=$(/usr/bin/qubesdb-read /qubes-ip6 2> /dev/null)
if [ "x$ip" != x ]; then if [ "x$ip" != x ]; then
#netmask=$(/usr/bin/qubesdb-read /qubes-netmask) #netmask=$(/usr/bin/qubesdb-read /qubes-netmask)
gateway=$(/usr/bin/qubesdb-read /qubes-gateway) gateway=$(/usr/bin/qubesdb-read /qubes-gateway)
gateway6=$(/usr/bin/qubesdb-read /qubes-gateway6)
primary_dns=$(/usr/bin/qubesdb-read /qubes-primary-dns 2>/dev/null || echo "$gateway") primary_dns=$(/usr/bin/qubesdb-read /qubes-primary-dns 2>/dev/null || echo "$gateway")
secondary_dns=$(/usr/bin/qubesdb-read /qubes-secondary-dns) secondary_dns=$(/usr/bin/qubesdb-read /qubes-secondary-dns)
/sbin/ethtool -K "$INTERFACE" sg off /sbin/ethtool -K "$INTERFACE" sg off
@ -28,32 +30,72 @@ mac-address=$(ip l show dev "$INTERFACE" |grep link|awk '{print $2}')
id=VM uplink $INTERFACE id=VM uplink $INTERFACE
uuid=de85f79b-8c3d-405f-a652-cb4c10b4f9ef uuid=de85f79b-8c3d-405f-a652-cb4c10b4f9ef
type=802-3-ethernet type=802-3-ethernet
__EOF__
[ipv6] ip4_nm_config=""
method=ignore ip6_nm_config=""
if ! qsvc disable-dns-server ; then
ip4_nm_config="${ip4_nm_config}
dns=${primary_dns};${secondary_dns}"
fi
if ! qsvc disable-default-route ; then
ip4_nm_config="${ip4_nm_config}
addresses1=$ip;32;$gateway"
if [ -n "$ip6" ]; then
ip6_nm_config="${ip6_nm_config}
addresses1=$ip6;128;$gateway6"
fi
else
ip4_nm_config="${ip4_nm_config}
addresses1=$ip;32"
if [ -n "$ip6" ]; then
ip6_nm_config="${ip6_nm_config}
addresses1=$ip6;128"
fi
fi
if [ -n "$ip4_nm_config" ]; then
cat >> "$nm_config" <<__EOF__
[ipv4] [ipv4]
method=manual method=manual
may-fail=false may-fail=false
$ip4_nm_config
__EOF__ __EOF__
if ! qsvc disable-dns-server ; then
echo "dns=$primary_dns;$secondary_dns" >> "$nm_config"
fi
if ! qsvc disable-default-route ; then
echo "addresses1=$ip;32;$gateway" >> "$nm_config"
else else
echo "addresses1=$ip;32" >> "$nm_config" cat >> "$nm_config" <<__EOF__
[ipv4]
method=ignore
__EOF__
fi fi
if [ -n "$ip6_nm_config" ]; then
cat >> "$nm_config" <<__EOF__
[ipv6]
method=manual
may-fail=false
$ip6_nm_config
__EOF__
else
cat >> "$nm_config" <<__EOF__
[ipv6]
method=ignore
__EOF__
fi
chmod 600 "$nm_config" chmod 600 "$nm_config"
# reload connection # reload connection
nmcli connection load "$nm_config" || : nmcli connection load "$nm_config" || :
else else
# No NetworkManager enabled, configure the network manually # No NetworkManager enabled, configure the network manually
/sbin/ifconfig "$INTERFACE" "$ip" netmask 255.255.255.255 /sbin/ifconfig "$INTERFACE" "$ip" netmask 255.255.255.255
if [ -n "$ip6" ]; then
/sbin/ifconfig "$INTERFACE" add "$ip6"/128
fi
/sbin/ifconfig "$INTERFACE" up /sbin/ifconfig "$INTERFACE" up
/sbin/route add -host "$gateway" dev "$INTERFACE" /sbin/route add -host "$gateway" dev "$INTERFACE"
if ! qsvc disable-default-route ; then if ! qsvc disable-default-route ; then
/sbin/route add default gw "$gateway" /sbin/route add default gw "$gateway"
if [ -n "$gateway6" ]; then
/sbin/route -6 add default gw "$gateway6" dev "$INTERFACE"
fi
fi fi
if ! is_protected_file /etc/resolv.conf ; then if ! is_protected_file /etc/resolv.conf ; then
echo > /etc/resolv.conf echo > /etc/resolv.conf

View File

@ -29,8 +29,16 @@ lockfile=/var/run/xen-hotplug/vif-lock
# shellcheck disable=SC2154 # shellcheck disable=SC2154
if [ "${ip}" ]; then if [ "${ip}" ]; then
# get first IPv4 and first IPv6
for addr in ${ip}; do
if [ -z "$ip4" ] && [[ "$addr" = *.* ]]; then
ip4="$addr"
elif [ -z "$ip6" ] && [[ "$addr" = *:* ]]; then
ip6="$addr"
fi
done
# IPs as seen by this VM # IPs as seen by this VM
netvm_ip="$ip" netvm_ip="$ip4"
netvm_gw_ip=$(qubesdb-read /qubes-netvm-gateway) netvm_gw_ip=$(qubesdb-read /qubes-netvm-gateway)
netvm_dns1_ip=$(qubesdb-read /qubes-netvm-primary-dns) netvm_dns1_ip=$(qubesdb-read /qubes-netvm-primary-dns)
netvm_dns2_ip=$(qubesdb-read /qubes-netvm-secondary-dns) netvm_dns2_ip=$(qubesdb-read /qubes-netvm-secondary-dns)
@ -38,12 +46,14 @@ if [ "${ip}" ]; then
back_ip="$netvm_gw_ip" back_ip="$netvm_gw_ip"
# IPs as seen by the VM - if other than $netvm_ip # IPs as seen by the VM - if other than $netvm_ip
appvm_gw_ip="$(qubesdb-read "/mapped-ip/$ip/visible-gateway" 2>/dev/null || :)" appvm_gw_ip="$(qubesdb-read "/mapped-ip/$ip4/visible-gateway" 2>/dev/null || :)"
appvm_ip="$(qubesdb-read "/mapped-ip/$ip/visible-ip" 2>/dev/null || :)" appvm_ip="$(qubesdb-read "/mapped-ip/$ip4/visible-ip" 2>/dev/null || :)"
fi fi
# Apply NAT if IP visible from the VM is different than the "real" one # Apply NAT if IP visible from the VM is different than the "real" one
# See vif-qubes-nat.sh for details # See vif-qubes-nat.sh for details
# XXX: supported only for the first IPv4 address, IPv6 is dropped if this
# feature is enabled
if [ -n "$appvm_ip" ] && [ -n "$appvm_gw_ip" ] && [ "$appvm_ip" != "$netvm_ip" ]; then if [ -n "$appvm_ip" ] && [ -n "$appvm_gw_ip" ] && [ "$appvm_ip" != "$netvm_ip" ]; then
# shellcheck disable=SC2154 # shellcheck disable=SC2154
if test "$command" == online; then if test "$command" == online; then
@ -83,9 +93,19 @@ if [ "${ip}" ] ; then
# the guest using those addresses. # the guest using those addresses.
for addr in ${ip} ; do for addr in ${ip} ; do
${cmdprefix} ip route "${ipcmd}" "${addr}" dev "${vif}" metric "$metric" ${cmdprefix} ip route "${ipcmd}" "${addr}" dev "${vif}" metric "$metric"
if [[ "$addr" = *:* ]]; then
ipt=ip6tables-restore
else
ipt=iptables-restore
fi
echo -e "*raw\n$iptables_cmd -i ${vif} ! -s ${addr} -j DROP\nCOMMIT" | \
${cmdprefix} flock $lockfile $ipt --noflush
done done
echo -e "*raw\n$iptables_cmd -i ${vif} ! -s ${ip} -j DROP\nCOMMIT" | \ # if no IPv6 is assigned, block all IPv6 traffic on that interface
${cmdprefix} flock $lockfile iptables-restore --noflush if ! [[ "$ip" = *:* ]]; then
echo -e "*raw\n$iptables_cmd -i ${vif} -j DROP\nCOMMIT" | \
${cmdprefix} flock $lockfile ip6tables-restore --noflush
fi
${cmdprefix} ip addr "${ipcmd}" "${back_ip}/32" dev "${vif}" ${cmdprefix} ip addr "${ipcmd}" "${back_ip}/32" dev "${vif}"
fi fi