Another VPN support request! I am really quite lost with nft
and looking for help debugging/troubleshooting my situation.
I am using Qubes 4.2.3, I believe.
I am required to use the Invanti Pulse Secure VPN Client which is distributed as a .deb
and requires depreciated packages, but I’ve managed to install it successfully in ProxyVMs based on debian-12-minimal
and debian-12-xfce
templates with a bit of dependency management. The ProxyVMs have the network-manager service added in Settings. Within the ProxyVM itself, I can successfully load sites and domains that are on the internal VPN-accessed network, so everything is working there as expected.
However from any AppVMs that I try to route through the ProxyVM, I am unable to load sites on the internal network as expected, specifically if they use https. Sites on the Internet (eg google.com) will load fine. Internal sites on http appear to work. Internal sites over https will timeout.
DNS appears to work. I can see that the VPN client updates nft
to use the internal network DNS servers. Lookups with dig
from the ProxyVM and AppVM yield the same correct result for internal domain names. It’s just loading the actual pages that fails.
I have trying to mess with nft
rules in my ProxyVM but I am at a loss. I’m looking for help, either advice on how to change the rules, or steps I can try to debug/troubleshoot it.
Here is the output of sudo nft list ruleset
in my ProxyVM after opening and connecting the Pulse Secure VPN client (which only changes the chain dnat-dns
I believe, which I’ve redacted here):
table ip qubes {
set downstream {
type ipv4_addr
elements = { 10.137.0.20 }
}
set allowed {
type ifname . ipv4_addr
elements = { "vif38.0" . 10.137.0.20 }
}
chain prerouting {
type filter hook prerouting priority raw; policy accept;
iifgroup 2 goto antispoof
ip saddr @downstream counter packets 0 bytes 0 drop
}
chain antispoof {
iifname . ip saddr @allowed accept
counter packets 0 bytes 0 drop
}
chain postrouting {
type nat hook postrouting priority srcnat; policy accept;
oifgroup 2 accept
oif "lo" accept
masquerade
}
chain input {
type filter hook input priority filter; policy drop;
jump custom-input
ct state invalid counter packets 0 bytes 0 drop
iifgroup 2 udp dport 68 counter packets 0 bytes 0 drop
ct state established,related accept
iifgroup 2 meta l4proto icmp accept
iif "lo" accept
iifgroup 2 counter packets 0 bytes 0 reject with icmp host-prohibited
counter packets 0 bytes 0
}
chain forward {
type filter hook forward priority filter; policy accept;
jump custom-forward
ct state invalid counter packets 0 bytes 0 drop
ct state established,related accept
oifgroup 2 counter packets 0 bytes 0 drop
}
chain custom-input {
}
chain custom-forward {
}
chain dnat-dns {
type nat hook prerouting priority dstnat; policy accept;
ip daddr 10.139.1.1 udp dport 53 dnat to INTERNALDNS.1
ip daddr 10.139.1.1 tcp dport 53 dnat to INTERNALDNS.1
ip daddr 10.139.1.2 udp dport 53 dnat to INTERNALDNS.2
ip daddr 10.139.1.2 tcp dport 53 dnat to INTERNALDNS.2
}
}
table ip6 qubes {
set downstream {
type ipv6_addr
}
set allowed {
type ifname . ipv6_addr
}
chain antispoof {
iifname . ip6 saddr @allowed accept
counter packets 10 bytes 656 drop
}
chain prerouting {
type filter hook prerouting priority raw; policy accept;
iifgroup 2 goto antispoof
ip6 saddr @downstream counter packets 0 bytes 0 drop
}
chain postrouting {
type nat hook postrouting priority srcnat; policy accept;
oifgroup 2 accept
oif "lo" accept
masquerade
}
chain _icmpv6 {
meta l4proto != ipv6-icmp counter packets 0 bytes 0 reject with icmpv6 admin-prohibited
icmpv6 type { nd-router-advert, nd-redirect } counter packets 0 bytes 0 drop
accept
}
chain input {
type filter hook input priority filter; policy drop;
jump custom-input
ct state invalid counter packets 0 bytes 0 drop
ct state established,related accept
iifgroup 2 goto _icmpv6
iif "lo" accept
ip6 saddr fe80::/64 ip6 daddr fe80::/64 udp dport 546 accept
meta l4proto ipv6-icmp accept
counter packets 0 bytes 0
}
chain forward {
type filter hook forward priority filter; policy accept;
jump custom-forward
ct state invalid counter packets 0 bytes 0 drop
ct state established,related accept
oifgroup 2 counter packets 0 bytes 0 drop
}
chain custom-input {
}
chain custom-forward {
}
}
table ip qubes-firewall {
chain forward {
type filter hook forward priority filter; policy drop;
ct state established,related accept
iifname != "vif*" accept
ip saddr 10.137.0.20 jump qbs-10-137-0-20
}
chain prerouting {
type filter hook prerouting priority raw; policy accept;
iifname != "vif*" ip saddr 10.137.0.20 drop
}
chain postrouting {
type filter hook postrouting priority raw; policy accept;
oifname != "vif*" ip daddr 10.137.0.20 drop
}
chain qbs-10-137-0-20 {
accept
reject with icmp admin-prohibited
}
}
table ip6 qubes-firewall {
chain forward {
type filter hook forward priority filter; policy drop;
ct state established,related accept
iifname != "vif*" accept
}
chain prerouting {
type filter hook prerouting priority raw; policy accept;
}
chain postrouting {
type filter hook postrouting priority raw; policy accept;
}
}
table inet qubes-nat-accel {
flowtable qubes-accel {
hook ingress priority filter
devices = { eth0, lo, vif38.0 }
}
chain qubes-accel {
type filter hook forward priority filter + 5; policy accept;
meta l4proto { tcp, udp } iifgroup 2 oifgroup 1 flow add @qubes-accel
counter packets 109 bytes 11505
}
}
Thank you