Как защитить сценарий на основе sudo

Попробуйте Micro.

https://github.com/zyedidia/micro

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

Как видно из названия, micro стремится стать чем-то вроде преемника редактора nano, поскольку его легко установить и использовать в крайнем случае, но micro также стремится к тому, чтобы его было приятно использовать постоянно, независимо от того, работаете ли вы в терминале, потому что вы предпочитаете это (как я), или потому, что вам нужно (через ssh).

Скриншоты и цветовые схемы

Это почти идеально. Выделение со стрелкой Shift работает отлично. Control-C (вырезать), Control-V (вставить), Control-Z (отменить), Control-S (сохранить) - все работает должным образом. Он также отлично выделяет отступы и снимает выделение.

Вам нужен эмулятор терминала, который должным образом поддерживает клавишу Shift. Терминатор отлично работает из коробки. Некоторые терминалы на базе Android не поддерживают выбор сдвига, но JuiceSSH (самый популярный в Google Play) работает, хотя я еще не тестировал его всесторонне.

6
21.07.2016, 12:14
7 ответов

Я бы немного изменил ваш список критериев защиты сценария.Учитывая эту или аналогичную запись в / etc / sudoers :

 www-data ALL = (ALL) NOPASSWD: / usr / local / sbin / mycommand 
 

мы может указывать, что сценарий:

  • должен быть доступен для записи только пользователю root
  • должен быть доступен для чтения и исполняться пользователем root
  • должен находиться в иерархии каталогов, которые могут быть записаны только пользователем root
  • должны проверить свой ввод «в достаточной степени» для использования и отклонить что-либо еще
  • должен иметь наименьший набор привилегий, необходимых для выполнения своей задачи (не обязательно setuid root)
  • должен определить свой ПУТЬ перед использование любых внешних команд
  • должно установить все переменные в известное значение перед их использованием
  • должен генерировать контрольный журнал, чтобы показать не только, когда и как он был вызван, но также и результирующее действие (подумайте logger ])

Кроме того, во многих случаях нет реальной необходимости запускать сценарий от имени пользователя root - он может запускать setgid или даже setuid для какой-либо другой учетной записи. В общем случае рассмотрите эти варианты, чтобы избежать предоставления скрипту полного корневого доступа.

Для сред SELinux можно создать политику, которая предотвращает выполнение сценарием каких-либо неожиданных действий. Такие возможности, как CAP_NET_ADMIN, более детализированы, чем общие привилегии root, и их также стоит рассмотреть.

В указанном вами конкретном случае, когда вы хотите проверить один IPv4-адрес и передать его iptables , вы можете обойтись без проверки IP-адреса. адрес как последовательность неспецифических октетов. В данном случае 444.555.666.999 можно считать правдоподобным, зная, что сам iptables отклонит все, что не является настоящим IP-адресом. В одном крайнем случае вы можете решить, что сопоставление RE / ^ [0-9.] + $ / достаточно, чтобы передать значение в iptables . С другой стороны, есть много ответов на StackExchange и в других местах , которые касаются проблемы проверки IP-адреса. Некоторые лучше, чем другие.

Особые случаи, которые следует учитывать, - это адреса RFC1918, адреса многоадресной рассылки и ваш собственный диапазон внешних IP-адресов. Да, и зарезервированный блок, ранее известный как Class E. Нужна ли вам поддержка IPv6?

Что произойдет, если ваш скрипт будет вызывать сотни раз в минуту? Вам нужно подготовиться к такому повороту событий? Будет ли ваша цепочка iptables переполнена? Если вы думаете, что вам понадобятся сотни правил в вашей цепочке, [более эффективно будет использовать расширение ipset до iptables , а не линейный список. Вот хороший учебник . Что касается защиты, он позволяет создавать наборы из тысяч (если не десятков тысяч ) похожих правил, которые могут выполняться без значительного замедления трафика, проходящего через ваши наборы правил.

Внезапно ваше очевидно прямое требование становится довольно сложным.

6
27.01.2020, 20:21

Вещи, которые могут повлиять на программу setuid

Давайте рассмотрим некоторые способы, которыми вызывающий пользователь может повлиять на поведение процесса setuid. Я разделю то, что нужно рассмотреть, на три группы: 1) сама программа, 2) входные данные для программы и 3) среда, в которой она выполняется.

Двоичный файл: Если непривилегированный пользователь может изменить исполняемый двоичный файл, что было бы простым способом изменить привилегированный процесс. Сюда входят случаи, когда путь к файлу программы проходит через доступные для записи каталоги и символические ссылки. Обязательно убедитесь, что файл программы и путь к нему не доступны для записи неавторизованным пользователям. (И sudo , похоже, не проверяет.)

Бинарные файлы Setuid на самом деле более невосприимчивы к модификации таким образом, поскольку бит setuid является свойством inode, а не путем, поэтому обман символической ссылки не будет работать. (Кроме того, похоже, что в некоторых Linux сбрасывается бит setuid, если другой пользователь записывает в файл, но я бы не стал на это рассчитывать.)

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

Если программе требуется какой-либо ввод от пользователя (вместо того, чтобы всегда делать что-то одно), мы не можем этого избежать. Таким же образом сетевые службы должны быть осторожны с вводом данных. (Для примера посмотрите SQL-инъекции и т. Д.Я думаю, что обработка ввода особенно сложна для таких вещей, как сценарии оболочки, где все данные являются текстом, а весь текст находится на расстоянии одной кавычки от превращения, так сказать, в команду.

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

Окружающая среда - более широкая проблема. Очевидно, он включает переменные среды, такие как PATH (которые могут изменять выполняемый подпроцесс), LC _ * и POSIXLY_CORRECT (которые могут изменить выходной формат оболочки команды), HOME (который может использоваться для доступа к файлам) и LD _ * (которые изменяют поведение динамического загрузчика) среди других. Это простые вещи.

Но рассмотрите что-то вроде ограничений ресурсов, cgroups Linux, chroots, контексты SELinux, пространства имен и неизвестно что еще. Установка, скажем, жесткого ограничения для использования стека или количества процессов может привести к сбою привилегированного процесса в неожиданной точке или невозможности запуска подпроцессов. Неожиданный сбой может произойти после того, как процесс заблокировал какой-то ресурс, но до того, как у него появится возможность зафиксировать и разблокировать его ...

(Хотя многие из последних не могут быть изменены непривилегированными пользователями, поэтому они могут не быть Серьезная проблема.Исполняемый файл setuid, доступный из ограниченной среды, может все же должным образом работать в ограниченной среде.)

Что с этим делать

По крайней мере, вы должны

  • Убедитесь, что исполняемый файл доступен для записи только авторизованным пользователям, включая как сам файл, так и путь к нему. Делать его нечитаемым не обязательно, если программа не содержит встроенных секретов.
  • Сброс среды при запуске, включая установку известного значения ПУТЬ . Использование абсолютных путей кажется безопасным, но я не могу сказать, какой эффект это произвело бы, если бы путь поиска был известен. env_reset в sudo должен это сделать.
  • ( Переменные LD _ * обрабатываются динамическим компоновщиком до того, как вы получите возможность их сбросить, но компоновщик должен игнорировать их для процессов setuid.)
  • Подтвердите свой ввод. Конечно. Хотя это также может быть легче сказать, чем сделать, особенно если вы планируете ввести пользовательский ввод в сценарий оболочки.
  • Принимать конфиденциальный ввод (пароли) через канал или стандартный ввод.
  • Сбросьте ограничения ресурсов или рискните выйти из строя в неожиданной точке.

Теоретически должно быть возможно создать «безопасную» программу, запускаемую с помощью setuid или sudo, в традиционной среде, но менее распространенные системные особенности может быть труднее проверить.

(И, кстати, я мог бы сказать, что программа setuid не будет всегда легко открывать брешь в системе безопасности, поскольку во многих системах есть такие вещи, как passwd , su , и sudo , которые являются setuid, но не считаются относительно безопасными.)

Альтернатива setuid

Другая возможность, помимо sudo или setuid, - это поговорить с привилегированным процессом через конвейер (или сокет). Это имеет то преимущество, что работающий двоичный файл легко защищен, среда его выполнения известна, и непривилегированный пользователь не имеет возможности повлиять на него.

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

У сокетов нет этой проблемы, но они также не доступны для обычных функций файловой системы. Вместо этого к ним нужно обращаться через функции сокета. (например, echo foo> / my / socket не будет работать. socat может быть полезен в скриптах).

3
27.01.2020, 20:21

Не говоря уже о том, является ли ваш подход хорошей идеей, если mycommand интерактивный, вы должны запретить экранирование оболочки с помощью директивы noexec . Это предотвращает выполнение других команд, предварительно устанавливая системные вызовы exec () на бездействие. (Это достигается с помощью механизмов LD_PRELOAD, см. Sudo.conf (5).) Предостережение: это не пуленепробиваемое - если mycommand статически связана, то это не сработает.

0
27.01.2020, 20:21

Лучше всего использовать возможность "Digest_Spec" в файл sudoers для проверки контрольной суммы вашего исполняемого файла

Извлечение страницы руководства:

Если имя команды имеет префикс Digest_Spec, команда будет успешно соответствовать только в том случае, если ее можно проверить с помощью указанный дайджест SHA-2.

Используя openssl, чтобы сгенерировать контрольную сумму:

 $ openssl dgst -sha224 / usr / local / sbin / mycommand 
SHA224 (/ usr / local / sbin / mycommand) = 
52246fd78f692554c9f6be9c8ecd34bbc9 
 

Затем в вашем файле sudoers (в той же строке):

 www-data ALL=(ALL) NOPASSWD: 
    ssha224:52246fd78f692554c9f6be9c8ea001c9131c3426c27c88dbbad08365
    /usr/local/sbin/mycommand
6
27.01.2020, 20:21

Именованный подход к трубе. От имени root запустите

mkfifo -m 666 /tmp/foo
/tmp/readpipe.sh &

И можете, как пользователь www-data, записать в трубу

echo test >>/tmp/foo

readpipe.sh в его простейшей форме (perl с taint был бы лучше) :

#!/bin/sh
while read A </tmp/foo
do
 echo received $A     
done
4
27.01.2020, 20:21

Что еще можно сделать для защиты сценария на основе sudo: использовать PAM - подключаемые модули аутентификации.

Руководство администратора PAM: http://www.linux-pam.org/Linux-PAM-html/Linux-PAM_SAG.html

Руководство разработчика модуля PAM: http: // www. linux-pam.org/Linux-PAM-html/Linux-PAM_MWG.html

Руководство разработчика приложения PAM: http://www.linux-pam.org/Linux-PAM-html/Linux-PAM_ADG. html

также проверьте / usr / share / doc / packages / pam / pdf в вашей системе, чтобы найти эти документы, которые будут иметь отношение к версии PAM в вашей системе.

PAM - один из основных механизмов безопасности в Linux. Он используется для защиты и блокировки многих вещей, двумя примерами являются процесс входа в систему и процесс смены пароля.Когда вы применяете ограничения пароля, такие как минимальная длина символа и срок действия, это делается с помощью PAM. Если PAM достаточно хорош для основных системных процессов, он определенно достаточно хорош для вашего скрипта. сначала загляните в Руководство по администрированию системы PAM, чтобы получить представление о том, что вы уже можете использовать, несколько примеров:

  • pam_time: не аутентифицирует пользователя, а вместо этого ограничивает доступ к системе и / или конкретным приложениям в разное время день и в определенные дни или по различным конечным линиям. Этот модуль можно настроить для отказа в доступе (отдельным) пользователям на основе их имени, времени суток, дня недели, услуги, на которую они обращаются, и их терминала, с которого они делают запрос.

  • pam_env: вызывать установку или отключение переменных среды при вызове, используйте это в своих интересах при создании модуля pam

  • pam_localuser: помогите реализовать политики входа в систему на уровне всего сайта, где они обычно включают подмножество пользователей сети и несколько учетных записей, локальных для конкретной рабочей станции. Использование pam_localuser и pam_wheel или pam_listfile - эффективный способ ограничить доступ либо локальным пользователям, либо подмножеству пользователей сети. Список

  • можно продолжить, обратитесь к руководству системного администратора и используйте его по мере необходимости.

вы также можете найти это полезным: http://freecode.com/projects/pam_script/

Отсюда вам нужно будет прочитать руководство по написанию модуля и руководство по разработке приложений. Это предназначение подключаемых модулей аутентификации PAM ... .Вы эффективно пишете код, и, если вы еще этого не сделали, когда закончите, станете программистом. Это не "ИТ", где вы устанавливаете некоторые флажки, включенные / отключенные, как в Microsoft Windows. Причина использования PAM заключается в том, что системный администратор может подключить модуль (иногда просто, а иногда нет необходимости писать его) из соображений безопасности, чтобы делать что угодно. Например, пользователь, использующий passwd чтобы изменить свой пароль, в целях безопасности используется PAM, и вы не набираете «sudo passwd», чтобы изменить свой пароль. В зависимости от того, что должен делать ваш скрипт, вам может даже не понадобиться sudo, если вы правильно используете PAM и устанавливаете права собственности и SUID / GUID вашего скрипта, как и / usr / bin / passwd .

Когда вы спрашиваете [себя], что еще я могу сделать, чтобы обезопасить это ... может быть признаком того, что это не лучший способ что-то сделать. В этом случае использование sudo для предоставления повышенных привилегий для запуска скрипта / исполняемого файла. Вместо этого посмотрите на установленные механизмы того, как Linux уже обрабатывает такие вещи ... конкретный случай, когда пользователь использует / usr / bin / passwd для редактирования / etc / passwd и Файлы / etc / shadow , которые принадлежат пользователю root и требуют разрешения root для изменения. А с помощью PAM вы можете ограничить круг лиц, которые могут запускать ваш скрипт, на основе идентификатора пользователя, идентификатора группы, локальной учетной записи пользователя в течение заданного времени и т. Д. Идя дальше, я уверен, что вы можете создать отдельную групповую учетную запись с собственным паролем с единственной целью - запускать ваш скрипт только с этими пользователями, и тогда вы не выдадите пароль root для запуска вашего скрипта.Вы будете следовать схеме группы wheel только для тех пользователей, которые могут использовать su для получения root-прав. надеюсь это поможет.

0
27.01.2020, 20:21

Я добавлю следующее :

Не делайте скрипт вызываемым напрямую, а вызывайте вторичный скрипт, первый скрипт будет использоваться для выполнения log:

#!/bin/bash

[ "$USER" != "www-data" ] && exit
set -a 
sudo realscript &>/var/log/myscript.log 

и realscript:

[ "$USER" != "root" ] && exit 

В sudo поставьте realscript как разрешенный sudo, а не вызываемый скрипт, как вы используете.

И выберите myscript.log как www-data owned, но с 222 разрешениями (да, возможна только запись!). Сделайте резервное копирование журнала в cron.

Не позволяйте www-data видеть содержимое myscript, а только выполнять его!

chmod 111 mylogscript
chmod 111 myrealscript

Разрешение 111 - это хорошо, потому что вы не хотите, чтобы пользователи читали скрипт, а только выполняли его.

Если есть возможность, попробуйте скомпилировать shell-скрипт:

shc mylogscript
shc myrealscript

Да, shc - это компилятор shell, так что вы можете преобразовать ваш скрипт в двоичный файл, и он будет более безопасным - но в некоторых случаях нестабильным, так что будьте осторожны!

Старайтесь не использовать параметры внутри сценария оболочки, такие как $1 $2, это может быть использовано для инъекции сценария. Вместо этого попробуйте экспортировать переменные окружения, которые shell может просматривать, или временные файлы. Параметр или не использовать все в каком-то виде шифрования openssl (смотрите этот пост: Как заставить openssl шифровать пароли как php через командную строку

0
27.01.2020, 20:21

Теги

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