Node.js EACCES ошибка при прослушивании на большинстве портов

250

Я тестирую приложение (надеюсь запустить на heroku, но у меня тоже проблемы локально). Это вызывает ошибку EACCES при запуске http.Server.listen () - но это происходит только на некоторых портах.

Итак, локально я бегу:

joe@joebuntu:~$ node
> var h = require('http').createServer();
> h.listen(900);
Error: EACCES, Permission denied
    at Server._doListen (net.js:1062:5)
    at net.js:1033:14
    at Object.lookup (dns.js:132:45)
    at Server.listen (net.js:1027:20)
    at [object Context]:1:3
    at Interface.<anonymous> (repl.js:150:22)
    at Interface.emit (events.js:42:17)
    at Interface._onLine (readline.js:132:10)
    at Interface._line (readline.js:387:8)
    at Interface._ttyWrite (readline.js:564:14)

У меня ничего не работает на порте 900 (или на любом из 20 других портов, которые я пробовал), так что это должно работать. Странная часть является то , что он делает работу на некоторых портах. Например, порт 3000 работает отлично.

Что вызвало бы это?

Обновление 1:

Я понял, что на моем локальном компьютере появляется ошибка EACCES, потому что мне нужно запустить узел от имени пользователя root, чтобы привязаться к этим определенным портам. Я не знаю, почему это происходит, но использование sudo исправляет это. Тем не менее, это не объясняет, как бы я это исправить на Heroku. На Heroku нет способа работать с правами root, так как я могу прослушивать порт 80?

jwegner
источник
23
Порты менее 1024 традиционно требуют повышенных разрешений. В Heroku вы не слушаете порт 80, вы слушаете порт, о котором они вам говорят, через переменные окружения, и позволяете их уровню маршрутизации обрабатывать привязку порта 80 на границе.
Mâtt Frëëman
Ваше обновление 1 помогло мне. 'sudo node myporgram.js' заставил его работать.
Сэйбер

Ответы:

352

Запуск на вашей рабочей станции

Как правило, процессы, выполняющиеся без привилегий root, не могут привязываться к портам ниже 1024.

Поэтому попробуйте порт более высокого уровня или запустите с повышенными привилегиями через sudo. Вы можете понизить привилегии после привязки к низкому порту, используя process.setgidи process.setuid.

Бег на героку

При запуске ваших приложений на heroku вы должны использовать порт, указанный в переменной окружения PORT.

Смотрите http://devcenter.heroku.com/articles/node-js

const server = require('http').createServer();
const port = process.env.PORT || 3000;

server.listen(port, () => console.log(`Listening on ${port}`));
Бен Табер
источник
3
Означает ли это, что я должен использовать порт, предоставленный Heroku, и тогда они замаскируют магию, чтобы перенести это на порт 80? Что если я хочу запустить что-то не на 80-м порту?
Jwegner
12
Да. Вы можете слушать только тот порт, который мы сообщаем вам на портале $ PORT. Мы позаботимся о маршрутизации 80 или 443 на ваш порт. Фактический порт меняется все время, пока мы перемещаем ваш динамо. На данный момент мы поддерживаем только публичную маршрутизацию от 80 и 443.
Будет
@ Будет ли шанс снятия этого ограничения? В частности, возможность прослушивать порты, отличные от 80 или 443? Это довольно ограничительный набор, учитывая все обстоятельства.
Гэйс
2
Почему вы хотите, чтобы ваше приложение работало с портом, отличным от http и https?
Будет
1
@ Я бы хотел разместить на Heroku простой игровой сервер. Unity нужно передавать crossdomain.xmlчерез 843 порт.
polkovnikov.ph
178

Непривилегированный пользователь (не root) не может открыть прослушивающий сокет на портах ниже 1024.

user1303768
источник
5
Upvoted - это хорошее общее правило, но есть исключения из этого, например, «возможности» в Linux.
mikemaccana
3
Вы только что сэкономили мне часы отладки. Я не знал об этом.
Малхархак
6
Мне не нравится это, хотя, я не хочу иметь sudoпри запуске экспресс-сервера с использованием узла (на самом деле глоток). Так что не имеет смысла
блин
этот кусочек мудрости
Морис
4
@blamb Тогда используйте решение MeetMehta ; ^)
ruffin
108

Проверьте эту ссылку ссылку :

Дайте безопасное пользовательское разрешение на использование порта 80

Помните, мы НЕ хотим запускать ваши приложения от имени пользователя root, но есть загвоздка: ваш безопасный пользователь не имеет разрешения использовать порт HTTP по умолчанию (80). Ваша цель - иметь возможность публиковать веб-сайт, который могут использовать посетители, перейдя по такому простому URL-адресу, как http://ip:port/

К сожалению, если вы не войдете в систему как root, вам обычно придется использовать URL-адрес, например, http://ip:portгде номер порта> 1024.

Многие люди застряли здесь, но решение легко. Там несколько вариантов, но это тот, который мне нравится. Введите следующие команды:

sudo apt-get install libcap2-bin
sudo setcap cap_net_bind_service=+ep `readlink -f \`which node\``

Теперь, когда вы сообщаете приложению Node, что хотите, чтобы оно работало на порту 80, оно не будет жаловаться.

Познакомьтесь с Мехтой
источник
5
Это определенно лучшее решение.
Марк Лагендейк
1
@MarkLagendijk: Спасибо, Марк. Я также задал тот же вопрос по ошибке и разместил подробный ответ здесь stackoverflow.com/questions/23281895/… . Не стесняйтесь редактировать это также.
Познакомьтесь с Мехтой
6
почему это не ответ?
KhaledMohamedP
@KhaledMohamedP: рад, что помог :)
Встречайте Мехту
Кто сказал, что это все еще не работает с модулем pm2. Убейте свой pm2 и используйте pm2 killего заново.
Прасант Джая
10

Другой подход заключается в перенаправлении портов:

sudo iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 900 -j REDIRECT --to-port 3000

И запустите ваш сервер на> 1024 порту:

require('http').createServer().listen(3000);

ps, кстати, то же самое можно сделать для порта https (443).

одиннадцать
источник
1
Спасибо Спасибо! Это сэкономило мне один час отладки для безопасных портов, еще один час для перенаправления SSL, а также позволило ограничить видимость сервера разработки на AWS Lightstail (который не позволяет настраивать запросы по IP-адресу).
Мигельморин
3

Это означает, что узел не может прослушивать определенный порт. Измените его на что-то вроде 1234 или 2000 или 3000 и перезагрузите сервер.

Марк Карвовски
источник
3

О, МОЙ БОГ!! В моем случае я делал ....listen(ip, port)вместо, ...listen(port, ip)и это выдает ошибку msg:Error: listen EACCES localhost

Я использовал номера портов> = 3000 и даже пытался с правами администратора. Ничего не получилось. Затем, при ближайшем рассмотрении, я заметил проблему. Изменил это на...listen(port, ip) все и все заработало нормально !!

Просто вызывать это в случае, если это полезно для кого-то еще ...

Дилип Мутхукуруссимана
источник
Спасибо! У меня такая же проблема. Я привык ко всем другим API, используя имя хоста, порт.
Дэвид
У меня была эта проблема, когда я пытался запустить образ докера Wekan. Я решил использовать этот совет. Спасибо.
Анджело Полотто
@ dilip-muthukurussimana Вы намеревались иметь ....listen(ip, port)в своем ответе (с четырьмя .)? Мне потребовалась минута, чтобы понять, что из-за этого вы говорили о порядке аргументов.
bschlueter
Да, я имел в виду только порядок аргументов. Просьба не помещать ....(четыре точки) там, что я думал, было очевидно.
Дилип Мутхукуруссимана
2

Я получил эту ошибку на моем Mac, потому что он по умолчанию запускал сервер apache, используя тот же порт, который использовался сервером узлов, в моем случае это был порт 80. Все, что мне нужно было сделать, это остановить его sudo apachectl stop

Надеюсь, это кому-нибудь поможет.

mabounassif
источник
2

Я тоже получил эту ошибку на своем Mac. Я использую npm run devдля запуска моего приложения Nodejs в Windows, и он работает нормально. Но я получил эту ошибку на моем Mac - error given was: Error: bind EACCES null:80.

Один из способов решить эту проблему - запустить его с правами root. Вы можете использовать sudo npm run devи вам нужно будет ввести свой пароль.

Как правило, предпочтительнее обслуживать ваше приложение через непривилегированный порт, например 3000, который будет работать без прав root.

ссылка: Node.js EACCES ошибка при прослушивании через порт http 80 (разрешение отклонено)

ZILONG PAN
источник
2

У меня была похожая проблема, что он отказывался работать на порте 8080, но также любой другой.

Оказывается, это потому, что env.localфайл, который он читал, содержал комментарии после имен переменных вроде:

PORT=8080 # The port the server runs at

И он интерпретировал это так, пытаясь использовать порт "8080 # The port the server runs at ", который, очевидно, является недопустимым портом (-1). Удаление комментариев полностью решило проблему.

Кстати, используя Windows 10 и Git Bash.


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

Fusseldieb
источник
Да, я испытал это. Комментарии после значений в .env файлах могут быть причиной этого.
Даноз
1

Помните, что если вы используете sudo для привязки к порту 80 и используете переменные env PORT & NODE_ENV, вы должны повторно экспортировать эти переменные, так как вы сейчас находитесь в корневом профиле, а не в своем профиле пользователя. Итак, чтобы заставить это работать на моем Mac, я сделал следующее:

sudo su
export NODE_ENV=production
export PORT=80
docpad run
Шон
источник
1

это происходит, если порт, на котором вы пытаетесь разместить локально, настроен на порт

Джаспер Смит
источник
1

Попробуйте authbind:

http://manpages.ubuntu.com/manpages/hardy/man1/authbind.1.html

После установки вы можете добавить файл с именем номера порта, который вы хотите использовать, в следующую папку: / etc / authbind / byport /

Дайте ему 500 разрешений с помощью chmod и измените владельца на пользователя, под которым вы хотите запустить программу.

После этого выполните «authbind node ...» в качестве этого пользователя в вашем проекте.

DraughtGlobe
источник
1

Моя ошибка была исправлена ​​путем изменения номера порта в server.js, особенно в этой строке

const port = process.env.PORT || 8085;

Я изменил свой номер порта на 8085 с 8080.

Надеюсь, поможет.

Алок Ранджан
источник
0

Попробовав много разных способов, переустановка IIS на мои окна решила проблему.

CageE
источник
0

Моя ошибка устранена с помощью (В Windows)

app.set('PORT', 4000 || process.env.PORT);

app.listen(app.get('PORT'), <IP4 address> , () => {
    console.log("Server is running at " + app.get('PORT'));
});

Разрешить приложению NodeJS доступ к сети в брандмауэре Windows.

Prathamesh Подробнее
источник
0

перезагрузки не хватило! Единственный способ решить эту проблему заключается в следующем:

Вы должны убить службу, которая работает в этом порту.

в cmd, запустите от имени администратора, затем введите: netstat -aon | найти / я "слушаю"

затем вы получите список с активной службой, найдите порт, работающий на 4200, и используйте идентификатор процесса, который является последним столбцом для его уничтожения

: taskkill / F / PID 2652

Krebto
источник