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

6 Usage Tips

In this chapter we will explain how to write GNU Rush configuration rules for several popular remote copy and version control system utilities. For this purpose, we assume the following setup:

6.1 scp

The scp utility is executed on the server side with option -t, when copying files to server, and with -f when copying from it. Thus, the basic templates for scp rules are:

# Copying to server:
rule scp-to
  match $command ~ "^scp -t"
  ...

# Copying from server:
rule scp-from
  match $command ~ "^scp -f"
  ...

You may also wish to allow for -v (‘verbose’) command line option. In this case, the ‘scp-to’ rule will become:

rule scp-to
  match $command ~ "^scp (-v )?-t"
  ...

Now, we want users to be able to upload files to /home/ftp/incoming directory. Moreover, the /home/ftp directory prefix must be invisible to them. We should also make sure that the user cannot get outside the incoming directory by using ../ components in his upload path. So, our first rule for scp uploads will be:

rule scp-to-incoming
  match $command ~ "^scp (-v )?-t /incoming/" && \
                   ${-1} !~ "\\.\\./"
  set command "/bin/scp"
  set [-1] =~ "s|^|/home/ftp/|"

The match statement ensures that no relative components are used. The two set statements ensure that the right scp binary is used and that /home/ftp prefix is prepended to the upload path.

Other than uploading to /incoming, users must be able to use scp to manage public_html directories located in their homes. They should use relative paths for that, i.e., the command:

$ scp file.html server:

will copy file file.html to ~/public_html/file.html on the server. The corresponding rule is:

rule scp-home
  match $command ~ "^scp (-v )?-[tf] [^/].*" && \
                   ${-1} !~ "\\.\\./"
  set [0] = "/bin/scp"
  set [-1] =~ "s|^|public_html/|"
  chdir "~"

Finally, we provide two trap rules for diagnostic purposes:

rule scp-to-trap
  match $command ~ "^scp (-v )?-t"
  exit "Error: Uploads to this directory prohibited"

rule scp-from
  match $command ~ "^scp (-v )?-f"
  exit Error: Downloads from this directory prohibited

6.2 rsync

On the server side, rsync is executed with the --server command line option. In addition, when copying files from the server, the --sender option is used. This makes it possible to discern between incoming and outgoing requests.

In our setup, rsync is used the same way as scp, so the two rules will be:

rule rsync-incoming
  match $command ~ "^rsync --server" && \
        $command !~ --sender && \
        ${-1} ~ "/incoming/" && ${-1} !~ "\\.\\./"
  set [0] =~ "s|^|/usr/bin/|"
  set [-1] =~ "s|^|/home/ftp/|"

rule rsync-home
  match $command ~ "^rsync" && \
        ${-1} !~ "^[^/]" && \
        ${-1} !~ "\\.\\./"
  set [0] = "s|^|/usr/bin/|"
  set [-1] =~ "s|^|public_html/|"
  chdir "~"

The trap rules for rsync are trivial:

rule rsync-to-trap
  match $command ~ "^rsync.*--sender"
  exit "Error: Downloads from this directory prohibited"

rule rsync-from-trap
  match $command ~ "^rsync"
  exit "Error: Uploads to this directory prohibited"

6.3 sftp

Executing sftp on the client machine invokes sftp-server, without arguments, on the server.

We want to allow our users to use sftp to manage their public_html directories. The sftp-server will be executed with the user’s home directory as root, in a chrooted environment. For this to work, each user’s home must contain a copy of sftp-server (which we’ll place in ~/bin subdirectory) and all files it needs for normal execution: /etc/group and /etc/passwd with one entry (for the user and his group), and, unless the binary is linked statically, all the shared libraries it is linked with, in the subdirectory ~/lib.

Given these prerequisites, the following rule will ensure proper sftp interaction:

rule sftp-incoming
  match $command ~ "^.*/sftp-server"
  set [0] = "/bin/sftp-server"
  chroot "~"
  chdir "public_html"

Notice the last action. Due to it, users don’t have to type cd public_html at the beginning of their sftp sessions.

6.4 cvs

Using cvs over ssh invokes cvs server on the server machine. In the simplest case, the following rule will do to give users access to CVS repositories:

rule cvs
  match $command ~ "^cvs server"
  set command ~ "s|^cvs|/usr/bin/cvs -f"

However, cvs as of version 1.12.13 does not allow to limit root directories that users are allowed to access. It does have --allow-root option, but unfortunately this option is ignored when invoked as cvs server. To restrict possible roots, we have to run cvs in a chrooted environment. Let’s suppose we created an environment for cvs in directory /var/cvs, with the cvs binary located in /var/cvs/bin and repository root directory being /var/cvs/cvsroot. Then, we can use the following rule:

rule cvs
  match $command ~ "^cvs server"
  set [0] = "/bin/cvs"
  chroot "/var/cvs"

6.5 svn

Remote access to SVN repositories is done via svnserve binary. It is executed on server with -t option. The -r option can be used to restrict access to a subset of root directories. So, we can use the following rule:

rule svn
  match $command ~ "^svnserve -t"
  set command =~ "s|-r *[^ ]*||"
  set command =~ \
      "s|^svnserve |/usr/bin/svnserve -r /svnroot|"

The first set command action removes any -r options the user might have specified and enforces a single root directory. A more restrictive action can be used to improve security:

  set command =~ "s|.*|/usr/bin/svnserve -r /svnroot|"

6.6 git

Remote access to Git repositories over ssh causes execution of git-receive-pack and git-upload-pack on the server. The simplest rule for Git is:

rule git
  set $command ~ "^git-(receive|upload)-pack"
  set [0] =~ "s|^|/usr/bin/|"

The set action is necessary to ensure the proper location of Git binaries to use. This example supposes they are placed in /usr/bin, you will have to tailor it if they are located elsewhere on your system.

To limit Git accesses to repositories under /gitroot directory, modify the ‘$1’, as shown in the example below:

rule git
  match $command ~ "^git-(receive|upload)-pack"
  set [1] =~ "^/gitroot[^ ]+\.git$"
  set [0] =~ "s|^|/usr/bin/|"

To provide more helpful error messages, you may follow this rule by a trap rule (see trap rules):

# Trap the rest of Git requests:
rule git-trap
  match $command ~ "^git-.+"
  exit "fatal: access to this repository is denied."

6.7 Notification

In this section we will show how to set up a mail notification for Rush rules. Let’s suppose we wish to receive emails for each upload by scp-to rule (see scp). To do so, we add the following fall through rule to the beginning of rush.rc:

rule default
  post-socket "inet://localhost"
  fall-trough

This will enable notifications for each rule located below this one. Missing port in post-socket statement means rush will be using the default ‘tcpmux’ port.

To receive and process these requests, you will need an inetd capable to handle TCPMUX. We recommend the one from GNU Inetutils package (GNU Inetutils). In /etc/inetd.conf file, we add:

# Enable TCPMUX handling.
tcpmux          stream  tcp  nowait root  internal
# Handle ‘scp-to’ service.
tcpmux/+scp-to  stream  tcp  nowait root  \
                        /usr/sbin/tcpd  /bin/rushmail

The program /bin/rushmail does the actual notification. Following is its simplest implementation:

#! /bin/sh

read user command

/usr/sbin/sendmail -oi -t <<EOT
From: GNU Rush Notification <devnull@localhost>
To: <root@localhost>
Subject: GNU Rush notification

Be informed that $user executed $command.
EOT

GNU Rush – a restricted user shell (split by chapter):   Section:   Chapter:FastBack: Usage Tips   Up: Usage Tips   FastForward: Test Mode   Contents: Table of ContentsIndex: Concept Index