Смена UID, GID это capcbilities процесса. Если у процесса есть такие capabilities, то он cможет менять UID, GID вне зависимости от пользователя, который его запустил. Capabilities это свойства программ и от пользователя они не зависят.
Соотв. тебе нужно как-то ловить процессы, которые запускает пользователь и отбирать у них соотв. capabilities. Единственное, что приходит в голову, это запускать пользователя в chroot окружении, в котором ты убрал у всех программ CAP_SETUID, CAP_CHOWN и пр… Будет ли такая система работать с нужным тебе функционалом – вопрос.
во-первых, тут видно, что auid=sparks, поэтому это не аргумент. во-вторых, тут видно, что failure случилось на USER_AUTH на не на системном вызове, скорее всего, где-то внутри PAM с поддержкой SE Linux.
Тут все почему-то про setuid() пишут, но дело не совсем не в нём. setuid() обычно и так, кроме рута, никому не доступен. У тебя ж пользователь - не рут?
Уточни что ты имеешь ввиду. «Опасная» смена пользоватиеля в su происходит вовсе не в момент вызова setuid(), а в момент запуска самого su - на нём стоит setuid-бит, и программа эта запускается от рута. Так что смотреть надо, видимо, запрет обработки setuid-битов для конкретного контекста. Но учти, setuid-биты есть не только у программ, меняющих в итоге пользователя, а и, например, у программы passwd, которая это использует чтобы уметь записывать в /etc/shadow, и даже более того - какие-то функции glibc внутри используют запуск setuid-бинарника-помощника, всё это тоже сломается.
auid - Records the Audit user ID. This ID is assigned to a user upon login and is inherited by every process even when the user’s identity changes (for example, by switching user accounts with su - john).
т.е. тот кто изначально залогинился в систему, а поле type
USER_AUTH - Triggered when a user-space authentication attempt is detected.
это «общий» эвент попытки аутентификации пользователя
Пользователь не рут.
Хочу реализовать следущую модель безопасности: пользователи не имеют пароля, в том числе рут (я один пользователь компьютера, не хочу вводить пароли, считаю это неудобным); обычные пользователи никак не должны иметь возможность делать смену пользователей, даже основной пользователь, под которым сижу в GUI (важно); чтобы иметь рутовый терминал, предпологаю запуск отдельного терминала с автоматическим рутовым логином, где-то из init-скриптов (пока не знаю как запускать такой терминал, подскажите), доступ к которому осуществляется по хоткею (хардварно с клавиатуры, пока не знаю, нужно ли как-то дополнительно ограничивать другие гуёвые программы от возможности эмулировать нажатие хоткея). Т.е. будет система, в которой обычные пользователи никак не могут повышать привилегии (в моей системе также нет sudo), будет работать гуёвый рутовый терминал, на который основной пользователь может переключаться по хоткею.
«Опасная» смена пользоватиеля в su происходит вовсе не в момент вызова setuid(), а в момент запуска самого su - на нём стоит setuid-бит, и программа эта запускается от рута.
Т.е. достаточно всего лишь запретить запуск su, и моя модель будет работать? Какие-то другие программы не смогут выполнять системные вызовы setuid()?
Если предполагать, что в софте нет багов, и что у тебя там не спрятался ещё какой-то клон su (sudo, doas, pkexec, их полно) - то да. Программы, которые переключаются на рута (с помощью бита setuid), всё равно будут, но они будут это делать для своих внутренних нужд и запустить с помощью них что-то ещё (если не найдётся баг) невозможно.
Собственно, то, что один юзер не может сам собой превратиться в другого - это дефолт. su и подобные проги создают исключения в этом дефолте. Наличие или отсутствие паролей вызову setuid() опять же не важно, пароль проверяет всё то же su, или другие «проги для логина» юзерспейсным кодом.
Насчёт эмуляции хоткеев - я не знаю, возможно ли это на уровне ядра, но вот перехватить их точно можно. То есть злонамеренная прога может нарисовать на экране что хочет, перехватить твой хоткей, нарисовать фейкокую рут-консоль (если она знает как она должна выглядеть) и украсть то что ты в эту рут-консоль планировал ввести. А так же вроде проги без всяких хоткеев можгут переключать эти консоли в любой момент времени (но тут не уверен).
Да нет, у него вполне здравая идея - юзеру с доступом к физической клаве выдать беспарольный доступ везде, а у софта его полностью забрать. Если за физический доступ он не беспокоится то почему бы нет.
Здравствуйте, хочу запретить огнестрел в стране, но чтобы у каждого была кнопка запуска ядерных ракет
Не у каждого, а только у основного юзера, и только переключением хоткеем на УЖЕ запущенный при старте терминал с рутом (запуск новых копий терминала с рутом будет невозможен).
Чем это менее безопасно всеми любимого sudo без пароля?
такой вопрос. вот я убрал setuid-бит с /usr/bin/su и теперь обычные пользователи не могут переключаться на других пользователей. что если всё же иногда нужно менять пользователя, например для понижения привелегий — запуск firefox от другого, ещё более ограниченного пользователя? или выпонение выключения/перезагрузки компьютера пользователем из GUI или по кнопке. Как реальзовать? Через suid-ные скрипты, запускающие нужную функцию от другого пользователя? а если надо poweroff запускать, то вешеть рутовый suid на скрипт? на сколько это безопасно?
Самый нормальный вариант, на мой взгляд - это написать программу на Си (и сделать её setuid-root), которая реализует ровно то, что ты хочешь разрешить и проверяя что оно действительно разрешено именно текущему юзеру. И никаких тупых пробрасываний аргументов куда-то - что-нить забудешь и получишь дыру, всё строго сначала парсим, потом выполняем действия. Узнать uid пользователя, её запустившего, можно через getuid(), а полученный из setuid-а root возвращается в geteuid().
запуск firefox от другого, ещё более ограниченного пользователя
Тут надо не забыть доступ к иксам пробросить ещё будет скорее всего - что очередная задача для кастомной проги с контролями доступа.
suid-ные скрипты
Скрипты нельзя suid. Можно си-обёртки, которые внутри запускают скрипты через system() или execve(), но как я уже выше написал, лучше по возможности вообще обойтись без скриптов и всё написать на Си.
1) делать тупо printf всего подряд нельзя, если хочешь передать строку, предоставленную юзером - её надо экранировать (это отдельная возня), иначе юзер может передать строку типа " ; echo qwe > /etc/passwd" которую шелл (функция system вызывает его) распарсит как команду
2) надо следить чтобы не переполнился буфер
Вобщем, не рекомендую этот способ, он чреват дырами, поэтому см. третий.
Третий способ - вызов нужной программы или скрипта без шелла
Тут программа просто запускает скрипт и передаёт ему все свои аргументы как есть. Опасности того, что на этом этапе что-то не так распарсится, нет - никакого парсинга тут не происходит. Вся ответственность за парсинг будет лежать на скрипте. На такую программу уже можно поставить setuid-root, в отличие от шелл-скрипта.
Но как скрипту в такой схеме узнать какой юзер его запустил я не знаю. Возможно там есть какой-нить аналог getuid().
а если проще? если для каждого скрипта своя обёртка? Т.е. есть скрипт, запускающий telinit 0, и есть обёртка, которая только это и запускает, без парсинга. ??? т.е. из обёртки только запускать /my_scripts/power_off или сразу /sbin/telinit 0 ??
Можно и свою для каждого, тогда можно даже убрать проверку прав из обёрток или скриптов и сделать её с помощью unix-прав доступа к запуску обёртки через группы.
Вообще делать одну обёртку для вообще всего я и не предлагал. Речь была про то, что какие-нить действия могут обязательно требовать какие-то параметры, которые придётся всё-таки брать от юзера.
Использовать пароли, но для актуального пользователя установить автологин. При этом вся ХХ-летняя история развития Линука будет работать на то, чтобы было невозможно сменить пользователя, не зная пароля
У иксов есть авторизация по uid и она часто используется. Сменишь юзера - может перестать работать. Если нет uid то нужен пароль от сессии - он обычно хранится в файле, имя которого указано в $XAUTHORITY. Если у проги и uid неподходящий и этот файл ты ей не подсунешь (чтоб смогла его прочесть) - подключение скорее всего не состоится. Можно настроить иксы чтобы пускали с локалхоста всех подряд без проверок, но это не очень хороший способ, лучше прокидывать Xauthority куда надо.
pscap у меня выводит необходимые и достаточные CAP для процессов. Сделал костылём-скриптом с помощью setpriv. Пользователю root привилегии с помощью CAP можно порезать сильно. Но буддте готовы, что если вы перезапустите какой-то сервис, то у него может не хватить привилегий для работы. init имеет больше привилегий чем пользователь root.
Реализация CAP в Linux мне не нравится. Хочу обработку filecapabilities для пользователя root как для всех, чтобы можно было xattr, setfcap отбирать привилегии у рутовых процессов, а не только раздавать обычным пользователям. Но Линус Торвальдс лично против. Он считает что админ не может знать какие привилегии необходимы процессу и дал возможность только программистам сбрасывать привилегии самому процессу. Но практически никто с разрабов ПО этим не пользуется. Правильное решение заметил только в smartd.
А давайте патч для ядра Linux напишем чтобы необходимые и достаточные CAP для root процесса можно было выставить filecapabilities.
Важное дополнение, вышеописанное даст гарантии для дистров без systemd, dbus, polkitd+JS понятно почему?
Потеринг проделал дырище в классической модели безопасности Linux - всё для удобства пользователей. Чтобы обычные пользователи имели возможность запускать процессы с рутовыми привилегиями. И права в этом случае контролируются polkitd, а правила контроля доступа пишутся на джава скрыпт. Это не шутка.
Polkitd - не корректно работает с памятью, использует JIT и требует выделения память для исполнения и изменения одновременно.
Формат правил контроля доступа нечетабелен - джаваскрипт.
Для компиляции требуется монстр sidermonkey который непонятно что делает.
А заем пользователю вообще выполнять какие либо команды в привилегированном режиме?
Выключить или перезагрузить комп может init, перехватив и обработав нажатие кнопки выключения на корпусе или ctrl+alt+del.
А если вдруг утилите ping требуется открыть net raw сокет, то не надо на нее s-bit ставить, хватит добавить файловые CAP: cap_net_raw. И их можно добавлять как наследуемые, только «+i» и по пользователям в /etc/security/capabilities.conf прописать пользователей имеющих привелегию наследовать cap_net_raw. Можно к файлам с установленными CAP зарезать доступ DAC.
Есть классические реализации контроля доступа в *NIX с конца 1960-тых годов: DAC и MAC. Потом в 1983 решили привилегии root порезать и ввели ещё CAP. Вредитель Леонард Потеринг делает целенаправленно дыру в безопасности GNU/Linux, чтобы обычные пользователи, минуя классические системы контроля доступа могли получить привилегии.
Лгут все те, кто хвалит: systemd, dbus, polkitd+JS. dbus
а от dbus какая угроза? знаю тока что мне надо создать правило, чтобы если в системе уже есть 1 клавиатура, чтобы вторая не появлялась, для защиты от флешек, прикидывающихся клавой. кстати, подскажите кто-нибудь такое правило, я сам правила dbus писать не умею.
init ловит ctrl+alt+del 100% только в консоли. Даже в консоли, init ещё обрабатывает файл /etc/shutdown.allow и принимает решение о перезагрузке в зависимости от залогиненых пользователей. Если запущен X11 то он может перехватывать все нажатия на клавиатуру, зависит от настроек конкретного X11.
Есть проще вариант: залочить root, и поставить пустой пароль. Убрать всех пользователей из wheel и удалить polkit. Ну и сделать автовход в root. Должно сработать. Но с nosuid надежнее =)
И да, лучше в таком случае и от systemd избавиться. Потому что комбайн, а ещё потому что он очень сложен в такой необычной настройке, что то обязательно упустите и… дыра.
Мне хочется плакать, но это правда. Я не как юзверь говорю, а как человек, который читал исходники polkitd, писал конфигурации для polkit.
Никак кроме диверсии назвать ЭТО язык не поворачивается. Мне хочется верить, что это не злой умысел, а просто человеческая глупость.
Сам dbus вряд ли сам по себе несёт опасность, скорее демоны, которые вывешивают в него опасные штуки. А в dbus, напомню, модель безопасности Unix слабо работает, это ж шина.
В мире NIX считают, что не привилегированные процессы не должны общаться с привилигированными. По этому init не принимает от пользователя команды, а перехватывает нажатие клавиш, кнопок и руководствуется настройками в /etc/
Процесы могут создавать сокеты, пайпы. На эти спец файлы распространяются классические средства контроля доступа: DAC, MAC. И другие процессы могут работать с этими файлами. Так взаимодействуют два процесса, даже разных пользователей, в *NIX.
dbus разрешает взаимодействовать непривилигированному и привилегированному процессу, контролируя доступ посредством polkitd, который принимает решение на основе скомпиленых правил написанных на Java script.
для защиты от флешек, прикидывающихся клавой. кстати, подскажите кто-нибудь такое правило