Controlling the source adress when exposing a port on an interface with multiple addresses

Hi all, I was trying to host a DNS server in a container and -p 53:53/udp but run into an weird issue. My host interface has multiple IPv6 address (let’s say they are fe80::1 and fe80::2). When I try to nslookup example.com fe80::2%eth0, the response packet always has fe80::1 as its source address (found that out by tracing the packets with ip6tables) and as a result the packets got ignored by nslookup due to the mismatch (and nslookup gave me a timeout error).

I did some research, and it seems for IPv4 docker implements exposing a port with

iptables -t nat -A DOCKER ! -i br-0165dac77969 -p udp -m udp --dport 53 -j DNAT --to-destination 172.16.6.2:53

for packets coming from outside of the host, where 172.16.6.2 is the address of the container, and

iptables -t nat -A POSTROUTING -s 172.16.6.2/32 -d 172.16.6.2/32 -p udp -m udp --dport 53 -j MASQUERADE

for packets on the way out.

If I understand correctly, -j MASQUERADE implies (for IPv4 packets) the source address of the response only depends on the destination address of the response (i.e., where the request comes from), and won’t necessarily match the destination address of the request if the interface has multiple addresses?

However I couldn’t figure out how exposing the port works for IPv6 (ip6tables -t nat -S seems to be empty). So my questions are:

  1. How is exposing a port implemented for IPv6 packets? (Is it handled by the userland proxy since link local addresses are not routable anyways?)
  2. If I want the response source address to match the request destination address so my DNS server will work, what is the best way to do that?

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.