-
-
Save Joeviocoe/6c4dc0c283f6d6c5b1a3f5af8793292b to your computer and use it in GitHub Desktop.
Qubes-os port forwarding to allow external connections
This file contains hidden or 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" |
Dear @Joeviocoe are the changes applied persistent upon next reboot or even beyond that?
Why this double fw thing tho?
nf and ip tables
In case someone wants to test, I improved a little bit the current version (https://gist.github.com/fepitre/941d7161ae1150d90e15f778027e3248), notably by adding option for persistence. I'll do some review again (and from others I hope) and we will probably refactor it a little bit again for putting it in @QubesOS-contrib
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Thanks. I haven't had time to implement these changes but they are good changes to make.
Honestly, I use a new script that is more in line with Qubism (not Picasso). Everything I need for port fowarding is TCP based... so this script is much safer and uses socat over Qubes own RPC. It connects the net-vm directly to the app-vm without the need for either NFT or IPtables on a proxy-vm/firewall.
It requires some 'install' commands outside/prior to the script... but that could be scripted as well.
https://gist.github.com/Joeviocoe/90ec9fd9a0769b4671a8ae9c87584187