GNU Rush – a restricted user shell (split by section):   Section:   Chapter:FastBack: Configuration File   Up: Configuration File   FastForward: Default Configuration   Contents: Table of ContentsIndex: Concept Index

4.2 Rule

The rule statement configures a GNU Rush rule. This is a block statement, which means that all statements located between it and the next rule statement (or end of file, whichever occurs first) modify the definition of the rule.

The syntax of the rule statement is:

Configuration: rule tag

The tag argument is optional. If it is given, it supplies a tag for the rule, i.e. a (presumably unique) identifier, which is used to label this rule. Rush uses this tag in its diagnostic messages. For rules without explicit tag, Rush supplies a default tag, which is constructed by concatenating ‘#’ character and the ordinal number of rule in the configuration file, in decimal notation. Rule numbering starts from ‘1’.

The following sub-sections describe statements that can be used within a rule.

4.2.1 Conditions

These statements define conditions that are used to match the rule with the request. A rule may contain any number of conditions. All conditions are tested in order of their appearance in the rule and are tied together using boolean shortcut ‘and’ evaluation: if any of them yields false, the rest is not evaluated and control is transferred to the subsequent rule.

Rule Config: command regex

True, if the current command line matches regular expression regex.

For example:

command ^scp (-v )?-t /incoming/(alpha|ftp)

By default, POSIX extended regular expressions are used. This, however can be changed using regex statement (see Regex).

Rule Config: match[ n] regexp

True, if nth word from the command line matches regular expression regexp. Notice, that square brackets form part of the statement syntax. A special value ‘$’ can be used instead of n to denote the last word. Unless changed by previous regex statement (see Regex), POSIX extended regular expressions are used.

The command line is split into words using the same rules as used in /bin/sh.

For example, the condition below yields true if the last argument is an absolute path name:

match[$] ^/.*
Rule Config: argc op num

Compare the number of command line arguments to num. The comparison operator is given by op, which can be one of the following: ‘=’ (or ‘==’), ‘!=’, ‘<’, ‘<=’, ‘>’, ‘>=’.

For example, the following condition matches if the number of arguments is less than 3:

argc < 3
Rule Config: uid [op] user-id

Compare current UID to user-id. The latter may be either a numeric UID or a name of an existing user.

The comparison operator is given by optional op, which can be one of the following: ‘=’ (‘==’), ‘!=’, ‘<’, ‘<=’, ‘>’, ‘>=’. If op is not given, equality (‘==’) is assumed.


uid smith
Rule Config: gid op group-id

Compare current GID to group-id, which is either a numeric value or a name of an existing group.

The comparison operator is given by op, which can be one of the following: ‘=’ (‘==’), ‘!=’, ‘<’, ‘<=’, ‘>’, ‘>=’. If op is not given, equality (‘==’) is assumed.

Rule Config: user names

Argument is a whitespace-separated list of user names. This condition yields true, if the user name matches one of the listed names. String comparisons are case-sensitive.

Rule Config: group names

Argument is a whitespace-separated list of group names. This condition yields true, if the the name of any group the user is a member of matches one of listed names. String comparisons are case-sensitive.

For example, to match users from groups ‘admin’ and ‘root’:

group admin root

Each condition allows for a negated form, by placing an exclamation sign between the condition keyword and expression. For example:

command ^scp

True, if the command line begins with ‘scp’.

command ! ^scp

True if the command line does not begin with ‘scp’.

4.2.2 Transformations

Special actions that allow to rewrite command line are called transformations. GNU Rush supports five kinds of transformations: ‘set’, ‘transform’, ‘delete’, ‘map’. All of them operate on command line split into words. Additionally, ‘set’ and ‘transform’ can operate on the entire command line.

Rush performs word splitting using the same rules as sh. Transformation actions refer to words by their index. Three kinds of indexes are supported. First of all, a word may be referred to by its ordinal number in the command line. The command name itself has index ‘0’. For example, given the command line:

/bin/scp -t /upload

one gets:


Negative indexes can also be used. They refer to words in the backward order, as illustrated in the following table:


Finally, the last word may be referred to as ‘$’, and the command name itself as ‘^’. There is a subtle difference between ‘0’ and ‘^’. The notation ‘^’ refers to the name of the program that rush will execute at the end of the matching rule, whereas the notation ‘0’ refers to the 0th argument that will be passed to that program (‘argv[0]’). Most of the time the two values coincide. Unless the rule modifies ‘^’, ‘0’th word will be used as the program name. There exist some cases when you need to explicitly set ‘^’. See Interactive, for a possible use of this feature.

Some of the transformations implement patterns. A pattern is a string which may contain meta-variables. Before using, these meta-variables are expanded using the following rules:

${user}User name
${group}Name of the user’s principal group
${home}User’s home directory
${gecos}User’s GECOS field
${program}Program name (‘^’)
${command}Full command line
$0 to $9Corresponding word from the command line
${N}Nth word (see above for the allowed values of N) Set

The ‘set’ transformation allows to replace entire command line, or any of its arguments, with the given value.

Rule Config: set pattern

Command line is replaced with the expansion of pattern (see patterns). E.g.:

set /bin/echo "Command forbidden: ${command}"

As another example, the following rule uses transform to ensure that /usr/bin/cvs binary is used:

rule cvs
  command ^cvs server
  set[0] /usr/bin/cvs

In versions of GNU Rush prior to 1.6, it was common to use the transform action for this purpose.

Rule Config: set[ n] pattern

Replace nth argument with the expansion of pattern. Notice, that square brackets are part of the statement syntax.

See indexing, for a description of n. See patterns, for a description of pattern. E.g.:

set[0] /bin/echo Delete

The ‘delete’ action deletes the given word, or range of words, from the command line. It has two forms.

Rule Config: delete[ n]

Delete nth word. See indexing, for a detailed description of n and its syntax. However, see the note below.

Rule Config: delete n m

Delete words from n to m, inclusive. For example, the following action removes all arguments, except the command name:

delete 1 $

Neither form can be used to delete the command name, i.e. ‘[0]’ or ‘[^]’. Transform

The transform action modifies the value of the command line, or any particular word of it, according to a sed s-expression. S-expressions are described in more detail below (see s-expression). This action has several forms.

Rule Config: transform expr

Apply expression expr to entire command line. For example, the action below adds a -t option after the command name:

transform s,^[^ ]+,& -t,
Rule Config: transform pattern expr

Expand pattern as described in patterns, apply expr to the expansion, and replace the command line with the result.

Rule Config: transform[ n] expr

Apply expression expr to nth word from the command line. Notice, that square brackets are part of the statement syntax. See indexing, for a detailed description of n and its syntax.

Rule Config: transform[ n] pattern expr

Apply expression expr to the expanded pattern and assign the result to nth word. See patterns, for a description of patterns and their expansion. See indexing, for a detailed description of n and its syntax.

The example below replaces the 0th argument with the base name of the command, prefixed by a dash:

transform[0] ${^} s,.*/,-,

For instance, if the command name is ‘/bin/bash’, ‘argv[0]’ will become ‘-bash’.

The transformation expression, expr, is a sed-like replace expression of the form:


where regexp is a regular expression, replace is a replacement for each part of the input that matches regexp. Both regexp and replace are described in detail in The ‘s’ Command in GNU sed.

As in sed, you can give several replace expressions, separated by a semicolon.

Supported flags are:


Apply the replacement to all matches to the regexp, not just the first.


Use case-insensitive matching


regexp is an extended regular expression (see Extended regular expressions in GNU sed).


Only replace the numberth match of the regexp.

Note: the POSIX standard does not specify what should happen when you mix the ‘g’ and number modifiers. Rush follows the GNU sed implementation in this regard, so the interaction is defined to be: ignore matches before the numberth, and then match and replace all matches from the numberth on.

Any delimiter can be used in lieu of ‘/’, the only requirement being that it be used consistently throughout the expression. For example, the following two expressions are equivalent:

transform s/one/two/
transform s,one,two,

Changing delimiters is often useful when the regex contains slashes. For instance, it is more convenient to write s,/,-, than s/\//-/.

For example, the following rule uses transform to ensure that /usr/bin/cvs binary is used:

rule cvs
  command ^cvs server
  transform[0] s|.*|/usr/bin/cvs|

The same effect can be achieved with a set statement, as shown in set-command.

As a more complex example, consider the following rule:

rule svn
  command ^svnserve -t
  transform s|-r *[^ ]*||;s|^svnserve |/usr/bin/svnserve -r /svnroot |

This transform expression first removes all occurrences of -r option and its arguments from the command line, and then adds its own -r option and replaces ‘svnserve’ with the full program file name. Map

The ‘map’ statement uses file lookup to find a new value for the command line word.

Rule Config: map[ n] file delim pattern kn vn
Rule Config: map[ n] file delim pattern kn vn default

Arguments are:


Argument index, as in indexing.


Name of the map file. It must begin with ‘/’ or ‘~/’. Before using, the file permissions and ownership are checked using the procedure described in security checks.


A string containing allowed field delimiters.


The value of the lookup key. Before using, it is expanded as described in patterns.


Number of the key field in file. Fields are numbered starting from 1.


Number of the value field.


If supplied, this value is used as a replacement value, when the key was not found in file.

The map file consists of records, separated by newline characters (in other words, a record occupies one line). Each record consists of fields, separated by delimiters, given in delim argument. If delim contains a space character, then fields may be delimited by any amount of whitespace characters (spaces and/or tabulations). Otherwise, exactly one delimiter delimits fields.

Fields are numbered starting from 1.

The map action works as follows:

  1. The pattern argument is expanded as described in patterns and the resulting value is used as lookup key.
  2. The file is scanned for a record whose knth field matches the lookup key.
  3. If such a record is found, the value of its vnth field is assigned to the nth command line word (see indexing, for a description of n).
  4. Otherwise, if default is supplied, it becomes the new value of the nth word.
  5. Otherwise, the nth word remains unchanged.

For example, suppose that the file /etc/passwd.rush has the same syntax as the system passwd file (see Password File in passwd(5) man page). Then, the following statement will replace ‘argv[0]’ with the value of ‘shell’ field, using the current user name as a key:

map[0] /etc/passwd.rush : ${user} 1 7

See also Interactive, for another example of using this statement.

4.2.3 System Actions

System actions provide an interface to the operating system.

Rule Config: umask mask

Set the umask. The mask must be an octal value not greater than ‘0777’. The default umask is ‘022’.

Rule Config: newgrp group-id
Rule Config: newgroup group-id

Changes the current group ID to group-id, which is either a numeric value or a name of an existing group.

Rule Config: chroot dir

Change the root directory to that specified in dir. This directory will be used for file names beginning with ‘/’. A tilde (‘~’) at the start of dir is replaced with the user’s home directory.

The directory dir must be properly set up to execute the commands. For example, the following rule defines execution of sftp-server in an environment, chrooted to the user’s home directory:

rule sftp
  command ^.*/sftp-server
  set[0] bin/sftp-server
  chroot ~

For this to work, each user’s home must contain the directory bin with a copy of sftp-server in it, as well as all directories and files that are needed for executing it, in particular lib.

Rule Config: chdir dir

Change to the directory dir. The argument is subject to tilde-expansion (see chroot, above). If both chdir and chroot are specified, then chroot is executed first.

Rule Config: limits res

Impose limits on system resources, as defined by res. The argument consists of commands, optionally separated by any amount of whitespace. A command is a single command letter followed by a number, that specifies the limit. The command letters are case-insensitive and coincide with those used by the shell ulimit utility:

CommandThe limit it sets
Amax address space (KB)
Cmax core file size (KB)
Dmax data size (KB)
Fmaximum file size (KB)
Mmax locked-in-memory address space (KB)
Nmax number of open files
Rmax resident set size (KB)
Smax stack size (KB)
Tmax CPU time (MIN)
Umax number of processes
Lmax number of logins for this user (see below)
Pprocess priority -20..20 (negative = high priority)

For example:

limits T10 R20 U16 P20

If some limit cannot be set, execution of the rule aborts. In particular, ‘L’ limit can be regarded as a condition, rather than action. The setting limit Ln succeeds only if no more than n rush instances are simultaneously running for the same user. This can be used to limit the number of simultaneously open sessions.

The use of ‘L’ resource automatically enables forked mode. See Accounting and Forked Mode, for more information about it.

4.2.4 Environment

The env action allows to modify the environment in which the program will be executed.

Rule Config: env args

Modify the environment.

Its arguments are a whitespace-delimited list of specifiers. Each specifier can contain references to variables from the inherited environment. The reference syntax is the same as in Bourne shell.

The following specifiers are understood:

- (a dash)

Clear the environment. This is understood only when used as a first word in args.


Unset the environment variable name.


Unset the environment variable name only if its value is val.


Retain the environment variable name.


Define environment variable name to have given value.


Retain variable name and append value to its value. If no such variable is present in the environment, it is created and value is assigned to it. However, if value starts with a punctuation character, this character is removed from it before the assignment. This is convenient for using this construct with environment variables like PATH, e.g.:


In this example, if PATH exists, ‘:/sbin’ will be appended to it. Otherwise, it will be created and ‘/sbin’ will be assigned to it.

This is roughly equivalent to


Retain variable name and prepend value to its value. If no such variable is present in the environment, it is created and value is assigned to it. However, if value ends with a punctuation character, this character is removed from it before assignment.

4.2.5 Fall-through

A fall-through rule is a special rule that does not execute the requested command. When a matching fall-through rule is encountered, rush evaluates it and continues scanning its configuration for the next matching rule. Any transformation and env actions found in the fall-through rule take effect immediately, which means that subsequent rules will see modified command line and environment. Execution of any other actions found in the fall-through rule is delayed until a usual rule is found.

A fall-through rule is declared using the following statement:

Rule Config: fall-through

Declare a fall-through rule.

Usually this statement is placed as the last statement in a rule, e.g.:

rule default
  umask 002

Fall-through rules provide a way to set default values for subsequent rules. For example, any rules that follow the ‘default’ rule shown above, will inherit the umask and environment set there.

One can also use fall-through rules to “normalize” command lines. For example, consider this rule:

rule default
  transform[0] s|.*/||;

It will remove all path components from the first command line argument. As a result, all subsequent rules may expect a bare binary name as the first argument.

Yet another common use for such rules is to enable accounting (see the next subsection), or set resource limits for the rest of rules:

rule default
  limit l1

4.2.6 Accounting and Forked Mode

GNU Rush is able to operate in two modes, which we call default and forked. When operating in the default mode, the process image of rush itself is overwritten by the command being executed. Thus, when it comes to launching the requested command, the running instance of rush ceases to exist.

There is also another operation mode, which we call forked mode. When running in this mode, rush executes the requested command in a subprocess, and remains in memory supervising its execution. Once the command terminates, rush exits.

One advantage of the forked mode is that it allows to run accounting, i.e. to note who is doing what and to keep a history of invocations. The accounting, in turn, can be used to limit simultaneous executions of commands (logins, in GNU Rush terminology), as requested by ‘L’ command to limit statement (see L limit).

The forked mode is enabled on a per-rule basis, for rules that contain either ‘L’ command in the limit statement, or ‘acct on’ command:

Rule Config: acct bool

Turn accounting mode on or off, depending on bool. The argument can be one of the following: ‘yes’, ‘on’, ‘t’, ‘true’, or ‘1’, to enable accounting, and ‘no’, ‘off’, ‘nil’, ‘false’, ‘0’, to disable it.

Notice, that there is no need in explicit acct on command, if you use limit L.

The notion ‘rule contains’, used above, means that either the rule in question contains that statement, or inherits it from one of the above fall-through rules (see Fall-through). In fact, in most cases the accounting should affect all rules, therefore we suggest to enable it in a fall-through rule at the beginning of the configuration file, e.g.:

rule default
  acct on

If the need be, you can disable it for some of the subsequent rules by placing acct off in it. Notice, that this will disable accounting only, the forked mode will remain in action. To disable it as well and enforce default mode for a given rule, use fork off statement:

Rule Config: fork bool

Enable or disable forked mode. This statement is mainly designed as a way of disabling the forked mode for a given rule.

Once the accounting enabled, you can view the list of currently logged in users using rushwho command (see Rushwho) and view the history of last logins using rushlast command (see Rushlast).

4.2.7 Post-process Notification

Rush can be configured to send a notification over INET or UNIX sockets, after completing user request. It is done using the post-socket statement:

Rule Config: post-socket url

Notify URL about completing the user request. This statement implies forked mode (see Accounting and Forked Mode).

Allowed formats for url are:


Connect to remote host hostname using TCP/IP. Hostname is the host name or IP address of the remote machine. Optional port specifies the port number to connect to. It can be either a decimal port number or a service name from /etc/services. If port is absent, ‘tcpmux’ (port 1) is assumed.


Connect to a UNIX socket filename.

For example:

rule default
  post-socket inet://localhost

The GNU Rush notification protocol is based on TCPMUX (RFC 1078).

After establishing connection, rush sends the rule tag followed by a CRLF pair. The rule tag acts as a service name. The remote party replies with a single character indicating positive (‘+’) or negative (‘-’) acknowledgment, immediately followed by an optional message of explanation, terminated with a CRLF.

If positive acknowledgment is received, rush sends a single line, consisting of the user name and the executed command line, separated by a single space character. The line is terminated with a CRLF.

After sending this line, rush closes the connection.

The post-process notification feature can be used to schedule execution of some actions after certain rules.

See notification example, for an example of how to use this feature.

4.2.8 Exit rule

An exit rule does not execute any commands. Instead, it writes the supplied error message to the specified file descriptor and exits immediately. An exit rule is defined using the following statement:

Rule Config: exit fd message
Rule Config: exit message

Write textual message message to a file descriptor, given by the optional argument fd. If fd is absent, ‘2’ (standard error) is used.

The message argument is subject to backslash interpretation (see Table 4.1).

For example (note the use of line continuation character):

exit \
    \r\nYou are not allowed to execute that command.\r\n\
    \r\nIf you think this is wrong, ask <> for assistance.\r\n

If message begins with a ‘@’ sign, the remaining characters are treated as the name of a predefined error message (see Error Messages). The corresponding message text is retrieved and used instead of message. For example:

  exit @nologin-message

If the characters after ‘@’ do not correspond to any predefined error message name, an error of type ‘config-error’ is signaled and rush exits.

If you need to begin your exit message with a ‘@’ sign, duplicate it, as in this example:

  exit @@Special error message

This example will produce ‘@Special error message’.

Exit actions are useful for writing trap rules, i.e. the rules that are intended to trap incorrect or prohibited command lines and to return customized reply messages in such cases. Consider the following rule:

rule git
  command ^git-.+
  match[1] ^/sources/[^ ]+\.git$
  transform s|.*|/usr/bin/git-shell -c "&"|

It allows to use only those Git repositories that are located under /sources directory6. If a user tries to access a repository outside this root, he will be returned a default error message, saying ‘You are not permitted to execute this command’ (see usage-error). You can, however, provide a more convenient message in this case. To do so, place the following after the ‘git’ rule:

rule git-trap
  command ^git-.+
  exit fatal: Use of this repository is prohibited.

This rule will trap all git invocations that do not match the ‘git’ rule.

4.2.9 Interactive Access

Sometimes it may be necessary to allow some group of users limited access to interactive shells. GNU Rush contains provisions for such usage. When rush is invoked without -c it assumes interactive usage. In this case only rules explicitly marked as interactive are considered, the rest of rules is ignored.

Rule Config: interactive

This statement marks the rule it appears in as interactive. This rule will match only if rush is invoked without command line arguments.

Unless command line transformations are applied, interactive rule finishes by executing /bin/sh. The first word in the command line (argv[0]) is normally set to the basename of the command being executed prefixed by a dash sign.

Consider the following example:

rule login
  group rshell
  map[^] /etc/ : ${user} 1 2
  transform[0] ${program} s,^,-r,

rule nologin
  exit You don't have interactive access to this machine.

The ‘login’ rule will match interactive user requests if the user is a member of the group ‘rshell’. It uses /etc/ to select a shell to use for that user (see map). This map file consists of two fields, separated by a colon. If the shell is found, its base name, prefixed with ‘-r’, will be used as ‘argv[0]’ (this indicates a restricted login shell). Otherwise, the trap rule ‘nologin’ will be matched, which will output the given diagnostics message and terminate rush.

To test interactive access, use the -i option:

rush --test -i 

4.2.10 Localization

GNU Rush is internationalized, which means that it is able to produce log and diagnostic messages in any language, if a corresponding translation file is provided. This file is called a localization or domain file. To find an appropriate localization file, rush uses the following parameters:


Locale name is a string that describes the language, territory and optionally, the character set to use. It consists of the language (ISO 639) and country (ISO 3166) codes, separated by an underscore character, e.g. ‘en_US’ or ‘pl_PL’. If a character set is specified, its name follows the country code and is separated from it by a ‘@’ character.

There are two special locale names: ‘C’ or ‘POSIX’ mean to use the default POSIX locale, and ‘""’ (an empty string), means to use the value of the environment variable LC_ALL as the locale name.


Directory where localization files are located. If not specified, a predefined set of directories is searched for the matching file.


Text domain defines the base name of the localization file.

Given these parameters, the name of the full pathname of the localization file is defined as:


GNU Rush produces three kinds of messages:


These are diagnostics messages that GNU Rush produces to its log output (syslog, unless in test mode).

error messages

Messages sent to the remote party when rush is not able to execute the request (see Error Messages).

exit messages

These are messages sent to the remote party by exit rules (see Exit).

These messages use different domain names (and may use different locale directories). The diagnostics and error messages use textual domain ‘rush’. The corresponding locale directory is defined at compile time and defaults to prefix/share/locale, where prefix stands for the installation prefix, which is /usr/local, by default.

GNU Rush is shipped with several localization files, which are installed by default. As of version 1.8, these files cover the following locales:


This is default domain, it is always supported and does not require any special handling. It is roughly equivalent to ‘en_US’ (English).


Polish messages.


Ukrainian messages.

If the localization you need is not in this list, visit If it is not there either, consider writing it (see Translators in GNU gettext utilities, for a detailed instructions on how to do that).

Exit messages use custom domain files. It is responsibility of the system administrator to provide and install such files. Localization Directives

The following configuration directives control localization. They are available for use in rule statements:

Configuration: locale name

Sets the locale name. To specify empty locale, use ‘""’ as name (recall that empty locale name means use the value of the environment variable LC_ALL as locale name).

Configuration: locale-dir name

Sets the name of the locale directory.

Configuration: text-domain name

Sets the textual domain name.

The following configuration fragment illustrates their use:

rule l10n
  locale pl_PL
  text-domain rush-config

Different users may have different localization preferences. See per-user l10n, for a description of how to implement this. Writing Your Localization

You need to write a localization file for your configuration script if it implements exit rules (see Exit) and changes user locale (see locale).

Preparing localization consists of three stages: extracting exit messages and forming a PO file, editing this file, compiling and installing it. The discussion below describes these stages in detail.

  1. Creating a ‘po’ file.

    A PO (Portable Object) file is a plain text file, containing original messages and their translations for a particular language. See The Format of PO Files in GNU gettext utilities, for a description of its format.

    The script rush-po.awk serves for extracting messages from the configuration file and forming a PO file. This script is installed in the prefix/share/rush directory7, where prefix stands for your installation prefix.

    Supposing the package is installed in the default prefix, the following command will create a PO file from your configuration file:

      awk -f /usr/local/share/rush/rush-po.awk \
             /usr/local/etc/rush.rc > myconf.po

    Please note, that rush-po.awk does not handle include directives (see Include). If your configuration file uses these directives, you need to specify each include file in the rush-po.awk command line, e.g.:

      awk -f /usr/local/share/rush/rush-po.awk \
             /usr/local/etc/rush.rc /home/*/.rush > myconf.po
  2. Editing the PO file

    Open the created PO file with your favorite editor and supply message translations after msgstr keywords. Although you can use any editor, capable of handling plain text files, we recommend to use GNU Emacs, which provides a special po-mode. See PO Files and PO Mode Basics in GNU gettext utilities, for guidelines on editing PO files and using the po-mode.

  3. Compiling the PO file

    When ready, the PO file needs be compiled into a MO (Message Object) file, which is directly readable by rush. This is done using msgfmt utility from GNU gettext:

      msgfmt -o myconf.po

    See msgfmt Invocation in GNU gettext utilities, for a detailed description of the msgfmt utility.

    After creating the MO file, copy it into appropriate directory. It is important that the installed MO file uses the naming scheme described in localization file naming.



See git, for a better way to handle Git accesses.


To be precise, it is installed in dataroot/rush, where dataroot is a directory for read-only architecture-independent data, which is set by the --datarootdir option to configure. Unless that option is used, this directory defaults to prefix/share/rush

GNU Rush – a restricted user shell (split by section):   Section:   Chapter:FastBack: Configuration File   Up: Localization   FastForward: Default Configuration   Contents: Table of ContentsIndex: Concept Index