Compiling and Installing dnsmasq from Source on Ubuntu 22.04

Posted on Thu 19 January 2023 in DevOps • 2 min read

Background

I was monitoring my nginx logs, when I stumbled across a peculiar error where nginx was trying to connect to a Firebase backend with a DNS entry that resolves to an IPv6 address.

[nginx][] 2023/01/06 07:32:38 [error] 61125#61125: *4683 connect() to
[fe80::cf4d:cab8:b943]:443 failed (101: Network is unreachable) while
connecting to upstream, client: 1.1.1.1, server: , request: 
"GET /file.json?v=3 HTTP/2.0", upstream: 
"https://[fe80::cf4d:cab8:b943]:443/file.json?v=3", host: "example.com", 
referrer: "https://example.com/worker.js"

This was rather perplexing, since none of my nginx servers have any IPv6 addresses attached to them, but discovered that the DNS lookup for my Firebase application was returning the same IPv6 address that I noticed in my nginx log file.

$ host example-app.firebaseapp.com
example-app.firebaseapp.com has address 192.168.1.1
example-app.firebaseapp.com has IPv6 address fe80::cf4d:cab8:b943

I then determined that the best way to solve this problem would be to set up dnsmasq as a DNS cache, and use the filter-AAAA option to prevent it from performing IPv6 lookups.

The problem with this, however, is that the latest version of the dnsmasq package in the Ubuntu 22.04 repositories is version 2.86 and the filter-AAAA feature was only introduced in dnsmasq version 2.87.

Ubuntu 23.04 (Lunar Lobster), which is currently under active development at the time of writing, is the only Ubuntu version that has a version of dnsmasq that supports the filter-AAAA feature, so I decided to compile and install dnsmasq from the source used by Ubuntu 23.04.

Download, Compile and Install dnsmasq from Source

Download source for dnsmasq version 2.88 from Ubuntu Launchpad site

cd /tmp
wget https://launchpad.net/ubuntu/+archive/primary/+sourcefiles/dnsmasq/2.88-1/dnsmasq_2.88.orig.tar.gz

Extract dnsmasq 2.88 source

tar zxvf dnsmasq_2.88.orig.tar.gz

Install dependency packages

sudo apt update
sudo apt install dnsmasq gettext

Compile dnsmasq

cd dnsmasq-2.88.orig
make all-i18n

Confirm the version of the compiled dnsmasq binary

src/dnsmasq -v

Stop the dnsmasq service

sudo systemctl stop dnsmasq

Copy the newly compiled binary over the old one

sudo cp src/dnsmasq /usr/sbin/dnsmasq

Remove file that is no longer supported by the new binary

sudo rm /usr/share/dns/root.ds

Edit the dnsmasq config file and configure it to exclude IPv6 lookups

sudo vim /etc/dnsmasq.conf

Paste the following content:

listen-address=127.0.0.53
port=53
bind-interfaces
user=dnsmasq
group=nogroup
pid-file=/var/run/dnsmasq/dnsmasq.pid

# Name resolution options
resolv-file=/etc/resolv.dnsmasq
cache-size=500
neg-ttl=60
domain-needed
bogus-priv
filter-AAAA

And save the file.

Configure the DNS resolver for the dnsmasq service

sudo bash -c "echo 'nameserver 1.1.1.1' > /etc/resolv.dnsmasq"

Configure DNS resolver for Consul (OPTIONAL)

sudo vim /etc/dnsmasq.d/10-consul

Paste the following content:

server=/consul/127.0.0.1#8600

And save the file.

Disable systemd resolved

sudo vim /etc/systemd/resolved.conf.d/noresolved.conf

Paste the following content:

[Resolve]
DNSStubListener=no

And save the file.

Restart the systemd-resolved and dnsmasq services

sudo systemctl restart systemd-resolved
sudo systemctl restart dnsmasq.service

Edit /etc/resolv.conf to use dnsmasq as the DNS resolver

sudo vim /etc/resolv.conf

Paste the following content:

nameserver 127.0.0.53

And save the file.

Verify that the DNS is now only resolving to IPv4 addresses and not IPv6 anymore

$ host example-app.firebaseapp.com
example-app.firebaseapp.com has address 192.168.1.1