Хоча 80 і 443 - системні порти, як же більшість веб-серверів здатні прив’язатись до них?


18

Запуск веб-сервісу, який прив'язується до порту 80, зазвичай не вимагає привілеїв sudoer. Оскільки порти 80/443 є системними портами, це означає, що ними можуть користуватися лише привілейовані користувачі, то чому вони можуть все-таки прив’язатись до цих портів?



1
"зазвичай не вимагає привілеїв судора" є неправильним.
tedder42

Відповіді:


29

В основному існує два різних підходи:

  1. Спочатку почніть працювати як root, прив'яжіть до привілейованого порту, а потім перейдіть до непривілейованого користувача.

  2. inetd або xinetd запускає привілейовані дані і пересилає запити на веб-сервер, який працює непривілейовано.


3
В Linux ви також можете застосувати CAP_NET_BIND_SERVICE можливість програми або застосувати iptables для перенаправлення системного порту на звичайний порт.
Зан Лінкс

10
і просто для уточнення для ОП: причина, що варіант №1 працює, полягає в тому, що коли процеси відмовляються від привілеїв, їм дозволяється зберігати відкриті дескриптори файлів - навіть якщо вони не дозволять їх відкрити вдруге.
strugee

Також є Authbind .
Борис Павук

5

Оскільки порт 80/443 є системними портами, тобто ними можуть користуватися лише привілейовані користувачі

Я думаю, ви помилилися. Будь-хто може використовувати ці порти. Прив’язування до них - привілейована операція.

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

Я зроблю демонстрацію з netcat.

Як звичайний користувач, я не можу прив’язати до порту 80:

$ nc -l -p 80
Can't grab 0.0.0.0:80 with bind : Permission denied

Я можу прив’язати до порту 8080:

$ nc -l -p 8080

Тим часом в іншому терміналі я можу підключитися до порту 80 і надіслати деякі дані, і побачити, як вони з'являються на кінці сервера, який я щойно почав:

$ nc 127.0.0.1 8080 <<<"Hello world"

Якщо я хочу прив’язати до порту 80, мені потрібно мати root:

$ sudo nc -l -p 80

Або я можу призначити CAP_NET_BIND_SERVICEздатність ncдвійковому:

$ cp `which nc` .
$ sudo setcap 'cap_net_bind_service=+ep' ./nc
$ ./nc -l -p 80

Інший варіант - написати серверну програму таким чином, що після її виклику listen()вона скидає root права. Це досить поширене рішення, і ви побачите це з більшістю демонів. Наприклад, Apache запускається з init як root, а потім скидає привілеї root і стає користувачем www-dataабо чимось подібним, як тільки він прив’язаний до порту 80. Спробуйте запустити /etc/init.d/apache startяк не root, і Apache, ймовірно, не вдасться запустити.


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