0

I have a simple systemd service that is activated by system socket.

It's as simple as that (a little simplified):

$ systemctl cat example.socket 
# /usr/lib/systemd/system/example.socket
[Unit]
Description=Example Server socket

[Socket]
ListenStream=80
Accept=true

[Install]
WantedBy=sockets.target
$ systemctl cat example@.service 
# /usr/lib/systemd/system/example@.service
[Unit]
Description=Example Server

[Service]
StandardInput=socket
StandardOutput=socket
StandardError=journal
ExecStart=/usr/libexec/example
User=example

Now what I want is to implement a basic access restriction by time. I.e. I want to limit the time a day the socket/service can be activated/reached from the outside, so it's only available at certain times a day, e.g.

I know I can use systemctl edit to override the options, but I did not found an option to set, actually. I looked through the man page regarding system sockets and the only options regarding times are TriggerLimitIntervalSec or so, which do not do what I want.

To compare this, the little oldish tool xinetdx, which can do the same i.e. listen on a socket and start a process (server) on demand has an option called access_times, which can be used to specify when a service should be available. But using this as another tool (/dependency) is not a thing I'd like. I'd aim for an integrated way into systemd.

8
  • 1
    As a completely alternate solution you could use a firewall rule. There does exist a match that compares the time of day with some values both in iptables and nftables. – A.B May 14 at 20:48
  • have you considered using a cron job to stop and start the service at the required times? – cas May 15 at 7:43
  • @cas It's a socket. and I want to use socket activation. Maybe I could though enable/disable the socket at the required times, but I'm not sure whether that is the most elegant solution – considering e.g. what happens if the device is down at the time and only start later or so. But if you want to submit this as an answer, feel free to do so. – rugk May 15 at 11:01
  • @A.B Yeah good idea, but I use firewall-cmd (Fedora system), and as far as I see it does not support that and so resorting to some lower-level tool for that is well… maybe not so nice, yet again. – rugk May 15 at 11:02
  • firewalld doesn't have to support it: nftables can use separate tables (eg: firewalld chooses its own firewalld table) and when a packet is dropped it won't come back. Anyway that was a suggestion, I'm not trying to convince. – A.B May 15 at 11:46
1

You can use some systemd timers to start/stop the socket at the required times.

To wakeup mysocket.socket every morning at 06:00 and put it to bed at 23:00 every night try this:

# mysocket.timer
[Unit]
Description=Socket Wakeup

[Timer]
OnCalendar=6:00
Unit=mysocket.socket

[Install]
WantedBy=timers.target
# mysocket-bedtime.timer
[Unit]
Description=Socket Bedtime

[Timer]
OnCalendar=23:00
Unit=mysocket-bedtime.service

[Install]
WantedBy=timers.target
# mysocket-bedtime.service
[Unit]
Description=MySocket bedtime enforcer
Conflicts=mysocket.socket

[Service]
Type=oneshot
ExecStart=/bin/true

mysocket.timer is pretty straight forward. It start Unit=mysocket.socket at 06:00 every morning. Stopping your socket is a little more difficult. It requires a Conflicts= relationship. We create mysocket-bedtime.timer to wake up that conflicting unit at 23:00 every night. mysocket-bedtime.service is that conflicting unit. For it to start, it will shut down anything it Conflicts= with (your socket). Then when your socket has stopped, it simply executes true and then stops itself.

2
  • Okay, nice one. But (how) is this better than just having two timers running systemctl start/stop example.socket or so manually? – rugk May 19 at 19:51
  • 1
    Well, if you were to do that, you'd need mysocket-wakeup.timer with mysocket-wakeup.service and mysocket-sleep.timer with mysocket-sleep.service. This solution uses one fewer units. Also, you are using native systemd unit relationships instead of systemctl. The native systemd relationships are designed for these situations and probably cover some edge cases better than using systemctl (which is not really designed to be invoked from a service). Finally, this is what the devs recommended when they closed your feature request. – Stewart May 19 at 20:22

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.