Можно ли настроить параметр ядра, чтобы позволить программе пользователя связываться с портами 80 и 443?
Причина, по которой я спрашиваю, заключается в том, что глупо разрешать привилегированному процессу открывать сокет и слушать. Все, что открывает сокет и прослушивает, представляет высокий риск, и приложения с высоким риском не должны запускаться с правами root.
Я бы предпочел попытаться выяснить, какой непривилегированный процесс прослушивает порт 80, а не пытаться удалить вредоносное ПО, проникшее с правами root.
Ответы:
Я не уверен, на что ссылаются другие ответы и комментарии здесь. Это возможно довольно легко. Существует два варианта, каждый из которых позволяет получить доступ к портам с низким номером без необходимости поднять процесс до уровня root:
Вариант 1. Используйте
CAP_NET_BIND_SERVICE
для предоставления доступа к процессу с низким номером порта:При этом вы можете предоставить постоянный доступ к определенному двоичному файлу для привязки к портам с низким номером с помощью
setcap
команды:Для получения дополнительной информации о части e / i / p см
cap_from_text
.После этого
/path/to/binary
сможете связываться с портами с низким номером. Обратите внимание, что вы должны использоватьsetcap
сам бинарный файл, а не символическую ссылку.Вариант 2: Используйте
authbind
для предоставления одноразового доступа с более точным контролем пользователя / группы / порта:Инструмент
authbind
( страница man ) существует именно для этого.Установите
authbind
с помощью вашего любимого менеджера пакетов.Настройте его для предоставления доступа к соответствующим портам, например, чтобы разрешить 80 и 443 от всех пользователей и групп:
Теперь выполните вашу команду через
authbind
(необязательно указав--deep
или другие аргументы, см. Справочную страницу):Например
Есть и плюсы и минусы обоих вышеперечисленных. Вариант 1 предоставляет доверие к двоичному файлу, но не обеспечивает контроль над доступом к порту. Вариант 2 предоставляет доверие пользователю / группе и обеспечивает контроль доступа к каждому порту, но AFAIK поддерживает только IPv4.
источник
rwx
разрешение?-p
intead of+eip
?setcap
разрешение на версию- конкретного рубинового исполняемого файла , например/usr/bin/ruby1.9.1
chmod
777byport
файлов - лучшая идея. Я видел , давая permisions в диапазоне от500
до744
. Я бы остановился на самом строгом, который работает для вас.Дейл Хэгглунд на месте. Так что я просто собираюсь сказать то же самое, но по-другому, с некоторыми особенностями и примерами. ☺
В мире Unix и Linux правильно сделать следующее:
Вы неправильно поняли, где находится высокий риск. Высокий риск заключается в чтении из сети и действии в отношении того, что читается, а не в простых действиях по открытию сокета, привязке его к порту и вызову
listen()
. Это часть службы, которая осуществляет фактическое общение с высоким риском. Части, которые открываются,bind()
иlisten()
, и даже (в некоторой степени), частиaccepts()
, которые не представляют высокого риска и могут эксплуатироваться под эгидой суперпользователя. Они не используют и не обрабатывают (за исключением IP-адресов источника в данномaccept()
случае) данные, которые находятся под контролем ненадежных незнакомцев по сети.Есть много способов сделать это.
inetd
Как говорит Дейл Хагглунд, старый «сетевой суперсервер»
inetd
делает это. Учетная запись, под которой запускается процесс обслуживания, является одним из столбцов вinetd.conf
. Он не разделяет часть прослушивания и часть удаления привилегий на две отдельные программы, маленькие и легко проверяемые, но он разделяет основной код службы на отдельную программу,exec()
созданную в процессе службы, который порождается дескриптором открытого файла. для розетки.Сложность аудита - не такая уж большая проблема, поскольку нужно проверять только одну программу.
inetd
Главная проблема не столько в аудите, сколько в том, что он не обеспечивает простого детального управления сервисом во время выполнения по сравнению с более поздними инструментами.UCSPI-TCP и daemontools
Daniel J. Бернштейна UCSPI-TCP и DaemonTools пакеты были разработаны , чтобы сделать это в совокупности. В качестве альтернативы можно использовать практически эквивалентный набор инструментов Брюса Гюнтера на бис .
Программа для открытия дескриптора файла сокета и привязки к привилегированному локальному порту
tcpserver
, из UCSPI-TCP. Это делаетlisten()
иaccept()
.tcpserver
затем порождает либо служебную программу, которая сама отбрасывает привилегии root (поскольку обслуживаемый протокол включает в себя запуск от имени суперпользователя, а затем «вход в систему», как в случае, например, с FTP или демоном SSH), илиsetuidgid
который является Самодостаточная небольшая и легко проверяемая программа, которая только отбрасывает привилегии и затем загружает их по цепочке в собственно сервисную программу (ни одна часть которой, таким образом, никогда не работает с привилегиями суперпользователя, как, например, в случае сqmail-smtpd
).run
Сценарий службы , таким образом, будет, например, (этот для dummyidentd для предоставления нулевой услуги IDENT):перекус
Мой пакет Nosh предназначен для этого. У него есть небольшая
setuidgid
утилита, как и у других. Небольшое отличие состоит в том, что его можно использовать соsystemd
службами -style "LISTEN_FDS", а также со службами UCSPI-TCP, поэтому традиционнаяtcpserver
программа заменяется двумя отдельными программами:tcp-socket-listen
иtcp-socket-accept
.Опять же, целевые утилиты порождают и загружают друг друга. Одна интересная особенность дизайна заключается в том, что можно отказаться от привилегий суперпользователя после,
listen()
но даже раньшеaccept()
. Вотrun
сценарий,qmail-smtpd
который действительно делает именно это:Программы , которые работают под эгидой суперпользователя являются небольшими инструментами цепи нагрузки сервиса-агностиком
fdmove
,clearenv
,envdir
,softlimit
,tcp-socket-listen
, иsetuidgid
. К моментуsh
запуска сокет открыт и привязан кsmtp
порту, и у процесса больше нет привилегий суперпользователя.S6, S6-сети и Execline
Пакеты Laurent Bercot для сетей s6 и s6 были разработаны для того, чтобы сделать это совместно. Команды структурно очень похожи на команды
daemontools
UCSPI-TCP.run
сценарии были бы почти такими же, за исключением заменыs6-tcpserver
дляtcpserver
иs6-setuidgid
дляsetuidgid
. Тем не менее, можно также использовать набор инструментов execline М. Bercot в то же время.Вот пример службы FTP, слегка модифицированной по сравнению с оригиналом Уэйна Маршалла , которая использует execline, s6, s6-network и программу сервера FTP из publicfile :
ipsvd
Ipsvd Gerrit Pape - это еще один набор инструментов, который работает по тем же принципам, что и ucspi-tcp и s6-network. Инструменты есть
chpst
и наtcpsvd
этот раз, но они делают то же самое, и код высокого риска, который выполняет чтение, обработку и запись вещей, отправленных по сети ненадежными клиентами, все еще находится в отдельной программе.Вот пример работы М. Пейпа
fnord
вrun
сценарии:systemd
systemd
новая система контроля и инициализации сервиса, которую можно найти в некоторых дистрибутивах Linux, предназначена для того, чтоinetd
может делать . Тем не менее, он не использует набор небольших автономных программ. Кsystemd
сожалению, нужно проводить аудит полностью.С помощью
systemd
одного создает файлы конфигурации, чтобы определить сокет, которыйsystemd
прослушивает, и сервис, которыйsystemd
запускается. Файл «единицы измерения» службы имеет настройки, которые позволяют значительно контролировать процесс обслуживания, в том числе, от имени какого пользователя он запускается.С этим пользователем, установленным как не суперпользователь, он
systemd
выполняет всю работу по открытию сокета, привязке его к порту и вызовуlisten()
(и, если требуется,accept()
) в процессе # 1 в качестве суперпользователя и в сервисном процессе, который он порождения запускаются без привилегий суперпользователя.источник
У меня довольно другой подход. Я хотел использовать порт 80 для сервера node.js. Мне не удалось это сделать, поскольку Node.js был установлен для пользователя, не являющегося пользователем sudo. Я пытался использовать символические ссылки, но у меня это не сработало.
Затем я узнал, что могу перенаправлять соединения с одного порта на другой порт. Итак, я запустил сервер на порту 3000 и настроил переадресацию порта с порта 80 на порт 3000.
Эта ссылка предоставляет фактические команды, которые могут быть использованы для этого. Вот команды -
Я использовал вторую команду, и она сработала для меня. Таким образом, я думаю, что это промежуточная точка для того, чтобы не позволить пользовательскому процессу получить доступ к нижним портам напрямую, а предоставить им доступ с помощью переадресации портов.
источник
Ваши инстинкты совершенно верны: плохая идея - запускать большую сложную программу от имени пользователя root, потому что их сложность затрудняет доверие.
Но также плохая идея разрешать обычным пользователям привязываться к привилегированным портам, потому что такие порты обычно представляют важные системные службы.
Стандартный подход к разрешению этого очевидного противоречия - разделение привилегий . Основная идея состоит в том, чтобы разделить вашу программу на две (или более) части, каждая из которых выполняет четко определенную часть общего приложения и взаимодействует посредством простых ограниченных интерфейсов.
В приведенном вами примере вы хотите разделить вашу программу на две части. Тот, который запускается от имени root, открывается и привязывается к привилегированному сокету, а затем каким-то образом передает его другой части, которая работает как обычный пользователь.
Эти два основных способа достижения этого разделения.
Единственная программа, которая запускается от имени пользователя root. Самое первое, что он делает, - это создает необходимый сокет настолько простым и ограниченным способом, насколько это возможно. Затем он отбрасывает привилегии, то есть он превращается в процесс обычного режима пользователя и выполняет всю другую работу. Правильно отбросить привилегии сложно, поэтому, пожалуйста, найдите время, чтобы изучить правильный способ сделать это.
Пара программ, которые обмениваются данными через пару сокетов, созданную родительским процессом. Программа непривилегированного драйвера получает начальные аргументы и, возможно, выполняет базовую проверку аргументов. Он создает пару подключенных сокетов с помощью socketpair (), а затем разветвляет и исполняет две другие программы, которые будут выполнять реальную работу, и обмениваться данными через пару сокетов. Один из них является привилегированным и создаст сокет сервера, а также любые другие привилегированные операции, а другой будет выполнять более сложное и, следовательно, менее надежное выполнение приложения.
[1] http://en.m.wikipedia.org/wiki/Privilege_separation
источник
Самое простое решение: удалить все привилегированные порты в Linux
Работает на Ubuntu / Debian:
(хорошо работает для VirtualBox с учетной записью без полномочий root)
Теперь будьте осторожны с безопасностью, потому что все пользователи могут связывать все порты!
источник