Мне нужно разрешить пользователю (отличному от root) запускать сервер, прослушивающий порт 80.
Есть какой-либо способ сделать это?
Мне нужно разрешить пользователю (отличному от root) запускать сервер, прослушивающий порт 80.
Есть какой-либо способ сделать это?
Ответы:
setcap 'cap_net_bind_service=+ep' /path/to/program
это будет работать для конкретных процессов. Но чтобы позволить конкретному пользователю привязываться к портам ниже 1024, вам придется добавить его в sudoers.
Посмотрите на это обсуждение для более.
(Некоторые из этих методов были упомянуты в других ответах; я даю несколько возможных вариантов в грубом порядке предпочтений.)
Вы можете перенаправить низкий порт на высокий порт и прослушивать высокий порт.
iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-ports 1080
Вы можете запустить свой сервер как root и удалить привилегии после того, как он начал прослушивать привилегированный порт. Желательно, вместо того, чтобы кодировать это самостоятельно, запустить свой сервер из оболочки, которая сделает эту работу за вас. Если ваш сервер запускает один экземпляр для каждого соединения, запустите его из inetd
(или аналогичной программы, такой как xinetd
). Для inetd
, используйте строку, как это в /etc/inetd.conf
:
http stream tcp nowait username:groupname /path/to/server/executable argv[0] argv[1]…
Если ваш сервер прослушивает один экземпляр, запустите его из такой программы, как authbind
. Либо создайте пустой файл /etc/authbind/byport/80
и сделайте его исполняемым для пользователя, работающего на сервере; или создайте /etc/authbind/byuid/1234
, где 1234 - это UID, на котором работает сервер, содержащий строку 0.0.0.0/0:80,80
.
Если исполняемый файл вашего сервера хранится в файловой системе, которая поддерживает возможности, вы можете предоставить ему такую возможность . Остерегайтесь, что возможности все еще относительно новы и все еще имеют несколько изломов .cap_net_bind_service
setcap cap_net_bind_service=ep /path/to/server/executable
-A INPUT -p tcp --dport 1080 -j ACCEPT
противном случае оно не сработало бы (у меня также есть универсальное решение -j DROP
). Поэтому у меня осталось два сокета прослушивания.
Короткий ответ: это невозможно по замыслу.
Длинный ответ заключается в том, что в мире с открытым исходным кодом много людей играют с дизайном и придумывают альтернативные методы. В целом это общепринятая практика, что это не должно быть возможным. Тот факт, что вы пытаетесь, вероятно, означает, что у вас есть другая ошибка проектирования в вашей системе, и вам следует пересмотреть всю архитектуру вашей системы в свете лучших рекомендаций * nix и последствий для безопасности.
Тем не менее, одна программа для авторизации некорневого доступа к низким портам - это authbind . И selinux, и grsecurity также предоставляют фреймворки для таких тонко настроенных аутентификаций.
Наконец, если вы хотите, чтобы определенные пользователи запускали определенные программы от имени пользователя root, и вам действительно нужно просто позволить пользователю перезапустить apache или что-то в этом роде, sudo
ваш друг!
Вы можете использовать переадресацию портов netcat, xinetd или iptables или использовать apache в качестве внешнего прокси-сервера и запускать процесс на непривилегированном порту.
Authbind , @Gilles уже упоминал об этом, но я бы хотел немного рассказать об этом.
Он имеет удобное управление доступом (подробности на странице руководства): вы можете фильтровать доступ по порту, адресу интерфейса, uid, диапазонам адресов или портов и их комбинации.
У него очень полезный параметр --depth
:
- глубокие уровни
Заставляет authbind влиять на программы, находящиеся глубоко в графе вызовов. По умолчанию это 1.
«Уровень глубоко» означает, что когда скрипт (или программа) запускает другой скрипт, он опускается на уровень. Таким образом, если у вас есть --depth 5
это, значит, на уровнях 1 (или 0?) Через 5 у вас есть разрешение на привязку, а на уровне 6 и выше - нет. Полезно, когда вы хотите, чтобы у скрипта был доступ, но не у программ, с которыми он работает или без вашего ведома.
Для иллюстрации, у вас может быть что-то вроде этого: в целях безопасности у вас есть пользователь, java
который предназначен только для запуска Java, и вы хотите дать ему доступ к порту 80:
echo > /etc/authbind/byport/80
chown root:java /etc/authbind/byport/80
chmod 710 /etc/authbind/byport/80
Я создал ../byport/80 file
, дал его java
группе пользователей (у каждого пользователя есть своя группа) и сделал его исполняемым по группе, что означает, что он исполняется java
пользователем. Если вы предоставляете доступ по порту, файл должен быть исполняемым пользователем, который должен иметь доступ, поэтому мы сделали это.
Этого может быть достаточно для обычного Джо, но, поскольку вы знаете, как использовать --depth
параметр, вы запускаете (как java
пользователь), authbind --depth [depth] my_web_app's_start_script
начиная --depth 1
и продолжая свой путь, пока не найдете наименьшую глубину, которая работает, и используйте ее.
Я пробовал метод iptables PREROUTING REDIRECT, но обнаружил, что он также влияет на перенаправленные пакеты. То есть, если машина также пересылает пакеты между интерфейсами (например, если она действует как точка доступа Wi-Fi, подключенная к сети Ethernet), то правило iptables также будет перехватывать подключения подключенных клиентов к адресатам Интернета и перенаправлять их на машина. Это не то, что я хотел - я только хотел перенаправить соединения, которые были направлены на саму машину.
Одна возможность - использовать переадресацию TCP-порта. Например, используя socat
:
socat TCP4-LISTEN:www,reuseaddr,fork TCP4:localhost:8080
Однако одним из недостатков этого метода является то, что приложение, которое прослушивает порт 8080, не знает адрес источника входящих соединений (например, для регистрации или других целей идентификации).