Onion

This VM provides transparent proxying for Tor Onion Services. Unlike Whonix VM, however, only .onion addresses are forwarded to the Tor network. This is useful when you need direct network access but also need to be able to access Onion Services.

Design

  • Dnsmasq is used to forward .onion requests to Tor. Other request, are forwarded to the DNS servers provided by Sys-Onion’s NetVM.

  • Tor assigns ephemeral addresses in the ranges 10.192.0.0/10 and fc7e:8e76::/32 to hidden services.

  • A Tor SOCKS5 proxy is reachable on port 9050 at the addresses 10.152.152.10 and fc7f:86a5::9050.

Setup

Install Tor in Template VM

  1. Install Tor

    See official documentation.

  2. Disable Tor by default:

    systemctl disable tor
    
  3. Install Dnsmasq:

    apt install dnsmasq
    
  4. Disable Dnsmasq by default:

    systemctl disable dnsmasq
    

Create VM in Dom0

  1. Create VM:

    qvm-create --property netvm=sys-firewall --label black sys-onion
    

    (Only tested with Debian-based VM template.)

  2. Make VM a ProxyVM:

    qvm-prefs sys-onion provides_network True
    
  3. Configure the firewall appropriately

In Sys-Onion

  1. Persist directories for Tor and Dnsmasq

    Add to /rw/config/qubes-bind-dirs.d/50_user.conf:

    binds+=( '/etc/tor/' )
    binds+=( '/var/lib/tor/' )
    binds+=( '/etc/dnsmasq.d/' )
    
  2. Reboot

  3. Replace Tor config at /etc/tor/torrc:

    Sandbox 1
    NoExec 1
    LongLivedPorts 21,22,706,1863,5050,5190,5222,5223,6523,6667,6697,8300,143
    
    ClientOnionAuthDir /var/lib/tor/authdir
    
    # Map onion services to virtual addresses
    AutomapHostOnResolve 1
    DNSPort 5353
    VirtualAddrNetworkIPv4 10.192.0.0/10
    VirtualAddrNetworkIPv6 fc7e:8e76::/32
    TransPort 0.0.0.0:9040 IsolateClientAddr IsolateClientProtocol IsolateDestAddr IsolateDestPort
    TransPort [::]:9040 IsolateClientAddr IsolateClientProtocol IsolateDestAddr IsolateDestPort
    
    # Publicly reachable SOCKS proxy
    SocksPort 0.0.0.0:9050 IsolateClientAddr IsolateClientProtocol IsolateDestAddr IsolateDestPort
    SocksPort [::]:9050 IsolateClientAddr IsolateClientProtocol IsolateDestAddr IsolateDestPort
    
  4. Create client_auth dir:

    mkdir /var/lib/tor/authdir/
    
  5. Example client auth file

    /var/lib/tor/authdir/myhost.auth_private:

    rgmp6tmqtio4o4rcisxwknsnan6jxovah74cp4ncp6gn67f2o6qqk7id.onion:descriptor:x25519:3dv5remvaf735roalamogbycqardymq6svmnm3ad7oguo56za2cq
    

    Tip

    • File extension must be .auth_private.

    • There must be but one line per file.

  6. Add Dnsmasq config at /etc/dnsmasq.d/onion.conf:

    # Needed to override local-service option
    interface=*
    
    # Have Tor resolve *.onion addresses
    server=/onion/127.0.0.1#5353
    
  7. Start Tor and Dnsmasq on boot:

    Add to /rw/config/rc.local:

    systemctl start tor
    systemctl start dnsmasq
    

    Ensure rc.local is executable:

    chmod +x /rw/config/rc.local
    
  8. Setup NAT and Firewall to allow other VM access to Tor:

    Add iptables rules to /rw/config/qubes-firewall-user-script:

    ip46tables() {
        command iptables "$@" && command ip6tables "$@"
    }
    
    # Virtual addresses for onion services
    iptables -t nat -I PREROUTING -i vif+ -d 10.192.0.0/10 -p tcp -m state --state NEW -j REDIRECT --to-ports 9040 -m comment --comment 'Proxy onion services'
    ip6tables -t nat -I PREROUTING -i vif+ -d fc7e:8e76::/32 -p tcp -m state --state NEW -j REDIRECT --to-ports 9040 -m comment --comment 'Proxy onion services'
    iptables -I INPUT -i vif+ -d 10.192.0.0/10 -p tcp -j ACCEPT -m comment --comment "Virtual onion service addresses"
    ip6tables -I INPUT -i vif+ -d fc7e:8e76::/32 -p tcp -j ACCEPT -m comment --comment "Virtual onion service addresses"
    iptables -I FORWARD -i vif+ -d 10.192.0.0/10 -j REJECT --reject-with icmp-admin-prohibited -m comment --comment 'Non-TCP traffic for onion services'
    ip6tables -I FORWARD -i vif+ -d fc7e:8e76::/32 -j REJECT --reject-with icmp6-adm-prohibited -m comment --comment 'Non-TCP traffic for onion services'
    ip46tables -I INPUT -i vif+ -p tcp --dport 9040 -j ACCEPT -m comment --comment "TransProxy port"
    
    # DNS
    iptables -t nat -I PREROUTING -i vif+ -d 10.139.1.1,10.139.1.2 -m state --state NEW -p tcp --dport 53 -j REDIRECT --to-port 53 -m comment --comment 'Use dnsmasq to resolve host names'
    iptables -t nat -I PREROUTING -i vif+ -d 10.139.1.1,10.139.1.2 -p udp --dport 53 -j REDIRECT --to-port 53 -m comment --comment 'Use dnsmasq to resolve host names'
    iptables -I INPUT -i vif+ -p tcp --dport 53 -j ACCEPT -m comment --comment "Allow dnsmasq access"
    iptables -I INPUT -i vif+ -p udp --dport 53 -j ACCEPT -m comment --comment "Allow dnsmasq access"
    
    # SOCKS
    iptables -t nat -I PREROUTING -i vif+ -d 10.152.152.10 -p tcp -m state --state NEW -j REDIRECT --to-ports 9050 -m comment --comment 'Publicly reachable SOCKS proxy'
    ip6tables -t nat -I PREROUTING -i vif+ -d fc7f:86a5::9050 -p tcp -m state --state NEW -j REDIRECT --to-ports 9050 -m comment --comment 'Publicly reachable SOCKS proxy'
    ip46tables -I INPUT -i vif+ -p tcp --dport 9050 -j ACCEPT -m comment --comment "Tor SOCKS port"
    

    Make firewall script is executeable:

    chmod +x /rw/config/qubes-firewall-user-script
    
  9. Reboot