/usr/local/bin/qvm-port-forward
#!/bin/sh
# Inspired by https://gist.github.com/daktak/f887352d564b54f9e529404cc0eb60d5
ip() { qvm-ls --raw-data --fields ip -- "$1"; }
netvm() { qvm-prefs -g -- "$1" netvm; }
forward() {
local from_domain=$1
local to_domain=$2
local port=$3
local from_ip=$(ip "$from_domain")
local to_ip=$(ip "$to_domain")
iface=$(qvm-run -p -u root "$from_domain" "ifconfig \
| grep -vE '^(vif|lo)' | grep -oE '^[^: ]+' | head -1")
external_ip=$(qvm-run -p -u root "$from_domain" "ifconfig $iface | grep 'inet ' | awk -F ' ' ' { print \$2 }'")
if [ "$external_ip" != "$from_ip" ] ; then from_ip="$external_ip" ; fi
qvm-run -p -u root "$from_domain" "iptables-save" | grep -q -- '--comment "Forward to '$to_domain' port '$port'"' || {
echo "$from_domain: forwarding on $iface port $port to $to_domain ($from_ip -> $to_ip)" >&2
qvm-run -p -u root "$from_domain" "iptables -t nat -A PREROUTING -i $iface -p tcp --dport $port ${from_ip:+-d} $from_ip -j DNAT --to-destination $to_ip -m comment --comment 'Forward to $to_domain port $port'"
qvm-run -p -u root "$from_domain" "iptables -I FORWARD 2 -i $iface ${to_ip:+-d} $to_ip -p tcp --dport $port -m conntrack --ctstate NEW -j ACCEPT -m comment --comment 'Forward to $to_domain port $port'"
}
}
input() {
local domain=$1
local port=$2
qvm-run -p -u root "$domain" "iptables-save" | grep -q -- '--comment "Accept from port '$port'"' || {
echo "$domain: allowing input to port $port" >&2
qvm-run -p -u root "$domain" "iptables -I INPUT 5 -p tcp --dport $port -m conntrack --ctstate NEW -j ACCEPT -m comment --comment 'Accept from port $port'"
}
}
recurse_netvms() {
local this_dom=$1
local port=$2
local outer_dom=$(netvm "$this_dom")
if [ -n "$outer_dom" ]; then
forward "$outer_dom" "$this_dom" "$port"
recurse_netvms "$outer_dom" "$port"
fi
}
usage() {
echo "Usage: ${0##*/} <vm> <port>" >&2
exit 1
}
[ $# -eq 2 ] || usage
input "$1" "$2"
recurse_netvms "$1" "$2"
/etc/systemd/system/[email protected]
[Unit]
Description=Enable port forwarding on %i
After=qubes-vm@%i.service
PartOf=qubes-vm@%i.service
ConditionKernelCommandLine=!qubes.skip_autostart
[Service]
Environment=DISPLAY=:0
# Default forwarded port is 22.
Environment=PORT=22
# Override which PORT to forward.
EnvironmentFile=-/etc/default/qvm-port-forward/%i
ExecStart=/usr/local/bin/qvm-port-forward %i $PORT
Group=qubes
Type=oneshot
RemainAfterExit=true
[Install]
WantedBy=qubes-vm@%i.service
Hope it's useful. This should probably be packaged as an RPM package addon for dom0
.
Pay now to fund the work behind this issue.
Get updates on progress being made.
Maintainer is rewarded once the issue is completed.
You're funding impactful open source efforts
You want to contribute to this effort
You want to get funding like this too