tasket / Qubes-vpn-support

VPN configuration in Qubes OS
GNU General Public License v3.0
126 stars 28 forks source link

Replace iptables with nftables #71

Open 1cho1ce opened 1 year ago

1cho1ce commented 1 year ago

Qubes dropped iptables support and replaced it with nftables: https://github.com/QubesOS/qubes-core-agent-linux/commit/28b95535c7cbd15543c804e822c0e4c997f5966e This pull request replaces iptables with nftables.

Removed allow established input rules from proxy-firewall-restrict since they are already present in nft tables ip/ip6 qubes.

TODO: Need to think of a better way to check in --check-firewall in qubes-vpn-setup script if the forward drop rules are present (or proxy-firewall-restrict script finished successfully).

tasket commented 1 year ago

Thanks for the PR. I will start reviewing this tomorrow and hopefully get the nftables support ready in June.

1cho1ce commented 1 year ago

Sorry, I didn't check openvpn and forgot to add forward rules for it. Also changed nft to use custom chains.

tquest1 commented 1 year ago

@1cho1ce - I have been trying to use your forked version on Qubes 4.2 and after a lot of trying, I couldn't get it to work with Fedora templates, but eventually when I changed to a Debian 11 template it worked fine.

I do have one problem though, I was previously (on 4.1) using edited qubes-firewall-user-script & rc.local to allow local network access (192.168.150.0/24 in my case). I have copied & adjusted these as below but can't get any lan access now:

# from qubes-firewall-user-script

#    Allow forwarding of connections through upstream network device
#    if they're to 192.168.150.x

#iptables -I FORWARD -o eth0 -d 192.168.150.0/24 -j ACCEPT
#iptables -I FORWARD -i eth0 -s 192.168.150.0/24 -j ACCEPT

nft 'insert rule ip filter FORWARD oifname "eth0" ip daddr 192.168.150.0/24 counter accept'
nft 'insert rule ip filter FORWARD iifname "eth0" ip saddr 192.168.150.0/24 counter accept'
# from rc.local
# Allow access to home network for backup, etc.
ip route add 192.168.150.0/24 via 10.137.0.7 dev eth0

TBH - I'm not very familiar with nft & edited the iptables-I FORWARD rules above using iptables-translate. Has anyone got local access working on 4.2 with nft?

1cho1ce commented 1 year ago

I have been trying to use your forked version on Qubes 4.2 and after a lot of trying, I couldn't get it to work with Fedora templates, but eventually when I changed to a Debian 11 template it worked fine.

I've fixed this issue with Fedora template.

I do have one problem though, I was previously (on 4.1) using edited qubes-firewall-user-script & rc.local to allow local network access (192.168.150.0/24 in my case). I have copied & adjusted these as below but can't get any lan access now:

You can replace these iptables rules:

iptables -I FORWARD -o eth0 -d 192.168.150.0/24 -j ACCEPT
iptables -I FORWARD -i eth0 -s 192.168.150.0/24 -j ACCEPT

With these nftables rules:

nft insert rule ip qubes custom-forward oifgroup 1 ip daddr 192.168.150.0/24 accept
nft insert rule ip qubes custom-forward iifgroup 1 ip saddr 192.168.150.0/24 accept
moonlitOrca commented 10 months ago

Is this pull request in good working order? Has it been deemed insufficient? I am just wondering what further needs to be done in order to create a working solution. I am not yet familiar with nftables rules, but I will research and see if I can help if something is missing.

dylangerdaly commented 9 months ago

Also would like to know if this PR works, I just need to be able to VPN with 4.2

Eric678 commented 9 months ago

This PR worked out of the box for me - many thanks. Not tested failure modes. Running on debian-12-minimal. @1cho1ce, like many others I am struggling with nft - would it be possible to add a paragraph to the Firewall Notes section to provide an example of port forwarding setup ? Thanks

[ed] My best guess that seems to be working - in a file in qubes-firewall.d: PORTS="{ 1234, 1235 }" nft add rule ip qubes dnat-dns iifgroup 9 tcp dport $PORTS dnat to 10.137.0.XX and the same for udp. Anything else recommended?

apparatius commented 1 day ago

There are a few errors in the PR with allowing traffic from VPN to qubes and typos related to IPv6. This was discussed here: https://forum.qubes-os.org/t/vpn-instructions-for-4-2/20738/78

Here is a patch: ``` diff --git a/files-main/proxy-firewall-restrict b/files-main/proxy-firewall-restrict index a3aba10..8142ad2 100644 --- a/files-main/proxy-firewall-restrict +++ b/files-main/proxy-firewall-restrict @@ -22,11 +22,9 @@ nft chain ip6 qubes forward '{ policy drop; }' nft insert rule ip6 qubes custom-forward oifgroup 1 drop nft insert rule ip6 qubes custom-forward iifgroup 1 drop -# Accept forward traffic between dowstream (vif+, group 2) and VPN interface (group 9) +# Accept forward traffic from dowstream (vif+, group 2) to VPN interface (group 9) nft insert rule ip qubes custom-forward iifgroup 2 oifgroup 9 accept -nft insert rule ip qubes custom-forward iifgroup 9 oifgroup 2 accept nft insert rule ip6 qubes custom-forward iifgroup 2 oifgroup 9 accept -nft insert rule ip6 qubes custom-forward iifgroup 9 oifgroup 2 accept # Block INPUT from tunnel(s): nft chain ip qubes input '{ policy drop; }' diff --git a/files-main/qubes-vpn-ns b/files-main/qubes-vpn-ns index 62510d4..d510954 100644 --- a/files-main/qubes-vpn-ns +++ b/files-main/qubes-vpn-ns @@ -85,11 +85,11 @@ up) if [[ ${#vpn_dns_ip6[@]} != 0 ]] && [[ ${#qubes_dns_ip6[@]} != 0 ]]; then for i in $(seq 0 $((${#qubes_dns_ip6[@]} - 1))); do if [[ $i < ${#vpn_dns_ip6[@]} ]] ; then - nft add rule ip6 qubes dnat-dns iifgroup 2 ip6 daddr ${qubes_dns_ip6[$i]} tcp dport 53 dnat to ${qubes_dns_ip6[$i]} - nft add rule ip6 qubes dnat-dns iifgroup 2 ip6 daddr ${qubes_dns_ip6[$i]} udp dport 53 dnat to ${qubes_dns_ip6[$i]} + nft add rule ip6 qubes dnat-dns iifgroup 2 ip6 daddr ${qubes_dns_ip6[$i]} tcp dport 53 dnat to ${vpn_dns_ip6[$i]} + nft add rule ip6 qubes dnat-dns iifgroup 2 ip6 daddr ${qubes_dns_ip6[$i]} udp dport 53 dnat to ${vpn_dns_ip6[$i]} else - nft add rule ip6 qubes dnat-dns iifgroup 2 ip6 daddr ${qubes_dns_ip6[$i]} tcp dport 53 dnat to ${qubes_dns_ip6[0]} - nft add rule ip6 qubes dnat-dns iifgroup 2 ip6 daddr ${qubes_dns_ip6[$i]} udp dport 53 dnat to ${qubes_dns_ip6[0]} + nft add rule ip6 qubes dnat-dns iifgroup 2 ip6 daddr ${qubes_dns_ip6[$i]} tcp dport 53 dnat to ${vpn_dns_ip6[0]} + nft add rule ip6 qubes dnat-dns iifgroup 2 ip6 daddr ${qubes_dns_ip6[$i]} udp dport 53 dnat to ${vpn_dns_ip6[0]} fi done fi diff --git a/files-main/qubes-vpn-setup b/files-main/qubes-vpn-setup index 995ae33..f9b3512 100755 --- a/files-main/qubes-vpn-setup +++ b/files-main/qubes-vpn-setup @@ -53,7 +53,7 @@ firewall_link() { case "$1" in --check-firewall) for i in 1 2 3; do - if (nft -j -s list chain ip qubes custom-forward && nft -j -s list chain ip qubes custom-forward) | python3 -c " + if (nft -j -s list chain ip qubes custom-forward && nft -j -s list chain ip6 qubes custom-forward) | python3 -c " import sys, json; def main(): rule_out_ipv4_exists = False ```

You can apply the patch using this command:

~/Qubes-vpn-support$ git apply /path/to/patch

Additional notes: If no Qubes OS virtual IPv6 DNS servers are used then the IPv6 DNS from VPN provider won’t be used and qubes will use their own IPv6 DNS servers. I saw a pull request from 1choice to add virtual IPv6 DNS support to Qubes OS so I guess that was related to this change. If no DNS is provided by VPN server then requests to virtual DNS IPs will leak from qubes. I guess it's better to use some default DNS like 9.9.9.9 in case no DNS will be provided by VPN.