Linux – Run Privileged Command on Successful SSH Login

linuxopensshrootsshd

I'd like to run a privileged command upon successful SSH logins at the server's end. However, this has to be in the server configuration (sshd_config or anything else that cannot be manipulated or circumvented by the user) as I need this to be mandatory. That is, however restricted the system account used is, it needs to be able to manipulate a piece of data that requires superuser privileges (namely use ipset add conditionally – which I can script). Oh and I'd like to be able to access the contents of SSH_CLIENT, please – despite privileged execution. The command also must be unaffected by ChrootDirectory.

I am aware of /etc/ssh/sshrc, but that appears to be "client-side", i.e. it's being run by the user who is logging into the machine.

Does such a facility exist in OpenSSH? I am using version 6.6.


Also, the man page (ssh(1)) isn't all too clear about sshrc:

/etc/ssh/sshrc
Commands in this file are executed by ssh when the user logs in, just before the user's
shell (or command) is started. See the sshd(8) manual page for more information.

So does this mean it also runs whenever external commands (via ForceCommand) or subsystems like internal-sftp get invoked, despite restricting settings like PTY allocation or forcing a chroot? If so, I could resort to a restrictive /etc/sudoers entry if there is no other way at all.

NB: I am not using inetd for obvious reasons (see sshd(8)) as described here.

Best Answer

You can do this using PAM and the pam_exec.so module.

You simply add a line to /etc/pam.d/sshd to the 'session' section such as the following:

session    optional    pam_exec.so /usr/local/bin/ipset-ssh

Where ipset-ssh is some script you create.

The script will be run as root. You can get the client's IP address with the PAM_RHOST variable. You'll also want to check the PAM_TYPE variable as your script will be executed both on login, and logout. On login PAM_TYPE will be set to open_session. On logout it's set to close_session.

Here is the complete list of variables that I get from a simple test (I put env > /tmp/pamenv in script):

PAM_SERVICE=sshd
PAM_RHOST=127.0.0.1
GNOME_KEYRING_CONTROL=/home/phemmer/.cache/keyring-vJUUda
PAM_USER=phemmer
PWD=/
GNOME_KEYRING_PID=19742
SHLVL=1
PAM_TYPE=open_session
PAM_TTY=ssh
_=/usr/bin/env

 

Your script could be as simple as:

#!/bin/bash
[[ "$PAM_TYPE" == "open_session" ]] && ipset add whitelist $PAM_RHOST
Related Question