Record ssh REMOTE_USER in audit or history logs

Posted on

Record ssh REMOTE_USER in audit or history logs – A server stack is the collection of software that forms the operational infrastructure on a given machine. In a computing context, a stack is an ordered pile. A server stack is one type of solution stack — an ordered selection of software that makes it possible to complete a particular task. Like in this post about Record ssh REMOTE_USER in audit or history logs was one problem in server stack that need for a solution. Below are some tips in manage your linux server when you find problem about linux, bash, auditd, , .

In our company we usually have a single production user user and we ssh to our servers via pasword-less login with ssh keys.

Now, quite a few people work on those servers and sometimes we need to understand why changes were made and who made them. For that we would like to audit bash commands but we also need to preserve the original remote user id. This explains how to define ${REMOTE_USER} variable but how can we store it in history/audit logs for each command?

Ideally, it’s best to provision everyone with their own ssh keypair, their own login account and use sudo to track who’s doing what, and where. If you don’t have centralized authentication and more than a couple servers, maintaining all those login accounts can be a mess (note: see ansible for an easier way without LDAP) not to mention maintaining password changes.

What I’ve done in the past, is require the remote user to export a variable on their system named LC_SSH_USER. This variable can be accepted by the sshd config via the AcceptEnv LANG LC_* setting. A script in /etc/profile.d runs on login and “sanitizes” the variable and/or terminates the connection if the variable is not found. Additionally, the readonly attribute is set on the variable so inadvertent changes to the variable cannot easily be made. This way, no matter what account the remote user had logged into (www-data, passenger, admin) the originating user is logged. The system can be circumvented easily enough by the user setting their variable to whatever they want however an HR policy can be put in place to deal with it.

sample script to place in /etc/profile.d/lc-ssh-user.sh which will log LC_SSH_USER to /var/log/auth.log (on Ubuntu) :

# only allow letters, numbers and underscores in passed LC_SSH_USER variable
lc_ssh_user_sanitize()
{
   arg="{$1}"
   # first, strip underscores
   clean="${arg//_/}"

   # next, replace spaces with underscores
   clean="${clean// /_}"

   # now, clean out anything that's not alphanumeric or an underscore
   ret="${clean//[^a-zA-Z0-9_]/}"

   echo "${ret}"
}

# if SSH_CLIENT is not set, and LC_SSH_USER is not set, then this is a local login or a new shell opened by same user
if [ -z "${SSH_CLIENT}" ] && [ -z "${LC_SSH_USER}" ]; then
   export LC_SSH_USER=${USER}
else
   # otherwise, this is an ssh session - extract the connecting IP from env
   con=`echo "${SSH_CLIENT}" | cut -d'=' -f2 | cut -d' ' -f1`

   # export some variables needed for the user environment
   # when using "su --preserve-environment  userxxx --login" be sure to fixup needed variables
   export USER=`whoami`
   export LOGNAME=${USER}
   export HOME=$( getent passwd "$USER" | cut -d: -f6 )
   cd ${HOME}

   # user login without LC_SSH_USER set on their local machine
   if [ -z "${LC_SSH_USER}" ]; then
      echo "Error: LC_SSH_USER not set in connection from ${con} as user $USER" | logger -p auth.info
      #
      # connection could probably be terminated here to enforce the use of LC_SSH_USER
      #

      # since there is no LC_SSH_USER in the connection, just use whatever the user logged in as
      export LC_SSH_USER=${USER}
      echo "Notice: LC_SSH_USER set from login ${USER} from ${con}" | logger -p auth.info
   else
      # user has LC_SSH_USER set, so sanitize it (just in case) and log the sanitized version to syslog via logger
      u_sanitized=$(lc_ssh_user_sanitize "${LC_SSH_USER}")
      echo "Notice: LC_SSH_USER ${u_sanitized} login from ${con} as user $USER" | logger -p auth.info
   fi
fi

# always make LC_SSH_USER  readonly in the users environment
readonly LC_SSH_USER

Update: git commit hook to use $LC_SSH_USER:

#!/bin/sh
# To enable this hook drop this in ".git/hooks/pre-commit" (chmod 0755)
# It will create .commit_template if it does not exist
# add these lines to .git/config:
# [commit]
#   template = .commit_template
#
test -f .commit_template && exit 
echo "
Fix   : 
Issue : 
Author: $LC_SSH_USER
" > .commit_template

Leave a Reply

Your email address will not be published.