This won’t work, because dnat-dns
chain will be automatically overwritten on network interface up/down, that’s why it doesn’t work for you.
You need to create a separate nat chain as stated in the linked guide.
I did this too, doesn’t work
What’s the output of this command with these rules?
sudo nft list ruleset
Did you try DNS resolution in qubes connected to sys-vpn with these rules?
Here’s what I have with these rules:
table ip qubes {
set downstream {
type ipv4_addr
}
set allowed {
type ifname . ipv4_addr
}
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 nat {
type nat hook prerouting priority dstnat; policy accept;
iifname "vif*" tcp dport 53 dnat to 9.9.9.9
iifname "vif*" udp dport 53 dnat to 9.9.9.9
}
chain dnat-dns {
type nat hook prerouting priority dstnat; policy accept;
ip daddr 10.139.1.1 udp dport 53 dnat to 10.139.1.1
ip daddr 10.139.1.1 tcp dport 53 dnat to 10.139.1.1
ip daddr 10.139.1.2 udp dport 53 dnat to 10.139.1.2
ip daddr 10.139.1.2 tcp dport 53 dnat to 10.139.1.2
}
}
table ip6 qubes {
set downstream {
type ipv6_addr
}
set allowed {
type ifname . ipv6_addr
}
chain antispoof {
iifname . ip6 saddr @allowed accept
counter packets 0 bytes 0 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
}
chain prerouting {
type filter hook prerouting priority raw; policy accept;
iifname != "vif*" ip saddr 10.137.0.15 drop
}
chain postrouting {
type filter hook postrouting priority raw; policy accept;
oifname != "vif*" ip daddr 10.137.0.15 drop
}
}
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;
}
}
# Warning: table ip filter is managed by iptables-nft, do not touch!
table ip filter {
chain amnvpn.anchors {
counter packets 4 bytes 184 jump amnvpn.a.000.allowLoopback
counter packets 4 bytes 184 jump amnvpn.a.320.allowDNS
counter packets 4 bytes 184 jump amnvpn.a.310.blockDNS
counter packets 4 bytes 184 jump amnvpn.a.300.allowLAN
counter packets 4 bytes 184 jump amnvpn.a.290.allowDHCP
counter packets 4 bytes 184 jump amnvpn.a.200.allowVPN
counter packets 4 bytes 184 jump amnvpn.a.120.blockNets
counter packets 4 bytes 184 jump amnvpn.a.110.allowNets
counter packets 4 bytes 184 jump amnvpn.a.100.blockAll
}
chain amnvpn.a.000.allowLoopback {
counter packets 0 bytes 0 jump amnvpn.000.allowLoopback
}
chain amnvpn.000.allowLoopback {
oifname "lo*" counter packets 0 bytes 0 accept
}
chain amnvpn.a.320.allowDNS {
counter packets 0 bytes 0 jump amnvpn.320.allowDNS
}
chain amnvpn.320.allowDNS {
oifname "amn0*" ip daddr 1.1.1.1 udp dport 53 counter packets 0 bytes 0 accept
oifname "amn0*" ip daddr 1.1.1.1 tcp dport 53 counter packets 0 bytes 0 accept
oifname "tun0*" ip daddr 1.1.1.1 udp dport 53 counter packets 0 bytes 0 accept
oifname "tun0*" ip daddr 1.1.1.1 tcp dport 53 counter packets 0 bytes 0 accept
oifname "tun2*" ip daddr 1.1.1.1 udp dport 53 counter packets 0 bytes 0 accept
oifname "tun2*" ip daddr 1.1.1.1 tcp dport 53 counter packets 0 bytes 0 accept
oifname "amn0*" ip daddr 1.0.0.1 udp dport 53 counter packets 0 bytes 0 accept
oifname "amn0*" ip daddr 1.0.0.1 tcp dport 53 counter packets 0 bytes 0 accept
oifname "tun0*" ip daddr 1.0.0.1 udp dport 53 counter packets 0 bytes 0 accept
oifname "tun0*" ip daddr 1.0.0.1 tcp dport 53 counter packets 0 bytes 0 accept
oifname "tun2*" ip daddr 1.0.0.1 udp dport 53 counter packets 0 bytes 0 accept
oifname "tun2*" ip daddr 1.0.0.1 tcp dport 53 counter packets 0 bytes 0 accept
oifname "amn0*" ip daddr 127.0.0.1 udp dport 53 counter packets 0 bytes 0 accept
oifname "amn0*" ip daddr 127.0.0.1 tcp dport 53 counter packets 0 bytes 0 accept
oifname "tun0*" ip daddr 127.0.0.1 udp dport 53 counter packets 0 bytes 0 accept
oifname "tun0*" ip daddr 127.0.0.1 tcp dport 53 counter packets 0 bytes 0 accept
oifname "tun2*" ip daddr 127.0.0.1 udp dport 53 counter packets 0 bytes 0 accept
oifname "tun2*" ip daddr 127.0.0.1 tcp dport 53 counter packets 0 bytes 0 accept
oifname "amn0*" ip daddr 127.0.0.53 udp dport 53 counter packets 0 bytes 0 accept
oifname "amn0*" ip daddr 127.0.0.53 tcp dport 53 counter packets 0 bytes 0 accept
oifname "tun0*" ip daddr 127.0.0.53 udp dport 53 counter packets 0 bytes 0 accept
oifname "tun0*" ip daddr 127.0.0.53 tcp dport 53 counter packets 0 bytes 0 accept
oifname "tun2*" ip daddr 127.0.0.53 udp dport 53 counter packets 0 bytes 0 accept
oifname "tun2*" ip daddr 127.0.0.53 tcp dport 53 counter packets 0 bytes 0 accept
}
chain amnvpn.a.310.blockDNS {
counter packets 0 bytes 0 jump amnvpn.310.blockDNS
}
chain amnvpn.310.blockDNS {
udp dport 53 counter packets 0 bytes 0 reject
tcp dport 53 counter packets 0 bytes 0 reject
}
chain amnvpn.a.300.allowLAN {
counter packets 0 bytes 0 jump amnvpn.300.allowLAN
}
chain amnvpn.300.allowLAN {
ip daddr 10.0.0.0/8 counter packets 0 bytes 0 accept
ip daddr 169.254.0.0/16 counter packets 0 bytes 0 accept
ip daddr 172.16.0.0/12 counter packets 0 bytes 0 accept
ip daddr 192.168.0.0/16 counter packets 0 bytes 0 accept
ip daddr 224.0.0.0/4 counter packets 0 bytes 0 accept
ip daddr 255.255.255.255 counter packets 0 bytes 0 accept
}
chain amnvpn.a.290.allowDHCP {
counter packets 0 bytes 0 jump amnvpn.290.allowDHCP
}
chain amnvpn.290.allowDHCP {
ip daddr 255.255.255.255 udp sport 68 udp dport 67 counter packets 0 bytes 0 accept
}
chain amnvpn.a.200.allowVPN {
counter packets 0 bytes 0 jump amnvpn.200.allowVPN
}
chain amnvpn.200.allowVPN {
oifname "amn0*" counter packets 0 bytes 0 accept
oifname "tun0*" counter packets 0 bytes 0 accept
oifname "tun2*" counter packets 0 bytes 0 accept
}
chain amnvpn.a.120.blockNets {
counter packets 0 bytes 0 jump amnvpn.120.blockNets
}
chain amnvpn.120.blockNets {
}
chain amnvpn.a.110.allowNets {
counter packets 0 bytes 0 jump amnvpn.110.allowNets
}
chain amnvpn.110.allowNets {
ip daddr [VPN's IP] counter packets 0 bytes 0 accept
}
chain amnvpn.a.100.blockAll {
counter packets 0 bytes 0 jump amnvpn.100.blockAll
}
chain amnvpn.100.blockAll {
counter packets 0 bytes 0 reject
}
chain OUTPUT {
type filter hook output priority filter; policy accept;
counter packets 4 bytes 184 jump amnvpn.anchors
}
}
# Warning: table ip6 filter is managed by iptables-nft, do not touch!
table ip6 filter {
chain amnvpn.anchors {
counter packets 9 bytes 576 jump amnvpn.a.000.allowLoopback
counter packets 9 bytes 576 jump amnvpn.a.310.blockDNS
counter packets 9 bytes 576 jump amnvpn.a.300.allowLAN
counter packets 8 bytes 520 jump amnvpn.a.290.allowDHCP
counter packets 8 bytes 520 jump amnvpn.a.250.blockIPv6
counter packets 8 bytes 520 jump amnvpn.a.200.allowVPN
counter packets 8 bytes 520 jump amnvpn.a.100.blockAll
}
chain amnvpn.a.000.allowLoopback {
counter packets 1 bytes 56 jump amnvpn.000.allowLoopback
}
chain amnvpn.000.allowLoopback {
oifname "lo*" counter packets 0 bytes 0 accept
}
chain amnvpn.a.310.blockDNS {
}
chain amnvpn.310.blockDNS {
udp dport 53 counter packets 0 bytes 0 reject
tcp dport 53 counter packets 0 bytes 0 reject
}
chain amnvpn.a.300.allowLAN {
counter packets 1 bytes 56 jump amnvpn.300.allowLAN
}
chain amnvpn.300.allowLAN {
ip6 daddr fc00::/7 counter packets 0 bytes 0 accept
ip6 daddr fe80::/10 counter packets 0 bytes 0 accept
ip6 daddr ff00::/8 counter packets 1 bytes 56 accept
}
chain amnvpn.a.290.allowDHCP {
counter packets 0 bytes 0 jump amnvpn.290.allowDHCP
}
chain amnvpn.290.allowDHCP {
ip6 daddr ff00::/8 udp sport 546 udp dport 547 counter packets 0 bytes 0 accept
}
chain amnvpn.a.250.blockIPv6 {
counter packets 0 bytes 0 jump amnvpn.250.blockIPv6
}
chain amnvpn.250.blockIPv6 {
oifname != "lo*" counter packets 0 bytes 0 reject
}
chain amnvpn.a.200.allowVPN {
}
chain amnvpn.200.allowVPN {
oifname "amn0*" counter packets 0 bytes 0 accept
oifname "tun0*" counter packets 0 bytes 0 accept
oifname "tun2*" counter packets 0 bytes 0 accept
}
chain amnvpn.a.100.blockAll {
counter packets 0 bytes 0 jump amnvpn.100.blockAll
}
chain amnvpn.100.blockAll {
counter packets 0 bytes 0 reject
}
chain OUTPUT {
type filter hook output priority filter; policy accept;
counter packets 9 bytes 576 jump amnvpn.anchors
}
}
table ip raw {
chain amnvpn.anchors {
counter packets 4 bytes 184 jump amnvpn.a.100.vpnTunOnly
}
chain amnvpn.a.100.vpnTunOnly {
}
chain amnvpn.100.vpnTunOnly {
counter packets 0 bytes 0 accept
}
chain PREROUTING {
type filter hook prerouting priority raw; policy accept;
counter packets 4 bytes 184 jump amnvpn.anchors
}
}
table ip6 raw {
chain amnvpn.anchors {
counter packets 6 bytes 396 jump amnvpn.a.100.vpnTunOnly
}
chain amnvpn.a.100.vpnTunOnly {
}
chain amnvpn.100.vpnTunOnly {
counter packets 0 bytes 0 accept
}
chain PREROUTING {
type filter hook prerouting priority raw; policy accept;
counter packets 6 bytes 396 jump amnvpn.anchors
}
}
# Warning: table ip nat is managed by iptables-nft, do not touch!
table ip nat {
chain amnvpn.anchors {
counter packets 2 bytes 104 jump amnvpn.a.100.transIp
}
chain amnvpn.a.100.transIp {
}
chain amnvpn.100.transIp {
counter packets 0 bytes 0 masquerade
}
chain POSTROUTING {
type nat hook postrouting priority srcnat; policy accept;
counter packets 2 bytes 104 jump amnvpn.anchors
}
}
# Warning: table ip6 nat is managed by iptables-nft, do not touch!
table ip6 nat {
chain amnvpn.anchors {
counter packets 2 bytes 144 jump amnvpn.a.100.transIp
}
chain amnvpn.a.100.transIp {
}
chain amnvpn.100.transIp {
counter packets 0 bytes 0 XT target MASQUERADE not found
}
chain POSTROUTING {
type nat hook postrouting priority srcnat; policy accept;
counter packets 2 bytes 144 jump amnvpn.anchors
}
}
# Warning: table ip mangle is managed by iptables-nft, do not touch!
table ip mangle {
chain amnvpn.anchors {
counter packets 4 bytes 184 jump amnvpn.a.100.tagPkts
}
chain amnvpn.a.100.tagPkts {
}
chain amnvpn.100.tagPkts {
meta cgroup 1383 counter packets 0 bytes 0 meta mark set 0x3211
}
chain OUTPUT {
type route hook output priority mangle; policy accept;
counter packets 4 bytes 184 jump amnvpn.anchors
}
}
# Warning: table ip6 mangle is managed by iptables-nft, do not touch!
table ip6 mangle {
chain amnvpn.anchors {
counter packets 9 bytes 576 jump amnvpn.a.100.tagPkts
}
chain amnvpn.a.100.tagPkts {
}
chain amnvpn.100.tagPkts {
meta cgroup 1383 counter packets 0 bytes 0 meta mark set 0x3211
}
chain OUTPUT {
type route hook output priority mangle; policy accept;
counter packets 9 bytes 576 jump amnvpn.anchors
}
}
I just tried DNS resolution in both sys-vpn and connected qubes. None of them works.
Maybe these DNS rules from AmneziaVPN are causing this issue.
Do you see the packet counter increasing in these rules when you try to resolve some DNS in the qube connected to sys-vpn?
I guess you can try to install systemd-resolved in the template of sys-vpn qube:
Maybe this will fix the issue.
Or you can use 1.1.1.1 or 1.0.0.1 DNS instead of 9.9.9.9 that is allowed by AmneziaVPN rules.
using 1.1.1.1 or 1.0.0.1 DNS instead of 9.9.9.9 seems not to help.
Here’s what I have when I’m trying to start systemd-resolved:
user@sys-vpn-2:~$ sudo systemctl start systemd-resolved
Failed to start systemd-resolved.service: Unit systemd-resolved.service not found.
Do you see the packet counter increasing in the amnvpn.a.310.blockDNS
/ amnvpn.310.blockDNS
chains when you try to resolve some DNS in the qube connected to sys-vpn?
I guess these rules that allow 1.1.1.1 and 1.0.0.1 are generated when you add these DNS servers in /etc/resolve.conf manually and start the AmneziaVPN, that’s why it didn’t work for you now when you didn’t add these servers manually.
You need to install the systemd-resolved package in the template of your sys-vpn qube.
No, I don’t see that.
So, what have worked - you were right. If I write 1.1.1.1 and 1.0.0.1 to /etc/resolv.conf manually and then start amnezia, dns resolution works until the reload of the qube or I guess network up\down.
I’m using a standaloneVM as sys-vpn qube, I’m not sure if installing systemd-resolved to the template would work, but I don’t know much about differences in qube types yet.
As I understand the 1st solution that I have now is install systemd-resolved, which should give an ability to Amnezia to use its own DNS (there’s an option in the app to toggle using DNS that will be instaleld onto my VPS)?
And the 2nd one is to override resolv.conf on qube’s start in rc.local. (I’m not sure what these things are doing that you suggested here: Xray with AmneziaVPN - can't access internet - #14 by klamantikuspl But I will leave it as you suggest, as you definitely understand much more than me).
It seems that 1st one is easier in terms of maintaining, as I’ll be able to manage it in the Amnezia’s app. But I’m not sure which type of qube I need to use. So, until I’m waiting for you advice, I will try to create new template for vpn qube (installing systemd-resolved) and create an AppVM, and if it won’t work, I’ll try a few other configurations.
Thank you for your support and efforts, means a lot!
Yes, it works! As it’s standaloneVM, I’ve installed systemd-resolved directly into it and now I finally have working VPN and I know why it works.
Now it’s time to discover which qube should I use: standalone on debian (as it’s more stable - that’s what gemini said ) or appVM with a template where systemd-resolved will be installed.
I guess I should use standalone.
I heard about minimal templates, so they won’t take so much space, but I don’t know what’s that yet and where can I get it.