remctld - Server for remctl, a remote command execution utility
remctld [ -dFhmSvZ
] [-b bind-address
[ -f config
] [-k keytab
] [-P file
[ -s service
is the server for remctl. It accepts a connection from remctl,
receives the command to execute and the arguments, verifies authorization of
the user and executes the command, returning the result back to the client.
All connections are authenticated using Kerberos GSS-API Kerberos, and all
transmissions are also encrypted using the GSS-API privacy layer.
is normally started using tcpserver
or from inetd
but it may be run in stand-alone mode as a daemon using -m
must be given to use an alternate identity (which will require the
same flag be used for remctl
client invocations), or it must be run as
root to read the host keytab file. remctld
logs its activity using
syslog (the daemon facility).
The location of the configuration file may be specified with the -f
option. The default location is /etc/remctl/remctl.conf
information on the format of the configuration file, see "CONFIGURATION
When the command is run, several environment variables will be set providing
information about the remote connection. See ENVIRONMENT below for more
Command-line and configuration options and ACL methods are annotated below with
the version at which they were added. For version information for more general
features, see COMPATIBILITY below.
The start of each option description is annotated with the version of
in which that option was added with its current meaning.
- -b bind-address
- [2.17] When running as a standalone server, bind to the
specified local address rather than listening on all interfaces. This
option may be given multiple times to bind to multiple addresses.
bind-address must be an IP address (either IPv4 or IPv6), not a
hostname. Only makes sense in combination with -m.
This option is ignored if remctld is passed already open sockets via
the systemd socket activation protocol. In that case, the bind addresses
of the sockets should be controlled via the systemd configuration.
- [1.10] Enable verbose debug logging to syslog (or to
standard output if -S is also given).
- [2.8] Normally when running in stand-alone mode
(-m), remctld backgrounds itself to run as a daemon, changes
directory to /, and drops any controlling terminal. This flag
suppresses this behavior, usually for debugging or so that remctld
can be monitored by other processes.
- -f config
- [1.0] The configuration file for remctld, overriding
the default path.
- [1.10] Show a brief usage message and then exit. This usage
method will include a list of supported ACL types and can be used to
determine if optional ACL methods were compiled into a given
- -k keytab
- [2.8] Use keytab as the keytab for server
credentials rather than the system default or the value of the KRB5_KTNAME
environment variable. Using -k just sets the KRB5_KTNAME
environment variable internally in the process.
- [2.8] Enable stand-alone mode. remctld will listen
to its configured port and fork a new child for each incoming connection.
By default, when this option is used, remctld also changes
directory to /, backgrounds itself, and closes standard input,
output, and error. To not background, pass -F as well. To not close
standard output and error and continue using them for logging, pass
-S as well.
To determine the port, remctld attempts to look up the
"remctl" service in the local /etc/services file and uses
the port defined there. If the "remctl" service could not be
found, it uses 4373, the registered remctl port.
- -P file
- [2.0] When running in stand-alone mode (-m), write
the PID of remctld to file. This option is ignored unless
-m is also given.
- -p port
- [1.0] When running in stand-alone mode, listen on port
port rather than the default. This option does nothing unless used
This option is ignored if remctld is passed already open sockets via
the systemd socket activation protocol. In that case, the listening port
should be controlled via the systemd configuration.
- [2.3] Rather than logging to syslog, log debug and routine
connection messages to standard output and error messages to standard
error. This option is mostly useful for testing and debugging.
- -s service
- [1.0] Specifies which principal is used as the server
identity for client authentication. The client must also use the same
identity as the server identity for authentication to succeed. By default,
remctld accepts any principal with a key in the default keytab file
(which can be changed with the -k option). This is normally the
most desirable behavior.
- [1.10] Print the version of remctld and exit.
- [3.7] When remctld is running in stand-alone mode,
after it has set up its network socket and is ready to answer requests,
raise SIGSTOP. This signals to upstart, when using "expect
stop", that the daemon is ready to accept connections, and upstart
will raise SIGCONT to allow remctld to continue. This option is
probably only useful when using upstart as the init system. Only makes
sense in combination with -m.
The configuration file defines the allowed commands and specifies access control
information. The configuration file format is lines of space- or tab-separated
strings, where each line is:
command subcommand executable [option=value ...] acl [acl ...]
Each command consists of a command, a subcommand, and zero or more arguments.
Each configuration line defines an acceptable command and subcommand (or, if
"ALL" is used as mentioned below under command
, a set of commands). The first configuration line matching
the received command is used, so list more specific entries before more
Blank lines and lines beginning with "#" are ignored. Lines can be
continued on the next line by ending them with a backslash ("\"). Be
aware that comments can be continued with a backslash as well.
As a special case, a line like:
will include file
as if its contents were pasted verbatim into the
configuration file at that point. file
may be a directory, in which
case all files whose names do not contain a period found in that directory
will be included (in no particular order). file
should be a fully
The meaning of the fields on each configuration line are:
- The command being issued or the special keyword
"ALL". Normally, related commands (such as all commands for
managing a particular service) are grouped together as subcommands under
If the keyword "ALL" is used instead of a specific subcommand,
this line matches all commands with the given subcommand (so "ALL
ALL" matches any command) and can be used to dispatch all commands to
the same executable with the same ACLs. Since the first matching entry is
used, list entries for specific commands first (if any) and then the
Note that while the subcommand is passed to the executable as a command-line
option, the command is not. The command is available to the executable in
the environment variable REMCTL_COMMAND (see ENVIRONMENT below).
The command "help" is handled specially if no such command is
defined in the configuration file. See below under the "help"
and "summary" options.
- The subcommand within the command being requested, such as
"release" for the release function of the AFS volume backend, or
one of the special keywords "ALL" or "EMPTY".
If the keyword "ALL" is used instead of a specific subcommand,
this line matches all subcommands with the given command and can be used
to dispatch all subcommands under that command to the same executable with
the same ACLs. Since the first matching entry is used, list entries for
specific services first (if any) and then the "ALL" catch-all.
If the keyword "EMPTY" is used instead of a specific subcommand,
this line matches only commands where no subcommand was given.
The subcommand is always passed as the first argument to the executable
program that is listed for that service unless no subcommand was
- The full path to the command executable to run for this
command and subcommand combination. (See examples below.)
- An option setting that applies to this command. Supported
option settings, annotated with the version at which that option was added
in its current form, are:
- [3.2] Specifies the argument for this command that will
print help for a particular subcommand to standard output.
If remctld receives the command "help" with one or two arguments,
and no "help" command is defined in the configuration file, the
server will take the command arguments as a command and subcommand. It
will then look through the configuration for a configuration line matching
that command and subcommand with a "help" option set. If one is
found and the user is authorized to run that command, the server will run
the specified executable with the argument arg and second
and optional third arguments taken from the arguments to the
"help" command, sending the output back to the user.
This permits a standard interface to get additional help for a particular
remctl command. Also see the "summary" option.
- [1.4] Limit logging of command arguments. Any argument
listed in the logmask list will have its value logged as
"**MASKED**". This is to avoid logging the arguments of commands
that take private information such as passwords. The logmask list should
contain argument numbers separated by commas, with the subcommand
considered argument 1. The command argument cannot be masked.
For example, if the command is "admin passwd username
password", then you'd want to set logmask to 3, so the
password argument gets logged as "**MASKED**". If the command is
"user passwd username old-password
new-password", you'd want to set logmask to
- stdin=(n | "last")
- [2.14] Specifies that the nth or last argument to
the command be passed on standard input instead of on the command line.
The value of this option must either be the number of argument to pass on
standard input (with the subcommand considered argument 1) or the
special value "last", which indicates that the final argument
(no matter how many there are) be passed on standard input.
The command cannot be passed on standard input, so n must be
at least 1. If this option is set to "last" and no arguments are
given except the command and possibly the subcommand,
nothing will be passed on standard input.
This option is used primarily for passing large amounts of data that may not
fit on the command line or data that contains NUL characters. It can also
be used for arguments like passwords that shouldn't be exposed on the
command line. Only at most one argument may be passed on standard input to
the command. Be aware that even if the subcommand is the designated
argument to pass on standard input ("stdin=1"), the
subcommand may not contain NUL characters.
- sudo=(username | #uid)
- [3.12] Run this command as the specified user using
sudo. This is exactly equivalent to prepending "sudo -u
username --" to the command before running it. The path to
sudo is determined when remctld is built.
The user option is simpler and easier if remctld is running as
root. However, it may be desirable in some configurations to run
remctld as a non-root user, and remctl-shell (which shares
the same configuration files) usually runs as a non-root user. In those
cases, this option can be used to use sudo to switch users before
running the command.
Since the argument is passed verbatim to sudo's -u option, you
can specify a numeric UID by prepending it with "#".
- [3.13] Specifies the argument for this command that will
print a usage summary to standard output.
If remctld receives the command "help" with no arguments, and no
"help" command is defined in the configuration file, the server
will look through the configuration for any command with a
"summary" option set. If this option is set, and the user is
authorized to run the command, the server will run the specified
executable with the argument arg, sending the output back to
the user. It will do this for every command in the configuration that
meets the above criteria.
This allows display of a summary of available commands to the user based on
which commands that user is authorized to run. It's a lightweight form of
service discovery. Also see the "help" option.
- user=(username | uid)
- [3.1] Run this command as the specified user, which can be
given as either a username or as a UID. Even if given as a UID, the user
must be found in the user database (searched via getpwuid(3)).
remctld will run the command as the specified user, including that
user's primary and supplemental groups.
- One or more entries of the form
[method:]data, where method specifies an access
control method to be used, and data contains parameters whose
meaning depends on the method. If the method is omitted, the data is
processed as described for the "file" method.
If method is omitted, acl must either begin with "/"
or must not contain "=". Otherwise, it will be parsed as an
option instead. If there is any ambiguity, prepend the method.
As a special exception for backward compatibility, the ACL
"ANYUSER" (case-sensitive) is treated as equivalent to
Each entry is checked in order, and access is granted as soon as an entry
matches. If no entry matches, access is denied. The following methods may
supported; however, be aware that the availability of several ACL types
depends on whether remctld was built with that support. Each ACL
type is annotated with the version in which it was added.
- [3.10] Permit access to any user. This comes in two
- Permit any authenticated user. This means not only the
local Kerberos realm but also any realm with which there is a cross-realm
- Permit entirely anonymous users. This means no
authentication whatsoever is required to run the command. Any client with
network access to the server can run the command (using anonymous PKINIT),
assuming that anonymous service tickets are enabled for the local Kerberos
For backwards compatibility, the ACL "ANYUSER" is treated as identical
to "anyuser:auth". This was the only supported any-user ACL syntax
prior to remctl 3.10.
- [2.13] The data is the full path of an ACL file or to a
directory containing ACL files. Directories are handled as described for
the include directive in configuration files. An ACL file contains one
entry per line, in the [ method:]data form described above.
Entries are handled exactly as if they had appeared in the configuration
file except that the default method is "princ" instead of
"file". Blank lines and lines beginning with "#" are
ignored in the ACL files.
For backward compatibility, a line like:
in an ACL file behaves exactly as if the "include" directive had
been omitted, except that the default method is "file". Thus,
in an ACL file is the same as writing:
and is handled identically to the include directive in configuration
- [2.13] The data is the name of a Kerberos v5 principal
which is to be granted access, such as
- [2.13] This method is used to selectively deny access. The
data is parsed as a [ method:]data and evaluated as
described above, with the default scheme being "princ". If it
matches, access is denied immediately without examining any further
entries. Otherwise, processing continues.
Remember that access is granted as soon as an entry matches. For
"deny" rules to be effective, they therefore must come before
any ACLs they are intended to override. Be careful when using
"deny" when including a directory of ACL files, since the files
in that directory are read in an undefined order (not in alphabetical
order by filename). It's best to explicitly include the file containing
"deny" ACL rules first.
Note that "deny" only denies access; it never grants it. Thus,
deny alone does not grant access to anyone, and using deny on itself as in
"deny:deny:foo" neither denies nor grants access to anyone.
- [2.13] This method is used to grant access based on the CMU
GPUT (Global Privileged User Table -- see gput(5)). The data is
either a GPUT role name or a string of the form
group[xform], where group is a GPUT role name and
xform is a GPUT transform string. Access is granted if the user is
a member of the specified GPUT group, after applying either the optional
xform or the default transform.
This method is supported only if remctld was compiled with GPUT
support by using the "--with-gput" configure option.
- [3.9] This method is used to grant or deny access based on
membership in local UNIX groups. The data is taken to be a name of a local
system group. The user principal is converted to a local user name with
krb5_aname_to_localname(3) and then compared to the members of the
For example, to allow access to the members of group "goodguys",
use an ACL of "localgroup:goodguys" syntax. To deny access to
the members of group "badguys", use
krb5_aname_to_localname() follows local configuration rules to
determine how to convert Kerberos principal to local users. If the realm
of the principal is not in a local realm and is not otherwise covered by
one of those rules, the principal will be unchanged, which will almost
certainly mean that it will not be a member of any local group and access
will be denied.
This method is supported only if remctld was built with Kerberos
support and the getgrnam_r(3) library function was supported by the
C library when it was built.
- [2.16] This method is used to grant or deny access based on
Perl-compatible regular expressions. The data is taken to be a
Perl-compatible regular expression and matched against the user identity.
To deny access, use the "deny:pcre: regex" syntax.
This method is supported only if remctld was compiled with PCRE
support by using the "--with-pcre" configure option.
- [2.16] This method is used to grant or deny access based on
POSIX extended regular expressions. The data is taken to be a POSIX
extended regular expression (like those used by egrep) and matched
against the user identity. To deny access, use the "deny:regex:
This method is supported only if a library for POSIX-compatible regular
expressions was found when remctld was built.
To see the list of ACL types supported by a particular build of remctld
run "remctld -h".
The keyword ANYUSER may be used instead of the ACLs to allow access to all
users. The user still needs to authenticate to remctld
; this only
affects authorization. This can be used for backend programs that want to
check ACLs themselves and will retrieve the authenticated principal from the
REMOTE_USER environment variable. Note that ANYUSER accepts any
authenticated user, including cross-realm users from foreign Kerberos
itself uses the following environment variables when run in
stand-alone mode ( -m
- If these environment variables are set, remctld will
expect to be provided its listening sockets via the systemd socket
activation protocol and will not attempt to bind its own sockets. For more
details on the protocol, see daemon(7) and
- If this environment variable is set, remctld will
notify the socket named in this variable when it is ready to accept
incoming packets using the systemd status notification protocol. For more
details, see daemon(7) and sd_notify(3).
Note that using socket activation is recommended when running under systemd
in stand-alone mode, and status notification is not necessary or useful
when using socket activation.
When running in stand-alone mode, these environment variables will be cleared by
before running any commands.
The following environment variables will be set for any commands run via
(annotated with the version at which they were added):
- [2.16] The command string that caused this command to be
run. This variable will contain only the command, not the subcommand or
any additional arguments (which are passed as command arguments).
- [2.1] The IP address of the remote host. This may be IPv4
- [3.10] The time (in seconds since UNIX epoch) when the
authenticated remote session will expire. This will normally be the
expiration time of the Kerberos ticket used to authenticate to the
- [2.1] The hostname of the remote host, if it was available.
If reverse name resolution failed, this environment variable will not be
This is determined via a simple reverse DNS lookup and should be considered
under the control of the client. remctl commands should treat it with
skepticism and not use it for anything other than logging purposes.
- [1.0 for REMUSER, 2.1 for REMOTE_USER] Set to the Kerberos
principal of the authenticated client.
If the -k
flag is used, remctld
will also set KRB5_KTNAME to the
provided keytab path. This is primarily for communication with the GSS-API
library, but this setting will also be inherited by any commands run by
is to be started as follows, where "hostname"
is the machine where remctld will run, and 4373 is the port:
tcpserver hostname 4373 remctld
The equivalent line for /etc/inetd.conf
4373 stream tcp nowait root /usr/sbin/tcpd /usr/sbin/remctld
remctl stream tcp nowait root /usr/sbin/tcpd /usr/sbin/remctld
if the "remctl" service is listed in your /etc/services
To start remctld
in stand-alone mode instead, run:
To start remctld
in stand-alone mode in the foreground, use:
remctld -F -m
This is a typical invocation with systemd using socket activation. For upstart
(with "expect stop"), use:
remctld -F -m -Z
Example configuration file:
# Comments can be used like this.
accounts create /usr/local/bin/doaccount /etc/acl/group1 \
accounts delete /usr/local/bin/doaccount /etc/acl/group3
accounts view /usr/local/bin/doaccount ANYUSER
accounts passwd /usr/local/bin/dopasswd logmask=3 /etc/acl/group1
printing ALL /usr/local/bin/printthing /etc/acl/group2
The commands "accounts create", "accounts delete", and so
forth will all be passed to /usr/local/bin/doaccount with the first argument
being the specific subcommand, with the exception of "accounts
passwd". That command will be passed to /usr/local/bin/dopasswd instead,
but it will still get "passwd" as its first argument. The third
argument to "accounts passwd" (presumably the password) will not be
logged to syslog. All commands starting with "printing" will be
passed to /usr/local/bin/printthing.
Example ACL file:
# This is a comment.
This ACL file will reject "baduser@EXAMPLE.ORG" even if that user
would have been allowed by one of the other ACL rules. It will then grant
access according to the ACL entries in /etc/remctl/acl/admins
specific principals "service/admin@EXAMPLE.ORG" and
"service/other@EXAMPLE.ORG". The last line takes advantage of the
default ACL method of "principal" when processing an ACL file.
The version at which various command-line and configuration options and ACL
methods were added to remctld
are noted in their descriptions. Below is
the version information for more general features, in reverse order of when
the feature was added.
Support for the systemd readiness protocol and socket activation, including
honoring the environment variables LISTEN_FDS, LISTEN_PID, and NOTIFY_SOCKET,
was added in version 3.7.
Special handling of the "help" and "summary" commands was
added in version 3.2.
Support for the "ALL" keyword in the command field of the
configuration file was added in version 2.15. (It has always been supported in
the subcommand field.)
Support for the "EMPTY" keyword in the subcommand field of the
configuration file was added in version 2.15.
Support for ACL schemes and the method
syntax was added in
remctl 2.13. Prior versions of remctld
expected only files in the main
configuration file, and only principals or lines starting with
"include" in those files, without any method
The default listening port with the -m
option was changed to the
IANA-registered port of 4373 in version 2.11.
Support for IPv6 addresses in the REMOTE_ADDR environment variable was added in
used to set the environment variable SCPRINCIPAL when running
commands, for (partial) backward compatibility with sysctld
stopped doing so in version 2.1.
"include" directives in ACL files were added in version 1.11.
"include" directives in configuration files were added in version
When using Heimdal with triple-DES keys and talking to old clients that only
speak version one of the remctl protocol, remctld
may have problems
with MIC verification. This doesn't affect new clients and servers since the
version two protocol doesn't use MICs. If you are using Heimdal and run into
MIC verification problems, see the COMPATIBILITY section of gssapi
does not itself impose any limits on the number of child
processes or other system resources. You may want to set resource limits in
your inetd server or with ulimit
when running it as a standalone daemon
or under tcpserver
Command arguments may not contain NUL characters and must be shorter than the
operating system limit on the length of a command line since they're passed to
the command as command-line arguments. The exception is an argument passed via
standard input using the "stdin=" option in the configuration file.
At most one argument may be passed that way.
The remctl port number, 4373, was derived by tracing the diagonals of a QWERTY
keyboard up from the letters "remc" to the number row.
was originally written by Anton Ushakov. Updates and current
maintenance are done by Russ Allbery <email@example.com>.
Copyright 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2014
The Board of Trustees of the Leland Stanford Junior University
Copying and distribution of this file, with or without modification, are
permitted in any medium without royalty provided the copyright notice and this
notice are preserved. This file is offered as-is, without any warranty.
The current version of this program is available from its web page at