BIND is resolving to IPv6 instead of IPv4

Started by defaultuserfoo, May 25, 2024, 08:23:31 PM

Previous topic - Next topic
Hi,

using the BIND plugin, it turns out that when asterisk running on my server requests an IP address of the server of the VOIP provider, OPNsense responds with IPv6 addresses instead of IPv4 addresses.

Running BIND on the server where asterisk is running, asterisk gets IPv4 addresses.

Since the trasports asterisk uses must be bound to the IPv4 address of the server because I can't get a static IPv6 prefix, the server of the VOIP provider becomes unreachable.

Shouldn't BIND on OPNsense resolve to IPv4 addresses when they are requested like BIND on the server does?  This seems like a bug.

How can I fix that other than to keep using the name server running on the server?

May 25, 2024, 09:54:08 PM #1 Last Edit: May 25, 2024, 10:09:45 PM by RamSense
for a quick test, does it get ipv4 when you go to opnsense- bind - configuration - general - and you tick Disable IPv6?

N.B. found another setting in opnsense - settings - general - you can enable "refer IPv4 over IPv6" -> [By default, if a hostname resolves IPv6 and IPv4 addresses IPv6 will be used. If you check this option, IPv4 will be used instead of IPv6. ]
Deciso DEC850v2

I doubt that the preference on OpnSense would change what a client gets. It will most probably only influence what OpnSense uses itself. You can change the order in many OSes, however.

By definition, if both IPv6 and IPv4 are supported, IPv6 is the preferred protocol. However, with DNS, it is up to the client what is being asked for or what is preferred. Since Asterisk obviously can handle IPv6, it will ask for that first, unless you configure it otherwise.

The only other way was to restrict bind or whatever DNS service you choose on OpnSense to only handle IPv4, but that limits most clients to use IPv4 only.

To put it short: If you want IPv4 adresses from a DNS service, ask for it (i.e. use the equivalent of "nslookup -query=A x.y.z" vs. "nslookup -query=AAAA x.y.z" or "nslookup x.y.z").
Intel N100, 4 x I226-V, 16 GByte, 256 GByte NVME, ZTE F6005

1100 down / 770 up, Bufferbloat A

With a pjsip transport bound to an IPv4 address, of course I expect asterisk to ask for IPv4 addresses and not for IPv6 ones.  It obviously does that because with bind running on Linux it works and asterisk registers just fine.

When I manually ping the server of the VOIP provider, ping uses an IPv6 address.  I have to use 'ping -4' to get an IPv4 address.  That also shows that asterisk must be asking for IPv4 and not for IPv6.

With bind running on OPNsense, it doesn't work. I have verified that when using the IP address of the server of the VOIP provider instead of the host name, it works and asterisk registers.  Again the conclusion is that bind on OPNsense is incorrectly answering with an IPv6 address instead of an IPv4 address.

Of course I don't want to generally restrict clients to use IPv4 only or to prefer IPv4 instead of IPv6.  If I wanted that, I could better turn off IPv6 altogether.

So why is the bind version OPNsense buggy, and when will that be fixed?  Or, if it's not buggy, then why does asterisk get the wrong answers?

For now, I've gone back to using bind on my server.  But I would have liked to use bind on OPNsense.

May 26, 2024, 01:04:45 AM #4 Last Edit: May 26, 2024, 01:06:49 AM by meyergru
Quote from: defaultuserfoo on May 26, 2024, 12:42:36 AM
When I manually ping the server of the VOIP provider, ping uses an IPv6 address.  I have to use 'ping -4' to get an IPv4 address.  That also shows that asterisk must be asking for IPv4 and not for IPv6.

No, it shows that when you advise the client (ping) to use IPv4, it will ask for the IPv4 address of its target only.
Try it yourself: If you use "nslookup <target>", you will get both adresses. Which of those are used is then up to the client (which will default to IPv6 if it is able to use it).

Quote from: defaultuserfoo on May 26, 2024, 12:42:36 AM
With bind running on OPNsense, it doesn't work. I have verified that when using the IP address of the server of the VOIP provider instead of the host name, it works and asterisk registers.  Again the conclusion is that bind on OPNsense is incorrectly answering with an IPv6 address instead of an IPv4 address.

You are wrong. The default for DNS is to return all addresses (in no specific order) and it is up to the client to decide which it uses. That is by design, not "incorrect". But as I said, you can restrict OpnSense or even bind itself to only use IPv4, as is probably the case with your other bind instance.

Consider this: If you want bind on OpnSense to return IPv6 adresses as well as IPv4, and you have three options:

1. Ask for IPv4
2. Ask for IPv6
3. Ask for any IP

and you say, you want to be able to do 2. and 3. (since you do not want to disable IPv6 altogether), what does your client have to do in order to get IPv4? See?

I would guess that your server bind installation is restricted to IPv4 only like this.
Intel N100, 4 x I226-V, 16 GByte, 256 GByte NVME, ZTE F6005

1100 down / 770 up, Bufferbloat A

maybe a quick "fix" for this is to make a dnsrewrite in opnsense-bind for this particular domain pointing to ipv4?

see here how this can be done in bind: https://www.redpill-linpro.com/techblog/2015/12/08/dns-rpz.html
Deciso DEC850v2

May 26, 2024, 07:52:42 PM #6 Last Edit: May 26, 2024, 07:54:41 PM by defaultuserfoo
Quote from: meyergru on May 26, 2024, 01:04:45 AM
Quote from: defaultuserfoo on May 26, 2024, 12:42:36 AM
When I manually ping the server of the VOIP provider, ping uses an IPv6 address.  I have to use 'ping -4' to get an IPv4 address.  That also shows that asterisk must be asking for IPv4 and not for IPv6.

No, it shows that when you advise the client (ping) to use IPv4, it will ask for the IPv4 address of its target only.

It only does that when using 'ping -4'.  I don't know what asterisk does.  I only know that it gets IPv4 address with bind on Linux and and IPv6 address with bind on OPNsense.  That means that there is a problem with bind on OPNsense.

However, it wouldn't make sense for asterisk to request an IPv6 address for a transport that is bound to an IPv4 address.  And apparently doesn't do that because if it did, it would get an IPv6 address just like ping and 'ping -6' get.

Quote
Try it yourself: If you use "nslookup <target>", you will get both adresses. Which of those are used is then up to the client (which will default to IPv6 if it is able to use it).

Right.  And?

Why would a client request an IPv6 address when it doesn't need/want/use one?

Why would asterisk decide to use an IPv6 address instead of an IPv4 address depending on which system the name server is running on?  Asterisk doesn't know where bind runs.

Quote
Quote from: defaultuserfoo on May 26, 2024, 12:42:36 AM
With bind running on OPNsense, it doesn't work. I have verified that when using the IP address of the server of the VOIP provider instead of the host name, it works and asterisk registers.  Again the conclusion is that bind on OPNsense is incorrectly answering with an IPv6 address instead of an IPv4 address.

You are wrong. The default for DNS is to return all addresses (in no specific order) and it is up to the client to decide which it uses. That is by design, not "incorrect".

If that is so, then why does asterisk decide not to use the IPv4 address when bind is running on OPNsense?

Quote
But as I said, you can restrict OpnSense or even bind itself to only use IPv4, as is probably the case with your other bind instance.

No, the bind on Linux is not restricted to IPv4.  And no, if I were to restrict bind on OPNsense to IPv4, that would mean to turn off IPv6 entirely, which is not what I want.

Quote
Consider this: If you want bind on OpnSense to return IPv6 adresses as well as IPv4, and you have three options:

1. Ask for IPv4
2. Ask for IPv6
3. Ask for any IP

and you say, you want to be able to do 2. and 3. (since you do not want to disable IPv6 altogether), what does your client have to do in order to get IPv4? See?

I also want to be able to do 1..  I don't know what a client needs to do to ask for an IPv4 address since I never had to do any programming for getting IPv4 or IPv6 addresses.

Quote
I would guess that your server bind installation is restricted to IPv4 only like this.

No, there is no restriction to IPv6.  For example:


# ping ipv64.net
PING ipv64.net (2a01:4f8:192:1326::bad:c0de) 56 data bytes
64 bytes from ipv64.net (2a01:4f8:192:1326::bad:c0de): icmp_seq=1 ttl=57 time=12.4 ms
[...]


# dig ipv64.net

; <<>> DiG 9.18.26 <<>> ipv64.net
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 5885
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
; COOKIE: 41379600a24aa64b010000006653753b6c1b0112247d26d9 (good)
;; QUESTION SECTION:
;ipv64.net.                     IN      A

;; ANSWER SECTION:
ipv64.net.              3446    IN      A       144.76.85.238

;; Query time: 0 msec
;; SERVER: 127.0.0.1#53(127.0.0.1) (UDP)
;; WHEN: Sun May 26 19:45:31 CEST 2024
;; MSG SIZE  rcvd: 82


# dig -t any ipv64.net

; <<>> DiG 9.18.26 <<>> -t any ipv64.net
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 64751
;; flags: qr rd ra; QUERY: 1, ANSWER: 8, AUTHORITY: 0, ADDITIONAL: 5

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
; COOKIE: 9072464819cc397a0100000066537571f28842cc104a0ef2 (good)
;; QUESTION SECTION:
;ipv64.net.                     IN      ANY

;; ANSWER SECTION:
ipv64.net.              3143    IN      SOA     ns1.ipv64.net. hostmaster.ipv64.net. 4239685 10800 3600 604800 3600
ipv64.net.              3520    IN      AAAA    2a01:4f8:192:1326::bad:c0de
ipv64.net.              3392    IN      A       144.76.85.238
ipv64.net.              3143    IN      NS      ns1.ipv64.net.
ipv64.net.              3143    IN      NS      ns2.ipv64.net.
ipv64.net.              3143    IN      TXT     "v=spf1 mx a -all"
ipv64.net.              3143    IN      TXT     "google-site-verification=8aQ-Dd65zb-d8CCA121kSqkuOOHHzrpxEg9f8ADm7f8"
ipv64.net.              3143    IN      MX      10 mail.schroederdennis.de.

;; ADDITIONAL SECTION:
ns1.ipv64.net.          88807   IN      A       195.201.223.103
ns2.ipv64.net.          88807   IN      A       157.90.241.20
ns1.ipv64.net.          88807   IN      AAAA    2a01:4f8:c2c:559c::1
ns2.ipv64.net.          88807   IN      AAAA    2a01:4f8:c012:9c97::1

;; Query time: 0 msec
;; SERVER: 127.0.0.1#53(127.0.0.1) (TCP)
;; WHEN: Sun May 26 19:46:25 CEST 2024
;; MSG SIZE  rcvd: 430



The only thing that may be suspicious is that dig shows the IPv4 address.  But it's apparently not a problem because I get the same behaviour when asking bind running on OPNsense:



dig -p 530 ipv64.net @192.168.3.1

; <<>> DiG 9.18.26 <<>> -p 530 ipv64.net @192.168.3.1
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 37648
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
; COOKIE: 3d90bb4740ed5194010000006653763ec95d7c5786cc36bc (good)
;; QUESTION SECTION:
;ipv64.net.                     IN      A

;; ANSWER SECTION:
ipv64.net.              3600    IN      A       144.76.85.238

;; Query time: 55 msec
;; SERVER: 192.168.3.1#530(192.168.3.1) (UDP)
;; WHEN: Sun May 26 19:49:50 CEST 2024
;; MSG SIZE  rcvd: 82


dig -p 530 -t any ipv64.net @192.168.3.1

; <<>> DiG 9.18.26 <<>> -p 530 -t any ipv64.net @192.168.3.1
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 21078
;; flags: qr rd ra; QUERY: 1, ANSWER: 8, AUTHORITY: 0, ADDITIONAL: 5

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
; COOKIE: 5148bcba6202632d010000006653769e52b873e71ac13dc5 (good)
;; QUESTION SECTION:
;ipv64.net.                     IN      ANY

;; ANSWER SECTION:
ipv64.net.              3600    IN      SOA     ns1.ipv64.net. hostmaster.ipv64.net. 4239843 10800 3600 604800 3600
ipv64.net.              3600    IN      AAAA    2a01:4f8:192:1326::bad:c0de
ipv64.net.              3504    IN      A       144.76.85.238
ipv64.net.              3600    IN      NS      ns1.ipv64.net.
ipv64.net.              3600    IN      NS      ns2.ipv64.net.
ipv64.net.              3600    IN      TXT     "google-site-verification=8aQ-Dd65zb-d8CCA121kSqkuOOHHzrpxEg9f8ADm7f8"
ipv64.net.              3600    IN      TXT     "v=spf1 mx a -all"
ipv64.net.              3600    IN      MX      10 mail.schroederdennis.de.

;; ADDITIONAL SECTION:
ns1.ipv64.net.          172704  IN      A       195.201.223.103
ns2.ipv64.net.          172704  IN      A       157.90.241.20
ns1.ipv64.net.          172704  IN      AAAA    2a01:4f8:c2c:559c::1
ns2.ipv64.net.          172704  IN      AAAA    2a01:4f8:c012:9c97::1

;; Query time: 37 msec
;; SERVER: 192.168.3.1#530(192.168.3.1) (TCP)
;; WHEN: Sun May 26 19:51:26 CEST 2024
;; MSG SIZE  rcvd: 430


So I assume that dig asks for IPv4 addresses unless instructed otherwise, unlike ping.

Quote from: RamSense on May 26, 2024, 10:25:38 AM
maybe a quick "fix" for this is to make a dnsrewrite in opnsense-bind for this particular domain pointing to ipv4?

see here how this can be done in bind: https://www.redpill-linpro.com/techblog/2015/12/08/dns-rpz.html

Cool, thanks, this is good to know :)

IIRC, it would have the same effect as using the IPv4 address of the server of the VOIP provider instead of the FQDN of that server in the configuration of asterisk.  I don't want to do that because if the address changes, asterisk might contact the wrong server and thus could leak passwords.  Also, I'd be wondering why the phones suddenly don't work anymore and spend a day or so to figure out why because I forgot that I used the IPv4 address instead of the FQDN.  I don't want to do that.

May 26, 2024, 08:08:45 PM #8 Last Edit: May 26, 2024, 08:14:45 PM by defaultuserfoo
[deleted by me, I misread a log file]

While I do not use asterisk, did some searching and maybe changing the config file of asteriks will work? do you have there ipv4 and ipv6 enabled? change it to bindaddr=0.0.0.0, see below, or http://lists.digium.com/pipermail/asterisk-users/2013-September/280696.html

Quote; With the current situation, you can do one of four things:
;  a) Listen on a specific IPv4 address.      Example: bindaddr=192.0.2.1
;  b) Listen on a specific IPv6 address.      Example: bindaddr=2001:db8::1
;  c) Listen on the IPv4 wildcard.            Example: bindaddr=0.0.0.0
;  d) Listen on the IPv4 and IPv6 wildcards.  Example: bindaddr=::
; (You can choose independently for UDP, TCP, and TLS, by specifying different values for
; "udpbindaddr", "tcpbindaddr", and "tlsbindaddr".)
; (Note that using bindaddr=:: will show only a single IPv6 socket in netstat.
;  IPv4 is supported at the same time using IPv4-mapped IPv6 addresses.)
;
; You may optionally add a port number. (The default is port 5060 for UDP and TCP, 5061
; for TLS).
;   IPv4 example: bindaddr=0.0.0.0:5062
;   IPv6 example: bindaddr=[::]:5062
;
; The address family of the bound UDP address is used to determine how Asterisk performs
; DNS lookups. In cases a) and c) above, only A records are considered. In case b), only
; AAAA records are considered. In case d), both A and AAAA records are considered. Note,
; however, that Asterisk ignores all records except the first one. In case d), when both A
; and AAAA records are available, either an A or AAAA record will be first, and which one
; depends on the operating system. On systems using glibc, AAAA records are given
; priority.

udpbindaddr=0.0.0.0             ; IP address to bind UDP listen socket to (0.0.0.0 binds to all)
                                ; Optionally add a port number, 192.168.1.1:5062 (default is port 5060)
Deciso DEC850v2

May 27, 2024, 10:43:26 PM #10 Last Edit: May 27, 2024, 10:49:09 PM by defaultuserfoo
Yes, the transport has always been bound to the IPv4 address of the server in pjsip.conf:


[transport-tls]
type=transport
protocol=tls
bind=192.168.3.50:5061
ca_list_file=/etc/pki/tls/certs/ca-bundle.crt
cert_file=/etc/asterisk/cert/cert.pem
priv_key_file=/etc/asterisk/cert/privkey.pem
method=tlsv1_2


If I wanted an IPv6 transport, I would have to set up another transport that binds to an IPv6 address.  Since I don't have static IPv6 addresses there's no point in doing that.  IPv6 is basically useless without static addresses just like IPv4.  ISPs need to be forced by law to give out static addresses on demand.

Still why doesn't it work with bind on OPNsense?