Приложение Node.js не может работать на 80-м порту, даже если другой процесс не блокирует порт.

94

Я запускаю экземпляр Debian на Amazon EC2 с установленным Node.js. Если я запустил код ниже:

http = require('http');

http.createServer(function (request, response){
  response.writeHead(200, {'Content-Type':'text/plain'});
  response.end('Hello World\n');
}).listen(80);
console.log("Running server at port 80");

Я получаю вывод ниже, который говорит мне, что через порт 80 прослушивается другой процесс:

Running server at port 80

events.js:72
        throw er; // Unhandled 'error' event
              ^
Error: listen EACCES
    at errnoException (net.js:901:11)
    at Server._listen2 (net.js:1020:19)
    at listen (net.js:1061:10)
    at Server.listen (net.js:1127:5)
    at Object.<anonymous> (/home/admin/nodetests/nodetest.js:6:4)
    at Module._compile (module.js:456:26)
    at Object.Module._extensions..js (module.js:474:10)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:312:12)
    at Function.Module.runMain (module.js:497:10)

Теперь, когда я проверяю, есть ли процесс (как root, если что-то скрыто) прослушивает порт 80, используя:

netstat -tupln

Я получаю следующий вывод, который говорит мне, что на порту 80 ничего не прослушивается:

Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      1667/sshd       
tcp6       0      0 :::22                   :::*                    LISTEN      1667/sshd

Я должен отметить, что в debian порт 80 открыт как правило для входящего трафика, если это имеет значение.

У меня вопрос: что я делаю не так? Почему я не могу идентифицировать процесс, прослушивающий порт 80? Почему он заблокирован в Debian? Какие шаги нужно предпринять, чтобы код работал правильно?

Брайан Йе
источник

Ответы:

197

Код ошибки EACCESозначает, что у вас нет необходимых разрешений для запуска приложений на этом порту. В системах Linux для любого порта ниже 1024 требуется root-доступ.

гексацианид
источник
5
таким образом, sudo node myapp.js сделает это, если у вас есть разрешение на использование sudo (просто прикрепите его для любых новичков).
AlexMA
21
@AlexMA, но запускать сервер как root - это большой запрет
Патрик Эванс
1
Тогда как же запустить узел на 80-м порту? Следует ли вам просто ... не использовать прокси?
AlexMA 07
9
@PatrickEvans Я полагаю, что лучше всего было бы запустить на другом порту и просто настроить правило переадресации портов, как упомянуто здесь: stackoverflow.com/questions/16573668/…
AlexMA
73

Вместо работы на порту 80 вы можете перенаправить порт 80 на порт вашего приложения (> 1024), используя

iptables -t nat -I PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 3000

Это будет работать, если ваше приложение работает на порту 3000.

Камрул
источник
1
сделал это. Выяснилось, что для запуска iptables в новой установке debian необходимо быть root, иначе $ PATH не будет указывать на него.
Брайан Йе
Да, это был, наверное, самый простой способ сделать это. Я использую Google Cloud Compute, из-за чего у меня возникли проблемы при касании порта 80. Это было здорово. Спасибо.
Энди
Это должно быть приемлемое решение. Запуск веб-сервера как sudo опасен, так как потенциально злоумышленник может получить root-доступ, если в приложении есть уязвимость; кроме того, если бы приложение создавало какие-либо файлы, они были бы недоступны для других пользователей, что заставило бы вас использовать их sudoеще больше.
jesusiniesta
Не уверен, почему, но на Ubuntu 14.04 у меня это не сработало. Теперь я использую переадресацию портов через ssh, что так же просто. Я разместил ответ ниже .
panepeter
19

Краткий ответ: вы можете разрешить узлу доступ к этому порту, используя:

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

длинный ответ

Редактировать:

Может не работать на новых версиях узлов

Реут Шарабани
источник
это сработало. @LinuxMint - sudo setcap 'cap_net_bind_service = + ep' / usr / local / bin / node
объединить
Иногда обновление меняет путь к узлу, и это перестает работать. Поэтому вам нужно будет запустить его снова для нового пути к узлу.
Steampowered
Похоже , что это больше не будет работать версия мимо узла 8. github.com/nodejs/node/issues/22648
timaw
6

Обратите внимание, что если у вас apacheзапущен, вы можете создать обратный прокси на виртуальном хосте. Если ваш узел работает на порту 8080:

<VirtualHost 127.0.0.1:80>
        ServerName myLocalServer

        ProxyPass        /  http://localhost:8080/
        ProxyPassReverse /  http://localhost:8080/
</VirtualHost>

Конечно, добавить сервер в /etc/hosts:

127.0.0.1    myLocalServer

Вам нужно будет включить соответствующие модули apache:

sudo a2enmod proxy_html
sudo a2enmod proxy_http
sudo a2enmod proxy_connect
sudo a2enmod proxy_ajp
sudo service apache2 restart

... и теперь вы можете подключиться к http://myLocalServer.

Redsandro
источник
3

Для тех, кто ищет быстрое и простое решение для среды разработки , переадресация портов через ssh может быть хорошей альтернативой:

ssh -L 80:localhost:3000 yourusername@localhost -N

Это перенаправляет порт 80 на локальном хосте на порт 3000 на локальном хосте.

Его нужно запускать как root (привилегированный порт). Чтобы отменить его, просто нажмите ctrl-c в терминале. (Вы можете добавить -fфлаг, чтобы команда выполнялась в фоновом режиме, но затем вам нужно будет найти его снова, чтобы убить его).

Это решение требует, чтобы у вас был запущен локальный ssh-сервер . Это можно сделать быстро , но помните о последствиях для безопасности, если вы находитесь в общей сети. Возможно, вы захотите применить хотя бы некоторый уровень дополнительной безопасности (отключить пароль и вход в систему с правами root).

Лично я использую это только на своей локальной машине. Я не уверен, как это повлияет на скорость обработки ваших запросов, если вы запустите это в продакшене, возможно, у кого-то есть идея. В любом случае вам нужно убедиться, что эта команда работает все время, что вызывает больше головной боли. Для производственных сред я предлагаю использовать обратный прокси, например nginx .

панепетер
источник
2

ответ на гексацианид правильный. но есть ли какое-нибудь решение, чтобы заставить эту работу работать?

ответ - да.

как?

вы можете использовать, reverse proxyнапример, запустить nginx reverse proxyпорт on 80и передать прокси в пункт назначения, ip:portкоторый использует этот узел.

вы можете настроить это с помощью, docker containerчто делает жизнь еще проще. это официальная сборка nginx в docker hub, которую вы можете вытащить.

есть еще больше преимуществ в использовании, reverse proxyчто вы можете погуглить.

Ali_Hr
источник
0

У меня такая же ошибка, и я попытался запустить свое приложение с помощью sudo, и у меня это сработало.

без sudo

mansi@mansi:~/NodePractice$ node myFirst.js 
events.js:141
      throw er; // Unhandled 'error' event
      ^

Error: listen EACCES 0.0.0.0:80
    at Object.exports._errnoException (util.js:870:11)
    at exports._exceptionWithHostPort (util.js:893:20)
    at Server._listen2 (net.js:1224:19)
    at listen (net.js:1273:10)
    at Server.listen (net.js:1369:5)
    at Object.<anonymous> (/home/mansi/NodePractice/myFirst.js:6:4)
    at Module._compile (module.js:410:26)
    at Object.Module._extensions..js (module.js:417:10)
    at Module.load (module.js:344:32)
    at Function.Module._load (module.js:301:12)

и с sudo

mansi@mansi:~/NodePractice$ sudo node myFirst.js 
^C
Парт Паччигар
источник
... это именно то, чего вы не хотите делать. Это создает проблемы с безопасностью.
bvdb
-1

Для использования PORT 80 требуются особые разрешения. Использование sudoперед запуском инструкции приложения решило мою проблему. например, если вы используете npm для запуска своего приложения, вы можете ввестиsudo npm start

веб-сканер
источник
1
Этот ответ ничего не добавляет к содержанию ответа, уже предоставленному другими. Пожалуйста, отвечайте, только если вы добавляете дополнительную информацию.
Brian Yeh
-2

Код ошибки EACCESозначает, что у вас нет необходимых разрешений для запуска приложений на этом порту. В системах Linux для любого порта ниже 1024 требуется root-доступ.

Запускаем программу с sudoразрешением. Выполните sudo suкоманду перед запуском программы.

Акшит Ранджан
источник
См. Комментарии к публикации под ответом гексацианидов. Спасибо.
Брайан Йе