Как запустить сервер на порту 80 как обычный пользователь в Linux?
Я довольно долго искал ее, но не мог найти ее.
Я на Ubuntu Linux и хочу запустить сервер на порту 80, но из-за механизма безопасности Ubuntu я получаю следующую ошибку:
java.net.BindException: разрешение отклонено: 80
Я думаю, что это должно быть достаточно просто, чтобы либо отключить этот механизм безопасности, чтобы порт 80 был доступен для всех пользователей, либо назначил требуемые права для текущего пользователя для доступа к порту 80.
20 ответов
Короткий ответ: вы не можете. Порты ниже 1024 могут быть открыты только root. В соответствии с комментарием - вы можете использовать CAP_NET_BIND_SERVICE , но этот подход, примененный к java bin, сделает любую java-программу запускаться с этой настройкой, что нежелательно, если не угроза безопасности.
Длинный ответ: вы можете перенаправить соединения на порт 80 на другой порт, который вы можете открыть как обычный пользователь.
Запуск от имени пользователя root:
# iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 8080
Поскольку устройства loopback (например, localhost) не используют правила предварительной настройки, если вам нужно использовать localhost и т. д., добавьте это правило также ( спасибо @Francesco ):
# iptables -t nat -I OUTPUT -p tcp -d 127.0.0.1 --dport 80 -j REDIRECT --to-ports 8080
ПРИМЕЧАНИЕ. Вышеупомянутое решение не соответствует , хорошо подходит для многопользовательских систем, так как любой пользователь может открыть порт 8080 (или любой другой высокий порт, который вы решите использовать), тем самым перехватив трафик. (Кредиты CesarB ).
РЕДАКТИРОВАТЬ: в соответствии с вопросом комментариев - для удаления вышеуказанного правила:
# iptables -t nat --line-numbers -n -L
Это приведет к тому, что:
Chain PREROUTING (policy ACCEPT)
num target prot opt source destination
1 REDIRECT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:8080 redir ports 8088
2 REDIRECT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:80 redir ports 8080
Правило, которое вас интересует, - nr. 2, поэтому для его удаления:
# iptables -t nat -D PREROUTING 2
Если ваша система поддерживает его, вы можете использовать возможности. Посмотрите возможности человека, который вам нужен, будет CAP_NET_BIND_SERVICE.
На новом Debian /Ubuntu вы можете запустить:
sudo apt-get install libcap2-bin
sudo setcap 'cap_net_bind_service=+ep' /path/to/program
Другим решением является создание вашего приложения setuid, чтобы он мог связываться с портом 80. В качестве пользователя root выполните следующие
chown root ./myapp
chmod +S ./myapp
Имейте в виду, что если это будет сделано абсолютно правильно, вы обнаружите потенциальные уязвимости в безопасности, потому что ваше приложение будет разговаривать с сетью и будет работать с полными привилегиями root. Если вы примете это решение, вы должны посмотреть исходный код для Apache или Lighttpd или что-то подобное, где они используют привилегии root для открытия порта, но затем немедленно откажутся от этих привилегий и станут «более привилегированными пользователями», угонщик не может захватить весь ваш компьютер.
Обновление: как показано в этот вопрос , похоже, что ядра Linux с версии 2.6.24 имеют новую возможность, которая позволяет отмечать исполняемый файл (но не скрипт, конечно) как имеющий" CAP_NET_BIND_SERVICE
". Если вы установите debian-пакет «libcap2-bin», вы можете сделать это, выпустив команду
setcap 'cap_net_bind_service=+ep' /path/to/program
Подход, предложенный Sunny и CesarB:
iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 8080
отлично работает, но имеет небольшой недостаток - он не мешает пользователю напрямую подключаться к порту 8080 вместо 80.
Рассмотрим следующий сценарий, когда это может быть проблемой.
Предположим, у нас есть сервер, который принимает HTTP-соединения на портах 8080 и HTTPS-соединениях на порту 8181.
Мы используем iptables для установки следующих перенаправлений:
80 ---> 8080
443 ---> 8181
Теперь предположим, что наш сервер решает перенаправить пользователя с HTTP-страницы на страницу HTTPS. Если мы не будем тщательно переписывать ответ, он будет перенаправлен на https://host:8181/
. В этот момент мы ввернуты:
- Некоторые пользователи будут добавлять URL-адрес
https://host:8181/
, и нам нужно будет поддерживать этот URL-адрес, чтобы не нарушать их закладки. - Другие пользователи не смогут подключиться, потому что их прокси-серверы не поддерживают нестандартные SSL-порты.
Я использую следующий подход:
iptables -t mangle -A PREROUTING -p tcp --dport 80 -j MARK --set-mark 1
iptables -t mangle -A PREROUTING -p tcp --dport 443 -j MARK --set-mark 1
iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 8080
iptables -t nat -A PREROUTING -p tcp --dport 443 -j REDIRECT --to-port 8181
iptables -I INPUT -m state --state NEW -m tcp -p tcp --dport 8080 -m mark --mark 1 -j ACCEPT
iptables -I INPUT -m state --state NEW -m tcp -p tcp --dport 8181 -m mark --mark 1 -j ACCEPT
В сочетании с стандартом REJECT по умолчанию в цепочке INPUT этот подход не позволяет пользователям напрямую подключаться к портам 8080, 8181
Я просто использую Nginx впереди. Он также может работать на локальном хосте.
-
apt-get install nginx
.. или ..
-
pkg_add -r nginx
.. или что когда-либо подходит вашей ОС.
Все, что вам нужно в nginx.conf, если выполняется на localhost, это:
сервер { слушайте 80; server_name some.domain.org; место нахождения /{ proxy_set_header Host $ host; proxy_set_header X-Real-IP $ remote_addr; proxy_set_header X-Forwarded-For $ proxy_add_x_forwarded_for; proxy_pass http://127.0.0.1:8081; } }
Традиционно в Unix только root может связываться с низкими портами (<1024).
Самый простой способ обойти это - запустить сервер на высоком (например, 8080) и использовать простое правило iptables для пересылки соединений с порта 80 на порт 8080. Примечание. что при этом вы теряете дополнительную защиту от низких портов; любой пользователь на вашем компьютере может привязываться к порту 8080.
Если ваша система поддерживает его, вы можете использовать возможности. См. man capabilities
. Нет, я никогда не использовал их сам, и я не знаю, действительно ли они работают: -)
Используйте обратный прокси (nginx, apache + mod_proxy) или кэширующий обратный прокси (Squid, Varnish) перед серверами приложений!
С обратным прокси-сервером вы можете получить много интересных вещей, таких как:
- балансировки нагрузки
- Перезапуск серверов приложений с пользователями, получающими причудливую страницу ошибок
- Ускорить работу с кешем
- Точные настройки, которые обычно выполняются с обратным прокси-сервером, а не с сервером приложений
Вы можете использовать программу redir:
sudo redir --lport=80 --laddr=192.168.0.101 --cport 9990 --caddr=127.0.0.1
Использовать sudo.
Настройте sudo, чтобы обычный пользователь мог запускать соответствующие команды:
/etc/init.d/httpd start
или
apachectl stop
или
/usr/local/apache2/apachectl restart
или
/myapp/myappbin start
(Или любую другую команду /скрипт, который вы используете для запуска /остановки вашего конкретного веб-сервера /приложения)
Ответ солнечный правильный, но вы можете столкнуться с дополнительными проблемами, поскольку интерфейс loopback не использует таблицу PREROUTING,
, поэтому правила iptables для добавления - это два:
iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 8080
iptables -t nat -I OUTPUT -p tcp -d 127.0.0.1 --dport 80 -j REDIRECT --to-ports 8080
В Linux у вас есть еще два варианта:
- Вы можете попробовать SELinux ( http://www.nsa.gov/selinux/)
- Вы можете попробовать grsecurity ( http://www.grsecurity.net/)
Оба расширения ядра Linux позволяют предоставлять права доступа на очень мелкозернистом уровне. Это позволит вам открыть этот процесс для открытия порта 80, но он не наследует ни один из других прав root.
Из того, что я слышал, grsecurity гораздо проще в использовании, но SELinux более безопасен.
Одним из решений является использование iptables для выполнения PAT для пакетов для порта 80. Вы можете использовать это для маршрутизации пакетов на локальный порт 8080, например. Обязательно установите и настройте исходящие пакеты обратно на порт 80.
По моему опыту мелкие свойства разрешений Linux не компилируются в стандартные ядра из-за проблем с безопасностью.
Если вы пытаетесь сделать это, чтобы пользовательская команда могла использовать порт 80, то ваши единственные решения - это трюки iptables или установка исполняемого файла setuid-to-root.
Как это делает Apache (он привязывается к порту 80, но работает как кто-то, кроме root) должен запускаться от имени root, привязываться к порту, а затем изменять права собственности на процесс на не привилегированного пользователя после того, как порт настроен. Если приложение, которое вы пишете, может быть run от пользователя root, вы можете заставить его изменить владельца на неприемлемого пользователя после настройки портов. Но если это просто для обычного пользователя, запускаемого из командной строки, вам придется использовать одно из других решений.
Когда у меня есть различные приложения для веб-приложений (скрипты python, двигатели tomcat, ...), которые я не хочу запускать как root, я обычно настраиваю веб-сервер Apache перед ними. Apache прослушивает порт 80, а tomcat - 8080.
В apache: s config:
ProxyPass /webapp http://localhost:8080/webapp
ProxyPassReverse /webapp http://localhost:8080/webapp
Дополнительную информацию см. в документации по mod-proxy: http://httpd.apache.org/docs/2.2/mod/mod_proxy. HTML
Я думаю, что лучшим решением является sgid для вашего приложения, и как только он будет связан своим портом, он должен отказаться от привилегий, переключившись на другого пользователя.
Некоторые хост-системы не разрешают использовать модуль NAT, «iptables» не решает проблему в этом случае.
Как насчет xinetd?
В моем случае (ubuntu 10.04)
# apt-get install xinetd
# touch /etc/xinetd.d/my_redirect
# vim /etc/xinetd.d/my_redirect
Вставьте конфигурацию:
service my_redirector_80
{
disable = no
socket_type = stream
protocol = tcp
user = root
wait = no
port = 80
redirect = localhost 8080
type = UNLISTED
}
Тогда:
# service xinetd restart
http://docs.codehaus.org/display/JETTY/port80 объясняет лучше.
Как в стороне, FreeBSD и Solaris (кто-нибудь помнит , что один?), вы можете сделать это (привязать к низким портам) без повышения привилегий (т. е. с помощью программ для переключения на root). Поскольку вы указали Linux, я просто отправляю это как уведомление другим, которые могут найти этот вопрос.
Necromancing.
Simple. С обычным или старым ядром вы этого не делаете.
Как отмечают другие, iptables может перенаправить порт.
Как также указано другими, CAP_NET_BIND_SERVICE также может выполнять эту работу.
Конечно, CAP_NET_BIND_SERVICE не удастся, если вы запустите свою программу из сценария, если вы не установите ограничение на интерпретаторе оболочки, что бессмысленно, вы можете просто запустить свою службу как root ...
например для Java, вы должны применить его к JAVA JVM
sudo /sbin/setcap 'cap_net_bind_service=ep' /usr/lib/jvm/java-8-openjdk/jre/bin/java
Очевидно, что это означает, что любая программа Java может связывать системные порты.
Dito для mono /.NET.
Я также уверен, что xinetd не лучший из идей.
Но поскольку оба метода - хаки, почему бы не просто снять лимит, сняв ограничение?
Никто не сказал, что вам нужно запускать нормальное ядро, поэтому вы можете просто запустить свой собственный.
Вы просто загрузите источник для последнего ядра (или того же, что у вас в настоящее время). Впоследствии вы переходите к:
/usr/src/linux-<version_number>/include/net/sock.h:
Здесь вы просматриваете эту строку
/* Sockets 0-1023 can't be bound to unless you are superuser */
#define PROT_SOCK 1024
и измените его на
#define PROT_SOCK 0
Если вы не хотите иметь небезопасную ситуацию ssh, вы можете изменить ее на следующее: #define PROT_SOCK 24
Как правило, я использую самый низкий параметр, который вам нужен, например 79 для http или 24 при использовании SMTP на порту 25.
Это уже все.
Скомпилируйте ядро и установите его.
Reboot.
Закончено - этот глупый лимит GONE, и это также работает для скриптов.
Вот как вы скомпилируете ядро:
https://help.ubuntu.com/community/Kernel/Compile
# You can get the kernel-source via package linux-source, no manual download required
apt-get install linux-source fakeroot
mkdir ~/src
cd ~/src
tar xjvf /usr/src/linux-source-<version>.tar.bz2
cd linux-source-<version>
# Apply the changes to PROT_SOCK define in /include/net/sock.h
# Copy the kernel config file you are currently using
cp -vi /boot/config-`uname -r` .config
# Install ncurses libary, if you want to run menuconfig
apt-get install libncurses5 libncurses5-dev
# Run menuconfig (optional)
make menuconfig
# Define the number of threads you wanna use when compiling (should be <number CPU cores> - 1), e.g. for quad-core
export CONCURRENCY_LEVEL=3
# Now compile the custom kernel
fakeroot make-kpkg --initrd --append-to-version=custom kernel-image kernel-headers
# And wait a long long time
cd ..
Вкратце, используйте iptables, если вы хотите оставаться в безопасности, скомпилируйте ядро, если вы хотите быть уверенным, что это ограничение никогда не беспокоит вас снова.