Take the 2-minute tour ×
Server Fault is a question and answer site for professional system and network administrators. It's 100% free, no registration required.

i am setting up an ssh notification system for my servers. the aim to for sshd to send me an email every time i log in to one of my servers with the hope of catching intruders. i'm using ubuntu 10.04 and 11.04.

in /etc/ssh/sshd_config i added the following line:

ForceCommand /usr/local/scripts/ssh_notifications.php

and the contents of this file are: (note i have replaced anything private here with xxx - these are not the actual values shown in my shell)

#!/usr/bin/php
<?php

$remote_host_ip = trim(shell_exec('echo $SSH_CONNECTION'));
$remote_host = strlen($remote_host_ip) ? "ip $remote_host_ip" : "unknown ip address";
$localhost = php_uname('n');
$now = str_replace('T', ' ', date('c'));

$to = 'xxx@xxxxxx.com';
$subject = "$localhost accessed via ssh";
$body = "date: $now, by: $remote_host";

//die("subject: [$subject], body: [$body]"); //debug use only
mail($to, $subject, $body);
exit(0);

?>

(i chose php just because i'm more proficient in it than raw shell scripting)

then i issue sudo /etc/init.d/ssh restart to restart my sshd and try accessing the server remotely. when i do so, the email correctly gets sent to my inbox, but i get the following error and i cannot access my server:

Connection to xxx closed.

however if i comment out the forcecommand line in sshd_config then i can login again fine. obviously i want to be able to log in as well as sending myself an email.

oh, also:

$ tail -5 /var/log/auth.log
Aug 22 12:33:32 xxxx sudo:    xxxx : TTY=pts/0 ; PWD=/usr/local/scripts ; USER=root ; COMMAND=/usr/bin/vi /etc/ssh/sshd_config
Aug 22 12:33:38 xxxx sshd[6863]: Accepted publickey for xxxx from 192.168.0.2 port 39446 ssh2
Aug 22 12:33:38 xxxx sshd[6863]: pam_unix(sshd:session): session opened for user xxxx by (uid=0)
Aug 22 12:33:38 xxxx sshd[6941]: Received disconnect from 192.168.0.2: 11: disconnected by user
Aug 22 12:33:38 xxxx sshd[6863]: pam_unix(sshd:session): session closed for user xxxx

this makes me think that forcecommand is overriding something crucial in sshd. i thought it might be pam, but i turned off pam with the line

UsePAM no

in /etc/ssh/sshd_config and still received the same "connection closed" message at the client.

has anyone had this problem before and can anyone suggest a solution?

alternate solution

i'm not sure why the ssh forcecommand didn't work, but i manage to achieve what i wanted (email notifications upon ssh access) with pam_exec like so:

$ grep -B 2 -A 1 php /etc/pam.d/sshd 

# run ssh notification script upon successful login
session    optional     pam_exec.so /usr/local/scripts/ssh_notifications.php

$ sudo /etc/init.d/ssh restart
share|improve this question
    
Holy smokes, those emails are going to drive you batty after a while. –  pjmorse Sep 18 '12 at 23:41
    
@pjmorse haha yeah. its a tradeoff between security and time for sure. –  mulllhausen Sep 20 '12 at 0:05
add comment

1 Answer

up vote 4 down vote accepted

It's doing exactly what you told it to do. Instead of running the command which the user requested (which is probably a shell), sshd is forcing a command to be run, namely your script. Your script does some stuff (sends an email), and then exits. Since the command which was executed by the SSH session is now finished, the connection is closed.

If you wanted to still execute the command requested by the user, it is your script's responsibility to make this happen. The original command is passed to the script in the SSH_ORIGINAL_COMMAND environment variable, so your script would have to explicitly execute this command after sending the email.

Your PAM solution for this specific use case is much nicer though.

share|improve this answer
    
ah right. i'm not explicitly sending a command via ssh though. ie to access the ssh server i just type ssh remoteuser@remotehost in the client, not ssh remoteuser@remotehost some_remote_command. i did see the SSH_ORIGINAL_COMMAND mentioned in sshd_config(5) but i figured that only applied to the some_remote_command part of the client call. i guess i was wrong. –  mulllhausen Aug 22 '12 at 6:32
    
@mulllhausen Then the command is implicitly set to the user's shell (e.g. /bin/bash). –  mgorven Aug 22 '12 at 6:36
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.