From: Stefano Brivio <sbrivio@redhat.com>
To: passt-dev@passt.top
Cc: Prafulla Giri <prafulla.giri@protonmail.com>
Subject: [PATCH] conf: Don't map DNS traffic to host, if host gateway is a resolver
Date: Mon, 3 Feb 2025 09:22:10 +0100 [thread overview]
Message-ID: <20250203082210.2114348-1-sbrivio@redhat.com> (raw)
This should be a relatively common case and I'm a bit surprised it's
been broken since I added the "gateway mapping" functionality, but it
doesn't happen with Podman, and not with systemd-resolved or similar
local proxies, and also not with servers where typically the gateway
is just a router and not a DNS resolver. That could be the reason why
nobody noticed until now.
By default, we'll map the address of the default gateway, in
containers and guests, to represent "the host", so that we have a
well-defined way to reach the host. Say:
0.0029: NAT to host 127.0.0.1: 192.168.100.1
But if the host gateway is also a DNS resolver:
0.0029: DNS:
0.0029: 192.168.100.1
then we'll send DNS queries directed to it to the host instead:
0.0372: Flow 0 (INI): TAP [192.168.100.157]:41892 -> [192.168.100.1]:53 => ?
0.0372: Flow 0 (TGT): INI -> TGT
0.0373: Flow 0 (TGT): TAP [192.168.100.157]:41892 -> [192.168.100.1]:53 => HOST [0.0.0.0]:41892 -> [127.0.0.1]:53
0.0373: Flow 0 (UDP flow): TGT -> TYPED
0.0373: Flow 0 (UDP flow): TAP [192.168.100.157]:41892 -> [192.168.100.1]:53 => HOST [0.0.0.0]:41892 -> [127.0.0.1]:53
0.0373: Flow 0 (UDP flow): Side 0 hash table insert: bucket: 31049
0.0374: Flow 0 (UDP flow): TYPED -> ACTIVE
0.0374: Flow 0 (UDP flow): TAP [192.168.100.157]:41892 -> [192.168.100.1]:53 => HOST [0.0.0.0]:41892 -> [127.0.0.1]:53
which doesn't quite work, of course:
0.0374: pasta: epoll event on UDP reply socket 95 (events: 0x00000008)
0.0374: ICMP error on UDP socket 95: Connection refused
unless the host is a resolver itself... but then we wouldn't find the
address of the gateway in its /etc/resolv.conf, presumably.
Fix this by making an exception for DNS traffic: if the default
gateway is a resolver, match on DNS traffic going to the default
gateway, and explicitly forward it to the configured resolver.
Reported-by: Prafulla Giri <prafulla.giri@protonmail.com>
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
---
conf.c | 16 ++++++++++------
passt.1 | 14 ++++++++++----
2 files changed, 20 insertions(+), 10 deletions(-)
diff --git a/conf.c b/conf.c
index df2b016..360ce21 100644
--- a/conf.c
+++ b/conf.c
@@ -426,10 +426,12 @@ static void add_dns_resolv(struct ctx *c, const char *nameserver,
if (IN4_IS_ADDR_UNSPECIFIED(&c->ip4.dns_host))
c->ip4.dns_host = ns4;
- /* Guest or container can only access local addresses via
- * redirect
+ /* Special handling if guest or container can only access local
+ * addresses via redirect, or if the host gateway is also a
+ * resolver and we shadow its address
*/
- if (IN4_IS_ADDR_LOOPBACK(&ns4)) {
+ if (IN4_IS_ADDR_LOOPBACK(&ns4) ||
+ IN4_ARE_ADDR_EQUAL(&ns4, &c->ip4.map_host_loopback)) {
if (IN4_IS_ADDR_UNSPECIFIED(&c->ip4.map_host_loopback))
return;
@@ -445,10 +447,12 @@ static void add_dns_resolv(struct ctx *c, const char *nameserver,
if (IN6_IS_ADDR_UNSPECIFIED(&c->ip6.dns_host))
c->ip6.dns_host = ns6;
- /* Guest or container can only access local addresses via
- * redirect
+ /* Special handling if guest or container can only access local
+ * addresses via redirect, or if the host gateway is also a
+ * resolver and we shadow its address
*/
- if (IN6_IS_ADDR_LOOPBACK(&ns6)) {
+ if (IN6_IS_ADDR_LOOPBACK(&ns6) ||
+ IN6_ARE_ADDR_EQUAL(&ns6, &c->ip6.map_host_loopback)) {
if (IN6_IS_ADDR_UNSPECIFIED(&c->ip6.map_host_loopback))
return;
diff --git a/passt.1 b/passt.1
index d9cd33e..7b6eabd 100644
--- a/passt.1
+++ b/passt.1
@@ -941,10 +941,16 @@ with destination 127.0.0.10, and the default IPv4 gateway is 192.0.2.1, while
the last observed source address from guest or namespace is 192.0.2.2, this will
be translated to a connection from 192.0.2.1 to 192.0.2.2.
-Similarly, for traffic coming from guest or namespace, packets with
-destination address corresponding to the \fB\-\-map-host-loopback\fR
-address will have their destination address translated to a loopback
-address.
+Similarly, for traffic coming from guest or namespace, packets with destination
+address corresponding to the \fB\-\-map-host-loopback\fR address will have their
+destination address translated to a loopback address.
+
+As an exception, traffic identified as DNS, originally directed to the
+\fB\-\-map-host-loopback\fR address, if this address matches a resolver address
+on the host, is \fBnot\fR translated to loopback, but rather handled in the same
+way as if specified as \-\-dns-forward address, if no such option was given.
+In the common case where the host gateway also acts a resolver, this avoids that
+the host mapping shadows the gateway/resolver itself.
.SS Handling of local traffic in pasta
--
@@ -941,10 +941,16 @@ with destination 127.0.0.10, and the default IPv4 gateway is 192.0.2.1, while
the last observed source address from guest or namespace is 192.0.2.2, this will
be translated to a connection from 192.0.2.1 to 192.0.2.2.
-Similarly, for traffic coming from guest or namespace, packets with
-destination address corresponding to the \fB\-\-map-host-loopback\fR
-address will have their destination address translated to a loopback
-address.
+Similarly, for traffic coming from guest or namespace, packets with destination
+address corresponding to the \fB\-\-map-host-loopback\fR address will have their
+destination address translated to a loopback address.
+
+As an exception, traffic identified as DNS, originally directed to the
+\fB\-\-map-host-loopback\fR address, if this address matches a resolver address
+on the host, is \fBnot\fR translated to loopback, but rather handled in the same
+way as if specified as \-\-dns-forward address, if no such option was given.
+In the common case where the host gateway also acts a resolver, this avoids that
+the host mapping shadows the gateway/resolver itself.
.SS Handling of local traffic in pasta
--
2.43.0
reply other threads:[~2025-02-03 8:22 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20250203082210.2114348-1-sbrivio@redhat.com \
--to=sbrivio@redhat.com \
--cc=passt-dev@passt.top \
--cc=prafulla.giri@protonmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://passt.top/passt
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for IMAP folder(s).