6

Using systemd-resolved how do I block, route, or resolve, a domain name to a black hole, or a nowhere address. Bonus points for subdomains as well.

I tried a single domain in /etc/hosts:

127.0.0.1 google.com
::1 google.com

I also tried /etc/systemd/network/100-blocked.network:

[Match]
Name=wlp113s0

[Network]
Description="Just block the domain, and sub domains"
DNS=127.0.0.255
DNS=::1

[Resolve]
Domains=google.com

sudo systemd-resolve --status:

Link 3 (wlp113s0)
      Current Scopes: DNS
       LLMNR setting: yes
MulticastDNS setting: no
      DNSSEC setting: no
    DNSSEC supported: no
         DNS Servers: 127.0.0.255
                      ::1
                      2001:4888:3a:ff00:304:d::
                      2001:4888:39:ff00:308:d::

for example using dnsmasq i was able to do:

server=192.168.43.1
address=/google.com/0.0.0.0
# a very long list of "address=/domain/0"

related:

jmunsch
  • 4,346
  • The /etc/hosts thing should still work. But I noticed that this works for some domains and not for others :/ – Pierre-Alain TORET Nov 08 '18 at 15:50
  • @Pierre-AlainTORET Can you give examples of domains that work and that don't? Would be interesting to look into the differences between those... – filbranden Nov 09 '18 at 03:32
  • 1
    My bad, actually I get it working for all with ping, my test in Firefox wasn't good. Sorry. The thing is how do you use systemd-resolved ? What tool do you use to test ? And what is the result of all your tests ? – Pierre-Alain TORET Nov 09 '18 at 09:42
  • @Pierre-AlainTORET default settings of firefox with caching disabled via dev tools. but sometimes curl, ping, dig – jmunsch Nov 09 '18 at 15:58

2 Answers2

2

Adding an entry to /etc/hosts is supposed to work and in my tests it worked as expected. My tests are on Fedora Rawhide, with version systemd-239-9.git9f3aed1.fc30.x86_64, so that's a pretty recent snapshot of systemd, maybe older versions will not work the same as expected...


Before adding the entry to /etc/hosts:

1) resolvectl query:

$ resolvectl query google.com
google.com: 172.217.6.78

-- Information acquired via protocol DNS in 1.4ms.
-- Data is authenticated: no

2) ping:

$ ping -c1 google.com
PING google.com (172.217.6.78) 56(84) bytes of data.
64 bytes from sfo07s17-in-f78.1e100.net (172.217.6.78): icmp_seq=1 ttl=54 time=12.4 ms

--- google.com ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 12.435/12.435/12.435/0.000 ms

3) curl:

$ curl http://google.com
<HTML><HEAD><meta http-equiv="content-type" content="text/html;charset=utf-8">
<TITLE>301 Moved</TITLE></HEAD><BODY>
<H1>301 Moved</H1>
The document has moved
<A HREF="http://www.google.com/">here</A>.
</BODY></HTML>

After adding the entry, in which case /etc/hosts looks like this:

$ cat /etc/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6

127.0.0.1 google.com
::1 google.com

Tests showed the blocking is working:

1) resolvectl query:

$ resolvectl query google.com
google.com: 127.0.0.1
            ::1

-- Information acquired via protocol DNS in 1.8ms.
-- Data is authenticated: yes

2) ping:

$ ping -c1 google.com
PING google.com(localhost (::1)) 56 data bytes
64 bytes from localhost (::1): icmp_seq=1 ttl=64 time=0.613 ms

--- google.com ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.613/0.613/0.613/0.000 ms

3) curl:

$ curl http://google.com
curl: (7) Failed to connect to google.com port 80: Connection refused

So the block seems to be working.


I expected this would work, since this was brought up recently in an issue filed against systemd. Issue #9718 talked about adding millions of entries to /etc/hosts, which has one usecase and that's blacklisting domains, such as here.

Please note that there are quite a few moving parts here, so it's important to consider those while troubleshooting this.

My /etc/systemd/resolved.conf has no overridden configuration, all entries are commented out, network setup is using systemd-networkd with DHCP and no overrides either.

Output of resolvectl status includes:

Global
       LLMNR setting: yes
MulticastDNS setting: yes
  DNSOverTLS setting: no
      DNSSEC setting: allow-downgrade
    DNSSEC supported: no
Fallback DNS Servers: 8.8.8.8
                      8.8.4.4
                      2001:4860:4860::8888
                      2001:4860:4860::8844

Link 2 (ens33)
      Current Scopes: DNS LLMNR/IPv4 LLMNR/IPv6
       LLMNR setting: yes
MulticastDNS setting: no
  DNSOverTLS setting: no
      DNSSEC setting: allow-downgrade
    DNSSEC supported: no

Configuration of /etc/resolv.conf is using the stub resolver:

$ ls -l /etc/resolv.conf
lrwxrwxrwx. 1 root root 39 Nov  7 22:08 /etc/resolv.conf -> ../run/systemd/resolve/stub-resolv.conf
$ grep '^[^#]' /etc/resolv.conf
nameserver 127.0.0.53

And nsswitch.conf is configured to use nss-resolve(8) according to the recommendation from its man page:

$ grep ^hosts: /etc/nsswitch.conf
hosts:      files resolve [!UNAVAIL=return] dns myhostname

If you still can't make it work, you might want to check these settings in your system and confirm they are all configured correctly. Or, at least, post your current configuration here (together with Linux distro and systemd version) to help diagnose why it might not be working for you.

filbranden
  • 21,751
  • 4
  • 63
  • 86
  • Is it really necessary to change nsswitch today? Systemd-resolved has the ReadEtcHosts parameter. If "yes" (the default), systemd-resolved will read /etc/hosts, and try to resolve hosts or address by using the entries in the file before sending query to DNS servers. https://www.freedesktop.org/software/systemd/man/resolved.conf.html#ReadEtcHosts= – TCB13 Nov 04 '20 at 19:17
0

I guess for this purpose you could modify your /etc/nsswitch.conf. Param. host in this file shows you sources which systemd-resolved uses for getting host by name. So you could modify it like this: hosts: files [!NOTFOUND=return] dns.

files - Local files, such as /etc/hosts and /etc/passwd

dns - Internet Domain Name System

In this case, systemd-resolved at first will be use /etc/hosts for getting host by name. Part !NOTFOUND=return means if name hasn't been found in /etc/hosts systemd-resolved will try to resolve it with dns.

metallic
  • 346
  • 1
  • 4