niccokunzmann / qvm-expose-port

Expose a qubes vm port to the public interfaces of the sys-net vm.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

R4.0 functional code

Rudd-O opened this issue · comments

/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/qvm-port-forward@.service

[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.

If you like, you can create a pull request with this or document some more for people who only read the README.md file.