[ISN] The Authprogs SSH Command Authenticator (Passwordless SSH part 4)

From: InfoSec News (isnat_private)
Date: Wed Jan 15 2003 - 23:11:10 PST

  • Next message: InfoSec News: "[ISN] Security UPDATE, January 15, 2003"

    |  Linux Security: Tips, Tricks, and Hackery                       |
    |  Published by Onsight, Inc.                                      |
    |                                                                  |
    |  15-January-2003                                                 |
    |  http://www.hackinglinuxexposed.com/articles/20030115.html       |
    This issue sponsored by Onsight, your Security Solution
    Onsight, Inc is a consulting firm specializing in network security.
    Our network consultants have extensive experience in host security
    for all Unix flavours, from Solaris and *BSD to HP-EX and Irix. We
    can provide custom firewall solutions, Intrusion Detection systems,
    assist in log monitoring and analysis, and clean up your systems
    after successful cracker intrusions.
    Of course, our speciality is Linux security and systems - we wrote
    the book on it: Hacking Linux Exposed. If you want to protect your
    Unix network from crackers, you want to talk to us.
    For more information, see http://www.onsight.com or email 
    The Authprogs SSH Command Authenticator (Passwordless SSH part 4)
    By Brian Hatch
    Summary: Introducing Authprogs, software which lets you control which
    machines can run authorized commands via SSH using SSH Identities.
    In the previous three[1] articles, I've shown you how to manually set
    up identity-based authentication with SSH, and how to use it to force
    a specific command, regardless the actual command that the client
    attempts to run. Unfortunately, this procedure requires that you have
    one identity for each program you want to allow, which can be a very
    big hassle.
    In this article, I introduce you to authprogs, which can be used to
    control what commands can be run on a host-by-host basis. I've been
    using this program for ages now, and finally took the time to put in
    comments and make it readable. I'll be maintaining the code at http:/
    /www.hackinglinuxexposed.com/tools/authprogs. There are several
    things left to be done[2] and I encourage folks to develop it
    further. Right now I'd call it version 0.5.
    Authprogs is a very simple perl script.[3] It looks for a file named
    ~/.ssh/authprogs.conf to get it's configuration. This file simply
    lists the programs that are allowed to be run from specified hosts.
    You begin with an IP address or list of IP addresses in brackets. On
    the following lines you put the commands that are allowed from this
    host or hosts. Here's an example configuration:
      # The uptime command is allowed from any host
      [ ALL ]
      # Localhost can list /tmp (now that's useless)
      [ ]
              /bin/ls /tmp/
      # allow multiple machines by listing them together
      [ ]
              rsync --server --sender -logtpr . /var/www/
      [ ]
              # Need to imbed spaces?  Use quotes.
              ls -l "/path/to/some graphic.png"
      [ ]
              cd /webroot; rm *.html; wmk
    In this case, any machine (ALL is a wildcard for any machine) can run
    uptime. The machine (localhost) can run /bin/ls /tmp[4]
    In the third section, we list an rsync command that can be run by two
    machines. You could have created a separate section for
    with this rsync command, and copied the command in the previous entry
    for, but this is a bit cleaner, depending on your needs.
    The entire file is read until a match is found, so you can have
    multiple sections for a given host.
    As you see in the fourth section, if you need to allow spaces in your
    command arguments, just use double or single quotes normally. You can
    also put comments on their own line anywhere in this file, as long as
    you have them on their own line.
    Lastly, it's completely fine to have multiple commands on one line,
    or even shell meta-characters. For example if the user from wanted to run the authorized command above, they'd run
    the following:
$ ssh user@server -i /path/to/identity 'cd /webroot; rm *.html; wmk'
    The quotes here are needed to make sure that the local shell doesn't
    expand *.html or execute the rm and wmk locally. All the commands to
    be run on the server must be passed through unaltered.
    So, how do you install the authprogs program? You can put it in your
    ~/.ssh/ directory, or install it system wide in /usr/local/bin, or
    anywhere else you want. Just make sure to chmod a+rx it when you're
    done. Then set up your authorized_keys to run authprogs using the
    command= option in your authorized_keys file, create a ~/.ssh/
    authprogs.conf file, and you're all set.
    Ok, so that's a long list. We'll walk through it.
    Let's craft an example similar to the one from last week. The host
    beepbeep.example.net is our backup server. It wants to run the
    following program to back up the /etc/ directory on host
      backups@beepbeep$ cat backup_futzy
        # Go into our backups directory for futzy
        cd /backups/futzy/etc
        # Tell rsync to use ssh with a specific key.  The key we
        # created for this purpose is stored in /home/backups/keys/futzy
        RSYNC_RSH="ssh -i /home/backups/keys/futzy"
        export RSYNC_RSH
        # Sync the etc directory to a local backup.
        rsync -logptr rootat_private:/etc/ .
    Let's set up futzy to allow the rsync command to succeed. First,
    install authprogs:
      root@futzy# cp authprogs /usr/local/bin/authprogs
      root@futzy# chmod a+rx /usr/local/bin/authprogs
    Now install the public key part of /home/backups/keys/futzy on futzy.
      backups@beepbeep$ scp /home/backups/keys/futzy.pub root@futzy:/root
      root's password: <enter password>
      root@futzy# cat /root/futzy.pub
      ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAIEA3nCnBRQR2x4Ak7I3gS62ASXGiC+5o
      kc5iAyVnHAf08Lqk= backupsat_private
      root@futzy# vi /root/.ssh/authorized_keys
      # Now read in futzy.pub and make changes until it looks like
      # the listing below.
      root@futzy# cat /root/.ssh/authorized_keys
      ommand="/usr/local/bin/authprogs" ssh-rsa AAAAB3NzaC1yc2EAAAABIwA
      lXFYh49a18i++SScHnycmiL8AmEb06Obrhkc5iAyVnHAf08Lqk= backups@beepb
    We added several "no-" arguments to turn off SSH features this key
    doesn't need access to, and then the crucial "command=" argument
    which will force our authprogs command to run. You may notice that I
    left off the "from=" option which could have been used to limit this
    key to work only from specified hosts. You can either use it or not
    as you choose. The authprogs program will drop unauthorized commands
    or unauthorized hosts, so it's not strictly needed.
    Now we haven't set up our authprogs.conf file yet, so the rsync
    command should fail. Let's run it for grins:
      # Sync the etc directory to a local backup.
      backups@beepbeep$ rsync -logptr rootat_private:/etc/ .
      You're not allowed to run 'rsync --server --sender -logtpr . /etc/'
          from 53251 22
      protocol version mismatch - is your shell clean?
      (see the rsync man page for an explanation)
      rsync error: protocol incompatibility (code 2) at compat.c(58)
    The authprogs program actually shoots an error to STDERR (the "You're
    not allowed..." line above) to let the client know the command is
    rejected. You can use this error to determine what command was sent,
    and add this command to the authprogs.conf file.
    However, the authprogs program also keeps a log of the commands that
    are attempted. Looking at the log, we can see which commands were
    run, and which were denied:
      root@futzy# tail -1 /root/.ssh/authprogs.log
      2003/01/14 17:02:43 authprogs[25958]: Denying request
       'rsync --server --sender -logtpr . /etc/' from 53251 22
    This log entry indicates that the machine (beepbeep's
    IP address) tried to run the command "rsync --server --sender -logtpr
    . /etc/". The two numbers 53251 and 22 at the end of the line
    indicate the source and destination port of this SSH connection, and
    aren't terribly interesting.
    So, armed with the knowledge of the command rsync is attempting to
    run on the server, let's set up our authprogs.conf file:
      root@futzy# vi /root/.ssh/authprogs.conf
      # make changes
      root@futzy# cat /root/.ssh/authprogs.conf
          # Allow beepbeep to rsync the /etc/ directory:
          [ ]
                rsync --server --sender -logtpr . /etc/
    Excellent! Let's run our command from beepbeep and test it out:
      backups@beepbeep$ du -s .
      1      .
      # Sync the etc directory to a local backup.
      backups@beepbeep$ rsync -logptr rootat_private:/etc/ .
      (rsync runs...)
      backups@beepbeep$ du -s .
      9928   .
    Voila! It works!
    Now the beauty of authprogs is that you can use this key for many
    different commands, without every allowing it to have unrestricted
    access to the system.[5] It also means you have one file to maintain
    which lists the hosts that can run specific commands without a
    You can use the same private key on multiple machines, because the
    authprogs.conf file still dictates which commands a machine can run.
    However I still prefer creating unique keys on each client that needs
    passwordless access, just to be safe. Reusing keys doesn't buy you
    In summary, the authprogs program is a very simply way to create
    passwordless access to accounts with fine granularity. Unlike custom
    shells, it is usable on any account. (You wouldn't want to change
    root's shell to something that only allowed you to run "hostname" for
    example.) There are some obvious areas it could be improved, but it
    works as advertised.
    [1] Starting with http://www.hackinglinuxexposed.com/articles/
    [2] The TODO is available at http://www.hackinglinuxexposed.com/tools
    [3] I apologize to the purists who think everything should be written
    in C. Call me a Perl lover, a lazy hack, or whatever you like.
    [4] An example of a completely useless example if I ever wrote one.
    [5] Of course you should really avoid having any shell
    meta-characters or backticks available in your allowed commands, lest
    an attacker manage to trick them into running commands you didn't
    think of. Explicit commands are not prone to this sort of trickery,
    and are your best bet to keeping things secure.
    Brian Hatch is Chief Hacker at Onsight, Inc and author of Hacking
    Linux Exposed and Building Linux VPNs. He's been using SSH to secure
    his remote logins since Tatu posted the first version of the code -
    even if the administrators of those machines refused to install it
    for him. Brian can be reached at brianat_private
    This newsletter is distributed by Onsight, Inc.
    The list is managed with MailMan (http://www.list.org). You can
    subscribe, unsubscribe, or change your password by visiting
    http://lists.onsight.com/ or by sending email to
    Archives of this and previous newsletters are available at
    Copyright 2003, Brian Hatch.
    ISN is currently hosted by Attrition.org
    To unsubscribe email majordomoat_private with 'unsubscribe isn'
    in the BODY of the mail.

    This archive was generated by hypermail 2b30 : Thu Jan 16 2003 - 01:13:13 PST