Lỗi EACCES của Node.js khi nghe trên hầu hết các cổng


250

Tôi đang thử nghiệm một ứng dụng (hy vọng sẽ chạy trên heroku, nhưng cũng gặp vấn đề cục bộ). Nó gây ra lỗi EACCES cho tôi khi chạy http.Server.listen () - nhưng nó chỉ xảy ra trên một số cổng.

Vì vậy, tại địa phương tôi đang chạy:

joe@joebuntu:~$ node
> var h = require('http').createServer();
> h.listen(900);
Error: EACCES, Permission denied
    at Server._doListen (net.js:1062:5)
    at net.js:1033:14
    at Object.lookup (dns.js:132:45)
    at Server.listen (net.js:1027:20)
    at [object Context]:1:3
    at Interface.<anonymous> (repl.js:150:22)
    at Interface.emit (events.js:42:17)
    at Interface._onLine (readline.js:132:10)
    at Interface._line (readline.js:387:8)
    at Interface._ttyWrite (readline.js:564:14)

Tôi không có bất cứ thứ gì chạy trên cổng 900 (hoặc bất kỳ trong số 20 cổng khác mà tôi đã thử), vì vậy điều này sẽ hoạt động. Phần lạ là nó không làm việc trên một số cổng. Ví dụ, cổng 3000 hoạt động hoàn hảo.

Điều gì sẽ gây ra điều này?

Cập nhật 1:

Tôi đã tìm ra rằng trên máy tính cục bộ của tôi, lỗi EACCES đang đến vì tôi phải chạy nút dưới dạng root để liên kết với các cổng nhất định đó. Tôi không biết tại sao điều này xảy ra, nhưng sử dụng sudo sẽ sửa nó. Tuy nhiên, điều này không giải thích cách tôi sẽ sửa nó trên Heroku. Không có cách nào để chạy bằng root trên Heroku, vậy làm thế nào tôi có thể nghe trên cổng 80?


23
Các cổng ít hơn 1024 theo truyền thống yêu cầu quyền nâng cao. Trên Heroku bạn không nghe cổng 80, bạn lắng nghe cổng mà họ bảo bạn thông qua các biến môi trường và để lớp định tuyến của họ xử lý liên kết cổng 80 ở cạnh.
Mâtt Frëëman

Bản cập nhật của bạn 1 đã giúp tôi. 'sudo nút myporgram.js' đã làm cho nó chạy.
Saber

Câu trả lời:


352

Chạy trên máy trạm của bạn

Theo nguyên tắc chung, các quy trình chạy không có quyền root có thể liên kết với các cổng dưới 1024.

Vì vậy, hãy thử một cổng cao hơn hoặc chạy với các đặc quyền nâng cao thông qua sudo. Bạn có thể hạ cấp đặc quyền sau khi bạn đã ràng buộc với cổng thấp bằng cách sử dụng process.setgidprocess.setuid.

Chạy trên heroku

Khi chạy các ứng dụng của bạn trên heroku, bạn phải sử dụng cổng như được chỉ định trong biến môi trường PORT.

Xem http://devcenter.heroku.com/articles/node-js

const server = require('http').createServer();
const port = process.env.PORT || 3000;

server.listen(port, () => console.log(`Listening on ${port}`));

3
Điều này có nghĩa là tôi phải sử dụng cổng do Heroku cung cấp, và sau đó họ sẽ thực hiện một số phép thuật đằng sau hậu trường để chuyển nó sang cổng 80? Nếu tôi muốn chạy một cái gì đó không phải trên cổng 80 thì sao?
bộ

12
Đúng. Bạn chỉ có thể nghe cổng mà chúng tôi nói với bạn trên $ PORT Chúng tôi đảm nhiệm việc định tuyến 80 hoặc 443 đến cổng của bạn. Cổng thực tế thay đổi tất cả thời gian khi chúng tôi di chuyển dyno của bạn xung quanh. Tại thời điểm này, chúng tôi chỉ hỗ trợ định tuyến công khai từ 80 và 443.
Sẽ

@ Sẽ, bất kỳ cơ hội của hạn chế nâng? Cụ thể, có thể nghe trên các cổng khác ngoài 80 hoặc 443? Đó là một bộ khá hạn chế, tất cả mọi thứ được xem xét.
ghayes

2
Tại sao bạn muốn ứng dụng của mình chạy trên một cổng khác với http và https?
Sẽ

1
@ Tôi muốn lưu trữ một máy chủ trò chơi đơn giản trên Heroku. Unity cần chuyển crossdomain.xmlqua cổng 843.
polkovnikov.ph

178

Người dùng không có đặc quyền (không phải root) không thể mở ổ cắm nghe trên các cổng dưới 1024.


5
Được nâng cấp - đây là một quy tắc chung tốt, nhưng vẫn có ngoại lệ cho điều này, ví dụ: 'khả năng' trên Linux.
mikemaccana

3
Bạn vừa tiết kiệm cho tôi hàng giờ gỡ lỗi. Tôi không biết về điều đó.
Malharhak

6
Mặc dù vậy, tôi không thích điều này, tôi không muốn phải sudochạy một máy chủ tốc hành bằng nút (gulp thực sự). Vì vậy, không có ý nghĩa
blamb

mảnh khôn ngoan này
mauris

4
@blamb Sau đó, sử dụng giải pháp của MeetMehta ; ^)
ruffin

107

Kiểm tra liên kết tham khảo này :

Cấp phép người dùng an toàn để sử dụng cổng 80

Hãy nhớ rằng, chúng tôi KHÔNG muốn chạy các ứng dụng của bạn với tư cách là người dùng root, nhưng có một trở ngại: người dùng an toàn của bạn không có quyền sử dụng cổng HTTP mặc định (80). Mục tiêu của bạn là có thể xuất bản một trang web mà khách truy cập có thể sử dụng bằng cách điều hướng đến một URL dễ sử dụng như http://ip:port/

Thật không may, trừ khi bạn đăng nhập bằng root, thông thường bạn sẽ phải sử dụng một URL như http://ip:port - nơi số cổng> 1024.

Rất nhiều người bị mắc kẹt ở đây, nhưng giải pháp rất dễ dàng. Có một vài lựa chọn nhưng đây là cái tôi thích. Nhập các lệnh sau:

sudo apt-get install libcap2-bin
sudo setcap cap_net_bind_service=+ep `readlink -f \`which node\``

Bây giờ, khi bạn nói với ứng dụng Node rằng bạn muốn nó chạy trên cổng 80, nó sẽ không phàn nàn.


5
Đây chắc chắn là giải pháp tốt nhất.
Mark Lagendijk

1
@MarkLagendijk: Cảm ơn Mark. Tôi cũng đã hỏi nhầm câu hỏi tương tự và đăng câu trả lời chi tiết lên đây stackoverflow.com/questions/23281895/ . Hãy chỉnh sửa nó là tốt.
Gặp Mehta

6
Tại sao đây không phải là câu trả lời
KhaledMohamedP

@KhaledMohamedP: Vui mừng vì nó đã giúp :)
Gặp Mehta

Ai nói điều này vẫn không hoạt động với mô-đun pm2. Giết pm2 của bạn bằng cách sử dụng pm2 killvà tạo lại nó.
Prasanth Jaya

10

Một cách tiếp cận khác là thực hiện chuyển hướng cổng:

sudo iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 900 -j REDIRECT --to-port 3000

Và chạy máy chủ của bạn trên> cổng 1024:

require('http').createServer().listen(3000);

Nhân tiện, điều tương tự cũng có thể được thực hiện đối với cổng https (443).


1
Cảm ơn cảm ơn! Điều này giúp tôi tiết kiệm được một giờ gỡ lỗi cho các cổng an toàn, một giờ nữa để chuyển hướng SSL và cũng cho phép tôi hạn chế khả năng hiển thị của máy chủ phát triển trên AWS Lightstail (không cho phép tinh chỉnh các yêu cầu theo địa chỉ IP).
Miguelmorin

3

Nó có nghĩa là nút không thể nghe trên cổng được xác định. Thay đổi nó thành một cái gì đó như 1234 hoặc 2000 hoặc 3000 và khởi động lại máy chủ của bạn.


3

CHÚA ƠI!! Trong trường hợp của tôi, tôi đã làm ....listen(ip, port)thay vì ...listen(port, ip)và đó là thông báo lỗi:Error: listen EACCES localhost

Tôi đã sử dụng số cổng> = 3000 và thậm chí đã thử với quyền truy cập của quản trị viên. Không có gì làm việc ra. Sau đó, với một relook gần hơn, tôi nhận thấy vấn đề. Thay đổi nó ...listen(port, ip)và mọi thứ bắt đầu hoạt động tốt !!

Chỉ cần gọi nó ra trong trường hợp nếu nó hữu ích cho người khác ...


Cảm ơn bạn! Tôi đã từng gặp vấn đề tương tự. Tôi đã sử dụng tất cả các API khác bằng tên máy chủ, cổng.
David

Tôi gặp vấn đề này khi tôi thử chạy hình ảnh docker Wekan. Tôi đã giải quyết bằng mẹo này. Cảm ơn bạn.
Ângelo Polotto

@ Dilip-muthukurussimana Bạn có ý định ....listen(ip, port)trả lời (với bốn .) không? Phải mất một phút để tôi nhận ra bạn đang nói về thứ tự của các cuộc tranh luận vì điều đó.
bschlueter

Vâng, tôi chỉ có nghĩa là thứ tự của các đối số. Xin đừng đặt ....(bốn dấu chấm) ở đó, mà tôi nghĩ là rõ ràng.
Dilip Muthukurussimana

2

Tôi đã gặp lỗi này trên máy mac của mình vì nó chạy máy chủ apache theo mặc định sử dụng cùng một cổng với máy chủ nút được sử dụng trong trường hợp của tôi là cổng 80. Tất cả những gì tôi phải làm là dừng nó với sudo apachectl stop

Hy vọng điều này sẽ giúp được ai đó.


2

Tôi cũng gặp lỗi này trên máy mac. Tôi sử dụng npm run devđể chạy ứng dụng Nodejs của mình trong Windows và nó hoạt động tốt. Nhưng tôi đã gặp lỗi này trên máy mac của tôi - error given was: Error: bind EACCES null:80.

Một cách để giải quyết điều này là chạy nó với quyền truy cập root. Bạn có thể sử dụng sudo npm run devvà sẽ cần bạn nhập mật khẩu của bạn.

Nói chung, tốt hơn là phục vụ ứng dụng của bạn trên một cổng không có đặc quyền, chẳng hạn như 3000, sẽ hoạt động mà không có quyền root.

tham khảo: Lỗi EACCES của Node.js khi nghe trên cổng http 80 (quyền bị từ chối)


2

Tôi gặp một vấn đề tương tự là nó đã từ chối chạy trên cổng 8080, nhưng cũng có bất kỳ khác.

Hóa ra, đó là vì env.localtập tin nó đọc chứa các bình luận sau các tên biến như:

PORT=8080 # The port the server runs at

Và nó diễn giải nó như thế, cố gắng sử dụng cổng "8080 # The port the server runs at ", rõ ràng là một cổng không hợp lệ (-1). Loại bỏ các ý kiến ​​hoàn toàn giải quyết nó.

Bằng cách sử dụng Windows 10 và Git Bash.


Tôi biết đó không chính xác là vấn đề được mô tả ở đây, nhưng nó có thể giúp đỡ ai đó ngoài kia. Tôi rơi vào câu hỏi này để tìm kiếm vấn đề cho câu trả lời của mình, vì vậy ... có lẽ?


Đúng, tôi đã trải nghiệm điều này. Nhận xét sau các giá trị trong tệp .env có thể gây ra điều này.
Danoz

1

Hãy nhớ nếu bạn sử dụng sudo để liên kết với cổng 80 và đang sử dụng biến env PORT & NODE_ENV, bạn phải xem lại các vars đó vì bạn hiện đang ở trong hồ sơ gốc chứ không phải hồ sơ người dùng của bạn. Vì vậy, để làm việc này trên máy Mac của tôi, tôi đã làm như sau:

sudo su
export NODE_ENV=production
export PORT=80
docpad run

1

điều này xảy ra nếu cổng bạn đang cố lưu trữ cục bộ trên đó được portfowarded


1

Hãy thử xác thực:

http://manpages.ubfox.com/manpages/hardy/man1/authbind.1.html

Sau khi cài đặt, bạn có thể thêm một tệp có tên của số cổng bạn muốn sử dụng trong thư mục sau: / etc / authbind / byport /

Cung cấp cho nó 500 quyền bằng chmod và thay đổi quyền sở hữu cho người dùng bạn muốn chạy chương trình theo.

Sau đó, thực hiện "nút xác thực ..." với tư cách là người dùng đó trong dự án của bạn.


1

Lỗi của tôi đã được giải quyết chỉ bằng cách thay đổi số cổng trong server.js Đặc biệt trong dòng này

const port = process.env.PORT || 8085;

Tôi đã thay đổi số cổng của mình thành 8085 từ 8080.

Hy vọng nó giúp.


0

Sau khi thử nhiều cách khác nhau, cài đặt lại IIS trên windows của tôi đã giải quyết được vấn đề.


0

Lỗi của tôi được giải quyết bằng (Trên Windows)

app.set('PORT', 4000 || process.env.PORT);

app.listen(app.get('PORT'), <IP4 address> , () => {
    console.log("Server is running at " + app.get('PORT'));
});

Cho phép ứng dụng NodeJS truy cập mạng trong Tường lửa Windows.


0

khởi động lại là không đủ! Cách duy nhất để giải quyết vấn đề là bằng cách sau:

Bạn phải giết dịch vụ chạy ở cảng đó.

tại cmd, chạy với tư cách quản trị viên, sau đó nhập: netstat -aon | tìm / tôi "lắng nghe"

sau đó bạn sẽ nhận được một danh sách với dịch vụ đang hoạt động, tìm kiếm cổng đang chạy ở 4200 và sử dụng id quá trình là cột cuối cùng để giết nó

: tác vụ / F / PID 2652

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.