-
-
Save w1k1n9cc/6143a89464125f642c2247ac744207b0 to your computer and use it in GitHub Desktop.
Qubes-os port forwarding to allow external connections
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/sh | |
# Inspired by https://gist.github.com/daktak/f887352d564b54f9e529404cc0eb60d5 | |
# Inspired by https://gist.github.com/jpouellet/d8cd0eb8589a5b9bf0c53a28fc530369 | |
ip() { qvm-prefs -g -- "$1" ip; } | |
netvm() { qvm-prefs -g -- "$1" netvm; } | |
forward() { | |
local from_domain=$1 | |
local to_domain=$2 | |
local port=$3 | |
local type=$4 | |
local from_ip=$(ip "$from_domain") | |
local to_ip=$(ip "$to_domain") | |
local iface=$(qvm-run -p -u root "$from_domain" "ifconfig \ | |
| grep cast -B 1 --no-group-separator | grep -vE '^(vif|lo)' | grep -oE '^[^: ]+' | head -1") | |
local from_ip=$(qvm-run -p -u root "$from_domain" "hostname -I | cut -d ' ' -f 1") | |
if [ X"$from_ip" = XNone ] ; then local from_ip= ; fi | |
if [[ $3 = "clear" && $4 = "all" ]] | |
then | |
echo "$from_domain: Clearing Port Forwarding from $1 iptables" >&2 | |
qvm-run -p -u root "$from_domain" "iptables-save | grep -v 'PortFwd $1' | iptables-restore" | |
local nft_cmd="nft list table ip qubes-firewall -a | tr -d '\"' | grep 'iifname $iface accept # handle' | awk '{print \$NF}'" | |
local nft_handle=$(qvm-run -p -u root "$from_domain" "$nft_cmd") | |
if [[ $nft_handle =~ ^[0-9]+$ ]] ; then qvm-run -p -u root "$from_domain" "nft delete rule ip qubes-firewall forward handle $nft_handle" ; fi | |
else | |
echo "$from_domain: Forwarding on $iface port $port to $to_domain | |
($from_ip -> $to_ip)" >&2 | |
qvm-run -p -u root "$from_domain" "iptables-save | grep -v 'PortFwd $1>$2:$4$3' | iptables-restore" | |
qvm-run -p -u root "$from_domain" "iptables -t nat -A PREROUTING -i $iface -p $type ${from_ip:+-d} $from_ip --dport $port -j DNAT --to-destination $to_ip \ | |
-m comment --comment 'PortFwd $1>$2:$4$3'" | |
qvm-run -p -u root "$from_domain" "iptables -I FORWARD 2 -i $iface -p $type ${to_ip:+-d} $to_ip --dport $port -m conntrack --ctstate NEW -j ACCEPT \ | |
-m comment --comment 'PortFwd $1>$2:$4$3'" | |
qvm-run -p -u root "$from_domain" "nft add rule ip qubes-firewall forward meta iifname $iface accept" | |
fi | |
} | |
input() { | |
local domain=$1 | |
local port=$2 | |
local type=$3 | |
if [[ $2 = "clear" && $3 = "all" ]] | |
then | |
echo "$domain: Clearing Port Forwarding from $1 iptables" >&2 | |
qvm-run -p -u root "$domain" "iptables-save | grep -v 'PortFwd $1' | iptables-restore" | |
else | |
echo "$domain: Allowing input to port $port" >&2 | |
qvm-run -p -u root "$domain" "iptables-save | grep -v 'PortFwd $1:$3$2' | iptables-restore" | |
qvm-run -p -u root "$domain" "iptables -I INPUT 5 -p $type --dport $port -m conntrack --ctstate NEW -j ACCEPT \ | |
-m comment --comment 'PortFwd $1:$3$2'" | |
fi | |
} | |
recurse_netvms() { | |
local this_dom=$1 | |
local port=$2 | |
local type=$3 | |
local outer_dom=$(netvm "$this_dom") | |
if [[ -n "$outer_dom" && "$outer_dom" != "None" ]]; then | |
forward "$outer_dom" "$this_dom" "$port" "$type" | |
recurse_netvms "$outer_dom" "$port" "$type" | |
fi | |
} | |
usage() { | |
echo "Usage: ${0##*/} <vm> <port> <proto> | <vm> clear all" >&2 | |
exit 1 | |
} | |
[ $# -eq 3 ] || usage | |
input "$1" "$2" "$3" | |
recurse_netvms "$1" "$2" "$3" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment