0

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

1

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

...
| improve this answer | |
  • 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 8 at 21:37

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.