First of all, a positive observation: after upgrading to Core Update 203, memory usage on my IPFire systems is now only about 30% of what it was before. That is a very welcome improvement, so thank you for the work on the move to Knot Resolver.
I have, however, found what appears to be an issue when Knot Resolver is used together with a Keepalived virtual IP address.
My setup consists of two IPFire systems:
-
Primary IPFire: 192.168.222.251
-
Secondary IPFire: 192.168.222.252
-
Keepalived virtual IP: 192.168.222.254
The virtual IP is used as both the default gateway and the primary DNS server for clients on the GREEN network.
The virtual IP is present correctly on the active node:
inet 192.168.222.251/24 scope global green0
inet 192.168.222.254/32 scope global proto keepalived green0
Knot Resolver is listening on:
0.0.0.0:53
The generated configuration contains:
network:
listen:
- interface: 0.0.0.0@53
When a client sends a DNS query to the virtual address, the reply is sent from the physical address of the active IPFire system:
nslookup google.com 192.168.222.254
reply from unexpected source: 192.168.222.251#53,
expected 192.168.222.254#53
A query sent directly to 192.168.222.251 works correctly.
It therefore looks as though Knot receives the query on the virtual IP but chooses the primary interface address as the source address for the UDP reply. Clients reject that reply because it does not come from the address they queried.
Most of my normal clients still appear to work because DHCP also provides 1.1.1.1 as a secondary DNS server. Some Docker containers did not recover in the same way and lost DNS resolution completely until I configured them to use 1.1.1.1 directly.
I realise that Keepalived is not a standard IPFire configuration, and I would prefer not to manually edit /etc/knot-resolver/config.yaml, since it is generated by IPFire and may be overwritten.
Would it be possible for IPFire to support this type of setup by generating explicit listening addresses instead of only 0.0.0.0@53? For example, perhaps the resolver could bind explicitly to the physical address and to any configured virtual address, using freebind where necessary so that the backup node can start before it owns the virtual IP.
Alternatively, is there another supported way to make Knot Resolver send DNS replies using the destination address on which the query was received?
The system is currently usable because of the secondary public DNS server, but DNS failover through the Keepalived virtual IP is not working as intended.
Thank you again for the update and especially for the substantial reduction in memory usage.