Skip to content

Instantly share code, notes, and snippets.

@AfroThundr3007730
Last active June 1, 2026 14:23
Show Gist options
  • Select an option

  • Save AfroThundr3007730/79cf11a5baf7b9274640fe94c0273f15 to your computer and use it in GitHub Desktop.

Select an option

Save AfroThundr3007730/79cf11a5baf7b9274640fe94c0273f15 to your computer and use it in GitHub Desktop.
Remote inhibitor template for systemd services

Remote systemd inhibitors

This setup allows for attaching inhibitors of remote systems as dependencies of systemd units.

This is especially useful when a task requires a remote system to be available to complete successfully.

This configuration can be applied both to system and user service units.

Setup

The inhibitor service template (stub file):

# ~/.config/systemd/user/remote-inhibit-@.service
[Unit]
Description=Inhibit remote machine %j during active operations (unit: %i)
StopWhenUnneeded=true

[Service]
Type=exec
Restart=no
ExecStart=/usr/bin/ssh -aqtto IdentityAgent=none %u@%j \
          systemd-run --user --scope \
          systemd-inhibit --who %u@%l --why %i sleep infinity
ExecStop=/bin/kill -INT $MAINPID

To use the template stub, hardlink it to include the hostname or FQDN of the remote system:

ln ~/.config/systemd/user/remote-inhibit-@.service \
   ~/.config/systemd/user/remote-inhibit-hostname@.service

And add a requires drop-in on the dependent service (example):

systemctl --user edit --drop-in requires my-service.service

Populate it with the following contents:

# ~/.config/systemd/user/my-service.service.d/requires.conf
[Unit]
Requires=remote-inhibit-hostname@%n.service

Now anytime my-service.service starts, it will start remote-inhibit-hostname@my-service.service.service.

Prerequisites

For this configuration to work, you'll need to setup ssh keys on the remote system for passwordless login:

ssh-keygen -t ed25519 # if no key exists already
ssh-copy-id user@hostname # follow the prompts

You will need to create a PolicyKit rule on the remote system to allow normal users to inhibit shutdown:

// /etc/polkit-1/rules.d/50-inhibit-shutdown-sudo.rules
polkit.addRule(function(action, subject) {
    if ((action.id == "org.freedesktop.login1.inhibit" ||
         action.id == "org.freedesktop.login1.inhibit-block-shutdown")
        && subject.isInGroup("sudo")) {
        return polkit.Result.YES;
    }
});

Replace sudo with the admin group you want to grant access to, then restart polkit.service.

Notes

  • The stub link is done via hardlink instead of symlink, since systemd refuses to follow nested symlinks.
  • The remote hostname is taken from the local part of the inhibit unit name (between inhibit- and @).
    • Encoding a long name or IP can be avoided by adding an alias in ~/.ssh/config and using that.
  • The inhibit instance name is derived from the full unit name of the invoking service unit.
    • This also applies to other instance units. Ex: inhibit-hostname@myservice@instance1.service.service
  • The inhibit unit assumes the remote user will be the same as the one running the service.
    • If needed the unit file can be adjusted by changing %u with another username.
  • The setup works best with passwordless SSH access, so a local keyfile is preferable to an agent.
    • If necessary, the key can be restricted in the remote ~/.ssh/authorized_hosts file.

References

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment