1

I tried to create a systemd startup script that starts an rkhunter scan 30 minutes after system start of my laptop, like this:

[Unit]
Description=starts rkhunter and displays any findings with zenity

[Service]
ExecStartPre=/bin/sleep 1800
ExecStart=/usr/local/sbin/rkhunter-check

[Install]
WantedBy=default.target

But this fails with a timeout error

Job for rkhunter.service failed because a timeout was exceeded.

It seems like the ExecStartPre does not work like this.

How do I solve this?

A perfect solution would be:

  • first run 30 minutes after boot
  • repeat every 48 hours (in case you never shutdown your laptop)
  • knowing nothing much about systemd (for "reasons") i'd see if you can override the default timeout in that particular unit to see if there is a "systemd way" of doing it. otherwise i'd change the script it calls so that the script it calls simply sets an at or cron task for now+30 min which calls your original rkhunter command – ivanivan Jul 19 '19 at 21:50
  • See this question for some clues. – Jim L. Jul 19 '19 at 22:16
  • Do you want to run rkhunter-check on a regular basis, or just once after bootup? Some versions of crontab allow you to specify @bootup as the time to run, so your command to run could just be sleep 1800; rkhunter-check. You could use a systemd timer rather than a service to start things 30 minutes after boot, and then either a finite or an infinite amount of time between runs. – icarus Jul 19 '19 at 22:37
  • You could use a timer with OnBootSec=30min – Rusi Jul 20 '19 at 1:47
4

Use a timer unit to schedule your service start times. A timer unit is flexible enough that you can use a single one to schedule both the initial run, 30 minutes after boot, as well as the repeats 48 hours after the first run. (And you can even decide if you want it 48 hours after it first started or 48 hours after it finished running.)

File rkhunter.service:

[Unit]
Description=rkhunter check with zenity findings

[Service]
Type=oneshot
ExecStart=/usr/local/sbin/rkhunter-check

File rkhunter.timer:

[Unit]
Description=timer for rkhunter check

[Timer]
OnBootSec=30min
OnUnitActiveSec=48h

[Install]
WantedBy=timers.target

Note that you don't need an [Install] section in your service unit, since you don't want to "enable" it, as that would run it during the boot sequence and what you want is to only run it 30 minutes later.

You'll want to enable the timer unit, so it actually gets enabled on boot and starts the service unit at the configured times. So:

systemctl daemon-reload
systemctl enable rkhunter.timer

If you previously had the service enabled, you'll want to disable it explicitly, since it should now only be started by your timer unit:

systemctl disable rkhunter.service

If you never enabled this service before and are implementing this setup from scratch, there's no need for that command.

After you reboot, this should work right as you described your requirements.

  • 1
    Do you need both the timer and the service or is the timer an alternative to the service? – rubo77 Jul 20 '19 at 12:21
  • @rubo77 Yes, you need both, since the timer unit will simply start a service at the appropriate time. The service unit will have all the information on what to run and how. By default, a timer unit will start a service with the same name, but you can configure that with the Unit= directive. – filbranden Jul 20 '19 at 16:05
  • 1
    I found out something important here: "It is important that the service is disabled (so it doesn't start at boot), and the timer enabled, for all this to work: systemctl disable foo.service; systemctl enable foo.timer " – rubo77 Jul 20 '19 at 19:43
  • @rubo77 I actually thought this was clear from my post, as I said: "Note that you don't need an [Install] section in your service unit, since you don't want to 'enable' it". If you think this can be reworded for clarity, can you maybe propose a better wording for it? – filbranden Jul 20 '19 at 22:19
  • 1
    @rubo77 You only needed systemctl disable rkhunter.service because you had the service enabled earlier... If you did a clean room implementation you wouldn't have needed it. I'll edit once again to clarify that. – filbranden Jul 22 '19 at 5:38
0

If you want to use a long sleep command in the service at ExecStartPre you need to disable the timeout with TimeoutStartSec=infinity:

[Unit]
Description=starts rkhunter and displays any findings with zenity

[Service]
TimeoutStartSec=infinity
ExecStartPre=/bin/sleep 1800
ExecStart=/usr/local/sbin/rkhunter-check

[Install]
WantedBy=default.target

If you want to repeatedly start the service every 48h, add a timer as suggested by @filbranden

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.