The systemd-resolved
service serves as a modern DNS resolver for Linux systems, implementing several key features:
- DNS stub resolver (listening on 127.0.0.53:53 by default)
- LLMNR (Link-Local Multicast Name Resolution) responder
- mDNS (Multicast DNS) responder (port 5355)
- DNS-over-TLS support
- DNSSEC validation
# To view active services:
$ systemctl status systemd-resolved
● systemd-resolved.service - Network Name Resolution
Loaded: loaded (/usr/lib/systemd/system/systemd-resolved.service; enabled)
Active: active (running) since Thu 2023-11-16 14:20:43 UTC; 1h ago
The service binds to 0.0.0.0:5355 specifically for mDNS/LLMNR functionality, which requires:
- Multicast traffic handling across all interfaces
- Local network service discovery
- Link-local name resolution
For regular DNS resolution, it uses 127.0.0.53:53 (stub resolver) which doesn't expose externally.
While mDNS on 0.0.0.0 is by design, it can present risks in IoT environments:
# Check listening ports:
$ sudo ss -tulnp | grep resolved
udp UNCONN 0 0 0.0.0.0:5355 0.0.0.0:* users:(("systemd-resolve",pid=240,fd=13))
Hardening recommendations:
# Disable mDNS (add to /etc/systemd/resolved.conf):
[Resolve]
MulticastDNS=no
# Restrict LLMNR:
LLMNR=no
# Then restart:
$ sudo systemctl restart systemd-resolved
Disabling systemd-resolved would:
Feature | Impact |
---|---|
DNS Caching | Applications would query upstream directly |
DNSSEC | Validation would need handling at application level |
mDNS | Local service discovery would break |
For headless IoT devices, consider:
# Minimal /etc/systemd/resolved.conf:
[Resolve]
DNS=8.8.8.8 1.1.1.1
FallbackDNS=
Domains=
LLMNR=no
MulticastDNS=no
DNSSEC=allow-downgrade
Cache=yes
DNSStubListener=yes
This maintains core DNS functionality while reducing attack surface.
After configuration changes:
# Verify settings:
$ resolvectl status
Global
LLMNR setting: no
MulticastDNS setting: no
DNSOverTLS setting: no
DNSSEC setting: allow-downgrade
DNSSEC supported: yes
# Test resolution:
$ drill example.com @127.0.0.53
;; ->>HEADER<<- opcode: QUERY, rcode: NOERROR, id: 12345
;; flags: qr rd ra ; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0
;; QUESTION SECTION:
;; example.com. IN A
;; ANSWER SECTION:
example.com. 86399 IN A 93.184.216.34
For IoT devices specifically, also check with:
# Check open ports from network perspective:
$ nmap -sU -p 5355 [device_ip]
systemd-resolved is a critical system service in modern Linux distributions that handles DNS resolution for local applications. It acts as a local DNS stub resolver, caching DNS responses and implementing features like DNSSEC validation and DNS-over-TLS. Unlike traditional resolvers, it integrates tightly with systemd's network management.
The service listens on all interfaces (0.0.0.0) primarily for two reasons:
- To respond to mDNS (multicast DNS) and LLMNR (Link-Local Multicast Name Resolution) queries on port 5355
- To provide DNS resolution for containers and virtual machines that might use different network interfaces
Here's how you can verify the listening ports:
sudo ss -tulnp | grep systemd-resolved
# Output example:
# udp UNCONN 0 0 0.0.0.0:5355 0.0.0.0:* users:(("systemd-resolved",pid=240,fd=12))
# tcp LISTEN 0 4096 0.0.0.0:5355 0.0.0.0:* users:(("systemd-resolved",pid=240,fd=13))
While listening on all interfaces is by design, it does present potential security concerns:
- Exposure to local network attacks if the device has multiple interfaces
- Potential information leakage through DNS queries
- Attack surface for DNS-based vulnerabilities
For IoT devices like the Intel Galileo, this is particularly concerning as they often operate in less secure environments.
Here are several approaches to secure the service:
1. Restrict Listening Interfaces
Edit the systemd-resolved configuration file:
sudo nano /etc/systemd/resolved.conf
Add or modify these lines:
[Resolve]
DNSStubListener=udp:127.0.0.1:53
DNSStubListenerExtra=udp:192.168.1.100:5355 # Replace with your specific IP
MulticastDNS=no
LLMNR=no
2. Disable Unnecessary Features
For IoT devices, you might want to disable features you don't need:
[Resolve]
DNSSEC=allow-downgrade
Cache=no
DNSOverTLS=opportunistic
3. Firewall Rules
Add specific iptables rules to restrict access:
sudo iptables -A INPUT -p udp --dport 5355 -i lo -j ACCEPT
sudo iptables -A INPUT -p udp --dport 5355 -j DROP
If you choose to disable the service completely:
sudo systemctl disable --now systemd-resolved
Be aware of these potential impacts:
- Applications using glibc's getaddrinfo() will fall back to /etc/resolv.conf
- Loss of DNS caching may increase network latency
- DNSSEC validation will need to be handled elsewhere
- Some systemd-networkd features may not work properly
For resource-constrained IoT devices, consider this minimal configuration:
[Resolve]
DNS=8.8.8.8 1.1.1.1
DNSStubListener=no
FallbackDNS=
Domains=
LLMNR=no
MulticastDNS=no
DNSSEC=no
Cache=no
Remember to update your /etc/resolv.conf if you make significant changes:
sudo ln -sf /run/systemd/resolve/resolv.conf /etc/resolv.conf
After making changes, verify with these commands:
systemd-resolve --status
dig example.com
systemd-analyze security systemd-resolved.service