Дозволити користувачу дозволити прослуховувати порт нижче 1024


63

Мені потрібно дозволити користувачеві (відмінному від root) запускати сервер, який прослуховує порт 80.

Чи можна це зробити?


1
Це питання є відкритим для тлумачення. Я сподіваюся, що ви маєте на увазі "ви створили нову системну службу, яку ви (як root) хочете запустити в непривілейований обліковий запис з міркувань безпеки" (вважається хорошою практикою), а не "У мене є користувач, який запитає, чи можуть вони запустити власний веб-сервер у моїй системі, як дозволити їм отримати доступ? " (вважається досить поганою практикою)
Майкл Шоу

3
@Ptolemy, фактична причина полягає в тому, що моя машина стоїть за брандмауером, який блокує будь-який порт, окрім 80. Я хочу розмістити сервер (який не скидає привілеїв!), Тому потрібно слухати його на порту 80, але не не довіряйте йому запускатися як root (з очевидних причин безпеки). Мені дозволено це робити, якщо вам байдуже.
пеоро

Відповіді:


50

setcap 'cap_net_bind_service=+ep' /path/to/program

це буде працювати для конкретних процесів. Але щоб дозволити конкретному користувачу прив’язатись до портів нижче 1024, вам доведеться додати його до судерів.

Погляньте на цю дискусію докладніше.


31

(Деякі з цих методів були згадані в інших відповідях; я даю декілька можливих варіантів у приблизному порядку.)

Ви можете перенаправити низький порт на високий порт і слухати на високому порту.

iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-ports 1080

Ви можете запустити свій сервер як root і drop права після його прослуховування на привілейованому порту. Переважно, а не кодувати це самостійно, запускайте свій сервер із обгортки, яка виконує цю роботу за вас. Якщо ваш сервер запускає один примірник на з'єднання, запустіть його з 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

4
У кожному випадку, з яким мені доводилося стикатися, виконуваним файлом був сценарій, який запускав Java або Python. Оскільки хлопець без 10 годин, щоб витратити їх на точні бали, ваше рішення iptables покриває це безболісно.
шприц

Для рішення iptables мені довелося також додати правило фільтра, як -A INPUT -p tcp --dport 1080 -j ACCEPTінакше воно не буде працювати (у мене також є -j DROPзагальний доступ). Тому мені залишаються дві розетки для прослуховування.
thom_nic

4

Коротка відповідь - це неможливо за допомогою дизайну.

Довга відповідь полягає в тому, що у відкритих кодах світу є багато людей, які грають з дизайном і придумують альтернативні методи. Загалом є загальноприйнятою практикою, що цього не можна зробити. Той факт, що ви намагаєтесь, мабуть, означає, що у вашій системі є ще одна помилка дизайну, і слід переглянути всю вашу архітектуру системи з огляду на найкращі практики * та наслідки для безпеки * nix.

Однак, одна програма для авторизації некореневого доступу до низьких портів є authbind . Як selinux, так і grsecurity також забезпечують рамки для такої тонкої настройки аутентифікації.

Нарешті, якщо ви хочете, щоб конкретні користувачі запускали конкретні програми як root, а вам дійсно потрібно лише дозволити користувачеві перезапустити apache або щось подібне, sudoце ваш друг!


8
"Безпека" порту насправді не дуже дає вам у сучасному світі.
pjc50

3
@ pjc50: Так. Йдеться про мається на увазі довіру. Низька кількість портів означає високу довіру. Очікується, що SSH, POP, FTP та інші демони запитуватимуть паролі на рівні системи та інші облікові дані, коли їх порти відкриються. Якщо користувачам було дозволено слухати низькі порти на коробці, вони могли запустити фальшиві демони на невикористаних (або збійних) портах та збирати паролі з нічого не підозрюючих користувачів. Ці паролі можуть бути використані у цьому полі для компрометації інших облікових записів, включаючи root.
Калеб

8
Це досить слабка форма безпеки. Якщо ви підключились до чогось і не зробили транзакції з сертифікатом, то ви не маєте уявлення про те, з ким ви говорите - тобто MITM-атаки.
pjc50

5
Я припускаю, що потрібне порушити порти: тоді ви можете "заглушити поштовий порт25", то (а) ваш поштовий демон не потрібно запускати з кореневими приватними та (б) ніхто більше не може його захопити.
pjc50

7
Хоча це, можливо, було правдою "задумом", коли Linux був у зародковому стані, це має дуже мало сенсу тоді і зараз. Безпека - це те, що користувач може, а що не може робити. Наприклад, дозволити тільки користувачеві root використовувати порт 80, наприклад, це величезний ризик для безпеки, оскільки це означає, що ви повинні надати root доступ людям, яким потрібно використовувати порт 80, але не повинні мати кореневий доступ. Якщо ви довіряєте некорінному користувачеві X використовувати порт 80, ви повинні мати можливість кодувати цю довіру до вашої ОС. На щастя, як ви вже згадували, існують шалені робочі місця, які дозволяють зробити це, як автозахист.
BT

3

Ви можете використовувати netcat або xinetd або iptables переадресацію портів, або використовувати apache як проксі-сервер переднього кінця та запускати процес на непривілейованому порту.


3

Authbind , @Gilles вже згадував про це, але я хотів би трохи розширити його.

Він має зручний контроль доступу (детальна інформація на вхідній сторінці): ви можете фільтрувати доступ через порт, адресу інтерфейсу, uid, діапазони адреси або порт та комбінацію цих.

Він має дуже корисний параметр --depth:

- рівень глибини

Викликає автоматичне зв’язування впливати на програми, що знаходяться в глибині графіка виклику. За замовчуванням - 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і працюючи вгору, поки не знайдете найменшої глибини, яка працює і використовуйте цю функцію.

Прочитайте сторінку людини для отримання детальної інформації .


1

Я спробував iptables PREROUTING REDIRECT метод, але виявив, що він також впливає на переслані пакети. Тобто, якщо машина також пересилає пакети між інтерфейсами (наприклад, якщо вона діє як точка доступу Wi-Fi, підключена до мережі Ethernet), то правило iptables також захопить з'єднання підключених клієнтів до Інтернет-адресатів та перенаправить їх на машина. Це не те, чого я хотів - я хотів лише перенаправляти з'єднання, спрямовані на саму машину.

Однією з можливостей є використання переадресації TCP-портів. Наприклад, використовуючи socat:

socat TCP4-LISTEN:www,reuseaddr,fork TCP4:localhost:8080

Однак одним недоліком цього методу є те, що програма, яка прослуховує порт 8080, тоді не знає адресу джерела вхідних з'єднань (наприклад, для ведення журналів або інших цілей ідентифікації).

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.