Класс 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
Вы также можете ограничить ключи допустимыми командами (в файле authorized_keys).
I.e. пользователь не будет входить в систему через ssh, а затем имеет ограниченный набор команд, а может быть разрешен только для выполнения этих команд через ssh (например, «ssh somehost bin / showlogfile»)
Возможно, вы захотите посмотреть установку тюрьмы .
Еще один способ взглянуть на это с помощью POSIX ACL, он должен поддерживаться вашей файловой системой, однако вы можете иметь тонкую настройку всех команд в Linux так же, как у вас есть один и тот же элемент управления в Windows (только без более удобный пользовательский интерфейс). link
Еще одна вещь, которую нужно изучить, - PolicyKit .
Вам нужно будет сделать довольно много поискового запроса, чтобы получить все, что работает, это определенно не сила Linux на данный момент.
Вы должны приобрести `rssh ', ограниченную оболочку
. Вы можете следовать приведенным выше руководствам по ограничениям, они все довольно понятны и просты для подражания. Понимать термины «chroot jail» и как эффективно реализовывать конфигурации sshd / terminal и т. Д.
Будучи так же, как большинство ваших пользователей получают доступ к вашим терминалам через sshd, вы также должны, вероятно, посмотреть в sshd_conifg, файл конфигурации демона SSH, чтобы применить определенные ограничения через SSH. Однако будьте осторожны. Правильно понимайте, что вы пытаетесь реализовать, поскольку последствия неправильной конфигурации, вероятно, довольно тяжелые.
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]
.
git-receive-pack '/git/';dd if=/dev/urandom of=/dev/sda
?
– Yeti
29 July 2017 в 16:46
case
, не выглядит правильным для меня.
– Kaz
29 July 2017 в 21:07
/bin/bash -c "$2"
небезопасен (аналогично тому, как работает SQL-инъекция). Вы можете отфильтровать строку с помощью «волшебных кавычек». как PHP. Но простой способ обеспечить безопасность - это вызвать команду вручную, а затем передать параметры в двойных кавычках. Потому что безопасность всего этого зависит от того, какая команда является самым слабым звеном (сложнее проверить). Самое интересное, чтобы увидеть, как ваш ответ имеет 22 оборота, но никто этого не заметил;) Вы обновите свой собственный ответ?
– Yeti
29 July 2017 в 21:14
set
, а затем берет только первые два слова. Первая должна быть разрешенной командой git-
, а вторая должна быть каноническим путем, проверяться на разрешенный префикс, а также проверяться на наличие. Можете ли вы придумать любой способ нарушить это?
– Kaz
29 July 2017 в 21:29
То, что вы ищете, называется Restricted Shell . 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-символы, такие как ;
, &
, &&
, ||
, $
и обратные выходы.
В зависимости от свободы, которую вы предоставляете пользователю, не станет намного безопаснее этого. Я обнаружил, что часто мне нужно только сделать пользователя, который имеет доступ только к нескольким соответствующим командам, и в этом случае это действительно лучшее решение. Однако вы хотите предоставить больше свободы, тюрьма и разрешения могут быть более уместными. Ошибки легко создаются и замечаются только тогда, когда уже слишком поздно.
ln="service httpd restart"
, с: ${ln[@]}
. Не забудьте подумать о проблемах безопасности, в этом случае полезен белый список только для буквенно-цифровых символов и пробелов. Но вы также можете просто сделать: if [[ "$ln" == "restart-httpd"];then service httpd restart;fi
и работать с такими простыми командами.
– Yeti
20 March 2018 в 11:08
/root/rbash.sh
в /etc/shells
? Это зависит от распределения. Вы также можете попробовать временно отключить selinux
и проверить сообщения журнала для подсказок (посмотрите на метку времени) в файлах в /var/log
.
– Yeti
23 March 2018 в 09:32
Google - наш друг . Среди первых хитов:
HTH