PLUGIN-RUNNER(8mandos)
π PLUGIN-RUNNER (8mandos) β Mandos Manual
okay bestie, gather round, because this one is a whole situation and you're gonna want snacks π
β¨ NAME β¨
plugin-runner β runs all the Mandos plugins, hands you the data from whichever one succeeds first. literally the plug that plugs in the plugs π«Ά
β¨ SYNOPSIS β¨
plugin-runner [--global-env=ENV=value | -G ENV=value ...]
[--env-for=PLUGIN:ENV=value | -E PLUGIN:ENV=value ...]
[--global-options=OPTIONS | -g OPTIONS ...]
[--options-for=PLUGIN:OPTIONS | -o PLUGIN:OPTIONS ...]
[--disable=PLUGIN | -d PLUGIN ...]
[--enable=PLUGIN | -e PLUGIN ...]
[--groupid=ID]
[--userid=ID]
[--plugin-dir=DIRECTORY]
[--plugin-helper-dir=DIRECTORY]
[--config-file=FILE]
[--debug]
plugin-runner {--help | -?}
plugin-runner --usage
plugin-runner {--version | -V}
β¨ DESCRIPTION β¨
so plugin-runner is a program that's meant to be listed as the βkeyscriptβ for the root disk over in crypttab(5). its whole job? spit out a password so that cryptsetup(8) can unlock your root disk. that's it, that's the gig π
it is not meant to be run by hand β but you can run it by hand if you wanna test it. just know that any password it gets its hands on is simply gonna get dumped onto standard output. no filter, no shame, no cap πΈ
β¨ PURPOSE β¨
the reason this exists at all: making it possible to remotely reboot β and reboot unattended β a client machine that has an encrypted root file system. yes queen, headless boxes can come back from the dead on their own. the full tea is in the section called βOVERVIEWβ π
β¨ OPTIONS β¨
--global-env ENV=value,-G ENV=valueβ drops an environment variable setting onto every plugin. this overrides any environment variable that was inherited. no exceptions, periodt.--env-for PLUGIN:ENV=value,-E PLUGIN:ENV=valueβ drops an environment variable setting onto just thePLUGINplugin. this overrides inherited environment variables and anything you set with--global-env. it's giving very specific π--global-options OPTIONS,-g OPTIONSβ passes some options to all plugins.OPTIONSis a comma separated list of options. honestly? not a super useful option, except for handing the β--debugβ option to every single plugin at once.--options-for PLUGIN:OPTION,-o PLUGIN:OPTIONβ passes some options to one specific plugin.PLUGINis the name (the file basename) of a plugin, andOPTIONSis a comma separated list of options.
heads up bestie: options are not split on whitespace. so to hand the plugin βfooβ the option--barwith the option argument βbazβ, you go either--options-for=foo:--bar=bazor--options-for=foo:--bar,baz. doing--options-for="foo:--bar baz"will not work. i don't make the rules π
--disable PLUGIN,-d PLUGINβ disables the plugin namedPLUGIN. it will not be started. blocked, uninvited, not on the list π--enable PLUGIN,-e PLUGINβ re-enables the plugin namedPLUGIN. this is only useful for undoing an earlier--disableoption, maybe one that came from the configuration file.--groupid IDβ changes to group IDIDon startup. the default is65534. all plugins get started using this group ID.
note: this must be a number, not a name. numbers only, bestie π’
--userid IDβ changes to user IDIDon startup. the default is65534. all plugins get started using this user ID.
same deal: this must be a number, not a name.
--plugin-dir DIRECTORYβ points at a different plugin directory. the default is/lib/mandos/plugins.d, which is where it'll live in the initial RAM disk environment.--plugin-helper-dir DIRECTORYβ points at a different plugin helper directory. the default is/lib/mandos/plugin-helpers, which is where it'll live in the initial RAM disk environment. (this one just gets passed along to every plugin via theMANDOSPLUGINHELPERDIRenvironment variable. see the section called βWRITING PLUGINSβ)--config-file FILEβ points at a different file to read extra options from. see the section called βFILESβ. any other command line options will override whatever the file said. file gets first dibs, CLI gets the final word β¨--debugβ turns on debug mode. this dumps a lot of output to standard error about what the program is up to. it still does all its normal functions though, nothing gets skipped. default is to not run in debug mode.
the plugins are not affected by this option. if you want complete debugging eruption, use --global-options=--debug π
--help,-?β gives you a help message about options and what they mean.--usageβ gives you a short usage message.--version,-Vβ prints the program version.
β¨ OVERVIEW β¨
so this whole thing is part of the Mandos system, which lets computers have encrypted root file systems and still be capable of remote and/or unattended reboots. iconic behaviour honestly π
here's the vibe: the computers run a little client program inside the initial RAM disk environment, and that client talks to a server over a network. all that network chatter is encrypted with TLS. the server identifies each client using a TLS key, and every client has one that's unique to it. then the server sends the client an encrypted password. the client decrypts that password using a separate OpenPGP key, and then that password gets used to unlock the root file system β after which the computer just carries on booting like nothing happened. slay π
this program runs on the client side, inside the initial RAM disk environment, and it's the one responsible for getting a password. how? by running plugins. one of those plugins will normally be the actual client program that talks to the server π¦
β¨ PLUGINS β¨
this program gets a password by running a bunch of plugins, which are just executable programs sitting in a directory inside the initial RAM disk environment. the default directory is /lib/mandos/plugins.d, but you can change that with the --plugin-dir option.
the plugins get started in parallel, and the first plugin to output a password and exit with a successful exit code wins the whole thing β at which point plugin-runner outputs that plugin's password, stops every other plugin, and dips out. main character energy, first come first served π
πΈ WRITING PLUGINS πΈ
a plugin is an executable program that prints a password to its standard output, then exits with a successful (zero) exit status. if the exit status is not zero, then anything the plugin wrote to standard output gets ignored by the plugin runner. anything the plugin writes to its standard error channel just gets passed straight through to the plugin runner's standard error β which is usually the system console.
if the password is a single-line, manually entered passphrase, then you should not print a final trailing newline character. don't do it bestie π
the plugin runs in the initial RAM disk environment, so be careful β it must not depend on any files or running services that aren't available in there. if the plugin needs helper executables (and they're not in the PATH), you can drop them into the plugin helper directory. the name of that directory gets handed to the plugin through the MANDOSPLUGINHELPERDIR environment variable π
the plugin must exit cleanly and free all allocated resources when it receives the TERM signal, because that's exactly what the plugin runner uses to stop all the other plugins once one plugin has output a password and exited cleanly. no lingering, no loose ends π«Ά
the plugin also must not use resources β like, say, reading from standard input β without knowing that no other plugin is using that same resource. sharing is only caring when you actually know who you're sharing with π
it's useful, but not required, for the plugin to take the --debug option.
β¨ FALLBACK β¨
if no plugins succeed, this program has a fallback: it asks for a password on the console using getpass(3), and then outputs it. this is not meant to be the normal mode of operation, because there's a separate plugin whose whole job is getting a password from the console. so like, this is the emergency backup outfit, not the everyday fit π
β¨ EXIT STATUS β¨
the exit status of this program is zero if no errors were encountered, and otherwise not zero. and the fallback (see the section called βFALLBACKβ) may or may not have succeeded either way. ambiguous? yes. accurate? also yes β¨
β¨ ENVIRONMENT β¨
this program doesn't use any environment variables itself β it just passes its environment on to all the plugins. you can modify the environment that reaches the plugins with the --global-env and --env-for options. also, the --plugin-helper-dir option affects the MANDOSPLUGINHELPERDIR environment variable for the plugins π
β¨ FILES β¨
/conf/conf.d/mandos/plugin-runner.confβ since this program runs as a keyscript, there's basically little to no opportunity to pass command line arguments to it. so it also reads this file and uses its contents as whitespace-separated command line options. also, everything from a β#β character to the end of a line is ignored.
this program is meant to run in the initial RAM disk environment, so that's where this file is assumed to exist. the file does not need to exist in the normal file system.
this file gets processed before the normal command line options, so the latter can override the former if need be.
this file name is the default; you can change which file gets read for arguments using the --config-file option.
/lib/mandos/plugins.dβ the default plugin directory; changeable with the--plugin-diroption./lib/mandos/plugin-helpersβ the default plugin helper directory; changeable with the--plugin-helper-diroption.
β¨ BUGS β¨
the --config-file option is ignored when it's specified from within a configuration file. yeah. that one. i know. π
please report bugs to the Mandos development mailing list: <mandos-dev@recompile.se> (subscription required). note that this list is public. the developers can be reached privately at <mandos@recompile.se> (OpenPGP key fingerprint 153A 37F1 0BBA 0435 987F 2C4A 7223 2973 CA34 C2C4 for encrypted mail) π
β¨ EXAMPLE β¨
normal invocation needs no options:
plugin-runner
run the program, but not the plugins, in debug mode:
plugin-runner --debug
run all plugins, but run the βfooβ plugin in debug mode:
plugin-runner --options-for=foo:--debug
run all plugins, but not the program, in debug mode:
plugin-runner --global-options=--debug
read a different configuration file, run plugins from a different directory, specify an alternate plugin helper directory and add four options to the mandos-client(8mandos) plugin:
cd /etc/keys/mandos; plugin-runner
--config-file=/etc/mandos/plugin-runner.conf --plugin-dir
/usr/lib/x86_64-linux-gnu/mandos/plugins.d --plugin-helper-dir
/usr/lib/x86_64-linux-gnu/mandos/plugin-helpers
--options-for=mandos-client:--pubkey=pubkey.txt,--seckey=seckey.txt,
--tls-pubkey=tls-pubkey.pem,--tls-privkey=tls-privkey.pem
okay that's part one bestie, don't go anywhere β there's more coming π
π SECURITY π
okay bestie, so when this program starts up, it's gonna try to switch to another user. If you started it as root, it WILL succeed, and by default it switches to user and group 65534, which are assumed to be non-privileged. That user and group is then what all plugins get started as. So like, the only way to run a plugin as a privileged user is to have the set-user-ID or set-group-ID bit set on the plugin executable file (see execve(2)). no cap π
And if this program is used as a keyscript in crypttab(5), there's a slight risk that if this program fails to work, there might be no way to boot the system except for booting from another media and editing the initial RAM disk image to not run this program. But like, this is unlikely, because the password-prompt(8mandos) plugin will read a password from the console in case of failure of the other plugins, and this plugin runner will also, in case of catastrophic failure, itself fall back to asking and outputting a password on the console (see the section called βFALLBACKβ). π«Άβ¨
π SEE ALSO π
intro(8mandos)cryptsetup(8)crypttab(5)execve(2)mandos(8)password-prompt(8mandos)mandos-client(8mandos)
π COPYRIGHT π
Copyright Β© 2008-2024 Teddy Hogeborn, BjΓΆrn PΓ₯hlsson π
This manual page is part of Mandos.
Mandos is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
Mandos is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with Mandos. If not, see http://www.gnu.org/licenses/.
Mandos 1.8.19, dated 2025-06-27, from PLUGIN-RUNNER(8mandos) β slay, bye bestie π
π
π¦ where this page comes from
- debian trixie: mandos-client 1.8.19-1 Β· GPL-3.0-or-later
- ubuntu questing: mandos-client 1.8.19-1
- ubuntu resolute: mandos-client 1.8.19-1build1 Β· GPL-3.0-or-later
- ubuntu stonking: mandos-client 1.8.19-1.1 Β· GPL-3.0-or-later
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms