Câu hỏi Ứ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


Tôi đang chạy một thể hiện của Debian trên Amazon EC2 với Node.js được cài đặt. Nếu tôi chạy mã dưới đây:

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 dưới đây cho tôi biết có một quá trình nghe tại 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 quá trình (như là root trong trường hợp bất cứ điều gì bị ẩn), hãy lắng nghe trên cổng 80 bằng cách sử dụng:

netstat -tupln

Tôi nhận được kết quả dưới đây, cho tôi biết không có gì nghe ở 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ư là một quy tắc gửi đến nếu điều đó tạo nên 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 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 đúng?


86
2017-09-22 18:31


gốc




Các câu trả lời:


Mã lỗi EACCES có 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 các 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.


171
2017-09-22 18:53



do đó, sudo node myapp.js sẽ làm điều đó nếu bạn có quyền sử dụng sudo (chỉ cần tacking nó cho bất kỳ người mới bắt đầu). - AlexMA
@ AlexMA nhưng chạy một máy chủ như là một gốc không lớn không - Patrick Evans
Sau đó, làm thế nào để bạn chạy nút trên cổng 80 mặc dù? Bạn có nên ... không và sử dụng proxy không? - AlexMA
@PatrickEvans Tôi cho rằng thực hành tốt nhất là chạy trên một cổng khác và chỉ thiết lập quy tắc chuyển tiếp cổng như đã đề cập ở đây: stackoverflow.com/questions/16573668/… - AlexMA


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.


56
2017-09-22 22:48



đã làm điều này. Phát hiện ra rằng bạn phải root để chạy iptables trong một cài đặt debian mới, nếu không $ PATH sẽ không trỏ đến nó. - Brian Yeh
Yep đây có lẽ là cách dễ nhất để làm điều đó. Tôi đang sử dụng Google Cloud Compute đã mang lại cho tôi các vấn đề khi chạm vào Cổng 80. Điều này thật tuyệt. Cảm ơn. - Andy
Đây sẽ là giải pháp được chấp nhận. Chạy máy chủ web là sudo nguy hiểm, có khả năng cho phép truy cập root của kẻ tấn công 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 sử dụng sudo nhiều hơn nữa. - jesusiniesta
Không chắc chắn tại sao, nhưng trên Ubuntu 14.04 điều này đã không làm việc cho tôi. Tôi bây giờ sử dụng cổng chuyển tiếp thông qua ssh, mà chỉ là dễ dàng. tôi đã đăng lên một câu trả lời dưới đây. - panepeter


Câu trả lời ngắn gọn: bạn có thể cho phép truy cập nút 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


14
2017-11-24 01:22



đã làm được điều đó. @LinuxMint - sudo setcap 'cap_net_bind_service = + ep' / usr / local / bin / nút - Combine
Bạn sẽ cần phải làm lại điều này sau mỗi lần cập nhật. - Redsandro
Đôi khi bản cập nhật sẽ thay đổi đường dẫn vị trí thành 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 đến nút mới. - steampowered


Lưu ý rằng nếu bạn có apache 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, thêm máy chủ vào /etc/hosts:

127.0.0.1    myLocalServer

Bạn sẽ cần phải 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.


4
2018-05-12 19:50





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

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 phải chạy dưới dạng root (cổng đặc quyền). Để hủy bỏ nó, chỉ cần nhấn ctrl-c trong terminal. (Bạn có thể thêm -f cờ để có lệnh chạy trong nền, nhưng sau đó bạn cần phải tìm lại nó để giết nó).

Giải pháp này yêu cầu bạn phải có một máy chủ ssh chạy cục bộ. Nó có thể được thực hiện một cách nhanh chóng, nhưng xin lưu ý đến 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ố mức độ bảo mật bổ sung (vô hiệu hóa mật khẩu và đăng nhập root).

Cá nhân tôi chỉ sử dụng nó trên máy cục bộ của tôi. Tôi không chắc làm thế nào nó ảnh hưởng đế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ó một ý tưởng. Dù sao, bạn sẽ cần phải chắc chắn rằng lệnh này tiếp tục chạy tất cả các thời gian, trong đó giới thiệu thêm đau đầu. Dành cho môi trường sản xuất, Tôi đề nghị sử dụng proxy ngược như nginx.


1
2018-02-27 09:08





Tôi đã có lỗi tương tự và tôi đã cố gắng chạy ứng dụng của tôi bằng cách sử dụng sudo và nó làm việc cho 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

0
2018-01-14 00:15





Mã lỗi EACCES có 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 các 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 sudopermision. Chạy sudo su lệnh trước khi chạy chương trình.


-2
2018-02-24 12:05



Xem bài bình luận dưới câu trả lời hexacyanides. Cảm ơn. - Brian Yeh