Aplikacja Node.js nie może działać na porcie 80, mimo że żaden inny proces nie blokuje portu

94

Uruchamiam instancję Debiana na Amazon EC2 z zainstalowanym Node.js. Jeśli uruchomię poniższy kod:

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");

Otrzymuję dane wyjściowe poniżej, które mówią mi, że inny proces nasłuchuje na porcie 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)

Teraz, gdy sprawdzam, czy istnieje proces (jako root, jeśli coś jest ukryte) nasłuchujący na porcie 80 przy użyciu:

netstat -tupln

Otrzymuję poniższe wyjście, które mówi mi, że nic nie nasłuchuje na porcie 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

Powinienem zauważyć, że debian ma otwarty port 80 jako regułę przychodzącą, jeśli to robi różnicę.

Moje pytanie brzmi: co robię źle? Dlaczego nie mogę zidentyfikować procesu nasłuchującego na porcie 80? Dlaczego jest blokowany w Debianie? Jakie kroki należy podjąć, aby kod działał poprawnie?

Brian Yeh
źródło

Odpowiedzi:

197

Kod błędu EACCESoznacza, że ​​nie masz odpowiednich uprawnień do uruchamiania aplikacji na tym porcie. W systemach Linux każdy port poniżej 1024 wymaga uprawnień administratora.

heksacyjanek
źródło
5
w ten sposób węzeł sudo myapp.js zrobi to, jeśli masz uprawnienia do używania sudo (po prostu włącz go dla początkujących).
AlexMA
21
@AlexMA, ale prowadzenie serwera jako root to wielkie nie
Patrick Evans
1
Jak więc uruchomić węzeł na porcie 80? Czy powinieneś po prostu ... nie używać serwera proxy?
AlexMA,
9
@PatrickEvans Przypuszczam, że najlepszą praktyką byłoby uruchomienie na innym porcie i po prostu skonfigurowanie reguły przekierowania portów, jak wspomniano tutaj: stackoverflow.com/questions/16573668/ ...
AlexMA
73

Zamiast pracować na porcie 80, możesz przekierować port 80 do portu aplikacji (> 1024) za pomocą

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

To zadziała, jeśli Twoja aplikacja działa na porcie 3000.

Kamrul
źródło
1
zrobił to. Okazało się, że musisz być rootem, aby uruchomić iptables w nowej instalacji Debiana, w przeciwnym razie $ PATH nie wskaże go.
Brian Yeh
Tak, to był prawdopodobnie najłatwiejszy sposób na zrobienie tego. Korzystam z Google Cloud Compute, co spowodowało problemy podczas dotykania portu 80. To było świetne. Dzięki.
Andy
To powinno być przyjęte rozwiązanie. Uruchamianie serwera WWW jako sudo jest niebezpieczne, potencjalnie dając atakującemu dostęp do roota, jeśli istnieje jakakolwiek luka w aplikacji; Ponadto, jeśli aplikacja miałaby tworzyć jakiekolwiek pliki, byłyby niedostępne dla innych użytkowników, co spowodowałoby, że używasz ich sudojeszcze więcej.
jesusiniesta
Nie wiem dlaczego, ale na Ubuntu 14.04 to nie zadziałało. Teraz używam przekierowania portów przez ssh, co jest równie łatwe. Poniżej zamieściłem odpowiedź .
panepeter
19

Krótka odpowiedź: możesz zezwolić węzłowi na dostęp do tego portu za pomocą:

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

długa odpowiedź

Edytować:

Może nie działać w nowych wersjach węzłów

Reut Sharabani
źródło
to załatwiło sprawę. @LinuxMint - sudo setcap 'cap_net_bind_service = + ep' / usr / local / bin / node
Połącz
Czasami aktualizacja zmieni ścieżkę lokalizacji do węzła, co przestanie działać. Musisz więc uruchomić go ponownie dla nowej ścieżki do węzła.
steampowered
Wygląda na to, że to nie będzie działać w przypadku wersji 8 węzła. Github.com/nodejs/node/issues/22648
timaw
6

Zwróć uwagę, że jeśli masz apacheuruchomione, możesz utworzyć odwrotne proxy na serwerze vhost. Jeśli twój węzeł działa na porcie 8080:

<VirtualHost 127.0.0.1:80>
        ServerName myLocalServer

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

Oczywiście dodaj serwer do /etc/hosts:

127.0.0.1    myLocalServer

Będziesz musiał włączyć odpowiednie moduły Apache:

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

... a teraz możesz się połączyć http://myLocalServer.

Redsandro
źródło
3

Dla tych, którzy szukają szybkiego i łatwego rozwiązania dla środowiska programistycznego , przekazywanie portów przez ssh może być dobrą alternatywą:

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

To przekazuje port 80 na hoście lokalnym do portu 3000 na hoście lokalnym.

Musi być uruchomiony jako root (uprzywilejowany port). Aby anulować, po prostu naciśnij ctrl-c w terminalu. (Możesz dodać -fflagę, aby polecenie działało w tle, ale wtedy musisz ją znaleźć ponownie, aby ją zabić).

To rozwiązanie wymaga lokalnego serwera ssh . Można to zrobić szybko , ale pamiętaj o konsekwencjach dla bezpieczeństwa w przypadku korzystania z sieci współdzielonej. Możesz chcieć zastosować przynajmniej pewien poziom dodatkowego bezpieczeństwa (wyłącz hasło i login root).

Osobiście używam tego tylko na moim komputerze lokalnym. Nie jestem pewien, jak to wpływa na szybkość przetwarzania twoich żądań, jeśli uruchomisz to na produkcji, może ktoś ma pomysł. W każdym razie musisz upewnić się, że to polecenie działa przez cały czas, co powoduje więcej bólów głowy. W przypadku środowisk produkcyjnych sugeruję użycie odwrotnego serwera proxy, takiego jak nginx .

panepeter
źródło
2

odpowiedź heksacyjanku jest prawidłowa. ale czy jest jakieś rozwiązanie, które sprawi, że to zadziała?

odpowiedź brzmi tak.

w jaki sposób?

możesz użyć reverse proxyna przykład uruchomić nginx reverse proxyna porcie 80i przekazać proxy do miejsca docelowego, w ip:portktórym węzeł go używa.

możesz to ustawić, używając docker containertego, co jeszcze bardziej ułatwia życie. to jest oficjalna kompilacja nginx w docker hub, którą możesz pobrać.

jest jeszcze więcej korzyści z używania, reverse proxyże możesz go wygooglować.

Ali_Hr
źródło
0

Mam ten sam błąd i próbowałem uruchomić moją aplikację za pomocą sudo i zadziałało.

bez 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)

iz sudo

mansi@mansi:~/NodePractice$ sudo node myFirst.js 
^C
Parth Pachchigar
źródło
... czyli dokładnie to, czego nie chcesz robić. Stwarza problemy bezpieczeństwa.
bvdb
-1

Korzystanie z PORT 80 wymaga pewnych specjalnych uprawnień. Użycie sudoprzed uruchomieniem instrukcji aplikacji rozwiązało mój problem. na przykład, jeśli używasz npm do uruchamiania aplikacji, możesz wpisaćsudo npm start

webcrawler
źródło
1
Ta odpowiedź nie dodaje nic do treści odpowiedzi już dostarczonych przez innych. Odpowiadaj tylko wtedy, gdy dodajesz dodatkowe informacje.
Brian Yeh,
-2

Kod błędu EACCESoznacza, że ​​nie masz odpowiednich uprawnień do uruchamiania aplikacji na tym porcie. W systemach Linux każdy port poniżej 1024 wymaga uprawnień administratora.

Uruchom program z sudouprawnieniami. Uruchom sudo supolecenie przed uruchomieniem programu.

akshith ranjan
źródło
Zobacz komentarze do postu pod odpowiedzią heksacyjanidów. Dzięki.
Brian Yeh,