Skip to content

Instantly share code, notes, and snippets.

@jpouellet
Last active February 1, 2024 12:50
Show Gist options
  • Save jpouellet/d8cd0eb8589a5b9bf0c53a28fc530369 to your computer and use it in GitHub Desktop.
Save jpouellet/d8cd0eb8589a5b9bf0c53a28fc530369 to your computer and use it in GitHub Desktop.
Forwards a specified port to a specified VM, auto-detecting its NetVM chain. (Qubes OS)
#!/bin/sh
# Inspired by https://gist.github.com/daktak/f887352d564b54f9e529404cc0eb60d5
ip() { qvm-ls --raw-data 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")
[ X"$from_ip" = XNone ] && from_ip=
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"
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"
}
input() {
local domain=$1
local port=$2
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"
}
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"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment