Zadání

Cílem je z menu mít relativně rychle dostupné jednotné prostředí s předpřipraveným VPN přístupem k různým zákazníkům.

  • Jedna AppVM work, která drží persistentní konfiguraci v /home/ adresáři.
  • pro každého zákazníka
    • work-zákazníkX disposable pro práci u konkrétního zákazníka
    • vpn-zákazníkX s VPN klientem k zákazníkX

Architektura

[work-zákazník1] ──► [vpn-zákazník1] ──► [sys-firewall] ──► [sys-net]
[work-zákazník2] ──► [vpn-zákazník2] ──► [sys-firewall] ──► [sys-net]

Každý Named DispVM se při startu vytvoří čistý z šablony, má vlastní VPN tunel a po zavření se smaže.


1. Připrav base AppVM jako DispVM šablonu

Máš AppVM (řekněme work), kde máš nainstalované SSH klienty, nástroje atd. Tu nastavíš jako šablonu pro disposable:

# v dom0
qvm-prefs work template_for_dispvms True

AppVM work můžeš normálně používat a pokud budeš potřebovat nové work prostředí s VPN ke konkrétnímu zákazníkovi spustíš odpovídající work disposable.

Networking u work samotné můžeš nastavit na none, pokud budeš používat jen disposable. Síť se řeší až na úrovni Named DispVMs:

qvm-prefs work netvm none

Veškerý software (SSH klient, wireshark, nmap…) instaluješ do TemplateVM, ze které work vychází (např. debian-13). Samotná work AppVM pak slouží jako DispVM šablona — přizpůsobení (dotfiles, SSH config) dáváš do /home/user/ v work.

Nezapomeň, že v disposable se nic persistentně na disk neukládá.


2. Vytvoř VPN ProxyVM pro každého zákazníka

Pro každého zákazníka potřebuješ samostatnou VM, která poběží jako VPN gateway.

# v dom0
qvm-create vpn-zákazník1 --class AppVM --template debian-13 --label orange
qvm-prefs vpn-zákazník1 netvm sys-firewall
qvm-prefs vpn-zákazník1 provides_network True

qvm-create vpn-zákazník2 --class AppVM --template debian-13 --label orange
qvm-prefs vpn-zákazník2 netvm sys-firewall
qvm-prefs vpn-zákazník2 provides_network True

provides_network True je klíčové — díky tomu se VM chová jako ProxyVM a ostatní VM ji můžou použít jako svůj netvm.

Konfigurace VPN uvnitř každé proxy VM

Spusť vpn-zákazník1 a nastav VPN. Příklad s WireGuard:

# uvnitř vpn-zákazník1
sudo nano /rw/config/vpn/wg0.conf
# vlož WireGuard config zákazníka 1

Aby se VPN spustila automaticky při startu, přidej do /rw/config/rc.local:

#!/bin/bash
cp /rw/config/vpn/wg0.conf /etc/wireguard/wg0.conf
systemctl start wg-quick@wg0

# Povolit forwarding (nutné pro ProxyVM funkci)
echo 1 > /proc/sys/net/ipv4/ip_forward
iptables -t nat -A POSTROUTING -o wg0 -j MASQUERADE
iptables -A FORWARD -i eth0 -o wg0 -j ACCEPT
iptables -A FORWARD -i wg0 -o eth0 -m state --state RELATED,ESTABLISHED -j ACCEPT

# Volitelně: blokuj traffic mimo tunel (kill switch)
iptables -A OUTPUT -o wg0 -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT
iptables -A OUTPUT -d 10.137.0.0/16 -j ACCEPT  # Qubes interní síť
iptables -A OUTPUT -p udp --dport 51820 -j ACCEPT  # WG endpoint
iptables -A OUTPUT -j DROP

Pro OpenVPN je postup analogický — místo WireGuard spustíš openvpn --config /rw/config/vpn/client.ovpn --daemon.

Totéž provedeš pro vpn-zákazník2 s konfigurací druhého zákazníka.


3. Vytvoř Named Disposables

# v dom0
qvm-create work-zákazník1 --class DispVM --template work --label green
qvm-prefs work-zákazník1 netvm vpn-zákazník1

qvm-create work-zákazník2 --class DispVM --template work --label blue
qvm-prefs work-zákazník2 netvm vpn-zákazník2

Tím vzniknou pojmenované DispVM, které se zobrazí v App menu a můžeš je spouštět opakovaně, pokaždé čisté, ale vždy s přiřazenou VPN.

Vytvoření skriptem

#!/bin/bash                                                                                                                           
ZAKAZNIK="${1}"

# Kontrola, zda je promenna ZAKAZNIK nastavena                                                                                        
if [ -z "${ZAKAZNIK}" ]; then
    # Pokud neni nastavena, zkontroluj prvni parametr                                                                                 
    if [ $# -eq 0 ] || [ -z "$1" ]; then
        echo "Chyba: Promenna ZAKAZNIK neni nastavena a nebyl poskytnut prvni parametr."
        echo "Zadejte hodnotu pro ZAKAZNIK:"
        read -r ZAKAZNIK
        if [ -z "${ZAKAZNIK}" ]; then
            echo "Chyba: ZAKAZNIK neni zadan. Skript konci."
            exit 1
        fi
    else
        ZAKAZNIK="$1"
    fi
fi

echo "Vytvorim: work-${ZAKAZNIK} jako NamedDispVM.."

qvm-create work-${ZAKAZNIK} --class DispVM --template work --label blue
qvm-prefs work-${ZAKAZNIK} netvm vpn-${ZAKAZNIK}

4. Ověření

# Spusť Named DispVM
qvm-run work-zákazník1 --auto gnome-terminal

# Uvnitř DispVM ověř IP
curl ifconfig.me
# Měla by se zobrazit VPN IP zákazníka 1

Shrnutí struktury

VM Třída NetVM Účel
work AppVM a DispVM šablona none / sys-firewall Šablona s nástroji a dotfiles
vpn-zákazník1 AppVM (provides_network) sys-firewall VPN tunel zákazníka 1
vpn-zákazník2 AppVM (provides_network) sys-firewall VPN tunel zákazníka 2
work-zákazník1 DispVM vpn-zákazník1 Pracovní session zákazník 1
work-zákazník2 DispVM vpn-zákazník2 Pracovní session zákazník 2

Tipy

Přidání dalšího zákazníka je vždy jen 3 příkazy v dom0 — vytvoř VPN proxy, nakonfiguruj VPN uvnitř, vytvoř Named DispVM s příslušným netvm.

SSH klíče — pokud používáš split-GPG/split-SSH, klíče zůstávají ve vault-net a DispVM si je vyžádá přes Qubes RPC. Nemusíš je kopírovat do každé disposable.

Persistentní SSH config/home/user/.ssh/config v work AppVM se propaguje do každého DispVM, takže aliasy, proxy jumpy atd. stačí nastavit jednou.