Как стать автором
Обновить

Комментарии 58

Как это защитит от ssh user@server /bin/bash -l?
Опередили. Правда, я хотел предложить ssh user@host /bin/sh
Проверил. Логируется.
Это потому что

# ls -l /bin/sh
lrwxrwxrwx 1 root root 4 Mar 7 08:33 /bin/sh -> bash

В центоси есть к примеру /bin/dash, ну и всякие tcsh и прочие обычно в комплекте у некоторых
У меня на тестовой машине Debian Squeeze:

root@server:~# ls -l /bin/sh
lrwxrwxrwx 1 root root 4 Jan 10  2013 /bin/sh -> dash
Вот не поверю, что ssh user@host «ls -l» тоже залогируется :)
Не логируется! Идей пока нет как решить, но чую, что если будут, то это будут большие костыли…
Есть идеи?
Как вариант есть возможность в ~/.ssh/authorized_keys сделать:
command="/bin/bash". Вижу сразу 2 нюанса:
1) Необходимо добавлять этот файл каждому пользователю
2) Авторизацию придётся запрещать по логину — только по ключу.
На уровне «положить файлик бла-бла-бла» — нет. Если серьёзно — смотреть в сторону:

а) сниффинга всего трафика, проходящего через псевдотерминалы
(более серьёзно)
б) систем аудита (SELinux/Apparmor/etc), которые будут записывать реально всё выполняемое.

Нужно понимать, что все эти screen, bash, history, etc — всего лишь условности интерфейсы, и никто не может принудить (то есть может — но это и есть SEL/AA) к их использованию.

Если пользователь может что-то запускать, значит у него тьюринг-полная система, значит, он может делать всякие странные вещи не оставляя следов. Если только сверху нет подобия *визора, фиксирующего всё на уровне ядра.

Вся описанная конструкция всего лишь паллиатив а-ля «запретить программу в window 9x». Решений много и все они обходятся из спортивного интереса.
Легко логируется враппером для sshd

ForceCommand /etc/ssh/rsh-hook.sh

а в хуке чтото вроде

if [[ ! -z ${SSH_ORIGINAL_COMMAND} ]]; then
        . /etc/bash.bashrc
        logger -p local6.debug -t "rem ${USER}" "${USER}: ${SSH_ORIGINAL_COMMAND}"
        ${SSH_ORIGINAL_COMMAND}
else
    cat /etc/motd
        ${SHELL}
fi


Спасибо за информацию.
Скрипт чуть модифицирован (не работали команды типа ssh user@server «ls -al /; sleep 5; echo Works», а также изменён метод записи в лог-файл — теперь это простое echo >>) и внесён в статью.
А может быть у вас и рецепт для логирования scp есть ?)
Если я правильно понимаю после аутентификации пользователь просто набирает /bin/bash -l. Проверил — логируется и это.
Нет, неправильно понимаете. ssh root@localhost -t /bin/bash -l и посмотрите логи.

Алсо, можно вообще /bin/bash -i, и тогда даже хистори не запишется.
И тот, и другой вариант логируется нормально.
Полагаю потому что bash при загрузке всё равно читает /etc/bash.bashrc.
А вот если эту возможность как-нибудь обойти… Надо подумать.
Ну в лоб — написать малюсенькую библиотеку, которая перехватывает fopen и подсовывает нужные. А потом через LD_PRELOAD ее грузить…

Но думаю, это точно выходит за возможности потенциального нарушителя :)
Полагаю это всё должно делаться из под рута и пока будет делаться, всё это будет логироваться:).
Предполагается, что команду печают не на севрере. Я localhost сказал, чтобы на самой машине проверить можно будет.
Я проверил и удалённо, и локально — логируется. С другой машины ввёл:
ssh root@server -t /bin/bash -l
root@server's password: 
root@server:~# this is a test message
bash: this: command not found

Выхожу, смотрю логи:
root@server:~# cat /var/log/screen/root@server-20130716-\ 9\:32\:04.log 
root@server:~# 
root@server:~# this is a test message
bash: this: command not found
root@server:~# ogout

--norc Do not read and execute the system wide initialization file /etc/bash.bashrc and the personal initialization file ~/.bashrc if the shell is interactive. This option is on by default if the shell is invoked as
sh.


Можно вот с этим ключиком и тогда ничего читать не будет, или можно указать при подключении явно, какой файл читать:
ssh root@localhost -t /bin/bash -i --rcfile <rc.file>
При такой команде всё равно попадает в screen и лог работает.
Да, вопрос наверное запоздалый. А почему бы просто не логгировать все происходящее с помощью conspy (http://ace-host.stuart.id.au/russell/files/conspy/) или аналогичного, который тупо грабит pts/*?
Насколько мне известно auditd не логирует вывод информации на экран.
Не логирует. Но зато это штатный функционал ядра и можно настроить аудит только нужного, важных типов событий.
Везде нужен баланс, в этой задаче — тоже. Иначе можно запросто задосить лог-сервер просто сделав cat /dev/urandom и уйдя спать.
НЛО прилетело и опубликовало эту надпись здесь
Согласен. Пожалуй security ради надо жёстко указать путь.
НЛО прилетело и опубликовало эту надпись здесь
А где ещё быть утилитам screen и kill и, главное, зачем?
Для меня это имеет смысл, когда приходится одни и те же скрипты запускать на Linux и OpenWRT. У них пути разные и which очень помогает.
P.S. Кстати изменения в текст статьи внёс — путь указал точно.
which kill и просто kill ничем отличаться не будет, т.к. PATH одинаковый.
Не будет, просто исключатся возможные махинации с PATH и, соответственно, запуск собственного screen-а или kill-а.
На логи можно попробовать натравить logrotate.
На удалённом сервере. Всё верно.
curl something | sh

Олсоу, логгирует ли оно всё происходящее в консольных редакторах вроде nano?
А еще можно так:
read -s a; eval $a

Вобщем, совершенно негодный способ
Логирует всё, что выводит текст. Есть даже побочные эффекты этого — если запустить top и забыть выключить, то будет очень много логов.
screen -X log — отключает логгирование, и биндинг не нужен…
Спасибо за информацию. Отключает логирование! Думаю как заблокировать эту команду.
Решение не найдено, кроме применения административных мер к пользователю («С какой целью запускал отключение логов?»).
Кастомная сборка screen…
## Force SHELL close on exit - we don't want to allow users to escape logging outside screen
$KILL -SIGHUP $PPID

Здесь бы и просто 'exit' хватило.
Нет, не хватает. Тогда при выходе из screen (^d или просто exit) попадаем в bash без логирования. Поэтому и надо убить родительский процесс.
read answer
if [ "$answer" != "n" ]; then
    screen -D -RR screen_name
    exit
fi

(это на сервера прописываю, при заходе если не ответить «n», открывает прошлую сессию)

Работает как надо. Вопрос на linuxquestions
Спасибо за информацию. Считаю это не совсем нужным действием — отвечать нужно ли подключать, ведь для того, чтобы отключиться от screen и оставить работать процессы в фоне — надо проделать «телодвижения», соответственно зачем их проделывать, если потом отвечать «не подключать screen». А если просто выйти (^d или exit), то и screen убивается.
Про ответ — это у меня так, не помню уже зачем, скорее всего когда-то была трудность с неправильной настройкой screen, из-за чего не мог подключиться.
скроллинг назад в скрине не совпадает с «обычным» поведением.
Так же не совсем понятна изначальная постановка задачи. Иными словами — логгировать — ладно. Но зачем?
Если просто ради тайп-каста, то по-моему script более для этого приспособлен чем screen.
А если что-то типа шпиона — то наверное лучше вообще подключиться где-нибудь на уровне системы и наблюдать, что происходит во всевозможных ttyX.
Скроллинг назад под screen у меня абсолютно нормальный (Shift+PgUp), не считая возврата к предыдущему состоянию, когда минуты в caption внизу страницы меняют своё значение. А вот обычный скроллинг страниц, к примеру man bash — притормаживает. Другие претензии к screen в плане удобства, которые у меня были вначале — отсутствие «пикания» и автозавершения команд — исправлены и рецепт приведёт в статье.
Я старался не проводить в статье обзор методов аудита в Linux. Это статья для тех, кто как я, решит остановиться на этом методе из обзорной статьи про script, screen, sudo, auditd.
Вариант с подключением на уровне системы к ttyX думаю лучше, но я с ним не знаком и их не было в статье, на основании которой был выбран метод (см.выше).
Ну так закачиваем скрипт на сервер через sftp и выполняем там.
Думаю для таких вариантов нужно более серьёзные решения (auditd, к примеру), но там непросто читать лог-информацию.
К примеру на команду
“hostname audit-test.home.private”

В логе окажется:
type=SYSCALL msg=audit(1358306046.744:260): arch=c000003e syscall=170 success=yes exit=0 a0=2025010 a1=17 a2=7 a3=18 items=0 ppid=23922 pid=26742 auid=1000 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts4 ses=16 comm="hostname" exe="/usr/bin/hostname" subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key="system-locale"
aureport, ausearch
А что должен выводить кусок "%{kc}%{-b}%D" в caption always?
У меня на этом месте выводится какой-то юникодный мусор.
У меня строка выглядит вот так (ну и разноцветно):
hostname | открытые окна        | load average   | date            | time
server   | 0*$(L) bash  1 bash  | 0.00 0.00 0.00 | Wed, 07/17/2013 | 13:14

Ага. Значит день недели у меня пытается вывестись по-русски, и не может.
А кто-нибудь может прокомментировать этот способ? Он работает, но при переходе в другой шелл перестаёт. Если все остальные шеллы сделать симлинками на bash, то будет ли такой вариант надёжным?

Мне этот способ гораздо интересней чем screen, ибо в последнем довольно кривая консоль.
Возможно, есть методы обойти screen и, соответственно, логирования при этой конфигурации. Хотелось бы услышать их и внести изменения

Ещё один метод обхода, не оставляющий следов:


Ctrl-A : log


Блокировка:


.screenrc


bind :


Пользователь теряет возможность выполнять команды screen и перенастраивать его.

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории