NAME

/etc/sshdoers - configuration file for sshdo(8)

DESCRIPTION

The /etc/sshdoers file specifies the commands that are allowed to be executed via incoming ssh(1) connections by users whose authorized keys force the use of the sshdo(8) command. If there is an /etc/sshdoers.d/ directory as well, then the files in it specify additional allowed commands. Any file in that directory whose name starts with a dot character (".") is ignored.

FILE FORMAT

The following sections describe the different types of line that make up the configuration files. There are comment lines and authorization, training, match, syslog, logfiles and banner directives.

Comment

Comment lines start with optional whitespace (e.g. " ") and a hash character ("#"). Comment lines and blank lines are ignored. Note that comments can't appear after any non-whitespace character because hash characters have special meaning in authorization directives (see the next section).

Authorization

Authorization directives specify which users and groups are allowed to execute which commands. They consist of one or more user names and/or group names, separated by whitespace, followed by optional whitespace, a colon character (":"), more optional whitespace, and a shell command.

Group names are preceded by a plus sign ("+"). A user name can be preceded by a minus sign ("-") to indicate that the user is not allowed to execute the command. These can be used together to allow most but not all members of a group to execute a command.

A user name or group name can also be followed by a forward slash character ("/") and a label that identifies which of the user's authorized keys to allow. The label comes from sshdo's command line argument(s), if any, in the command="" option in ~/.ssh/authorized_keys files (or in the ForceCommand directives in /etc/ssh/sshd_config). The label will usually be something that identifies the remote owner of the authorized key. Each authorized key in a ~/.ssh/authorized_keys file would usually have a different label but this isn't required. If multiple keys in a user's ~/.ssh/authorized_keys file use the same label, or no label, then they will just be indistinguishable to sshdo and they will all share the same authorizations. Labels might not be too useful when used with group names rather than user names but they are supported just in case.

The syntax of authorization directives is:

    AUTHORIZATION ::= ENTITY (" "+ ENTITY)* " "* ":" " "* COMMAND
    ENTITY ::= USER | "+" GROUP | "-" USER
    USER ::= username ("/" LABEL)?
    GROUP ::= groupname ("/" LABEL)?
    LABEL ::= short label with no whitespace or colons
    COMMAND ::= shell command | "<interactive>" | BINARY
    BINARY ::= "<binary>" " "* encoded shell command

Example:

    user1 user2/label +group3 -user3: cmd arg

The above example states that user1 may execute the command, cmd arg, for any authorized key. So may user2 but only for the authorized key(s) whose command="" option includes "label" as the command line argument to sshdo (i.e. command="/usr/bin/sshdo label"). Members of group3 may also execute the command but user3 may not, even if user3 is a member of group3.

Note that the command must specify the entire command. It is not just a prefix. The command can contain shell meta-characters. There is no aliasing or macros or line continuation. However, there is very limited pattern matching to represent commands that vary only in which specific digits appear on the command line (e.g. sequence numbers or date/time stamps). Any single hash character ("#") that appears in a command represents either a literal hash character, or a sequence of one or more digit characters. Any string of two or more hash characters represents that exact same number of hash or digit characters. See the Match section below for more detail.

Also, in the unlikely event that the shell command contains binary/unprintable characters, it must be specially encoded. It must start with "<binary>" followed by optional whitespace and the shell command with all binary/unprintable characters represented using hexadecimal notation (e.g. a newline character would be represented as "\x0a"). Also, all backslash characters ("\") in the shell command must be quoted with a preceding backslash character. But when the shell command does not contain any binary/unprintable characters, none of this encoding is necessary.

If an incoming ssh connection's requested command matches a command in the configuration, it will be executed by passing it to the user's login shell as the argument to its -c option (e.g. sh -c 'cmd arg'). If an incoming ssh connection has no requested command, then an interactive login is being requested. This is represented in the configuration and in log messages as "<interactive>". If allowed, the user's login shell will be executed as an interactive login shell (i.e. the first character of argv[0] is the dash character ("-"), e.g. "-sh").

Training

Training directives specify which users and groups are allowed to execute as yet unknown commands for the purpose of training the sshdo configuration. They consist of the word "training" optionally followed by user names and/or group names all separated by whitespace.

Group names are preceded by a plus sign ("+"). A user name can be preceded by a minus sign ("-") to indicate that the user is not to be put into training mode. These can be used together to put most but not all members of a group into training mode.

A user name or group name can also be followed by a forward slash character ("/") and a label that indicates which of the user's authorized keys to put into training mode. See the Authorization section above for details on labels.

The syntax of training directives is:

    TRAINING ::= "training" (" "+ ENTITY)*
    ENTITY ::= USER | "+" GROUP | "-" USER
    USER ::= username ("/" LABEL)?
    GROUP ::= groupname ("/" LABEL)?
    LABEL ::= short label with no whitespace or colons

Example:

    training user1 user2/label +group3 -user3

The above example states that user1 is in training mode for any authorized key. So is user2 but only for the authorized key(s) whose command="" option includes "label" as the command line argument to sshdo (i.e. command="/usr/bin/sshdo label"). Members of group3 are also in training mode but user3 is not, even if user3 is a member of group3.

If no user names or group names appear in a training directive, then training mode applies to all keys of all users. This is only recommended when first incorporating sshdo into your ssh infrastructure. Once sshdo policy is established, training mode should only be turned on when introducing new functionality for an existing key or when adding a new key to a user's ~/.ssh/authorized_keys file (unless you manually configure its allowed commands).

In training mode, sshdo will allow the execution of any command, including ones that aren't allowed in the configuration but they will be logged with type="training" rather than the usual type="disallowed". Note, however, that a command will still be disallowed and not executed for users who have been explicitly excluded from executing it (e.g. "-user: cmd arg").

This is useful for gathering the exact commands that are currently in use. For example, it's not at all obvious in advance which commands scp(1) or rsync(1) will require ssh to execute. Training mode makes it possible to learn which commands need to be added to /etc/sshdoers to keep a system functioning after sshdo is incorporated into it to improve security. Of course, training mode should not be left in place long-term.

Once training mode has been in place long enough to capture all necessary activity, sshdo can be invoked with the --learn option to output the configuration that needs to be added to /etc/sshdoers or /etc/sshdoers.d/ in order to allow the existing activity in future. Once that has been done, training mode can be turned off. Any disallowed commands encountered after that will not be executed.

Also note that sshdo can occasionally be invoked with the --unlearn option to identify authorization directives that have not been used recently and so no longer seem to be needed. It will output a new candidate configuration that will contain the authorization directives that are needed to continue to allow commands that are still in use but it will comment out the current authorization directives that no longer seem to be needed. If correct, this new candidate configuration can be used to replace the current configuration to maintain strict least privilege.

Note that, to avoid surprises, a global training directive with no user names or group names, that applies to all keys of all users, can only appear in /etc/sshdoers, not in /etc/sshdoers.d/*. However, training directives that only apply to the keys of particular users and/or groups can appear in either location. But it might be a good idea to keep all training directives in /etc/ssdoers anyway.

Match

The match directive specifies how hash characters ("#") are to be interpreted in shell commands in authorization directives. It also affects the patterns identified by sshdo's --learn and --unlearn options. It consists of the word "match" followed by whitespace and one of the following values: "exact", "digits" or "hexdigits". The default value is "digits". Note that the match directive can only appear in /etc/sshdoers, not in /etc/sshdoers.d/*. Also, there should only be one match directive. If there is more than one, the last one takes effect.

The value "exact" causes hash characters to match literal hash characters only. The value "digits" causes them to match literal hash characters or decimal digits ("0".."9"). The value "hexdigits" causes them to match literal hash characters or hexadecimal digits ("0".."9", "a".."f", "A".."F").

When matching "digits" or "hexdigits", a single hash character matches a single literal hash character or one or more matched characters (i.e. decimal or hexadecimal digits), and two or more hash characters match the exact same number of literal hash characters or matched characters (each character can either be a hash character or a digit).

The syntax of the match directive is:

    MATCH ::= "match" " "+ METHOD
    METHOD ::= "exact" | "digits" | "hexdigits"

Examples:

    match exact
    match digits
    match hexdigits

Syslog

The syslog directive specifies which syslog(3) facility to use for log messages. It consists of the word "syslog" followed by whitespace and one of the following syslog facility names: "auth", "user", "daemon", "local0", "local1", "local2", "local3", "local4", "local5", "local6" or "local7". The default value is "auth". Note that the syslog directive can only appear in /etc/sshdoers, not in /etc/sshdoers.d/*. Also, there should only be one syslog directive. If there is more than one, the last one takes effect.

The syntax of the syslog directive is:

    SYSLOG ::= "syslog" " "+ FACILITY
    FACILITY ::= "auth" | "daemon" | "user" | "local0" | "local1" |
        "local2" | "local3" | "local4" | "local5" | "local6" | "local7"

Examples:

    syslog auth
    syslog user
    syslog daemon
    syslog local0
    syslog local1
    syslog local2
    syslog local3
    syslog local4
    syslog local5
    syslog local6
    syslog local7

Note: Syntax errors in the configuration files are logged. The syslog directive should appear near the top of the configuration file so that it takes effect before any syntax errors are likely to be encountered. But if sshdo's --check option is used to perform a syntax check whenever the configuration changes, this isn't important.

Note: If the syslog directive is used, then you will almost certainly have to either use a logfiles directive (see the next section), or specify the appropriate corresponding log files when invoking sshdo with the --learn or --unlearn option.

Logfiles

Logfiles directives specify the file glob pattern(s) for locating the log files that contain sshdo log messages. These log files will be the default log file locations for sshdo's --learn and --unlearn options. Logfiles directives consist of the word "logfiles" followed by one or more file glob patterns all separated by whitespace. The default is /var/log/auth.log*. Log files can be uncompressed or gzip(1)-compressed. The logfiles argument can also be the dash character ("-") which causes sshdo to read log messages from standard input (stdin) by default (although that probably isn't very useful). Note that logfiles directives can only appear in /etc/sshdoers, not in /etc/sshdoers.d/*. There can be multiple logfiles directives and they will all be used.

Examples:

    logfiles /var/log/auth.log*
    logfiles /var/log/auth.log* /var/log/syslog*
    logfiles /var/log/auth.log /var/log/auth.log.1 /var/log/auth.log.?.gz

The banner directive specifies the path of a file whose contents are to be output to standard error (stderr) to ssh clients whose commands were disallowed and not executed. It consists of the word "banner" followed by whitespace and a file path. This can be used to inform clients that their command failed due to sshdo configuration rather than just silently failing to execute. Note that the banner directive can only appear in /etc/sshdoers, not in /etc/sshdoers.d/*. Also, there should only be one banner directive. If there is more than one, the last one takes effect.

Example:

    banner /etc/sshdo.banner

The default banner file contains the message:

    Access denied by sshdo policy.

But note that the default banner file is not used unless the banner directive in the configuration is uncommented.

EXAMPLE

    # /etc/sshdoers: Configure sshdo and define the commands that
    # are allowed via incoming ssh connections where authorized
    # keys include command="/usr/bin/sshdo" or where a ForceCommand
    # directive in /etc/ssh/sshd_config specifies /usr/bin/sshdo.
    #
    # See the manual pages sshdo(8) and sshdoers(5) for details.

    # Change the syslog facility for log messages if necessary.
    # The default is "auth".
    #
    # syslog auth
    # syslog user
    # syslog daemon
    # syslog local0
    # syslog local1
    # syslog local2
    # syslog local3
    # syslog local4
    # syslog local5
    # syslog local6
    # syslog local7

    # Change the default log files glob pattern(s) for --learn
    # and --unlearn if necessary.
    #
    # logfiles /var/log/auth.log*

    # Uncomment the banner directive and modify the banner file if
    # necessary to output its contents to standard error (stderr)
    # for ssh clients whose commands are disallowed and not executed.
    #
    # banner /etc/sshdo.banner

    # Change which characters are matched by hash characters ("#")
    # in shell commands in authorization directives if necessary.
    # The default is "digits".
    #
    # match exact
    # match digits
    # match hexdigits

    # Turn on training mode to allow but log unexpected commands either
    # for all users and keys (i.e. "training") or for specific users
    # and keys (e.g. "training user1 user2/label +group3 -user3").
    #
    # training

    # Add command authorization directives here or in /etc/sshdoers.d/*
    # (e.g. "user1 user2/label +group3 -user3: cmd arg").
    #

SUGGESTION

It might be a good idea to only use /etc/sshdoers for the configuration directives that can only appear in that file (i.e. match, syslog, logfiles, banner and global training directives), and to use files in /etc/sshdoers.d/ for authorization directives that allow users to execute commands.

If all authorization directives are the result of sshdo's --learn and --unlearn options, this would mean that the manual configuration is placed in /etc/sshdoers and the automatic configuration is kept separate in one or more files in /etc/sshdoers.d/.

After training mode has been in place to gather new or existing functionality that needs to be allowed, the corresponding new configuration can be added with:

    # sshdo --learn > /etc/sshdoers.d/.learned
    # vim /etc/sshdoers.d/.learned # Check that it is correct
    # sshdo --check /etc/sshdoers.d/.learned
    /etc/sshdoers.d/.learned syntax OK
    # cat /etc/sshdoers.d/.learned >> /etc/sshdoers.d/learned
    # rm /etc/sshdoers.d/.learned

Occasionally, any authorizations that are no longer in use can be removed from the configuration with:

    # sshdo --unlearn --accepting > /etc/sshdoers.d/.learned
    # vim /etc/sshdoers.d/.learned # Check that it is correct
    # sshdo --check /etc/sshdoers.d/.learned
    /etc/sshdoers.d/.learned syntax OK
    # mv /etc/sshdoers.d/.learned /etc/sshdoers.d/learned

CAVEAT

If there are errors in the configuration files, sshdo will ignore them and carry on. This is to avoid being too brittle. But of course, it would still be a problem. If a user name or group name is mistyped, commands that should be allowed will be disallowed. A complete failure to read the configuration files will mean that all commands will be disallowed. To avoid problems, always make changes to a copy of the configuration and then use sshdo's --check option to check the syntax of the copy before installing it as the new configuration. And test the new configuration after installing it.

Also make sure that the users with ~/.ssh/authorized_keys files that use sshdo have permission to read the configuration files. If you don't want the configuration files to be world readable, add all of the affected users to a new group (e.g. sshdoers) and make the configuration files readable by that group.

FILES

/etc/sshdoers - configures sshdo(8) and specifies allowed commands.
/etc/sshdoers.d/* - specifies additional allowed commands.
~/.ssh/authorized_keys - has ssh keys with command="/usr/bin/sshdo".
/var/log/auth.log - possible default destination for syslog messages.

SEE ALSO

sshdo(8), ssh(1), sshd(8), sshd_config(5), syslog(3), syslogd(8), logrotate(8).

AUTHOR

raf <raf@raf.org>