Node.js 앱은 포트를 차단하는 다른 프로세스가 없더라도 포트 80에서 실행할 수 없습니다.


94

Node.js가 설치된 Amazon EC2에서 Debian 인스턴스를 실행하고 있습니다. 아래 코드를 실행하면 :

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)

이제 다음을 사용하여 포트 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

데비안은 차이가 나는 경우 인바운드 규칙으로 포트 80이 열려 있다는 점에 유의해야합니다.

내 질문은 : 내가 뭘 잘못하고 있니? 포트 80을 수신하는 프로세스를 식별 할 수없는 이유는 무엇입니까? 데비안에서 차단 된 이유는 무엇입니까? 코드를 올바르게 실행하려면 어떤 단계를 수행해야합니까?

답변:


197

오류 코드 EACCES는 해당 포트에서 애플리케이션을 실행할 수있는 적절한 권한이 없음을 의미합니다. Linux 시스템에서 1024 미만의 모든 포트에는 루트 액세스가 필요합니다.


5
따라서 sudo 노드 myapp.js는 sudo를 사용할 수있는 권한이 있으면이를 수행합니다 (초보자에게만 적용).
AlexMA

21
@AlexMA하지만 루트로 서버를 실행하는 것은 더없이 큰입니다
릭 에반스

1
그렇다면 포트 80에서 노드를 어떻게 실행합니까? 그저 ... 아니고 프록시를 사용해야합니까?
AlexMA 2010 년

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를 실행하려면 루트 여야합니다. 그렇지 않으면 $ PATH가 해당 위치를 가리 키지 않습니다.
브라이언 예치

네 이것은 아마도 가장 쉬운 방법 일 것입니다. 저는 포트 80을 만질 때 문제를 일으킨 Google Cloud Compute를 사용하고 있습니다. 정말 좋았습니다. 감사.
Andy

이것이 허용되는 솔루션이어야합니다. 웹 서버를 sudo로 실행하는 것은 위험하며 애플리케이션에 취약점이있는 경우 공격자에게 루트 액세스 권한을 부여 할 수 있습니다. 또한 응용 프로그램이 파일을 만드는 경우 다른 사용자가 파일에 액세스 할 수 없으므로 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

관련 아파치 모듈을 활성화해야합니다.

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

... 이제에 연결할 수 있습니다 http://myLocalServer.


3

개발 환경을 위한 빠르고 쉬운 솔루션을 찾는 사람들에게는 ssh를 통한 포트 포워딩이 좋은 대안이 될 수 있습니다.

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

이것은 localhost의 포트 80을 localhost의 포트 3000으로 전달합니다.

루트 (특권 포트) 로 실행 해야합니다 . 취소하려면 터미널에서 Ctrl-c를 누르십시오. ( -f백그라운드에서 명령을 실행하기 위해 플래그를 추가 할 수 있지만, 종료하려면 다시 찾아야합니다).

이 솔루션을 사용하려면 로컬에서 실행 되는 ssh 서버 가 있어야합니다 . 신속하게 수행 할 수 있지만 공유 네트워크에있는 경우 보안 의미를 염두에 두십시오. 최소한 일정 수준의 추가 보안을 적용 할 수 있습니다 (비밀번호 및 루트 로그인 비활성화).

나는 개인적으로 이것을 내 로컬 컴퓨터에서만 사용합니다. 프로덕션에서 실행하면 요청의 처리 속도에 어떤 영향을 미치는지 잘 모르겠습니다. 누군가 아이디어가있을 수 있습니다. 어쨌든이 명령이 항상 실행되도록해야하므로 더 많은 골칫거리가 발생합니다. 들어 생산 환경 , 내가 사용하는 것이 좋습니다 의 nginx 같은 역방향 프록시를 .


2

헥사 시안화물 대답이 맞습니다. 그러나 이것을 작동시키는 해결책이 있습니까?

대답은 '예'입니다.

어떻게?

당신은 사용할 수 있습니다 reverse proxy예를 들어 실행 a를 nginx reverse proxy포트 80및 대상에 프록시를 통과 ip:port노드의 사용을.

당신 docker container은 삶을 더 쉽게 만드는 사용하여 이것을 설정할 수 있습니다 . 이것은 당신이 그것을 가져올 수있는 도커 허브 에있는 nginx공식 빌드입니다 .

reverse proxyGoogle 을 사용 하면 더 많은 이점 이 있습니다.


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 미만의 모든 포트에는 루트 액세스가 필요합니다.

sudo권한으로 프로그램을 실행하십시오 . 실행 sudo su프로그램을 실행하기 전에 명령을.


hexacyanides 답변 아래의 게시물 댓글을 참조하십시오. 감사.
Brian Yeh
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.