2019-06-18 16:07:36 +02:00
|
|
|
#!/bin/bash
|
2011-04-23 02:31:54 +02:00
|
|
|
|
2016-10-22 17:43:16 +02:00
|
|
|
# Source Qubes library.
|
2017-09-30 03:17:14 +02:00
|
|
|
# shellcheck disable=SC1091
|
2016-10-22 17:43:16 +02:00
|
|
|
. /usr/lib/qubes/init/functions
|
2020-11-11 20:00:24 +01:00
|
|
|
set -uo pipefail
|
2015-01-29 01:10:34 +01:00
|
|
|
|
2020-11-10 22:28:53 +01:00
|
|
|
add_host_route () {
|
|
|
|
/sbin/ip -- route replace to unicast "$1" dev "$2" onlink scope host
|
|
|
|
}
|
|
|
|
|
|
|
|
add_default_route () {
|
|
|
|
/sbin/ip -- route replace to unicast default via "$1" dev "$2" onlink
|
|
|
|
}
|
|
|
|
|
2019-06-18 16:07:36 +02:00
|
|
|
configure_network() {
|
2019-06-19 21:03:54 +02:00
|
|
|
local MAC="$1"
|
|
|
|
local INTERFACE="$2"
|
|
|
|
local ip="$3"
|
|
|
|
local ip6="$4"
|
|
|
|
local netmask="$5"
|
|
|
|
local netmask6="$6"
|
|
|
|
local gateway="$7"
|
|
|
|
local gateway6="$8"
|
|
|
|
local primary_dns="$9"
|
|
|
|
local secondary_dns="${10}"
|
2020-11-11 04:09:54 +01:00
|
|
|
local netvm_mac=fe:ff:ff:ff:ff:ff
|
2019-06-18 16:07:36 +02:00
|
|
|
|
|
|
|
/sbin/ifconfig "$INTERFACE" "$ip" netmask "$netmask"
|
2020-11-11 04:09:54 +01:00
|
|
|
/sbin/ip -- neighbour replace to "$gateway" dev "$INTERFACE" \
|
|
|
|
lladdr "$netvm_mac" nud permanent
|
2019-06-18 16:07:36 +02:00
|
|
|
if [ -n "$ip6" ]; then
|
|
|
|
/sbin/ifconfig "$INTERFACE" add "$ip6/$netmask6"
|
2020-11-11 04:09:54 +01:00
|
|
|
/sbin/ip -- neighbour replace to "$gateway6" dev "$INTERFACE" \
|
|
|
|
lladdr "$netvm_mac" nud permanent
|
2019-06-18 16:07:36 +02:00
|
|
|
fi
|
|
|
|
/sbin/ifconfig "$INTERFACE" up
|
2015-04-22 08:04:10 +02:00
|
|
|
|
2019-06-18 16:07:36 +02:00
|
|
|
if [ -n "$gateway" ]; then
|
2020-11-11 04:09:54 +01:00
|
|
|
add_host_route "$gateway" "$INTERFACE"
|
2019-06-18 16:07:36 +02:00
|
|
|
if [ -n "$gateway6" ] && ! echo "$gateway6" | grep -q "^fe80:"; then
|
2020-11-11 04:09:54 +01:00
|
|
|
add_host_route "$gateway6/$netmask6" "$INTERFACE"
|
2019-06-18 16:07:36 +02:00
|
|
|
fi
|
|
|
|
if ! qsvc disable-default-route ; then
|
2020-11-10 22:28:53 +01:00
|
|
|
add_default_route "$gateway" "$INTERFACE"
|
2019-06-18 16:07:36 +02:00
|
|
|
if [ -n "$gateway6" ]; then
|
2020-11-10 22:28:53 +01:00
|
|
|
add_default_route "$gateway6" "$INTERFACE"
|
2019-06-18 16:07:36 +02:00
|
|
|
fi
|
|
|
|
fi
|
|
|
|
fi
|
|
|
|
|
|
|
|
if [ -z "$primary_dns" ] && [ -n "$gateway" ]; then
|
|
|
|
primary_dns="$gateway"
|
|
|
|
fi
|
|
|
|
|
|
|
|
if ! is_protected_file /etc/resolv.conf ; then
|
|
|
|
echo > /etc/resolv.conf
|
|
|
|
if ! qsvc disable-dns-server ; then
|
|
|
|
echo "nameserver $primary_dns" > /etc/resolv.conf
|
|
|
|
echo "nameserver $secondary_dns" >> /etc/resolv.conf
|
|
|
|
fi
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
|
|
|
configure_network_nm() {
|
2019-06-19 21:03:54 +02:00
|
|
|
local MAC="$1"
|
|
|
|
local INTERFACE="$2"
|
|
|
|
local ip="$3"
|
|
|
|
local ip6="$4"
|
|
|
|
local netmask="$5"
|
|
|
|
local netmask6="$6"
|
|
|
|
local gateway="$7"
|
|
|
|
local gateway6="$8"
|
|
|
|
local primary_dns="$9"
|
|
|
|
local secondary_dns="${10}"
|
2019-06-18 16:07:36 +02:00
|
|
|
|
|
|
|
local prefix
|
|
|
|
local prefix6
|
|
|
|
local nm_config
|
|
|
|
local ip4_nm_config
|
|
|
|
local ip6_nm_config
|
|
|
|
local uuid
|
|
|
|
|
|
|
|
prefix="$(get_prefix_from_subnet "$netmask")"
|
|
|
|
prefix6="$netmask6"
|
|
|
|
uuid="de85f79b-8c3d-405f-a652-${MAC//:/}"
|
|
|
|
nm_config="/etc/NetworkManager/system-connections/qubes-uplink-$INTERFACE"
|
|
|
|
cat > "$nm_config" <<__EOF__
|
2014-11-09 05:31:22 +01:00
|
|
|
[802-3-ethernet]
|
|
|
|
duplex=full
|
2015-01-27 00:27:08 +01:00
|
|
|
|
2014-12-22 00:03:37 +01:00
|
|
|
[ethernet]
|
2019-06-18 16:07:36 +02:00
|
|
|
mac-address=$MAC
|
2014-11-09 05:31:22 +01:00
|
|
|
|
|
|
|
[connection]
|
|
|
|
id=VM uplink $INTERFACE
|
2019-06-18 16:07:36 +02:00
|
|
|
uuid=$uuid
|
2014-11-09 05:31:22 +01:00
|
|
|
type=802-3-ethernet
|
2017-12-03 03:27:45 +01:00
|
|
|
__EOF__
|
2019-06-18 16:07:36 +02:00
|
|
|
ip4_nm_config=""
|
|
|
|
ip6_nm_config=""
|
|
|
|
if ! qsvc disable-dns-server ; then
|
|
|
|
ip4_nm_config="${ip4_nm_config}
|
2017-12-03 03:27:45 +01:00
|
|
|
dns=${primary_dns};${secondary_dns}"
|
2019-06-18 16:07:36 +02:00
|
|
|
fi
|
|
|
|
if ! qsvc disable-default-route ; then
|
|
|
|
ip4_nm_config="${ip4_nm_config}
|
|
|
|
addresses1=$ip;$prefix;$gateway"
|
|
|
|
if [ -n "$ip6" ]; then
|
|
|
|
ip6_nm_config="${ip6_nm_config}
|
|
|
|
addresses1=$ip6;$prefix6;$gateway6"
|
|
|
|
fi
|
|
|
|
else
|
|
|
|
ip4_nm_config="${ip4_nm_config}
|
|
|
|
addresses1=$ip;$prefix"
|
|
|
|
if [ -n "$ip6" ]; then
|
|
|
|
ip6_nm_config="${ip6_nm_config}
|
|
|
|
addresses1=$ip6;$prefix6"
|
|
|
|
fi
|
|
|
|
fi
|
|
|
|
if [ -n "$ip4_nm_config" ]; then
|
|
|
|
cat >> "$nm_config" <<__EOF__
|
2014-11-09 05:31:22 +01:00
|
|
|
[ipv4]
|
|
|
|
method=manual
|
|
|
|
may-fail=false
|
2017-12-03 03:27:45 +01:00
|
|
|
$ip4_nm_config
|
|
|
|
__EOF__
|
2019-06-18 16:07:36 +02:00
|
|
|
else
|
|
|
|
cat >> "$nm_config" <<__EOF__
|
2017-12-03 03:27:45 +01:00
|
|
|
[ipv4]
|
|
|
|
method=ignore
|
2014-05-22 01:36:15 +02:00
|
|
|
__EOF__
|
2019-06-18 16:07:36 +02:00
|
|
|
fi
|
2017-12-03 03:27:45 +01:00
|
|
|
|
2019-06-18 16:07:36 +02:00
|
|
|
if [ -n "$ip6_nm_config" ]; then
|
|
|
|
cat >> "$nm_config" <<__EOF__
|
2017-12-03 03:27:45 +01:00
|
|
|
[ipv6]
|
|
|
|
method=manual
|
|
|
|
may-fail=false
|
|
|
|
$ip6_nm_config
|
|
|
|
__EOF__
|
2019-06-18 16:07:36 +02:00
|
|
|
else
|
|
|
|
cat >> "$nm_config" <<__EOF__
|
2017-12-03 03:27:45 +01:00
|
|
|
[ipv6]
|
|
|
|
method=ignore
|
|
|
|
__EOF__
|
2019-06-18 16:07:36 +02:00
|
|
|
fi
|
|
|
|
|
|
|
|
chmod 600 "$nm_config"
|
|
|
|
# reload connection
|
|
|
|
nmcli connection load "$nm_config" || :
|
|
|
|
}
|
|
|
|
|
|
|
|
configure_qubes_ns() {
|
|
|
|
gateway=$(qubesdb-read /qubes-netvm-gateway)
|
|
|
|
#netmask=$(qubesdb-read /qubes-netvm-netmask)
|
|
|
|
primary_dns=$(qubesdb-read /qubes-netvm-primary-dns 2>/dev/null || echo "$gateway")
|
|
|
|
secondary_dns=$(qubesdb-read /qubes-netvm-secondary-dns)
|
|
|
|
echo "NS1=$primary_dns" > /var/run/qubes/qubes-ns
|
|
|
|
echo "NS2=$secondary_dns" >> /var/run/qubes/qubes-ns
|
|
|
|
/usr/lib/qubes/qubes-setup-dnat-to-ns
|
|
|
|
}
|
|
|
|
|
|
|
|
qubes_ip_change_hook() {
|
|
|
|
if [ -x /rw/config/qubes-ip-change-hook ]; then
|
|
|
|
/rw/config/qubes-ip-change-hook
|
|
|
|
fi
|
|
|
|
# XXX: Backward compatibility
|
|
|
|
if [ -x /rw/config/qubes_ip_change_hook ]; then
|
|
|
|
/rw/config/qubes_ip_change_hook
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
|
|
|
have_qubesdb || exit 0
|
|
|
|
|
Move network uplink setup to a separate service
Previously, network uplink (eth0) was configured in two places:
- udev (asynchronously)
- qubes-misc-post.service - at the very end of the boot process
This caused multiple issues:
1. Depending on udev event processing (non-deterministic), network
uplink could be enabled too early, for example before setting up
firewall.
2. Again depending on udev processing, it can be enabled quite late in
the boot process, after network.target is up and services assume
network already configured. This for example causes qubes-firewall to
fail DNS queries.
3. If udev happen try to enable enable networking even earlier, it may
happend before qubesdb-daemon is started, in which case network setup
fill fail. For this case, there was network re-setup in
qubes-misc-post service - much later in the boot.
Fix the above by placing network uplink setup in a dedicated
qubes-network-uplink@${INTERFACE}.service unit ordered after
network-pre.target and pulled in by udev based on vif device existence,
to handle also dynamic network attach/detach.
Then, create qubes-network-uplink.service unit waiting for appropriate
interface-specific unit (if one is expected!) and order it before
network.target.
QubesOS/qubes-issues#5576
2020-11-12 01:37:12 +01:00
|
|
|
ACTION="$1"
|
|
|
|
INTERFACE="$2"
|
|
|
|
|
|
|
|
if [ -z "$INTERFACE" ]; then
|
|
|
|
echo "Missing INTERFACE argument" >&2
|
|
|
|
exit 1
|
|
|
|
fi
|
|
|
|
|
2020-12-03 20:51:49 +01:00
|
|
|
if [ "$ACTION" == "add" ]; then
|
|
|
|
MAC="$(get_mac_from_iface "$INTERFACE")"
|
|
|
|
if [ -n "$MAC" ]; then
|
|
|
|
ip="$(/usr/bin/qubesdb-read "/net-config/$MAC/ip" 2> /dev/null)" || ip=
|
|
|
|
ip6="$(/usr/bin/qubesdb-read "/net-config/$MAC/ip6" 2> /dev/null)" || ip6=
|
|
|
|
netmask="$(/usr/bin/qubesdb-read "/net-config/$MAC/netmask" 2> /dev/null)" || netmask=
|
|
|
|
netmask6="$(/usr/bin/qubesdb-read "/net-config/$MAC/netmask6" 2> /dev/null)" || netmask6=
|
|
|
|
gateway="$(/usr/bin/qubesdb-read "/net-config/$MAC/gateway" 2> /dev/null)" || gateway=
|
|
|
|
gateway6="$(/usr/bin/qubesdb-read "/net-config/$MAC/gateway6" 2> /dev/null)" || gateway6=
|
|
|
|
|
|
|
|
# Handle legacy values
|
|
|
|
LEGACY_MAC="$(/usr/bin/qubesdb-read /qubes-mac 2> /dev/null)" || LEGACY_MAC=
|
|
|
|
if [ "$MAC" == "$LEGACY_MAC" ] || [ -z "$LEGACY_MAC" ]; then
|
|
|
|
if [ -z "$ip" ]; then
|
|
|
|
ip="$(/usr/bin/qubesdb-read /qubes-ip 2> /dev/null)" || ip=
|
2019-05-18 12:19:54 +02:00
|
|
|
fi
|
2020-12-03 20:51:49 +01:00
|
|
|
if [ -z "$ip6" ]; then
|
|
|
|
ip6="$(/usr/bin/qubesdb-read /qubes-ip6 2> /dev/null)" || ip6=
|
|
|
|
fi
|
|
|
|
if [ -z "$gateway" ]; then
|
|
|
|
gateway="$(/usr/bin/qubesdb-read /qubes-gateway 2> /dev/null)" || gateway=
|
2017-12-03 03:27:45 +01:00
|
|
|
fi
|
2020-12-03 20:51:49 +01:00
|
|
|
if [ -z "$gateway6" ]; then
|
|
|
|
gateway6="$(/usr/bin/qubesdb-read /qubes-gateway6 2> /dev/null)" || gateway6=
|
2019-05-18 12:19:54 +02:00
|
|
|
fi
|
2020-12-03 20:51:49 +01:00
|
|
|
fi
|
2019-06-18 16:07:36 +02:00
|
|
|
|
2020-12-03 20:51:49 +01:00
|
|
|
if [ -z "$netmask" ]; then
|
|
|
|
netmask="255.255.255.255"
|
|
|
|
fi
|
|
|
|
if [ -z "$netmask6" ]; then
|
|
|
|
netmask6="128"
|
|
|
|
fi
|
2019-06-18 16:07:36 +02:00
|
|
|
|
2020-12-03 20:51:49 +01:00
|
|
|
primary_dns=$(/usr/bin/qubesdb-read /qubes-primary-dns 2>/dev/null) || primary_dns=
|
|
|
|
secondary_dns=$(/usr/bin/qubesdb-read /qubes-secondary-dns 2>/dev/null) || secondary_dns=
|
2019-06-18 16:07:36 +02:00
|
|
|
|
2020-12-03 20:51:49 +01:00
|
|
|
if [ -n "$ip" ]; then
|
|
|
|
/sbin/ethtool -K "$INTERFACE" sg off
|
|
|
|
/sbin/ethtool -K "$INTERFACE" tx off
|
|
|
|
|
|
|
|
# If NetworkManager is enabled, let it configure the network
|
|
|
|
if qsvc network-manager && [ -e /usr/bin/nmcli ]; then
|
|
|
|
configure_network_nm "$MAC" "$INTERFACE" "$ip" "$ip6" "$netmask" "$netmask6" "$gateway" "$gateway6" "$primary_dns" "$secondary_dns"
|
|
|
|
else
|
|
|
|
configure_network "$MAC" "$INTERFACE" "$ip" "$ip6" "$netmask" "$netmask6" "$gateway" "$gateway6" "$primary_dns" "$secondary_dns"
|
|
|
|
fi
|
2019-06-18 16:07:36 +02:00
|
|
|
|
2020-12-03 20:51:49 +01:00
|
|
|
network=$(qubesdb-read /qubes-netvm-network 2>/dev/null) || network=
|
|
|
|
if [ -n "$network" ]; then
|
|
|
|
if ! qsvc disable-dns-server; then
|
|
|
|
configure_qubes_ns
|
2019-05-18 12:19:54 +02:00
|
|
|
fi
|
2020-12-03 20:51:49 +01:00
|
|
|
qubes_ip_change_hook
|
2015-11-13 04:26:23 +01:00
|
|
|
fi
|
|
|
|
fi
|
2014-12-22 00:04:16 +01:00
|
|
|
fi
|
2020-12-03 20:51:49 +01:00
|
|
|
elif [ "$ACTION" == "remove" ]; then
|
|
|
|
# make sure network is disabled, especially on shutdown, to prevent
|
|
|
|
# leaks when firewall will get stopped too
|
|
|
|
ip link set "$INTERFACE" down 2>/dev/null || :
|
Move network uplink setup to a separate service
Previously, network uplink (eth0) was configured in two places:
- udev (asynchronously)
- qubes-misc-post.service - at the very end of the boot process
This caused multiple issues:
1. Depending on udev event processing (non-deterministic), network
uplink could be enabled too early, for example before setting up
firewall.
2. Again depending on udev processing, it can be enabled quite late in
the boot process, after network.target is up and services assume
network already configured. This for example causes qubes-firewall to
fail DNS queries.
3. If udev happen try to enable enable networking even earlier, it may
happend before qubesdb-daemon is started, in which case network setup
fill fail. For this case, there was network re-setup in
qubes-misc-post service - much later in the boot.
Fix the above by placing network uplink setup in a dedicated
qubes-network-uplink@${INTERFACE}.service unit ordered after
network-pre.target and pulled in by udev based on vif device existence,
to handle also dynamic network attach/detach.
Then, create qubes-network-uplink.service unit waiting for appropriate
interface-specific unit (if one is expected!) and order it before
network.target.
QubesOS/qubes-issues#5576
2020-11-12 01:37:12 +01:00
|
|
|
|
2020-12-03 20:51:49 +01:00
|
|
|
# If exists, we delete NetworkManager configuration file to prevent duplicate entries
|
|
|
|
nm_config="/etc/NetworkManager/system-connections/qubes-uplink-$INTERFACE"
|
|
|
|
rm -rf "$nm_config"
|
|
|
|
else
|
|
|
|
echo "Invalid action '$ACTION'" >&2
|
|
|
|
exit 1
|
2019-05-21 17:32:05 +02:00
|
|
|
fi
|