diff options
Diffstat (limited to 'security/safesh/files')
-rw-r--r-- | security/safesh/files/cvs-safesh.sh | 6 | ||||
-rw-r--r-- | security/safesh/files/safesh.1 | 546 | ||||
-rw-r--r-- | security/safesh/files/safesh.sh | 140 |
3 files changed, 692 insertions, 0 deletions
diff --git a/security/safesh/files/cvs-safesh.sh b/security/safesh/files/cvs-safesh.sh new file mode 100644 index 000000000000..e56e8116d7d1 --- /dev/null +++ b/security/safesh/files/cvs-safesh.sh @@ -0,0 +1,6 @@ +#!/bin/sh +if [ "$2" = "-l" ]; then + exec safesh $3@$1 -- "$@" +else + exec safesh $1 -- "$@" +fi diff --git a/security/safesh/files/safesh.1 b/security/safesh/files/safesh.1 new file mode 100644 index 000000000000..938cd43eb188 --- /dev/null +++ b/security/safesh/files/safesh.1 @@ -0,0 +1,546 @@ +.\"- +.\" Copyright (c) 2002 Eivind Eklund +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer +.\" in this position and unchanged. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. The name of the author may not be used to endorse or promote products +.\" derived from this software without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.\" $FreeBSD$ +.\" +.Dd January 26, 2002 +.Dt SAFESH 1 +.Sh NAME +.Nm safesh +.Nd safe key manager for OpenSSH +.Sh SYNOPSIS +.Nm +.Oo Ar user@ Oc Ns Ar host +.Oo +.Fl Fl +.Ar ssh-parameters ... +.Oc +.Nm safeshinstall +.Oo Ar user@ Oc Ns Ar host +.Nm cvs-safesh +.Oo Ar user@ Oc Ns Ar host +.Op Ar command +.Nm scpsh +.Oo Ar user@ Oc Ns Ar host +.Sh DESCRIPTION +NOTE: This text often refers to +.Va $VARIABLE +in description. +What each of the references will be replaced with when +.Nm +runs is described at the end of the manpage. +.Pp +The +.Nm +utility +automatically creates one DSA key (called an identity) for each host you +connect to, and stores this in a separate agent for each host. +It is also capable of adding keys for other hosts to this agent, so you can +use it for restricted forwarding of authentication. +Because each host uses its own +.Xr ssh-agent 1 , +the hosts you forward authentication to can only get at the authentication for +the hosts you specifically say it should be able to get at. +.Pp +When run, +.Nm : +.Bl -enum +.It +Normalizes the hostname you are talking about, using the +.Pa $HOME/.safesh/map +file. +.It +Checks if the user and host has an SSH DSA key in +.Pa $HOME/.safesh , +and creates one using +.Xr ssh-keygen 1 +if it does not. +The DSA key is stored in +.Pa $HOME/.safesh/$USER@$HOST-$PORT/dsa_id . +You will be asked for a passphrase when the key is created. +Note that if you use the same passphrase for all +.Nm +keys, you will only be asked for the passphrase once per host you connect to. +If you use different passphrases, you will be asked once per forwarded key +for each host you connect to (after a machine startup). +.It +Checks if you have the +.Xr ssh-agent 1 +for this host running, and starts it if not. +.It +Checks what keys you are supposed to have active when connecting to this host +(the key for the host and any keys listed in +.Pa $HOME/.safesh/$USER@$HOST-$PORT/extra_keys ) , +and which of these are missing from the active agent. +.It +If any identities were missing from the agent, it executes +.Xr ssh-add 1 +to add them to the agent. +.It +Executes +.Xr ssh 1 +with either +.Ar $USER@$HOST +or the extra command line supplied by the user. +.El +.Sh BASIC CONCEPT DESCRIPTION +The +.Nm +utility +is an authentication manager for OpenSSH. +It is an attempt at making it easy to use the built-in authentication features +of OpenSSH securely. +By default, the SSH security model is that all hosts the +user connects to are trusted, and are given complete access, including the +ability to authenticate as the user towards other hosts if the user is running +.Xr ssh-agent 1 . +OpenSSH has improved this security model somewhat by not forwarding SSH +authentication by default, but still allows the host that you connect to +to grab your credentials and authenticate as you to anybody else when you +do authentication forwarding to it. +.Sh SIMPLE HOWTO +Starting to make use of +.Nm +is trivial: +.Bl -enum +.It +Do +.Dq Li "safeshinstall <[user@]hostname>" . +.Pp +This will ask for a passphrase (three times), create a directory +.Pa $HOME/.safesh/<user>@<hostname>-22 , +which contains authentication +data for your user at +.Aq Ar hostname , +and add the contents of +.Pa $HOME/.safesh/<user>@<hostname>-22/id_dsa.pub +to +.Pa $HOME/.ssh/authorized_keys2 +on the host you connect to. +The latter will result in +.Xr ssh 1 +asking for authentication in the fashion you already use (most likely by +asking for your password). +.It +Log in with +.Dq Li "safesh <hostname>" +from now on. +.Pp +This will ask you for a passphrase if you have not logged into that host this +session, and otherwise just let right in. +.El +.Sh UTILITY COMMANDS +The +.Nm +utility +ships with two utility hacks to work around the fact that it is not a complete +.Xr ssh 1 +replacement, +.Nm scpsh +and +.Nm cvs-safesh . +.Pp +The +.Nm scpsh +utility +is for supporting use of +.Xr scp 1 +with +.Nm . +The +.Nm scpsh +.Oo Ar user@ Oc Ns Ar host +command +will start a new interactive shell (using the +.Ev SHELL +environment variable to determine which it should be), with the environment +variables for using +.Xr ssh-agent 1 +to authenticate to +.Oo Ar user@ Oc Ns Ar host +already set. +This allows use of +.Xr scp 1 +without having to type passwords to authenticate. +.Pp +The +.Nm cvs-safesh +utility +makes it easy to use +.Nm +along with +.Xr cvs 1 +and other programs that use +.Xr rsh 1 +or +.Xr ssh 1 +with the format +.Dq Li "ssh <user@host> <command>" +or +.Dq Li "ssh <host> <command>" . +To use with +.Xr cvs 1 , +just set +.Ev CVS_RSH +to +.Dq Li cvs-safesh +instead of +.Dq Li ssh . +.Sh FILES +.Bl -tag -width ".Pa $HOME/.safesh" +.It Pa $HOME/.safesh/ +Directory containing information for +.Nm . +.It Pa $HOME/.safesh/map +Mapping file for +.Nm , +describing how to map host names to their canonical form. +This is usually used to map short names to their long form. +The format of the file is one mapping per line, what it is mapped from as the +first word, what it is mapped to as the second. +.Pp +It is also possible to use this to map domain names to their safe form by having +the name of the host as the first parameter, and the name of the host with a +period +.Pq Ql .\& +at the end as the second parameter, +e.g., +.Dq Li freefall.freebsd.org freefall.freebsd.org. . +.It Pa $HOME/.safesh/$USER@$HOST-$PORT/ +Directory with data for a particular hostname. +Automatically generated on first connect to a host with +.Nm . +.It Pa $HOME/.safesh/$USER@$HOST-$PORT/dsa_id +Private key for use to authenticate as +.Ar $USER@$HOST . +Automatically generated on first connect to a host with +.Nm . +.It Pa $HOME/.safesh/$USER@$HOST-$PORT/dsa_id.pub +Public key for use by +.Ar $HOST +to authenticate +.Ar $USER . +To connect to +.Ar $HOST +as +.Ar $USER +using +.Nm +without giving a password, add the contents of this file +to the end of +.Pa $HOME/.ssh/authorized_keys2 . +Automatically generated on first connect to a host with +.Nm . +.It Pa $HOME/.safesh/$USER@$HOST-$PORT/$AUTHTARGET +Private key for use when +.Ar $HOST +authenticates towards +.Ar $AUTHTARGET . +This is used in preference to +.Pa $HOME/.safesh/$AUTHTARGET/dsa_id +for authentication forwarding through +.Ar $HOST +to +.Ar $AUTHTARGET . +The file is only used if +.Ar $AUTHTARGET +is listed in +.Pa $HOME/.safesh/$USER@$HOST-$PORT/extra_keys . +This file is not generated automatically by +.Nm . +It is only present if you have generated it using +.Xr ssh-keygen 1 . +Note that it is usually more than useless (can pose a security risk) to copy a +key used for other authentication to this location. +.Pp +The use of explict authentication files for authentication forwarding is +primarily for protection against the case where the machine you run +.Nm +on is compromised. +Using this file, you can use a separate passphrase from the one used for the +key for connecting directly to +.Ar $AUTHTARGET ; +that key need not even exist. +By using IP restrictions in the +.Pa authorized_keys +file for the key, you can make +sure that the host +.Nm +runs on cannot connect to +.Ar $AUTHTARGET +using the authentication forwarding +key. +The use of a separate forwarding key can also be used in combination with a +modified SSH to log which key was used where, and thus track key propagation. +.It Pa $HOME/.safesh/$USER@$HOST-$PORT/$AUTHTARGET.pub +Public key corresponding to the private key described above. +.It Pa $HOME/.safesh/$USER@$HOST-$PORT/extra_keys +List of extra keys to make available for this host. +Each line in the file is first attempted matched against the host/user/port +database in +.Pa $HOME/.safesh/ . +Username and/or port is added if just the hostname is specified +.Pa extra_keys , +and the hostname is always normalized using the map file. +If a key exists in +.Pa $HOME/.safesh/ , +.Nm +attempts to add that. +Otherwise, it first tries to look for the line as a file relative to +.Pa / , +then relative to +.Pa $HOME . +If it does not find either of these, +.Nm +will exit with an error message. +If it finds one, it will add it using +.Xr ssh-add 1 . +.It Pa $HOME/.safesh/$USER@$HOST-$PORT/activeagent-$YOURHOST.sh +Bourne shell (see +.Xr sh 1 , +.Xr bash 1 , +.Xr zsh 1 ) +script for setting up the environment variables for a particular +.Xr ssh-agent 1 +process used for this host. +Only valid if +.Nm +has been run against that host as this user since the machine +.Nm +runs on was last booted. +Note that this file must be source'd, not just run as a shell script. +.It Pa $HOME/.safesh/$USER@$HOST-$PORT/activeagent-$YOURHOST.csh +CSH (see +.Xr csh 1 , +.Xr tcsh 1 ) +script for setting up the environment variables for a particular +.Xr ssh-agent 1 +process used for this host. +Only valid if +.Nm +has been run against that host as this user since the machine +.Nm +runs on was last booted. +Note that this file must be source'd, not just run as a shell script. +.El +.Sh AUTHORS +The +.Nm +utility +was written by +.An Eivind Eklund Aq eivind@FreeBSD.org . +.Sh SEE ALSO +.Xr ssh 1 , +.Xr ssh-add 1 , +.Xr ssh-agent 1 , +.Xr ssh-keygen 1 +.Sh KNOWN ISSUES +The +.Nm +utility +does not handle whitespace in filenames specified in +.Pa extra_keys +correctly. +.Pp +The +.Xr ssh-agent 1 +processes that are started by +.Nm +will hang around until next reboot unless +you put the +.Dq Li "killall ssh-agent" +command in +.Pa .logout +or similar. +This allows any login to your account to use your authentication towards +machines you have connected to (including anybody with root on the box), +persisting after you log out. +You must always assume that root can grab your authentication at the moment +you run do it, so this is only an issue in that the authentication stays +available longer. +This is not resolvable without rewriting +.Xr ssh-agent 1 . +.Sh MISSING FEATURES +.Bl -tag -width 4n +.It Em Two-step secure SSH with an untrusted host in the middle +It is possible to use the port forwarding capability of +.Xr ssh 1 +to forward +authentication through another server, without allowing the other server to +indepently authenticate to a third party, and without allowing it to see +what is going on in your connection. +This is based on just forwarding a tunnel through the untrusted host, and +doing direct authentication to the server on the other side. +With the present version of OpenSSH, this has the problem of leaving the +actual port forwarding open while the tunnel is open, allowing other users to +set up their own tunnels, and weakening another side of the security model. +.It Em Read out fingerprints +The +.Nm +utility +should make it trivial to retrieve the fingerprint for: +.Bl -enum +.It +The host it is running on. +.Pp +This must presently be done with +.Dq Li "ssh-keygen -l /etc/ssh/ssh_host_key.pub" +(to get the fingerprint for SSH 1) and +.Dq Li "ssh-keygen -l -f /etc/ssh/ssh_host_dsa_key" +(for SSH 2). +.It +Other hosts, as registered in the +.Pa known_host +file on the host it is running +on. +.Pp +This must presently be done by manual inspection. +.El +.It Em Merge Pa known_hosts +The +.Nm +utility +should make it trivial to merge +.Pa known_hosts +and +.Pa known_hosts2 +with ones from +another host, including retrieving and uploading +.Pa known_hosts +as appropriate. +.It Em Manage Pa .ssh/authorized_keys2 +The +.Nm +utility +should be able to automatically remove keys from the +.Pa authorized_keys2 +file +on other machines, to make everything about the +.Nm +process self-contained. +.It Em Manage setup of key limitations +When managing +.Pa authorized_keys2 , +it is also reasonable to manage key limitation +in this. +IP restrictions +.Pq Qq Li from= +should be handled to make it easy to create setups +where the local machine does not have direct access to a target. +Command restrictions etc. would be good to have just for completeness. +.It Em Emulate the entire Xr ssh 1 Em syntax +Presently, the +.Nm +utility has a fairly weird syntax. +This is because it is a fairly quick hack, just made to be usable. +Later, it would be nice to rewrite it to be fully compatible with +.Xr ssh 1 . +This would allow use as a drop-in replacement. +.It Em Description of the trust/threat/security model +It would be nice to have a complete description of the normal SSH threat model +as well as the +.Nm +threat model, in order to make people fully conscious of their own model. +.It Em Emulate Xr scp 1 +The +.Xr scp 1 +utility +is very useful, and the only way to use it with +.Nm +at the moment is through a subshell created by +.Nm scpsh . +An ideal +.Nm +implementation would include wrapping of +.Xr scp 1 , +too. +.El +.Sh VARIABLE REPLACEMENT IN DESCRIPTIONS +.Bl -tag -width ".Va $AUTHTARGET" +.It Va $HOME +Path to your home directory. +.It Va $HOST +The name of the host you are running +.Nm +towards. +This is the machine you are +.Xr ssh 1 Ns 'ing +into. +.It Va $YOURHOST +The name of the host you are running +.Nm +on, as output by +.Xr hostname 1 . +This is the name of the machine you are +.Xr ssh 1 Ns 'ing +from. +The use of +.Va $YOURHOST +makes +.Nm +safe to use with NFS-mounted home directories. +.It Va $AUTHTARGET +The authentication target for an authentication forwarding. +This is +.Em not +the same as +.Va $HOST . +.Va $AUTHTARGET +is a machine you are +.Xr ssh 1 Ns 'ing +to +.Em from +.Va $HOST . +The format of +.Va $AUTHTARGET +is +.Sm off +.Ao Ar user Ac @ Ao Ar somehost Ac - Aq Ar someport , +.Sm on +where +.Aq Aq user +defaults to the username you run +.Nm +as, and +.Aq Aq someport +default to 22 (and it is not possible to set anything +else at this time). +.It Va $USER +The username used on +.Va $HOST ; +defaults to the same as the +username you have on +.Va $YOURHOST , +but will be different if you do +.Dq Li "safesh user@host" +instead of just +.Dq Li "safesh host" . +.It Va $PORT +The port used on +.Va $HOST . +Presently always 22. +.El diff --git a/security/safesh/files/safesh.sh b/security/safesh/files/safesh.sh new file mode 100644 index 000000000000..3ea1c18d85e6 --- /dev/null +++ b/security/safesh/files/safesh.sh @@ -0,0 +1,140 @@ +#!/bin/sh + +AKEYS=${HOME}/.safesh +# Use username as supplied on the command line if user@host syntax is used, +# otherwise use the presently active username +USER=`whoami` +USER=`echo $1 | sed -e "/^[^@]*\$/s/.*/$USER/" -e "/@/s/\\(.*\\)@.*/\\1/"` +# Use hostname as supplied on commandline, without username +HOST=`echo $1 | sed -e 's/.*@//' | tr A-Z a-z` + +# MY eXit +myx() { + echo $1 1>&2 + exit 1 +} + +# Normalize host name if necessary +normalizehost() { + cat ${AKEYS}/map 2> /dev/null | awk "(\$1 == \"$1\" && !gotit) {gotit = 1; print tolower(\$2)} END {if(!gotit) {print tolower(\"$1\")}}" +} + +HOST=`normalizehost $HOST` + +# +# Check that the user are using the right parameters +# +# XXX This should check for --, but it is unclear how to do that. +# +if ! shift; then + myx "Usage: $0 <hostname> [-- <ssh parameters>]" +fi + +# +# Lose the -- from the parameters - it is there for future extensibility +# using getopt() +# +shift 2> /dev/null; + +HOSTDIR=$AKEYS/$USER@${HOST}-22 +if [ ! -d $HOSTDIR ]; then + while ! [ "$answer" = "yes" -o "$answer" = "no" ]; do + echo -n "New user/host pair $USER@$HOST - create key (yes/no)? " 1>&2 + read answer + done + if [ "$answer" = "no" ]; then + exit 1 + fi + mkdir -p $HOSTDIR || myx "$0: Unable to create $HOSTDIR" +fi + +if [ ! -e $HOSTDIR/id_dsa ]; then + if [ "$DISPLAY" != "" ] && (which ssh-askpass > /dev/null 2>&1); then + (ssh-keygen -t dsa -f $HOSTDIR/id_dsa >/dev/null < /dev/null 2>&1) || myx "$0: Unable to create $HOSTDIR/id_dsa" + else + ssh-keygen -t dsa -f $HOSTDIR/id_dsa || myx "Unable to create $HOSTDIR/id_dsa" + fi +fi + +# We now have a key in $HOSTDIR/id_dsa + +ACTIVEAGENT=$HOSTDIR/activeagent-`hostname` +if [ -e $ACTIVEAGENT.sh ]; then + . $ACTIVEAGENT.sh || myx "$0: Unable to read $ACTIVEAGENT.sh" +fi + +if ! ssh-add -l > /dev/null 2>& 1; then + ssh-agent -s > $ACTIVEAGENT.tmp || myx "Unable to start ssh-agent" + sed '/^echo/d' < $ACTIVEAGENT.tmp > $ACTIVEAGENT.sh + rm -f $ACTIVEAGENT.tmp + . $ACTIVEAGENT.sh || myx "$0: Unable to read $ACTIVEAGENT.sh after creating it" + (echo setenv SSH_AUTH_SOCK $SSH_AUTH_SOCK\; + echo setenv SSH_AGENT_PID $SSH_AGENT_PID\;) > $ACTIVEAGENT.csh + #echo "Started agent with PID $SSH_AGENT_PID, socket $SSH_AUTH_SOCK" 1>&2 +fi + +# We now have a live agent, possibly without any keys in it + + +for i in $USER@${HOST}-22 `cat $HOSTDIR/extra_keys 2> /dev/null`; do + tmpuser=`echo $i | sed -e "/^[^@]*\$/s/.*/$USER/" -e "/@/s/\\(.*\\)@.*/\\1/"` + tmpport=`echo $i | sed -e '/-\([0-9][0-9]*\)/!s/$/-22/' -e 's/.*-\([0-9][0-9]*\)/\1/'` + tmphost=`echo $i | sed -e 's/.*@\(.*\)/\1/' -e 's/-[0-9][0-9]*$//' | tr A-Z a-z` + tmp=$USER@`normalizehost $tmphost`-$tmpport + if [ -f $HOSTDIR/$tmp ]; then + IDENTITY=$HOSTDIR/$tmp + elif [ -d $AKEYS/$tmp/ ]; then + if ! [ -f $AKEYS/$tmp/id_dsa ]; then + myx "Missing key $AKEYS/$tmp/id_dsa" + elif ! [ -r $AKEYS/$tmp/id_dsa ]; then + myx "$AKEYS/$tmp/id_dsa is not readable" + fi + IDENTITY=$AKEYS/$tmp/id_dsa + elif [ -f "/$i" ]; then + IDENTITY="/$i" + elif [ -f "$HOME/$i" ]; then + IDENTITY="$HOME/$i" + else + myx "Unable to find key for \"$i\"" + fi + # Only add it to the list if it isn't already in the agent. This is a + # workaround for a bug in ssh-add, which asks for the password FIRST, + # and checks for the existence of the the key in the agent AFTERWARDS + if [ "`(ssh-add -l && ssh-keygen -l -f "$IDENTITY") | awk '{print $1, $2}' | sort | uniq -d)`" = "" ]; then + KEYLIST="$KEYLIST $IDENTITY" + fi +done + +if [ "${KEYLIST}" != "" ]; then + if [ "$DISPLAY" != "" ] && (which ssh-askpass > /dev/null 2>&1); then + ssh-add $KEYLIST < /dev/null > /dev/null 2>&1 + else + ssh-add $KEYLIST + fi +fi + +BASENAME=`basename $0` +if [ "$BASENAME" = "scpsh" ]; then + # Print information if we are running entirely interactive (or + # somebody is attempting to make us believe we are) + if [ -t 0 -a -t 1 -a -t 2 ]; then + echo ">>>" 1>&2 + echo ">>> Starting up shell with authentication variables." 1>&2 + echo ">>> You can now scp to $USER@$HOST without passwords." 1>&2 + if [ "$TGT" = "" ]; then + echo ">>> $USER@$HOST is available through the shorthand \$TGT" 1>&2 + fi + echo ">>>" 1>&2 + fi + if [ "$TGT" = "" ]; then + TGT=$USER@$HOST + export TGT + fi + exec $SHELL +elif [ "$BASENAME" = "safeshinstall" ]; then + cat $HOSTDIR/id_dsa.pub | ssh $USER@$HOST 'mkdir -p .ssh && cat >> .ssh/authorized_keys2' +elif [ "$1" = "" ]; then + exec ssh -A $USER@$HOST +else + exec ssh "$@" +fi |