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.