Ứng dụng Node.js không thể chạy trên cổng 80 mặc dù không có quá trình nào khác chặn cổng


94

Tôi đang chạy một phiên bản Debian trên Amazon EC2 có cài đặt Node.js. Nếu tôi chạy mã bên dưới:

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

Tôi nhận được đầu ra bên dưới cho tôi biết có một quá trình khác đang nghe ở cổng 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)

Bây giờ khi tôi kiểm tra xem liệu có một tiến trình nào (như root trong trường hợp bất kỳ thứ gì bị ẩn) đang nghe trên cổng 80 hay không bằng cách sử dụng:

netstat -tupln

Tôi nhận được đầu ra bên dưới, cho tôi biết không có gì nghe thấy ở cổng 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

Tôi nên lưu ý rằng debian có cổng 80 mở như một quy tắc gửi đến nếu điều đó tạo ra sự khác biệt.

Câu hỏi của tôi là: Tôi đang làm gì sai? Tại sao tôi không thể xác định quá trình lắng nghe cổng 80? Tại sao nó bị chặn trong Debian? Tôi nên thực hiện các bước nào để mã chạy chính xác?

Câu trả lời:


197

Mã lỗi EACCEScó nghĩa là bạn không có quyền thích hợp để chạy các ứng dụng trên cổng đó. Trên hệ thống Linux, bất kỳ cổng nào dưới 1024 đều yêu cầu quyền truy cập root.


5
do đó, nút sudo myapp.js sẽ làm điều đó nếu bạn có quyền sử dụng sudo (chỉ bổ sung cho bất kỳ người mới bắt đầu nào).
AlexMA

20
@AlexMA nhưng chạy một máy chủ như là người chủ là một lớn không không
Patrick Evans

1
Sau đó, làm thế nào để bạn chạy nút trên cổng 80? Bạn có nên ... không và sử dụng proxy?
AlexMA

9
@PatrickEvans Tôi cho rằng việc thực hành tốt nhất là để chạy trên một cổng khác nhau và chỉ cần thiết lập một quy tắc port-forwarding như đã đề cập ở đây: stackoverflow.com/questions/16573668/...
AlexMA

73

Thay vì chạy trên cổng 80, bạn có thể chuyển hướng cổng 80 đến cổng của ứng dụng (> 1024) bằng cách sử dụng

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

Điều này sẽ hoạt động nếu ứng dụng của bạn đang chạy trên cổng 3000.


1
đã làm điều này. Phát hiện ra rằng bạn phải root để chạy iptables trong một bản cài đặt debian mới, nếu không $ PATH sẽ không trỏ đến nó.
Brian Yeh

Đúng, đây có lẽ là cách dễ nhất để làm điều đó. Tôi đang sử dụng Google Cloud Compute. Tôi gặp sự cố khi chạm vào Cổng 80. Điều này thật tuyệt. Cảm ơn.
Andy

Đây phải là giải pháp được chấp nhận. Chạy máy chủ web như sudo rất nguy hiểm, có khả năng cấp cho kẻ tấn công quyền truy cập root nếu có bất kỳ lỗ hổng nào trong ứng dụng; ngoài ra, nếu ứng dụng tạo bất kỳ tệp nào, chúng sẽ không thể truy cập được đối với những người dùng khác, khiến bạn sudothậm chí phải sử dụng nhiều hơn.
jesusiniesta

Không chắc tại sao, nhưng trên Ubuntu 14.04, điều này không hoạt động với tôi. Bây giờ tôi sử dụng chuyển tiếp cổng qua ssh, điều này thật dễ dàng. Tôi đã đăng một câu trả lời bên dưới .
panepeter

19

Câu trả lời ngắn gọn: Bạn có thể cho phép nút truy cập vào cổng đó bằng cách sử dụng:

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

câu trả lời dài

Biên tập:

Có thể không hoạt động trên các phiên bản nút mới


đó đã thực hiện thủ thuật. @LinuxMint - sudo setcap 'cap_net_bind_service = + ep' / usr / local / bin / node
Kết hợp

Đôi khi bản cập nhật sẽ thay đổi đường dẫn vị trí đến nút và điều này sẽ ngừng hoạt động. Vì vậy, bạn sẽ cần phải chạy lại nó cho đường dẫn mới đến nút.
steampowered

Có vẻ như tính năng này sẽ không còn hoạt động trước phiên bản nút 8. github.com/nodejs/node/issues/22648
timaw,

6

Lưu ý rằng nếu bạn apacheđang chạy, bạn có thể tạo proxy ngược trên vhost. Nếu nút của bạn đang chạy trên cổng 8080:

<VirtualHost 127.0.0.1:80>
        ServerName myLocalServer

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

Tất nhiên, hãy thêm máy chủ vào /etc/hosts:

127.0.0.1    myLocalServer

Bạn sẽ cần kích hoạt các mô-đun apache có liên quan:

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

... và bây giờ bạn có thể kết nối với http://myLocalServer.


3

Đối với những người đang tìm kiếm giải pháp nhanh chóng và dễ dàng cho môi trường phát triển , chuyển tiếp cổng qua ssh có thể là một lựa chọn thay thế tốt:

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

Điều này chuyển tiếp cổng 80 trên localhost đến cổng 3000 trên localhost.

Nó cần được chạy dưới dạng root (cổng đặc quyền). Để hủy nó, chỉ cần nhấn ctrl-c trong terminal. (Bạn có thể thêm -fcờ để lệnh chạy ẩn, nhưng sau đó bạn cần tìm lại để giết nó).

Giải pháp này yêu cầu bạn có một máy chủ ssh chạy cục bộ . Việc này có thể được thực hiện nhanh chóng , nhưng hãy lưu ý các tác động bảo mật nếu bạn đang sử dụng mạng chia sẻ. Bạn có thể muốn áp dụng ít nhất một số cấp độ bảo mật bổ sung (tắt mật khẩu và đăng nhập gốc).

Cá nhân tôi chỉ sử dụng cái này trên máy cục bộ của mình. Tôi không chắc nó ảnh hưởng như thế nào đến tốc độ xử lý các yêu cầu của bạn nếu bạn chạy điều này trên sản xuất, có thể ai đó có ý tưởng. Dù sao đi nữa, bạn cần phải đảm bảo rằng lệnh này luôn chạy mọi lúc, điều này sẽ khiến bạn đau đầu hơn. Đối với môi trường sản xuất , tôi khuyên bạn nên sử dụng proxy ngược như nginx .


2

câu trả lời hexacyanide là đúng. nhưng có giải pháp nào để làm cho việc này hoạt động không?

câu trả lời là có.

làm sao?

bạn có thể sử dụng một reverse proxyví dụ như chạy một nginx reverse proxycổng 80và chuyển proxy đến đích ip:portmà nút sử dụng nó.

bạn có thể thiết lập điều này bằng cách sử dụng docker containerđể làm cho cuộc sống dễ dàng hơn. đây là bản dựng chính thức của nginx trong trung tâm docker mà bạn có thể kéo nó.

thậm chí có nhiều lợi ích hơn trong việc sử dụng reverse proxymà bạn có thể google nó.


0

Tôi đã gặp lỗi tương tự và tôi đã thử chạy ứng dụng của mình bằng sudo và nó đã hoạt động với tôi.

không có 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)

và với sudo

mansi@mansi:~/NodePractice$ sudo node myFirst.js 
^C

... đó chính xác là những gì bạn không muốn làm. Nó tạo ra các vấn đề bảo mật.
bvdb

-1

Sử dụng PORT 80 yêu cầu một số quyền đặc biệt. Sử dụng sudocâu lệnh trước khi chạy của ứng dụng đã giải quyết được vấn đề của tôi. ví dụ: nếu bạn đang sử dụng npm để chạy ứng dụng của mình, bạn có thể nhậpsudo npm start


1
Câu trả lời này không thêm gì để trả lời nội dung đã được cung cấp bởi những người khác. Vui lòng chỉ trả lời nếu bạn đang thêm thông tin bổ sung.
Brian Yeh

-2

Mã lỗi EACCEScó nghĩa là bạn không có quyền thích hợp để chạy các ứng dụng trên cổng đó. Trên hệ thống Linux, bất kỳ cổng nào dưới 1024 đều yêu cầu quyền truy cập root.

Chạy chương trình với sudohoán vị. Chạy sudo sulệnh trước khi chạy chương trình.


Xem các bình luận bài viết dưới câu trả lời hexacyanides. Cảm ơn.
Brian Yeh
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.