Как ограничить пользователей SSH предопределенным набором команд после входа в систему? - PullRequest
77 голосов
/ 31 декабря 2008

Это идея для безопасности. Наши сотрудники должны иметь доступ к некоторым командам на сервере Linux, но не ко всем. Они должны, например, иметь возможность доступа к файлу журнала (less logfile) или запускать различные команды (shutdown.sh / run.sh).

Справочная информация:

Все сотрудники обращаются к серверу с одним и тем же именем пользователя: наш продукт работает с «обычными» правами пользователя, «установка» не требуется. Просто распакуйте его в каталог пользователя и запустите. Мы управляем несколькими серверами, на которых наше приложение «установлено». На каждой машине есть пользователь johndoe. Нашим сотрудникам иногда требуется доступ к приложению из командной строки для доступа и проверки файлов журнала или для перезапуска приложения вручную. Только некоторые люди должны иметь полный доступ к командной строке.

Мы используем проверку подлинности ppk на сервере.

Было бы замечательно, если employee1 может получить доступ только к лог-файлу, а employee2 также может выполнять X и т. Д. ...

Решение: В качестве решения я буду использовать опцию command, как указано в ответе принято . Я сделаю свой собственный небольшой сценарий оболочки, который будет единственным файлом, который может быть выполнен для некоторых сотрудников. Скрипт предложит несколько команд, которые могут быть выполнены, но никаких других. Я буду использовать следующие параметры в authorized_keys, как указано здесь :

command="/bin/myscript.sh",no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty
ssh-dss AAAAB3....o9M9qz4xqGCqGXoJw= user@host

Этого достаточно для нас. Спасибо, сообщество!

Ответы [ 9 ]

62 голосов
/ 31 декабря 2008

Вы также можете ограничить ключи допустимыми командами (в файле author_keys).

т.е. пользователь не будет входить через ssh, а затем будет иметь ограниченный набор команд, а будет иметь возможность выполнять эти команды только через ssh (например, «ssh somehost bin / showlogfile»)

29 голосов
/ 21 октября 2012

ssh следует традиции rsh, используя программу оболочки пользователя из файла паролей для выполнения команд.

Это означает, что мы можем решить эту проблему без использования конфигурации ssh.

Если вы не хотите, чтобы у пользователя был доступ к оболочке, просто замените оболочку этого пользователя на скрипт. Если вы посмотрите на /etc/passwd, вы увидите, что есть поле, которое назначает интерпретатор команд оболочки каждому пользователю. Скрипт используется в качестве оболочки как для интерактивного входа в систему ssh user@host, так и для команд ssh user@host command arg ....

Вот пример. Я создал пользователя foo, оболочкой которого является скрипт. Скрипт печатает сообщение my arguments are:, за которым следуют его аргументы (каждый в отдельной строке и в угловых скобках) и завершается. В журнале дела нет аргументов. Вот что происходит:

webserver:~# ssh foo@localhost
foo@localhost's password:
Linux webserver [ snip ]
[ snip ]
my arguments are:
Connection to localhost closed.

Если пользователь пытается выполнить команду, она выглядит следующим образом:

webserver:~# ssh foo@localhost cat /etc/passwd
foo@localhost's password:
my arguments are:
<-c>
<cat /etc/passwd>

Наша "оболочка" получает вызов в стиле -c со всей командой в качестве одного аргумента, точно так же, как /bin/sh получит ее.

Итак, как вы можете видеть, теперь мы можем разработать скрипт дальше, чтобы он распознавал случай, когда он был вызван с аргументом -c, а затем анализирует строку (скажем, путем сопоставления с образцом). Те строки, которые разрешены, могут быть переданы в реальную оболочку путем рекурсивного вызова /bin/bash -c <string>. Случай отклонения может напечатать сообщение об ошибке и завершиться (включая случай, когда отсутствует -c).

Вы должны быть осторожны, когда пишете это. Я рекомендую писать только положительные совпадения, которые допускают только очень конкретные вещи и запрещают все остальное.

Примечание: если вы root, вы все равно можете войти в эту учетную запись, переопределив оболочку в команде su, например, su -s /bin/bash foo. (Замена оболочки по выбору.) Некорневые пользователи не могут этого сделать.

Вот пример сценария: ограничить пользователя только использованием ssh для git доступа к репозиториям в /git.

#!/bin/sh

if [ $# -ne 2 ] || [ "$1" != "-c" ] ; then
  printf "interactive login not permitted\n"
  exit 1
fi

set -- $2

if [ $# != 2 ] ; then
  printf "wrong number of arguments\n"
  exit 1
fi

case "$1" in
  ( git-upload-pack | git-receive-pack )
    ;; # continue execution
  ( * )
    printf "command not allowed\n"
    exit 1
    ;;
esac

# Canonicalize the path name: we don't want escape out of
# git via ../ path components.

gitpath=$(readlink -f "$2")  # GNU Coreutils specific

case "$gitpath" in
  ( /git/* )
     ;; # continue execution
  ( * )
    printf "access denied outside of /git\n"
    exit 1
    ;;
esac

if ! [ -e "$gitpath" ] ; then
   printf "that git repo doesn't exist\n"
   exit 1
fi

"$1" "$gitpath"

Конечно, мы верим, что эти программы Git git-upload-pack и git-receive-pack не имеют дыр или аварийных люков, которые предоставят пользователям доступ к системе.

Это присуще такой схеме ограничения. Пользователь проходит проверку подлинности для выполнения кода в определенном домене безопасности, и мы ограничиваемся ограничением этого домена поддоменом. Например, если вы позволяете пользователю запускать команду vim для определенного файла, чтобы отредактировать его, пользователь может просто получить оболочку с :!sh[Enter].

14 голосов
/ 31 декабря 2008

То, что вы ищете, называется Restricted Shell . Bash предоставляет такой режим, в котором пользователи могут выполнять только команды, присутствующие в их домашних каталогах (и они не могут перемещаться в другие каталоги), что может быть достаточно для вас.

Я нашел эту ветку очень показательной, хотя и немного устаревшей.

4 голосов
/ 01 января 2009

Вы должны приобрести `rssh ', ограниченную оболочку

Вы можете следовать упомянутым выше руководствам по ограничению, все они довольно понятны и просты в использовании. Понимать термины "chroot jail" и как эффективно реализовывать конфигурации sshd / терминала и так далее.

Поскольку большинство ваших пользователей получают доступ к вашим терминалам через sshd, вам, вероятно, следует также заглянуть в sshd_conifg, файл конфигурации демона SSH, чтобы применить определенные ограничения через SSH. Будьте осторожны, однако. Поймите правильно, что вы пытаетесь реализовать, потому что последствия неправильных конфигураций, вероятно, довольно страшны.

3 голосов
/ 05 мая 2017

Почему бы вам не написать свой собственный логин-оболочку? Для этого было бы довольно просто использовать Bash, но вы можете использовать любой язык.

Пример в Bash

Используйте ваш любимый редактор для создания файла /root/rbash.sh (это может быть любое имя или путь, но должно быть chown root:root и chmod 700):

#!/bin/bash

commands=("man" "pwd" "ls" "whoami")
timestamp(){ date +'%Y-%m-%s %H:%M:%S'; }
log(){ echo -e "$(timestamp)\t$1\t$(whoami)\t$2" > /var/log/rbash.log; }
trycmd()
{
    # Provide an option to exit the shell
    if [[ "$ln" == "exit" ]] || [[ "$ln" == "q" ]]
    then
        exit

    # You can do exact string matching for some alias:
    elif [[ "$ln" == "help" ]]
    then
        echo "Type exit or q to quit."
        echo "Commands you can use:"
        echo "  help"
        echo "  echo"
        echo "${commands[@]}" | tr ' ' '\n' | awk '{print "  " $0}'

    # You can use custom regular expression matching:
    elif [[ "$ln" =~ ^echo\ .*$ ]]
    then
        ln="${ln:5}"
        echo "$ln" # Beware, these double quotes are important to prevent malicious injection

        # For example, optionally you can log this command
        log COMMAND "echo $ln"

    # Or you could even check an array of commands:
    else
        ok=false
        for cmd in "${commands[@]}"
        do
            if [[ "$cmd" == "$ln" ]]
            then
                ok=true
            fi
        done
        if $ok
        then
            $ln
        else
            log DENIED "$cmd"
        fi
    fi
}

# Optionally show a friendly welcome-message with instructions since it is a custom shell
echo "$(timestamp) Welcome, $(whoami). Type 'help' for information."

# Optionally log the login
log LOGIN "$@"

# Optionally log the logout
trap "trap=\"\";log LOGOUT;exit" EXIT

# Optionally check for '-c custom_command' arguments passed directly to shell
# Then you can also use ssh user@host custom_command, which will execute /root/rbash.sh
if [[ "$1" == "-c" ]]
then
    shift
    trycmd "$@"
else
    while echo -n "> " && read ln
    do
        trycmd "$ln"
    done
fi

Все, что вам нужно сделать, - установить этот исполняемый файл в качестве оболочки для входа. Например, отредактируйте файл /etc/passwd и замените текущую оболочку входа этого пользователя /bin/bash на /root/rbash.sh.

Это просто простой пример, но вы можете сделать его настолько продвинутым, насколько захотите, идея в этом. Будьте осторожны, чтобы не заблокировать себя, изменив оболочку входа в свой собственный и единственный пользователь. И всегда проверяйте странные символы и команды, чтобы убедиться, что они действительно безопасны.

Вы можете проверить это с помощью: su -s /root/rbash.sh.

Остерегайтесь , убедитесь, что соответствует всей команде, и будьте осторожны с подстановочными знаками! Лучше исключить Bash-символы, такие как ;, &, &&, ||, $ и обратные галочки, чтобы быть уверенным.

В зависимости от свободы, которую вы предоставляете пользователю, она не станет намного безопаснее, чем эта. Я обнаружил, что часто мне нужно было всего лишь сделать так, чтобы пользователь имел доступ только к нескольким соответствующим командам, и в этом случае это действительно лучшее решение. Однако, если вы хотите дать больше свободы, тюрьма и разрешения могут быть более подходящими. Ошибки легко совершаются, и замечаются только тогда, когда уже слишком поздно.

1 голос
/ 01 января 2009

Возможно, вы захотите взглянуть на настройку тюрьмы .

0 голосов
/ 24 апреля 2019

[Раскрытие: я написал sshdo, который описан ниже]

Если вы хотите, чтобы логин был интерактивным, тогда настройка ограниченной оболочки, вероятно, является правильным решением. Но если существует фактический набор команд, которые вы хотите разрешить (и ничего больше), и эти команды можно выполнять по отдельности через ssh (например, ssh user @ host cmd arg blah blah), тогда универсальный элемент управления списком команд SSH может быть то, что вам нужно. Это полезно, когда команды каким-то образом написаны на стороне клиента и не требуют, чтобы пользователь действительно вводил команду ssh.

Для этого есть программа sshdo. Он контролирует, какие команды могут выполняться через входящие ssh-соединения. Доступно для скачивания по адресу:

http://raf.org/sshdo/ (см. Страницы руководства здесь) https://github.com/raforg/sshdo/

Он имеет режим обучения, позволяющий использовать все команды, и опцию --learn для создания конфигурации, необходимой для постоянного доступа к изученным командам. Тогда режим тренировки можно отключить, и любые другие команды не будут выполняться.

У него также есть опция --unlearn, чтобы прекратить разрешать команды, которые больше не используются, чтобы поддерживать строгие минимальные привилегии при изменении требований со временем.

Очень суетно из-за того, что позволяет. Это не позволит команду с любыми аргументами. Допускаются только полные команды оболочки.

Но он поддерживает простые шаблоны для представления похожих команд, которые различаются только цифрами в командной строке (например, порядковые номера или метки даты / времени).

Это похоже на брандмауэр или контроль белого списка для команд ssh.

И он поддерживает разные команды, разрешенные для разных пользователей.

0 голосов
/ 01 января 2009

Еще один способ взглянуть на это - использовать POSIX ACL, он должен поддерживаться вашей файловой системой, однако вы можете выполнить детальную настройку всех команд в linux так же, как и тот же элемент управления в Windows (только без лучший интерфейс). ссылка

Другая вещь, на которую стоит обратить внимание: PolicyKit .

Вам нужно будет немного погуглить, чтобы все заработало, поскольку в данный момент это определенно не является сильной стороной Linux.

0 голосов
/ 31 декабря 2008
...