Ограничить выполнение команды на удаленном сервере только одним [дубликатом]

Класс SimpleNamespace может использоваться для создания новых атрибутов с помощью setattr или подкласса SimpleNamespace и создания вашей собственной функции для добавления новых имен атрибутов (переменных).

from types import SimpleNamespace

variables = {"b":"B","c":"C"}
a = SimpleNamespace(**v)
setattr(a,"g","G")
a.g = "G+"
something = a.a
71
задан Marcel 2 January 2009 в 10:58
поделиться

8 ответов

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

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

60
ответ дан HD. 22 August 2018 в 21:48
поделиться
  • 1
    Это выглядит интересно. Можно ли определить несколько команд? – Marcel 31 December 2008 в 11:43
  • 2
    В этой статье вы найдете несколько вариантов для нескольких команд с использованием файла authorized_keys: linuxjournal.com/article/8257 – Bash 31 December 2008 в 18:59
  • 3
    @ rd834 ...: Большое спасибо. Я думаю, что это дало мне «хороший». решение ... (добавлено в вопрос). Я буду принимать этот ответ как «правильно». – Marcel 2 January 2009 в 10:53
  • 4
    В книге O'Reilly SSH есть отличное объяснение, как это сделать, в том числе разрешить несколько команд, настроив скрипт, который смотрит на переменную среды SSH_ORIGINAL_COMMAND. oreilly.com/catalog/sshtdg/chapter/ch08.html – Alex Dupuy 11 November 2011 в 22:28
  • 5
    этот ответ serverfault имеет хороший совет, как разрешить несколько команд с помощью экспортированной переменной SSH_ORIGINAL_COMMAND. – MattBianco 13 January 2015 в 13:00

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

1
ответ дан Alan W. Smith 22 August 2018 в 21:48
поделиться

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

Еще одна вещь, которую нужно изучить, - PolicyKit .

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

0
ответ дан Bryan Rehbein 22 August 2018 в 21:48
поделиться

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

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

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

4
ответ дан Chuah 22 August 2018 в 21:48
поделиться
  • 1
    Обратите внимание, что pizzashack.org/rssh является отличным (возможно лучшим) решением для специального случая, когда вы хотите разрешить scp / sftp / rdist / rsync / cvs (и не нуждаетесь в доступе ко всему вне тюрьмы chroot) - однако он не решает общий вопрос об исходном плакате, который хотел, чтобы пользователи могли просматривать файлы журналов и запускать определенные сценарии запуска / выключения. – Alex Dupuy 11 November 2011 в 20:45

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, вы все равно можете войти в эту учетную запись, переопределив shell в команде su, как su -s /bin/bash foo. (Замените оболочку по выбору.) Не-root не может этого сделать.

Вот пример скрипта: ограничьте использование пользователем только 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].

27
ответ дан Kaz 22 August 2018 в 21:48
поделиться
  • 1
    Серьезно, это ОЧЕНЬ ОПАСНО. Что мешает мне выполнить git-receive-pack '/git/';dd if=/dev/urandom of=/dev/sda? – Yeti 29 July 2017 в 16:46
  • 2
    @Yeti У нас есть отверстие для ввода команд здесь? Это необходимо решить. Кроме того, злоупотребление файловыми шаблонами, которые я совершил в case, не выглядит правильным для меня. – Kaz 29 July 2017 в 21:07
  • 3
    Да, /bin/bash -c "$2" небезопасен (аналогично тому, как работает SQL-инъекция). Вы можете отфильтровать строку с помощью «волшебных кавычек». как PHP. Но простой способ обеспечить безопасность - это вызвать команду вручную, а затем передать параметры в двойных кавычках. Потому что безопасность всего этого зависит от того, какая команда является самым слабым звеном (сложнее проверить). Самое интересное, чтобы увидеть, как ваш ответ имеет 22 оборота, но никто этого не заметил;) Вы обновите свой собственный ответ? – Yeti 29 July 2017 в 21:14
  • 4
    @Yeti Да; Я только что сделал. Я заменил скрипт тем, который разбивает аргумент -c на set, а затем берет только первые два слова. Первая должна быть разрешенной командой git-, а вторая должна быть каноническим путем, проверяться на разрешенный префикс, а также проверяться на наличие. Можете ли вы придумать любой способ нарушить это? – Kaz 29 July 2017 в 21:29
  • 5
    Если кто-то не создает псевдоним (или переопределяет команду) для любой из заданных команд, то нет, двойные кавычки Bash должны быть безопасными (а если нет, то это ошибка в Bash). – Yeti 29 July 2017 в 22:09

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

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

14
ответ дан Vinko Vrsalovic 22 August 2018 в 21:48
поделиться
  • 1
    Что делать, если пользователь делает это?! / Bin / sh & quot; или некоторые из них из менее быстрого? – PEZ 31 December 2008 в 12:02
  • 2
    @Ubersoldat: Пожалуйста, вырастите и смягчите агрессию на всех ваших постах. Он спрашивал, распространяется ли ограничение только на bash или детские процессы (и для ответа на его вопрос, оказывается, это не так). – user 31 December 2008 в 23:30
  • 3
    Основная проблема с ограниченной оболочкой заключается в том, что для ее защиты вы должны использовать .profile или .bashrc, чтобы ограничить PATH, отключить встроенные функции и т. Д., Но эти файлы вызываются только для интерактивных оболочек. Если пользователь использует ssh для запуска удаленной команды, они не вызываются. Это позволяет пользователю с доступом ssh к учетной записи с SHELL = / bin / rbash просто делать что-то вроде ssh remotehost bash & quot; для получения неинтерактивной, но неограниченной оболочки. Вам нужны SSH принудительные команды с поддержкой HD, но это может защитить от экранов оболочки, как это задал PEZ (после того, как PATH заблокирован - по умолчанию он включает / bin: / usr / bin). – Alex Dupuy 11 November 2011 в 20:58
  • 4
    Я беру это обратно, bash будет вызывать .bashrc (не .profile) при запуске неинвазивно в sshd; однако вы должны убедиться, что вы устанавливаете PATH явно и отключите встроенные и псевдонимы в .bashrc - изменение в подкаталог не в / над PATH или .ssh / или .bashrc также является хорошей идеей. Наличие любой команды, которая может писать произвольные файлы, создаст проблему - это не всегда очевидно, например. Команда sed 'w' может использоваться для перезаписывания .bashrc и выхода. Хрочная тюрьма всегда будет более безопасной, если вы сможете ее использовать, а принудительные команды ssh будут более ограниченными. – Alex Dupuy 11 November 2011 в 22:17

Почему бы вам не написать свою собственную оболочку для входа? Было бы довольно просто использовать 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-символы, такие как ;, &, &&, ||, $ и обратные выходы.

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

2
ответ дан Yeti 22 August 2018 в 21:48
поделиться
  • 1
    Мне очень понравился этот подход. Вы знаете, как мы можем обрабатывать многословные команды, такие как «service httpd restart» ?? – Farzan 20 March 2018 в 00:23
  • 2
    @Farzan Вы можете выполнять команды в переменной, например. ln="service httpd restart", с: ${ln[@]}. Не забудьте подумать о проблемах безопасности, в этом случае полезен белый список только для буквенно-цифровых символов и пробелов. Но вы также можете просто сделать: if [[ "$ln" == "restart-httpd"];then service httpd restart;fi и работать с такими простыми командами. – Yeti 20 March 2018 в 11:08
  • 3
    /root/rbash.sh: Permission denied Я тоже пробовал chmod 777 – Christian 22 March 2018 в 12:44
  • 4
    @Christian, вы добавили /root/rbash.sh в /etc/shells? Это зависит от распределения. Вы также можете попробовать временно отключить selinux и проверить сообщения журнала для подсказок (посмотрите на метку времени) в файлах в /var/log. – Yeti 23 March 2018 в 09:32
  • 5
    @yeti no, объяснили, чтобы добавить в / root :) Попробуем сейчас. – Christian 23 March 2018 в 09:39
  • 1
    chroot и тюрьма - хорошие инструменты. Но для моей проблемы я не думаю, что это решение. Я не хочу скрывать другие каталоги, чем домашний каталог, я хочу ограничить доступ к файлам in домашнему директорию пользователя! – Marcel 2 January 2009 в 11:00
  • 2
    @Zsolt, выше это не фактический ответ, а ссылки на ответы. Этого следует избегать, поскольку связи неизбежно со временем сошли с ума. Это хорошо, давая ссылки, но мясо ответа должно быть прямо там в вашем собственном тексте. – zrajm 26 January 2016 в 15:21
Другие вопросы по тегам:

Похожие вопросы: