I would like to run Whonix directly using QEMU instead of using libvirt and I want to manually setup internal and external network. Using libvirt I would need to run those commands:
virsh net-define Whonix-External.xml
virsh net-define Whonix-Internal.xml
virsh net-start Whonix-External.xml
virsh net-start Whonix-Internal.xml
Whonix-External.xml:
<network>
<name>Whonix-External</name>
<forward mode='nat'/>
<bridge name='virbr1' stp='on' delay='0'/>
<ip address='10.0.2.2' netmask='255.255.255.0'/>
</network>
Whonix-Internal.xml:
<network>
<name>Whonix-Internal</name>
<bridge name='virbr2' stp='on' delay='0'/>
</network>
I only know that I have to use ip link
and ip tuntap
commands for that but I'm not even sure where to start, especially that Whonix-Gateway uses both networks and both Whonix-Gateway and Whonix-Workstation share Whonix-Internal network. I also know I will have to add -netdev
and -device
options to the QEMU command but I don't know how to make the VM pick the right network e.g. how to tell Whonix-Workstation to use Whonix-Internal instead of Whonix-External. If there are any other informations needed let me know and I will edit the post if needed.
Solution
After a month of searching for a solution I found a way to set up both networks and I decided to share it here.
Firstly I created bridge called virbr1
and tap device called vnet0
which is Whonix-External network for Whonix-Gateway:
virbr1
ip link add virbr1 type bridge
ip link set virbr1 type bridge stp_state 1
ip link set virbr1 up
vnet0
ip tuntap add dev vnet0 mode tap user $(whoami)
ip link set vnet0 master virbr1
ip link set vnet0 up
Secondly I created bridge called virbr2
and tap device called vnet1
which is Whonix-Internal network for Whonix-Gateway:
virbr2
ip link add virbr2 type bridge
ip link set virbr2 type bridge stp_state 1
ip link set virbr2 up
vnet1
ip tuntap add dev vnet1 mode tap user $(whoami)
ip link set vnet1 master virbr2
ip link set vnet1 up
Thirdly I created tap device called vnet2
which would be used by Whonix-Workstation to connect to Whonix-Internal network:
vnet2
ip tuntap add dev vnet2 mode tap user $(whoami)
ip link set vnet2 master virbr2
ip link set vnet2 up
Lastly I added iptables
rules (which I decided to put into separate chains so it will be easier to clean things up later) and enabled IP forwarding:
iptables -N WHONIX_FORWARD
iptables -A WHONIX_FORWARD -s 10.0.2.0/24 -j ACCEPT -i virbr1
iptables -A WHONIX_FORWARD -d 10.0.2.0/24 -j ACCEPT -o virbr1 -m state --state RELATED,ESTABLISHED
iptables -A FORWARD -j WHONIX_FORWARD
iptables -t nat -N WHONIX_POSTROUTING
iptables -t nat -A WHONIX_POSTROUTING -s 10.0.2.0/24 ! -d 10.0.2.0/24 -j MASQUERADE
iptables -t nat -A POSTROUTING -j WHONIX_POSTROUTING
sysctl -wq net.ipv4.ip_forward=1
To make it all work I had to add these options to Whonix-Gateway's QEMU command:
-device virtio-net-pci,id=net0,netdev=hostnet0,bus=pci.0,addr=0x5,mac=MAC
-netdev tap,id=hostnet0,ifname=vnet0,script=no,downscript=no
-device virtio-net-pci,id=net1,netdev=hostnet1,bus=pci.0,addr=0x6,mac=MAC
-netdev tap,id=hostnet1,ifname=vnet1,script=no,downscript=no
and I had to add those options to Whonix-Workstation's QEMU command:
-device virtio-net-pci,id=net0,netdev=hostnet0,bus=pci.0,addr=0x5,mac=MAC
-netdev tap,id=hostnet0,ifname=vnet2,script=no,downscript=no
After virtual machines will shut down I can clean everything up with those commands:
ip link del virbr1
ip tuntap del dev vnet0 mode tap
ip tuntap del dev vnet1 mode tap
ip link del virbr2
ip tuntap del dev vnet2 mode tap
iptables -D FORWARD -j WHONIX_FORWARD
iptables -F WHONIX_FORWARD
iptables -X WHONIX_FORWARD
iptables -t nat -D POSTROUTING -j WHONIX_POSTROUTING
iptables -t nat -F WHONIX_POSTROUTING
iptables -t nat -X WHONIX_POSTROUTING
sysctl -wq net.ipv4.ip_forward=0