Смена 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, а правила контроля доступа пишутся на джава скрыпт. Это не шутка.