1

This is the first time that I have to mess around with systemd. I can't find a solution how to manage, that my service starts after the network is up. I try to start knockd.service on startup on my Raspbian system.

After Boot I check if the service is running:

systemctl status knockd
   Loaded: loaded (/lib/systemd/system/knockd.service; enabled; vendor preset: enabled)
   Active: failed (Result: exit-code) since Thu 2019-06-27 14:36:26 CEST; 7min ago
     Docs: man:knockd(1)
  Process: 516 ExecStart=/usr/sbin/knockd $KNOCKD_OPTS (code=exited, status=1/FAILURE)
 Main PID: 516 (code=exited, status=1/FAILURE)

Jun 27 14:36:26 pins2 systemd[1]: Started Port-Knock Daemon.
Jun 27 14:36:26 pins2 knockd[516]: could not get IP address for eth0
Jun 27 14:36:26 pins2 systemd[1]: knockd.service: Main process exited, code=exited, status=1/FAILURE
Jun 27 14:36:26 pins2 systemd[1]: knockd.service: Unit entered failed state.
Jun 27 14:36:26 pins2 systemd[1]: knockd.service: Failed with result 'exit-code'.

I think the Problem is this:

could not get IP address for eth0

After I investigated a lot (like here and there) I found some good hints, but unfortunately it still does not work. My .service file looks like this:

systemctl cat knockd
# /lib/systemd/system/knockd.service
[Unit]
Description=Port-Knock Daemon
Documentation=man:knockd(1)                                                                         
#Requires=network-online.target                                                                     
#Wants=network-online.target                                                                     
After=network-online.target                                                                    

[Service]                                                                                           
EnvironmentFile=-/etc/default/knockd                                                                
ExecStart=/usr/sbin/knockd $KNOCKD_OPTS                                                             
ExecReload=/bin/kill -HUP $MAINPID                                                                  
KillMode=mixed                                                                                      
SuccessExitStatus=0 2 15                                                                            
ProtectSystem=full                                                                                  
CapabilityBoundingSet=CAP_NET_RAW CAP_NET_ADMIN                                                     

[Install]                                                                                           
WantedBy=multi-user.target                                                                          
Alias=knockd.service                

I already use After=network-online.target in my Unit section. What else do I have to do, I already tried Requires= and Wants=?

After Boot my system has an IP Address, and starting the Service manually works without any problems. On another network with some faster network I did not have any Problems even without the network-online target.

As you can imagine it is quite essential, that knockd starts reliably, because if not, I am locked out.

If this works reliably, will this also work, if the network cable is connected some time after boot?

BTW, I know that I should not edit the .service file in /lib/systemd/... I just did that to sort out possible override problems. I will fix that after everything is working. Thank you for your help.

3
  • 1
    The example on freedesktop.org indicates both an "After" and a "Wants"; does adding "Wants" help?
    – Jeff Schaller
    Jun 27, 2019 at 13:21
  • Shoud I better start the Service by placing the start Command in /etc/network/if-up.d/? Jun 27, 2019 at 13:39
  • could not get IP address for eth0: do you even have an eth0 interface? What does ip link list say?
    – NickD
    Jun 27, 2019 at 14:51

3 Answers 3

1

You need the Wants= directive since network-online.target is not pulled in the dependency chain by default (see systemd.special(7) manpage).

You also might want to enable ifupdown-wait-online.service (systemctl enable ifupdown-wait-online.service) if you are not using NetworkManager

0
1

@Bigon has the right general idea.

The core problem here is that network-online.target isn't normally pulled into the dependency tree for systemd. When systemd processes the After=network-online.target line in your unit it determines that it can ignore it because network-online.target isn't going to happen.

What you need is a unit that pulls network-online.target into the dependency tree at a point when the network is ::drum roll:: online. Many distroes provide such a unit. Network managers also often provide this functionality.

Since I don't know your distro it's difficult for me to know what unit to tell you to enable. And, while switching to networkmanager will likely solve your problem networkmanager will make a lot of other changes to how your system works as well, possibly conflicting with existing configuration.

1
  • I like this answer since it tells the story more generic and still contains more details.
    – doak
    May 5, 2021 at 20:00
-2

Simply install network-manager worked fine for me on Rasbian.

Network Manager allows NetworkManager-wait-online.service. Since the interfaces are not ready at startin of knockd, this gives time to the network to bring the interface up.

3
  • How would this solve the issue with the knockd service being started too early?
    – Kusalananda
    Aug 8, 2019 at 14:51
  • Actually, it would solve it. But I agree that a good answer needs to explain why. Aug 8, 2019 at 14:53
  • @Jacques please edit that information into your answer, it would make it much more useful. Aug 8, 2019 at 15:50

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .