it-swarm.com.ru

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

Я запускаю экземпляр 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? Какие шаги я должен предпринять, чтобы код работал правильно? 

88
Brian Yeh

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

187
hexacyanide

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

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

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

66
Kamrul

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

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

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

17
Reut Sharabani

Обратите внимание, что если у вас запущен Apache, вы можете создать обратный прокси на vhost. Если ваш узел работает на порту 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.

6
Redsandro

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

ssh -L 80:localhost:3000 [email protected] -N

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

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

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

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

2
panepeter

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

без судо 

[email protected]:~/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)

и с судо

[email protected]:~/NodePractice$ Sudo node myFirst.js 
^C
0
Parth Pachchigar