Мені потрібно дозволити користувачеві (відмінному від root) запускати сервер, який прослуховує порт 80.
Чи можна це зробити?
Мені потрібно дозволити користувачеві (відмінному від root) запускати сервер, який прослуховує порт 80.
Чи можна це зробити?
Відповіді:
setcap 'cap_net_bind_service=+ep' /path/to/program
це буде працювати для конкретних процесів. Але щоб дозволити конкретному користувачу прив’язатись до портів нижче 1024, вам доведеться додати його до судерів.
Погляньте на цю дискусію докладніше.
(Деякі з цих методів були згадані в інших відповідях; я даю декілька можливих варіантів у приблизному порядку.)
Ви можете перенаправити низький порт на високий порт і слухати на високому порту.
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
-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
:
- рівень глибини
Викликає автоматичне зв’язування впливати на програми, що знаходяться в глибині графіка виклику. За замовчуванням - 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, тоді не знає адресу джерела вхідних з'єднань (наприклад, для ведення журналів або інших цілей ідентифікації).