Use dnsmasq on OpenSUSE


I ran into this bug of steam on linux. Basically, steam fires up tons of DNS queries when downloading/updating and constantly triggers the throttling mechanism on the DNS servers, resulting a terribly slow download speed.

It's a shame that this bug has been there for over 4 years and steam did little to nothing to address it. And that's where dnsmasq comes to the rescue.

dnsmasque works as a local DNS server which can bridge the DNS queries in your local network and the real DNS server, hence can provide DNS caching, which is exactly what we need to prevent steam from triggering the remote DNS server's throttling mechanism. It is also capable of local DHCP management but that's not our concern here, so this article will skip on that. As usual, I am writing about using it on OpenSUSE, other distros follows pretty much the same steps of configuration.

Installation

Use the following command to install dnsmasq (chances are it's already there by default).

zypper in dnsmasq

Configuration

The configuration file is located at /etc/dnsmasq.conf. Open it, find and uncomment the following lines.

conf-file=/etc/dnsmasq.d/trust-anchors.conf
dnssec

resolv-file=/etc/resolv.dnsmasq.conf

listen-address=::1,127.0.0.1

cache-size=2500


log-queries
log-facility=/var/log/dnsmasq.log
  1. The conf-file and dnssec lines enable DNSSEC, which validates replies from the DNS server and can guard you against spoofing and cache poisoning.

  2. The resolv-file line sets the path for a file where dnsmasq looks for addresses of DNS servers, other than the system default /etc/resolv.conf. We need to put the DNS server addresses (basically those in /etc/resolv.conf) in this file, then change the content of /etc/resolv.conf into:

    nameserver 127.0.0.1 
    

  3. The listen-address line tells dnsmasq where to listen for DNS queries, in our case, it listens on the local machine.

  4. The cache-size line tells dnsmasq how many entries of DNS records should be cached. Note that because we enabled DNSSEC, this size must be larger than a certain number (eg. we use 2500 here), otherwise dnsmasq will give the following complaint.

    cannot reduce cache size from default when DNSSEC enabled

  5. The log-queries and log-facility lines allow dnsmasq to log the received queries to your given path. It is convenient to have this for testing, you can comment them out later if everything works fine.

Run
  1. Enable and start the dnsmasq service.

    systemctl enable dnsmasq.service
    systemctl start dnsmasq.service
    

  2. Restart your network.

    systemctl restart NetworkManager.service
    

  3. Open your browser to test if everything works, check the logs if necessary.

Some notes

OpenSUSE has default apparmor profile for dnsmasq, which will be enabled once you install and run dnsmasq. It may prevent dnsmasq to read non-default files and cause problems. For example, we have set the resolv-file option for dnsmasq to look for actual DNS servers, but this file is not given read permission in the app armor profile, and we may find that dnsmasq refuse all the DNS queries it received and report the following error in the log.

failed to read /etc/resolv.dnsmasq.conf: Permission denied

To fix this, we have to edit the apparmor profile for dnsmasq. Use the following command to find out the profile name:

aa-unconfined
In my case, I have something like below in the output.

2285 /usr/sbin/dnsmasq confined by '/usr/sbin/dnsmasq (enforce)'

It says dnsmasq is confined by /usr/sbin/dnsmasq, which then corresponds to the apparmor profile usr.sbin.dnsmasq located in /etc/apparmor.d/. Open the profile and add in the following line:

PATH_OF_FILE_NEED_READ_PERMISSION r,
where, PATH_OF_FILE_NEED_READ_PERMISSION corresponds to the path of the file that dnsmasq is complaining about having no read permission, which in my case is the value of resolv-file, i.e. /etc/resolv.dnsmasq.conf.

After that, restart apparmor, dnsmasq and your network:

systemctl restart apparmor.service
systemctl restart dnsmasq.service
systemctl restart NetworkManager.service

By