2

How can I configure a custom systemd service to start only after DNS resolution is ready to be handled?

The service is a oneshot script that mails me the current WAN and LAN ip addresses of the device, just after booting. It used to work, but after installing Pi-hole, it stopped working when run automatically at boot. Triggering the service manually with sudo systemctl start mail-ip-at-boot.service still works.

At boot, it's failing because there is an issue with name resolution (of e.g. the mail server's host name). From /var/log/syslog:

sendemail[1182]: ERROR => Connection attempt to smtp.<myisp>:25 failed IO:Socket::INET6 getaddrinfo: Temporary failure in name resolution.

I had a similar issue reported by dig (which I use in my mailip script): dig: couldn't get address for 'resolver1.opendns.com': failure. I already solved that one by replacing the resolver1 hostname with its fixed IP address. Of course, it's only a workaround.

The solution should work regardless of whether Pi-hole is installed or not.

Below is my current service definition.

me@raspberripi:~$ cat /etc/systemd/system/mail-ip-at-boot.service
[Unit]
Description=Mail WAN and LAN IP address
Wants=network-online.target
After=network-online.target

[Service]
Type=oneshot
ExecStart=/usr/local/bin/mailip.sh
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target

Temporary workaround:

    Wants=network-online.target nss-lookup.target
    After=network-online.target nss-lookup.target

Although looking very pormising, approach 1 doesn't seem to work.

  • Approach 2. I got it working by referring to the pihole-FTL.service. It appears (I have not tested it) that because of the Wants directive, it will still work if pihole-FTL is not available. See https://unix.stackexchange.com/a/423724/40237
    Wants=network-online.target pihole-FTL.service
    After=network-online.target pihole-FTL.service

I don't like approach 2 entirely, as I create coupling to pihole. Not good practice

Rabarberski
  • 201
  • 1
  • 8

1 Answers1

3

Create a new oneshot service that blocks until hostname lookups are working. For example, something like:

[Unit]
Description=Wait for DNS
Wants=network-online.target
After=network-online.target

[Service]
Type=oneshot
ExecStart=/bin/sh -c 'while ! host smtp.example.com; do sleep 1; done'

And then make your "Mail WAN and LAN IP address" service depend on that:

[Unit]
Description=Mail WAN and LAN IP address
Wants=network-online.target wait-for-dns.service
After=network-online.target wait-for-dns.service

...
larsks
  • 32,449
  • 5
  • 54
  • 70
  • Good suggestion. However, it still doesn't quite work. I see in the syslog that debug echos from the mail script are reported /before/ the syslog reports the dns service has completely started (which is indicated by "systemd[xx]: Started Wait for DNS"). The mail service dependency tree (systemctl list-dependencies mail-ip-at-boot.service) looks correct. I have to troubleshoot this further; maybe it's because the dns service refers to a multiple statement ExecStart? I am not sure what triggers the DNS service to consider it to be completed and allows the depending service to start... – Rabarberski Jan 08 '20 at 21:37