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.
Use the following command to install dnsmasq (chances are it's already there by default).
zypper in dnsmasq
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
The conf-file and dnssec lines enable DNSSEC, which validates replies from the DNS server and can guard you against spoofing and cache poisoning.
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
The listen-address line tells dnsmasq where to listen for DNS queries, in our case, it listens on the local machine.
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
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.
Enable and start the dnsmasq service.
systemctl enable dnsmasq.service systemctl start dnsmasq.service
Restart your network.
systemctl restart NetworkManager.service
Open your browser to test if everything works, check the logs if necessary.
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
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,
After that, restart apparmor, dnsmasq and your network:
systemctl restart apparmor.service systemctl restart dnsmasq.service systemctl restart NetworkManager.service
By Lynxiayel
yulinling.net
24 Nov 2018 24 Nov 2018