BETA RELEASE
Waiting for the Linux Gurus review. Looks good but not fully tested.
Features
- Killswitch-like protection when VPN is down
- VPN-only connectivity for all traffic
- DNS leak protection via namespace isolation
- AppVM DNS NAT compatibility
- IPv6 disabled
Usage
- Transfer the script from appvm to dom0 with:
[user@dom0 ~]$ qvm-run -p appvm 'cat ~/wireguard-namespace-qube.sh' > ~/wireguard-namespace-qube.sh - Place your WireGuard config to the desired folder:
[user@dom0 ~]$ mkdir -p wireguard
[user@dom0 ~]$ qvm-run -p appvm 'cat ~/wg0.conf' > ~/wireguard/wg0.conf - Make the script executable with:
[user@dom0 ~]$ chmod +x ~/wireguard-namespace-qube.sh - Run the script with:
[user@dom0 ~]$ bash ~/wireguard-namespace-qube.sh - Usage diagram:
sys-net ↔ sys-firewall ↔ sys-vpn ↔ appvms - Set the VPN target:
[user@dom0 ~]$ qvm-prefs appvm netvm sys-vpn - Start the VPN service:
[user@dom0 ~]$ qvm-start sys-vpn - Start the VPN target, e. g.:
[user@dom0 ~]$ qvm-run -q -a --service -- work qubes.StartApp+org.mozilla.firefox
NOTE: To create other services with different WireGuard configs, update the WG_CONFIG_NAME and VPN_SERVICE variables at the beginning of the script and rerun it.
wireguard-namespace-qube.sh
#!/bin/bash
################################################################################
# File Name : wireguard-namespace-qube.sh
# Description : WireGuard VPN setup for Qubes OS that routes all internet
# traffic through the wg0 interface using network namespace
# isolation to prevent IP and DNS leaks. Below set the desired
# values for your variables, note that you can rerun the
# script to create other VPN services.
# Usage : • Transfer this script from appvm to dom0 with:
# [user@dom0 ~]$ qvm-run -p appvm 'cat ~/wireguard-namespace-qube.sh' > ~/wireguard-namespace-qube.sh
# • Place your WireGuard config to the desired folder:
# [user@dom0 ~]$ mkdir -p wireguard
# [user@dom0 ~]$ qvm-run -p appvm 'cat ~/wg0.conf' > ~/wireguard/wg0.conf
# • Make the script executable with:
# [user@dom0 ~]$ chmod +x ~/wireguard-namespace-qube.sh
# • Run the script with:
# [user@dom0 ~]$ bash ~/wireguard-namespace-qube.sh
# Author : Me and the bois
# License : Free of charge, no warranty
# Last edited : 2025-10-28
################################################################################
# Safety first
set -euo pipefail
# Configuration (set default values here)
WG_CONFIG_NAME="wg0.conf"
VPN_SERVICE="sys-vpn"
WG_CONFIG_SOURCE="/home/user/wireguard"
BASE_TEMPLATE="debian-12-minimal"
CUSTOM_TEMPLATE="debian-vpn-template"
# Step 1: Verify and create base template
create_base_template() {
echo -e "\nStep 1: Verifying and creating: $BASE_TEMPLATE..."
if ! qvm-check "$BASE_TEMPLATE"; then
echo -e "\nInstalling $BASE_TEMPLATE..."
sudo qubes-dom0-update "qubes-template-$BASE_TEMPLATE"
fi
# Ensure template is shut down
qvm-shutdown --wait "$BASE_TEMPLATE" 2>/dev/null || true
if qvm-check "$BASE_TEMPLATE"; then
echo -e "\nUpdating $BASE_TEMPLATE..."
sudo qubesctl --show-output --skip-dom0 --targets="$BASE_TEMPLATE" state.sls update.qubes-vm
fi
echo -e "\nBase template setup complete"
}
# Step 2: Create custom template
create_custom_template() {
echo -e "\nStep 2: Creating $CUSTOM_TEMPLATE..."
if qvm-check "$CUSTOM_TEMPLATE"; then
echo -e "\n$CUSTOM_TEMPLATE already exists"
echo -e "\nContinuing to $VPN_SERVICE creation..."
else
echo -e "\nCreating $CUSTOM_TEMPLATE by cloning from $BASE_TEMPLATE..."
qvm-clone "$BASE_TEMPLATE" "$CUSTOM_TEMPLATE"
qvm-prefs "$CUSTOM_TEMPLATE" label orange
}
# Step 3: Verify and create custom template with packages (change as needed)
install_packages() {
echo -e "\nStep 3: Configuring environment and installing packages in $CUSTOM_TEMPLATE..."
qvm-start --skip-if-running "$CUSTOM_TEMPLATE"
qvm-run -p -u root "$CUSTOM_TEMPLATE" "echo 'TERM=xterm' >> /etc/environment"
qvm-run -p -u root "$CUSTOM_TEMPLATE" "sed -i 's/^# *\(en_US.UTF-8\)/\1/' /etc/locale.gen"
qvm-run -p -u root "$CUSTOM_TEMPLATE" "locale-gen en_US.UTF-8"
qvm-run -p -u root "$CUSTOM_TEMPLATE" "
apt install -y --no-install-recommends \
qubes-core-agent-passwordless-root \
qubes-core-agent-networking \
wireguard-tools \
nftables \
iproute2 \
dnsutils \
less \
psmisc \
xfce4-terminal"
echo -e "\n$CUSTOM_TEMPLATE configured successfully"
fi
qvm-shutdown --wait "$CUSTOM_TEMPLATE" 2>/dev/null || true
}
# Step 3: Create qube service
create_vpn_qube() {
echo -e "\nStep 3: Verifying and creating qube service: $VPN_SERVICE..."
if qvm-check "$VPN_SERVICE"; then
echo -e "\n$VPN_SERVICE already exists"
echo -e "\nExiting"
exit 1
else
echo -e "\nCreating $VPN_SERVICE..."
qvm-create \
--class AppVM \
--template "$CUSTOM_TEMPLATE" \
--label orange \
--property netvm=sys-firewall \
--property provides_network=True \
--property vcpus=1 \
--property memory=300 \
--property maxmem=400 \
--property autostart=False \
--property include_in_backups=False \
"$VPN_SERVICE"
echo -e "\nDisabling IPv6 in $VPN_SERVICE"
qvm-features "$VPN_SERVICE" ipv6 ''
echo -e "\nEnabling qubes-firewall service in $VPN_SERVICE"
qvm-service "$VPN_SERVICE" qubes-firewall on
echo -e "\nStarting $VPN_SERVICE to apply configuration..."
qvm-start "$VPN_SERVICE"
echo -e "\n$VPN_SERVICE created and configured"
fi
}
# Step 4: Comment out to configure via ip commands instead of wg-quick
comment_wg_config() {
echo -e "\nStep 4: Commenting out Address, DNS, and MTU in WireGuard config..."
local temp_config=$(mktemp)
cp "$WG_CONFIG_SOURCE/$WG_CONFIG_NAME" "$temp_config"
# Comment out the lines
sed -i 's/^Address/#Address/g' "$temp_config"
sed -i 's/^DNS/#DNS/g' "$temp_config"
sed -i 's/^MTU/#MTU/g' "$temp_config"
# Overwrite the original
mv "$temp_config" "$WG_CONFIG_SOURCE/$WG_CONFIG_NAME"
echo "WireGuard config automatically commented to configure via ip commands"
}
# Step 5: Copy the configuration file from dom0 to the VPN service qube
transfer_config() {
echo -e "\nStep 5: Transferring WireGuard configuration to the VPN service qube..."
if [[ ! -f "$WG_CONFIG_SOURCE/$WG_CONFIG_NAME" ]]; then
echo -e "\nError: Config file not found at $WG_CONFIG_SOURCE/$WG_CONFIG_NAME"
return 1
fi
echo -e "\nCopying..."
qvm-copy-to-vm "$VPN_SERVICE" "$WG_CONFIG_SOURCE/$WG_CONFIG_NAME"
sleep 2
qvm-run -p -u root "$VPN_SERVICE" "mkdir -p /rw/config"
qvm-run -p -u root "$VPN_SERVICE" "mkdir -p /rw/config/vpn"
qvm-run -p -u root "$VPN_SERVICE" "mv '/home/user/QubesIncoming/dom0/$WG_CONFIG_NAME' '/rw/config/vpn/'"
qvm-run -p -u root "$VPN_SERVICE" "chmod 600 '/rw/config/vpn/$WG_CONFIG_NAME'"
echo -e "\nConfig file moved to: /rw/config/vpn/$WG_CONFIG_NAME"
}
# Create WireGuard namespace setup script
create_wireguard_setup_script() {
echo -e "\nCreating WireGuard namespace setup script..."
local temp_script=$(mktemp)
cat > "$temp_script" << 'EOF'
#!/bin/bash
set -euo pipefail
echo -e "\nStarting WireGuard namespace setup"
sleep 5
# The WG_CONFIG_NAME variable must be passed via export from the main script
if [ -z "$WG_CONFIG_NAME" ]; then
echo "Error: WG_CONFIG_NAME environment variable not set"
echo "This script must be called with: export WG_CONFIG_NAME='wg0.conf'; /rw/config/setup-wireguard-namespace.sh"
exit 1
fi
INTERFACE="eth0"
echo -e "\nUsing interface: $INTERFACE"
# Get network configuration
PHYSICAL_IP=$(ip -4 addr show "$INTERFACE" | grep -oP "(?<=inet\s)\d+(\.\d+){3}/\d+")
PHYSICAL_ROUTE=$(ip route | grep default | awk '{print $3}')
WG_CONFIG="/rw/config/vpn/$WG_CONFIG_NAME"
# Extract WireGuard IP
WG_IP=$(grep -E "^(#)?Address" "$WG_CONFIG" | head -n1 | cut -d"=" -f2 | cut -d"/" -f1 | tr -d " ")
if [ -z "$WG_IP" ]; then
echo "Error: No Address found in WireGuard config"
exit 1
fi
WG_IP="${WG_IP}/32"
echo -e "\nUsing WG_IP: $WG_IP"
# Extract DNS for endpoint resolution
DNS_LINE=$(grep -E "^(#\s*)?DNS" "$WG_CONFIG" | head -1)
if [ -n "$DNS_LINE" ]; then
CLEAN_DNS_LINE=$(echo "$DNS_LINE" | sed -E "s/^#\s*//")
DNS_SERVERS=$(echo "$CLEAN_DNS_LINE" | cut -d= -f2 | sed "s/^[[:space:]]*//;s/[[:space:]]*\$//" | tr "," " ")
WG_DNS=$(echo "$DNS_SERVERS" | cut -d" " -f1)
echo -e "\nUsing DNS from WireGuard config for resolution: $DNS_SERVERS"
else
WG_DNS="9.9.9.9"
echo -e "\nUsing fallback DNS for resolution: $WG_DNS"
fi
# Extract endpoint
ENDPOINT=$(grep "^Endpoint" "$WG_CONFIG" | cut -d"=" -f2 | tr -d " " | cut -d: -f1)
PORT=$(grep "^Endpoint" "$WG_CONFIG" | cut -d"=" -f2 | tr -d " " | cut -d: -f2)
RESOLVED_IP=""
if [ -n "$ENDPOINT" ]; then
echo -e "\nResolving endpoint: $ENDPOINT"
for dns_server in $WG_DNS 10.139.1.1 9.9.9.9; do
IP=$(dig +short +time=2 +tries=2 "$ENDPOINT" "@$dns_server" 2>/dev/null | grep -E "^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+\$" | head -1)
if [ -n "$IP" ] && [ "$IP" != "127.0.0.1" ]; then
echo -e "\nResolved $ENDPOINT to $IP using DNS $dns_server"
RESOLVED_IP="$IP"
break
fi
done
fi
if [ -z "$RESOLVED_IP" ]; then
echo -e "\nError: Could not resolve endpoint $ENDPOINT"
exit 1
fi
echo -e "\nSetting up network namespace..."
# Clean up any existing namespace
ip netns delete physical 2>/dev/null || true
# Create namespace and move interface
ip netns add physical
ip link set "$INTERFACE" netns physical
ip -n physical link add wg0 type wireguard
ip -n physical link set wg0 netns 1
# Reconfigure physical interface in namespace
ip -n physical addr add "$PHYSICAL_IP" dev "$INTERFACE"
ip -n physical link set "$INTERFACE" up
ip -n physical route add default via "$PHYSICAL_ROUTE" dev "$INTERFACE" onlink
# Create temporary config with resolved IP
cp "$WG_CONFIG" /tmp/wg-config-temp.conf
sed -i "s/$ENDPOINT:[0-9]*/$RESOLVED_IP:$PORT/g" /tmp/wg-config-temp.conf
# Configure WireGuard (remove conflicting lines)
sed -i "/^Address/d;/^DNS/d;/^MTU/d" /tmp/wg-config-temp.conf
wg setconf wg0 /tmp/wg-config-temp.conf
rm -f /tmp/wg-config-temp.conf
ip addr add "$WG_IP" dev wg0
ip link set wg0 up
# Set up routing - all traffic through WireGuard
ip route del default 2>/dev/null || true
ip route add default dev wg0
echo -e "\nWireGuard namespace setup complete - all traffic routed through VPN"
EOF
qvm-copy-to-vm "$VPN_SERVICE" "$temp_script"
qvm-run -p -u root "$VPN_SERVICE" "mv '/home/user/QubesIncoming/dom0/$(basename $temp_script)' '/rw/config/setup-wireguard-namespace.sh'"
qvm-run -p -u root "$VPN_SERVICE" "chown root:root '/rw/config/setup-wireguard-namespace.sh'"
qvm-run -p -u root "$VPN_SERVICE" "chmod 755 '/rw/config/setup-wireguard-namespace.sh'"
rm -f "$temp_script"
echo "WireGuard namespace setup script created successfully"
}
# Create NFTables generator script that uses exported variables
create_nftables_generator_script() {
echo -e "\nCreating NFTables generator script..."
local temp_script=$(mktemp)
cat > "$temp_script" << 'EOF'
#!/bin/bash
set -e
echo "Generating NFTables configuration..."
# The WG_CONFIG_NAME variable must be passed via export
if [ -z "$WG_CONFIG_NAME" ]; then
echo "Error: WG_CONFIG_NAME environment variable not set"
exit 1
fi
WG_CONFIG="/rw/config/vpn/$WG_CONFIG_NAME"
# Check if config file exists
if [ ! -f "$WG_CONFIG" ]; then
echo "Error: WireGuard config file not found at $WG_CONFIG"
exit 1
fi
# Get physical IP for virtualif (same as PHYSICAL_IP from setup script)
VIRTUALIF=$(ip -4 addr show eth0 | grep -oP "(?<=inet\s)\d+(\.\d+){3}/\d+" | head -1)
if [ -z "$VIRTUALIF" ]; then
echo "Error: Could not determine physical IP"
exit 1
fi
# Extract DNS servers from WireGuard config
DNS_LINE=$(grep -E "^(#\s*)?DNS" "$WG_CONFIG" | head -1)
if [ -n "$DNS_LINE" ]; then
CLEAN_DNS_LINE=$(echo "$DNS_LINE" | sed -E "s/^#\s*//")
VPNDNS1=$(echo "$CLEAN_DNS_LINE" | cut -d'=' -f2 | sed 's/^[[:space:]]*//;s/[[:space:]]*$//' | tr ',' ' ' | awk '{print $1}')
else
echo "Error: No DNS found in WireGuard config"
exit 1
fi
echo "Using physical IP: $VIRTUALIF"
echo "Using VPN DNS: $VPNDNS1"
# Generate nftables config file
cat > /rw/config/nftables.conf << NFTEOF
#!/usr/sbin/nft -f
# Set variables
define virtualif = $VIRTUALIF
define vpndns1 = $VPNDNS1
# Flush existing rules in qubes dnat-dns chain
flush chain qubes dnat-dns
# Table for NAT and vpn-dns-redirect chain
table ip nat {
chain vpn-dns-redirect {
type nat hook prerouting priority -100; policy accept;
ip daddr 10.139.1.1 udp dport 53 dnat to \$vpndns1
ip daddr 10.139.1.1 tcp dport 53 dnat to \$vpndns1
}
}
# Mangle table (for MSS clamping)
table ip mangle {
chain forward {
type filter hook forward priority 0; policy accept;
tcp flags syn tcp option maxseg size set rt mtu;
}
}
NFTEOF
echo "NFTables configuration generated successfully at /rw/config/nftables.conf"
EOF
qvm-copy-to-vm "$VPN_SERVICE" "$temp_script"
qvm-run -p -u root "$VPN_SERVICE" "mv '/home/user/QubesIncoming/dom0/$(basename $temp_script)' '/rw/config/nftables-generator.sh'"
qvm-run -p -u root "$VPN_SERVICE" "chown root:root '/rw/config/nftables-generator.sh'"
qvm-run -p -u root "$VPN_SERVICE" "chmod 755 '/rw/config/nftables-generator.sh'"
rm -f "$temp_script"
echo "NFTables generator script created successfully"
}
# Create main startup script that uses exported variables
create_main_startup_script() {
echo -e "\nCreating main startup script..."
local temp_script=$(mktemp)
cat > "$temp_script" << 'EOF'
#!/bin/bash
set -e
echo "Starting WireGuard VPN setup..."
# Check if WG_CONFIG_NAME is set in environment
if [ -z "$WG_CONFIG_NAME" ]; then
echo "Error: WG_CONFIG_NAME environment variable not set"
echo "This script must be called with: export WG_CONFIG_NAME='wg0.conf'; /rw/config/start-wireguard.sh"
exit 1
fi
echo "Using WireGuard config: $WG_CONFIG_NAME"
# Generate NFTables configuration
echo "Generating NFTables DNS configuration..."
/rw/config/nftables-generator.sh
# Apply NFTables config
echo "Applying DNS redirection rules..."
nft -f /rw/config/nftables.conf
# Setup WireGuard namespace
echo "Setting up WireGuard namespace..."
/rw/config/setup-wireguard-namespace.sh
echo "WireGuard VPN setup completed"
EOF
qvm-copy-to-vm "$VPN_SERVICE" "$temp_script"
qvm-run -p -u root "$VPN_SERVICE" "mv '/home/user/QubesIncoming/dom0/$(basename $temp_script)' '/rw/config/start-wireguard.sh'"
qvm-run -p -u root "$VPN_SERVICE" "chown root:root '/rw/config/start-wireguard.sh'"
qvm-run -p -u root "$VPN_SERVICE" "chmod 755 '/rw/config/start-wireguard.sh'"
rm -f "$temp_script"
echo "Main startup script completed"
}
# Create rc.local entry that sets the environment variable
create_rclocal_entry() {
echo -e "\nCreating rc.local entry..."
local temp_script=$(mktemp)
cat > "$temp_script" << EOF
#!/bin/bash
# Start WireGuard VPN on boot
export WG_CONFIG_NAME="$WG_CONFIG_NAME"
/rw/config/start-wireguard.sh
EOF
qvm-copy-to-vm "$VPN_SERVICE" "$temp_script"
qvm-run -p -u root "$VPN_SERVICE" "mv '/home/user/QubesIncoming/dom0/$(basename $temp_script)' '/rw/config/rc.local'"
qvm-run -p -u root "$VPN_SERVICE" "chown root:root '/rw/config/rc.local'"
qvm-run -p -u root "$VPN_SERVICE" "chmod 755 '/rw/config/rc.local'"
rm -f "$temp_script"
echo "rc.local entry created successfully"
}
# Finalize
finalize() {
echo -e "\nFinalizing..."
# Clean up
qvm-run -p -u root "$VPN_SERVICE" "rmdir '/home/user/QubesIncoming/dom0' 2>/dev/null || true"
qvm-run -p -u root "$VPN_SERVICE" "rmdir '/home/user/QubesIncoming' 2>/dev/null || true"
# Generate NFTables config (using export to make the variable available to the script)
echo -e "\nGenerating NFTables DNS configuration..."
qvm-run -p -u root "$VPN_SERVICE" "export WG_CONFIG_NAME='$WG_CONFIG_NAME'; /rw/config/nftables-generator.sh"
# Apply NFTables config
echo -e "\nApplying DNS redirection rules..."
qvm-run -p -u root "$VPN_SERVICE" "nft -f /rw/config/nftables.conf"
# Verify the rules were applied
echo -e "\nVerifying NFTables rules..."
qvm-run -p -u root "$VPN_SERVICE" "nft list chain ip nat vpn-dns-redirect"
# Setup WireGuard (using export to make the variable available to the script)
echo -e "\nSetting up WireGuard namespace..."
qvm-run -p -u root "$VPN_SERVICE" "export WG_CONFIG_NAME='$WG_CONFIG_NAME'; /rw/config/setup-wireguard-namespace.sh"
# Verify WireGuard is running
echo -e "\nVerifying WireGuard connection..."
qvm-run -p -u root "$VPN_SERVICE" "wg show"
# Configure menu items
qvm-features "$CUSTOM_TEMPLATE" menu-items "debian-xterm.desktop xfce4-terminal.desktop"
qvm-features "$VPN_SERVICE" menu-items "debian-xterm.desktop xfce4-terminal.desktop"
# Shutdown
qvm-shutdown --wait "$VPN_SERVICE" 2>/dev/null || true
}
# Main function
main() {
echo -e "\nStarting WireGuard VPN setup..."
create_base_template
create_custom_template
install_packages
create_vpn_qube
comment_wg_config
transfer_config
create_wireguard_setup_script
create_nftables_generator_script
create_main_startup_script
create_rclocal_entry
finalize
echo -e "\nSetup completed!"
}
# Run
main "$@"
Here only the NFTables function:
create_nftables_generator_script
# Create NFTables generator script that uses exported variables
create_nftables_generator_script() {
echo -e "\nCreating NFTables generator script..."
local temp_script=$(mktemp)
cat > "$temp_script" << 'EOF'
#!/bin/bash
set -e
echo "Generating NFTables configuration..."
# The WG_CONFIG_NAME variable must be passed via export
if [ -z "$WG_CONFIG_NAME" ]; then
echo "Error: WG_CONFIG_NAME environment variable not set"
exit 1
fi
WG_CONFIG="/rw/config/vpn/$WG_CONFIG_NAME"
# Check if config file exists
if [ ! -f "$WG_CONFIG" ]; then
echo "Error: WireGuard config file not found at $WG_CONFIG"
exit 1
fi
# Get physical IP for virtualif (same as PHYSICAL_IP from setup script)
VIRTUALIF=$(ip -4 addr show eth0 | grep -oP "(?<=inet\s)\d+(\.\d+){3}/\d+" | head -1)
if [ -z "$VIRTUALIF" ]; then
echo "Error: Could not determine physical IP"
exit 1
fi
# Extract DNS servers from WireGuard config
DNS_LINE=$(grep -E "^(#\s*)?DNS" "$WG_CONFIG" | head -1)
if [ -n "$DNS_LINE" ]; then
CLEAN_DNS_LINE=$(echo "$DNS_LINE" | sed -E "s/^#\s*//")
VPNDNS1=$(echo "$CLEAN_DNS_LINE" | cut -d'=' -f2 | sed 's/^[[:space:]]*//;s/[[:space:]]*$//' | tr ',' ' ' | awk '{print $1}')
else
echo "Error: No DNS found in WireGuard config"
exit 1
fi
echo "Using physical IP: $VIRTUALIF"
echo "Using VPN DNS: $VPNDNS1"
# Generate nftables config file
cat > /rw/config/nftables.conf << NFTEOF
#!/usr/sbin/nft -f
# Set variables
define virtualif = $VIRTUALIF
define vpndns1 = $VPNDNS1
# Flush existing rules in qubes dnat-dns chain
flush chain qubes dnat-dns
# Table for NAT and vpn-dns-redirect chain
table ip nat {
chain vpn-dns-redirect {
type nat hook prerouting priority -100; policy accept;
ip daddr 10.139.1.1 udp dport 53 dnat to \$vpndns1
ip daddr 10.139.1.1 tcp dport 53 dnat to \$vpndns1
}
}
# Mangle table (for MSS clamping)
table ip mangle {
chain forward {
type filter hook forward priority 0; policy accept;
tcp flags syn tcp option maxseg size set rt mtu;
}
}
NFTEOF
echo "NFTables configuration generated successfully at /rw/config/nftables.conf"
EOF
qvm-copy-to-vm "$VPN_SERVICE" "$temp_script"
qvm-run -p -u root "$VPN_SERVICE" "mv '/home/user/QubesIncoming/dom0/$(basename $temp_script)' '/rw/config/nftables-generator.sh'"
qvm-run -p -u root "$VPN_SERVICE" "chown root:root '/rw/config/nftables-generator.sh'"
qvm-run -p -u root "$VPN_SERVICE" "chmod 755 '/rw/config/nftables-generator.sh'"
rm -f "$temp_script"
echo "NFTables generator script created successfully"
}
wireguard-namespace-qube.sh.log (16.1 KB)
References
Core References
- forum.qubes-os.org - WireGuard VPN w/ namespace killswitch
- wireguard.com - Network namespaces (netns)
- Qubes OS - Data leaks - The Role of the Firewall - Documentation
- Qubes OS - Firewall - Documentation
- Qubes OS - Networking - Documentation
- qvm-firewall – Manage VM outbound firewall
- Qubes OS - Config files - Documentation
- Qubes OS - How to make any file persistent (bind-dirs) - Documentation
- Qubes OS - VPN - "Documentation"
- Configuring a ProxyVM VPN Gateway - Community Guides - Qubes OS Forum (post #58)
- Wireguard VPN setup - Solene - Community Guides - Qubes OS Forum
- VPN instructions for 4.2 - Solene - Community Guides - Qubes OS Forum
- sys-wireguard - Salt Formulas for Qubes OS - ben-grande (GitHub)
- Qubes VPN Support - Tasket (GitHub)
- Qubes Mirage Firewall - Mirage (GitHub)
- Qubes OS Forum - Qubes cli firewall
- MMS Clamp and MTU - Wireguard VPN setup - Solene - Community Guides - Qubes OS Forum (post #239)
- VPN instructions for 4.2 - oijawyuh - User support - Qubes OS Forum
- Tutorial 4.2 and 4.1 - Mullvad Wireguard with Qubes - Pawelek85 - Community Guides - Qubes OS Forum
DNS References
- How do you manage DNS topic? - Qubes OS Forum
- DNS in NAT and PR-QBS chain - Qubes OS Forum (post #12)
- Wireguard VPN setup - Qubes OS Forum (post #220)
- DNS nftables - how-to setup a sys-dns qube - Qubes OS Forum (post #57)
- PR-QBS replaced by dnat-dns - how-to setup a sys-dns qube - Qubes OS Forum (post #65)
- Race condition - how-to setup a sys-dns qube - DNS nftables leakage - Qubes OS Forum (post #153)
- Race condition - Wi-Fi hotspot from Qubes OS - Qubes OS Forum (post #39)
- Race condition - VPN instructions for 4.2 - Qubes OS Forum (post #45)
- Custom DNS for AppVM - Qubes OS Forum (post #2)
- VPN NetVM: No Internet in Downstream Qubes (Amnezia VPN, WireGuard-based) - Qubes OS Forum
DNSCrypt References
- how-to setup a sys-dns qube - Qubes OS Forum
- Help with dnscrypt-proxy - User Support - Qubes OS Forum
- DNSCrypt - Arch Wiki
- DNSCrypt (GitHub)
- DNSCrypt packaged - General Discussion - Qubes OS Forum
Wireguard
NFTables
- HOWTO Documentation Page - Nftables Wiki
- KernelNewbies - Nftables examples
- Nftables - Arch Wiki
- nft(8) manpage - Options (Debian Trixie)
- Scripting - Nftables Wiki
- How to use defined variables in nftables through terminal - Server Fault
- Hooks - Nftables Wiki
Other Qubes Network References
- Qubes OS Forum - VLESS obfuscation VPN
- Qubes OS Forum - Tor over VPN
- Qubes OS Forum - Curl-proxy / wget-proxy scripts in Templates so users can add GPG distro keys linked to added external repositories
Other Generic Network References
- Whonix Wiki - Whonix versus VPNs
- Whonix Wiki - Tunnels
- NLnet Labs - Unbound - Resolver for Home Networks
- Unbound - Pi-hole as All-Around DNS Solution
- Mullvad - DNS over HTTPS and DNS over TLS
- Configuring and managing networking - Red Hat Enterprise Linux 10
- openresolv - Configuration - Roy Marples
- openresolv - RESOLVCONF(8) - System Manager's Manual
- openresolv - RESOLVCONF.CONF(5) - File Formats Manual
- systemd - systemd-resolved.service and VPNs
- systemd - Network Configuration Synchronization Points
Other topics
Other Qubes References
Bash References
- GNU Bash Manual
- bash(1) - Linux manual page
- GNU Awk Manual
- gawk(1) - Linux manual page
- GNU sed Manual
- sed(1) - Linux manual page
- Bash - Conditional Constructs
- GNU Manuals Online - The environment variable TERM
Regular expressions
Heredoc, escaping and quoting pitfalls
Rendering issue fixed using html encoding, duh !!!