I have created a pihole based firewall qube named sys-pihole. I want to open a browser in that qube to access pihole web portal. Pretty much all browses make internet connection preemptively for valid reasons. But I don’t want the browser in the sys-pihole qube to make any internet connection.
How do I stop an application in a qube from connecting to internet?
you could block all outgoing traffic of the sys-pihole qube to restrict to ports tcp 53 and udp 53, + DoH or DoT hosts if any
That way, your web browser will not be able to reach anything except the DNS servers.
There is no simple way I’m aware of to prevent a single program to use the network but localhost. Using a namespace, you can disable networking for a program, but you want to use firefox for checking pihole web-ui so it won’t work.
opensnitch could work but it’s quite heavy for the task
configuring a proxy in firefox to something that does not exists, and disable the proxy for reaching localhost (default setting) should work too, but it does not guarantee the web browser will not try networking without the proxy.
another solution would be to have a pihole-admin qube without network, that directly connect to pihole web interface using ConnectTCP qubes os RPC, but this is super heavy to setup (the first time). Although this design pattern is useful and can be reused many time if you have similar needs.
This is the only reliable solution to make sure the browser cannot access the internet the qubes way, using different domains. Note that if the server is vulnerable, it can be attacked by the browser qube to access the internet.
Here is the file contents you need to set it up. Check the .sls files on where they should go if you don’t want to use Salt.
for anyone interested the documentation of how to use ConnectTCP to connect to another qube is documented below. Personally, I think the qubes-rpc documentation page should link below document as that is the first place someone will look for information like below.
Borrowing an idea from the excellent Wireguard Interworkings page, you can easily setup a different network namespace where by default, only the “lo” interface exists.
Behold:
user@disp2170:~$ sudo ip netns add isolated
user@disp2170:~$ sudo ip -n isolated link
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN mode DEFAULT group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
user@disp2170:~$ ping -c4 8.8.8.8
PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
64 bytes from 8.8.8.8: icmp_seq=1 ttl=57 time=12.8 ms
64 bytes from 8.8.8.8: icmp_seq=2 ttl=57 time=13.9 ms
64 bytes from 8.8.8.8: icmp_seq=3 ttl=57 time=15.2 ms
64 bytes from 8.8.8.8: icmp_seq=4 ttl=57 time=14.3 ms
--- 8.8.8.8 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3005ms
rtt min/avg/max/mdev = 12.786/14.050/15.226/0.874 ms
user@disp2170:~$
user@disp2170:~$ sudo -E ip netns exec isolated sudo -E -u \#$(id -u) -g \#$(id -g) ping -c4 8.8.8.8
ping: connect: Network is unreachable
user@disp2170:~$
user@disp2170:~$ #Replace "ping -c4 8.8.8.8" with "firefox" on the previous command...
user@disp2170:~$# ... and you will only be able to reach localhost
user@disp2170:~$
(the commands were run in a “debian-12”-based dvm)
You can easily script this, checking for the existence of the “isolated” namespace to avoid errors, along the lines of:
#!/bin/bash
[[ $(sudo ip netns list) =~ isolated ]] || sudo ip netns add isolated
sudo -E ip netns exec isolated sudo -E -u \#$(id -u) -g \#$(id -g) firefox