У меня есть приложение, использующее ssh для аутентификации. Из-за множества правил (HIPAA и т. Д.) Пользователи могут входить в систему только на определенное время, и они могут входить в систему только один раз.
Я хочу, чтобы sshd автоматически отключал пользователя при попытке другого, второго подключения. Идея такая: подключен пользователь 1. пользователь 2 использует учетные данные пользователя 1, чтобы попытаться войти в систему. Оба они исключены (мы не уверены, является ли пользователь 1 или пользователь 2 законным).
Если это происходит более X раз за Y минут, учетная запись блокируется до тех пор, пока администратор не разморозит ее (скорее всего, из-за сброса пароля).
Прямо сейчас пользователи изолированы от собственных scponly каталоги; Я не уверен, что это имеет значение.
Пытаться уничтожить отдельные sshd-соединения - это как играть в whackamole, и я бы предпочел, чтобы это было что-то, что sshd делает сам, а не скрипт корневого уровня.
РЕДАКТИРОВАТЬ: Это на
2.6.31-22-server #73-Ubuntu SMP
И мой файл limits.conf содержит такие строки, как:
user1 hard maxlogins 1
user2 hard maxlogins 1
и мой файл sshd_config содержит строку:
UsePAM yes
Тем не менее, я все еще могу войти в систему как user1 с нескольких разных машин. Что я здесь делаю не так, чтобы хотя бы заблокировать пользователю user1 несколько входов в систему?
Здесь действительно работает установка лимита maxlogins. Просто убедитесь, что вы используете тип ограничения «-», а не «жесткий».
user1 - maxlogins 1
Если вы хотите выгнать пользователей, которые выполнили двойной вход с помощью scponly, вот быстрый и грязный сценарий, который это делает. Поместите его в crontab, чтобы он запускался каждую минуту.
#!/bin/sh
for user in `grep scponly /etc/passwd | gawk -F: '{print $1}'`; do
echo "Checking user: $user"
instances=`ps -u $user| grep scponly | wc -l`
echo "scponly instances $instances"
if [ $instances -gt 1 ] ; then
echo "Too many connections detected, slaying scponly for user $user"
if [ -e /tmp/$user ] ; then
attempts=`cat /tmp/$user`
echo "Detected $attempts attempts"
# increment attempts counter
echo $(($attempts+1)) > /tmp/$user
if [ $attempts -gt 3 ] ; then
echo "Blocking $user"
/usr/sbin/usermod -L $user
fi
else
echo "1" > /tmp/$user
fi
killall -u $user scponly
fi
done
Скачать скрипт: http://dl.dropbox.com/u/17194482/kill-scponly.sh
Ограничения PAM не будут перехватывать соединения scp или sftp, потому что им не выделен pty или не записан в utmp.
Вы можете посмотреть /etc/security/limits.conf, чтобы узнать о таких ограничениях. http://linux.die.net/man/5/limits.conf
Существует ограничение «maxlogins», которое можно настроить для каждого пользователя или группы пользователей. Это не отключит предыдущие сеансы, но ограничит одновременные сеансы.
Поскольку вы используете специальную оболочку без возможности удаленного выполнения, вы не можете немного взломать их оболочку входа в систему. Было бы довольно легко просто в оболочке выяснить, вошли ли они уже в систему, а если нет, выйти из системы.
Раньше мы простаивали, что и делало именно это. (http://idled.sourceforge.net/ или http://www.ibiblio.org/pub/Linux/system/admin/idle/!INDEX.html), Не похоже, что сейчас все в таком хорошем состоянии, поскольку PAM ожил.
PAM дает вам миллионы способов делать то, что вы хотите, см. Список модулей PAM здесь: http://www.kernel.org/pub/linux/libs/pam/modules.html
Любой из них, вероятно, не делает всего того, что вы хотите, но вместе вы можете делать все, что хотите, или даже написать свой собственный модуль. Как сказал @DerfK, вам нужно настроить SSH для использования PAM.
Если это связано с бухгалтерскими причинами, упомянутыми в комментариях, вы можете посмотреть на Утилиты бухгалтерского учета GNU. Это позволит вам делать все до и в том числе видеть, какие пользователи запускали какой процесс, как долго и сколько ЦП и ОЗУ им потребовалось. Это требует поддержки ядра, но в большинстве современных дистрибутивов она уже скомпилирована.
Я не уверен, что использование cron каждую минуту - лучший подход. Я попробовал этот обходной путь, и он мне подходит. Надеюсь, побочных эффектов нет.
Match User foo
ForceCommand /usr/sbin/sftp-limit
С помощью следующего сценария, перенаправляющего stdin / stdout в процесс sftp-server, только если количество процессов для данного пользователя не превышает переменную "SFTP_LIMIT_PER_USER".
#!/bin/bash
SFTP_LIMIT_PER_USER=1
out="$(ps aux | grep -c "${USER} .*sftp-server")"
if [ $out -gt $SFTP_LIMIT_PER_USER ]; then
logger "sftp-limit: limit reached for user $USER"
exit 0
fi
/usr/libexec/openssh/sftp-server <&0 >&1
HTH.