Приложение 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? Какие шаги следует предпринять для правильной работы кода?

Ответ 1

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

Ответ 2

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

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

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

Ответ 4

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

Ответ 5

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

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

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

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

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

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

Ответ 6

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

Ответ 7

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

Ответ 8

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

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