ข้อผิดพลาด Node.js EACCES เมื่อฟังบนพอร์ตส่วนใหญ่


250

ฉันกำลังทดสอบแอพ (หวังว่าจะทำงานกับ heroku แต่มีปัญหาในพื้นที่เช่นกัน) มันทำให้ฉันมีข้อผิดพลาด EACCES เมื่อมันทำงาน http.Server.listen () - แต่มันเกิดขึ้นในบางพอร์ตเท่านั้น

ดังนั้นภายในฉันกำลังทำงาน:

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)

ฉันไม่มีอะไรทำงานบนพอร์ต 900 (หรือพอร์ตอื่น ๆ อีก 20 พอร์ตที่ฉันได้ลอง) ดังนั้นจึงควรใช้งานได้ ส่วนที่แปลกก็คือว่ามันไม่ทำงานในบางพอร์ต ตัวอย่างเช่นพอร์ต 3000 ทำงานได้อย่างสมบูรณ์

อะไรจะทำให้เกิดสิ่งนี้

อัปเดต 1:

ฉันพบว่าในเครื่องคอมพิวเตอร์ของฉันข้อผิดพลาด EACCES กำลังมาเพราะฉันต้องเรียกใช้โหนดเป็นรูทเพื่อผูกเข้ากับพอร์ตเหล่านั้น ฉันไม่รู้ว่าทำไมสิ่งนี้ถึงเกิดขึ้น แต่การใช้ sudo แก้ไขมัน อย่างไรก็ตามนี่ไม่ได้อธิบายว่าฉันจะแก้ไขได้อย่างไรใน Heroku ไม่มีทางที่จะรูทเป็น Heroku ได้ฉันจะฟังพอร์ต 80 ได้อย่างไร


23
ตามปกติแล้วพอร์ตที่น้อยกว่า 1024 พอร์ตจำเป็นต้องได้รับการยกระดับ ใน Heroku คุณไม่ฟังพอร์ต 80 คุณฟังพอร์ตที่พวกเขาบอกคุณผ่านตัวแปรสภาพแวดล้อมและให้เลเยอร์การจัดเส้นทางของพวกเขาจัดการพอร์ต 80 ที่จับที่ขอบ
MâttFrëëman

อัปเดตของคุณ 1 ช่วยฉันด้วย 'sudo node myporgram.js' ทำให้มันทำงาน
เซเบอร์

คำตอบ:


352

ทำงานบนเวิร์กสเตชันของคุณ

ตามกฎทั่วไปกระบวนการที่ทำงานโดยไม่มีสิทธิ์รูทไม่สามารถผูกกับพอร์ตที่ต่ำกว่า 1024

sudoดังนั้นลองใช้พอร์ตที่สูงขึ้นหรือเรียกใช้ที่มีสิทธิ์สูงผ่าน คุณสามารถปรับลดสิทธิพิเศษหลังจากที่คุณได้ผูกไว้กับพอร์ตต่ำโดยใช้และprocess.setgidprocess.setuid

วิ่งบน heroku

เมื่อเรียกใช้แอพของคุณบน heroku คุณจะต้องใช้พอร์ตตามที่ระบุไว้ในตัวแปรสภาพแวดล้อม PORT

ดู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
นี่หมายความว่าฉันต้องใช้พอร์ตที่ Heroku จัดไว้ให้แล้วพวกเขาจะใช้เวทย์มนตร์เบื้องหลังเพื่อถ่ายโอนพอร์ตนั้นไปยังพอร์ต 80 หรือไม่? ถ้าฉันต้องการเรียกใช้บางสิ่งที่ไม่ได้อยู่ในพอร์ต 80
jwegner

12
ใช่. คุณสามารถฟังพอร์ตที่เราบอกคุณได้ใน $ PORT เราดูแลการกำหนดเส้นทาง 80 หรือ 443 ไปยังพอร์ตของคุณ พอร์ตที่แท้จริงเปลี่ยนแปลงตลอดเวลาเมื่อเราย้าย dyno ของคุณไปรอบ ๆ ณ เวลานี้เราสนับสนุนเฉพาะเส้นทางสาธารณะจาก 80 และ 443
จะ

@ จะมีโอกาสเกิดข้อ จำกัด อีกไหม? โดยเฉพาะความสามารถในการฟังบนพอร์ตอื่นที่ไม่ใช่ 80 หรือ 443? นั่นเป็นฉากที่ค่อนข้างเข้มงวดทุกสิ่งถูกพิจารณา
ghayes

2
ทำไมคุณต้องการให้แอปของคุณทำงานบนพอร์ตที่แตกต่างจาก http และ https
จะ

1
@ Will ฉันต้องการโฮสต์เซิร์ฟเวอร์เกมอย่างง่ายใน Heroku Unity ต้องถ่ายโอนcrossdomain.xmlผ่านพอร์ต 843
polkovnikov.ph

178

ผู้ใช้ที่ไม่ได้รับสิทธิพิเศษ (ไม่ใช่รูท) ไม่สามารถเปิดซ็อกเก็ตฟังในพอร์ตที่ต่ำกว่า 1024


5
Upvoted - นี่เป็นกฎทั่วไปที่ดี แต่มีข้อยกเว้นนี้เช่น 'ความสามารถ' บน Linux
mikemaccana

3
คุณเพิ่งบันทึกชั่วโมงการดีบัก ฉันไม่รู้เกี่ยวกับสิ่งนั้น
Malharhak

6
ฉันไม่ชอบสิ่งนี้ แต่ฉันไม่ต้องการsudoเมื่อใช้เซิร์ฟเวอร์ด่วนโดยใช้โหนด (อึกจริง ๆ ) ดังนั้นไม่มีเหตุผล
blamb

ภูมิปัญญาชิ้นนี้
อริส

4
@blamb จากนั้นใช้วิธีแก้ปัญหาของ MeetMehta ; ^)
ruffin

108

ตรวจสอบลิงค์อ้างอิงนี้:

ให้สิทธิ์ผู้ใช้อย่างปลอดภัยในการใช้พอร์ต 80

จำไว้ว่าเราไม่ต้องการเรียกใช้แอปพลิเคชันของคุณในฐานะผู้ใช้รูท แต่มีข้อผูกมัด: ผู้ใช้ที่ปลอดภัยของคุณไม่ได้รับอนุญาตให้ใช้พอร์ต HTTP เริ่มต้น (80) เป้าหมายของคุณคือการเผยแพร่เว็บไซต์ที่ผู้เยี่ยมชมสามารถใช้โดยไปที่ URL ที่ใช้งานง่ายเช่น http://ip:port/

น่าเสียดายถ้าคุณลงชื่อเข้าใช้ในฐานะรูทปกติคุณจะต้องใช้ URL เช่นhttp://ip:port- โดยที่หมายเลขพอร์ต> 1024

ผู้คนจำนวนมากติดอยู่ที่นี่ แต่วิธีแก้ปัญหานั้นง่าย มีตัวเลือกน้อย แต่นี่คือสิ่งที่ฉันชอบ พิมพ์คำสั่งต่อไปนี้:

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

ตอนนี้เมื่อคุณบอกแอปพลิเคชั่น Node ว่าคุณต้องการให้มันรันบนพอร์ต 80 มันจะไม่บ่น


5
นี่เป็นทางออกที่ดีที่สุดอย่างแน่นอน
Mark Lagendijk

1
@ MarkLagendijk: ขอบคุณมาร์ค ฉันยังถามคำถามเดียวกันเข้าใจผิดและโพสต์คำตอบรายละเอียดมากกว่าที่นี่stackoverflow.com/questions/23281895/... รู้สึกอิสระที่จะแก้ไขมันเช่นกัน
พบกับเมห์

6
ทำไมนี่ไม่ใช่คำตอบ👍
KhaledMohamedP

@KhaledMohamedP: ดีใจที่ได้ช่วย :)
พบ Mehta

ใครบอกว่าสิ่งนี้ยังใช้ไม่ได้กับโมดูล pm2 ฆ่า pm2 ของคุณโดยใช้pm2 killและสร้างใหม่
Prasanth Jaya

10

อีกวิธีคือทำการเปลี่ยนเส้นทางพอร์ต:

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

และเรียกใช้เซิร์ฟเวอร์ของคุณบน> 1024 พอร์ต:

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

ps เดียวกันสามารถทำได้สำหรับพอร์ต https (443) โดยวิธี


1
ขอบคุณ! สิ่งนี้ช่วยฉันในการดีบักหนึ่งชั่วโมงสำหรับพอร์ตที่ปลอดภัยอีกหนึ่งชั่วโมงสำหรับการเปลี่ยนเส้นทาง SSL และอนุญาตให้ฉัน จำกัด การมองเห็นเซิร์ฟเวอร์การพัฒนาบน AWS Lightstail (ซึ่งไม่อนุญาตการปรับแต่งคำขอตามที่อยู่ IP)
miguelmorin

3

หมายความว่าโหนดไม่สามารถฟังพอร์ตที่กำหนด เปลี่ยนเป็นอย่างเช่น 1234 หรือ 2000 หรือ 3000 แล้วรีสตาร์ทเซิร์ฟเวอร์ของคุณ


3

พระเจ้าช่วย!! ในกรณีของฉันฉันกำลังทำ....listen(ip, port)แทน...listen(port, ip)และนั่นก็ทำให้เกิดข้อผิดพลาด msg:Error: listen EACCES localhost

ฉันใช้หมายเลขพอร์ต> = 3000 และลองใช้กับการเข้าถึงของผู้ดูแลระบบ ไม่มีอะไรทำงานออกมา จากนั้นเมื่อลองใหม่อีกครั้งฉันก็พบปัญหา เปลี่ยนเป็น...listen(port, ip)ทุกอย่างเริ่มทำงานได้ดี !!

เพียงแค่เรียกสิ่งนี้ในกรณีที่เป็นประโยชน์กับคนอื่น ...


ขอบคุณ! ผมมีปัญหาเหมือนกัน. ฉันคุ้นเคยกับ API อื่น ๆ ทั้งหมดโดยใช้ชื่อโฮสต์พอร์ต
เดวิด

ฉันมีปัญหานี้เมื่อฉันพยายามเรียกใช้อิมเมจ Wekan Docker ฉันแก้ไขโดยใช้เคล็ดลับนี้ ขอบคุณ.
Ângelo Polotto

@ dilip-muthukurussimana คุณตั้งใจที่จะมี....listen(ip, port)คำตอบของคุณ (สี่.)? ฉันใช้เวลาสักครู่เพื่อตระหนักว่าคุณกำลังพูดถึงลำดับของข้อโต้แย้งเพราะเรื่องนั้น
bschlueter

ใช่ฉันหมายถึงเฉพาะลำดับของการโต้แย้ง กรุณาอย่าใส่....(สี่จุด) ที่นั่นซึ่งฉันคิดว่าชัดเจน
Dilip Muthukurussimana

2

ฉันได้รับข้อผิดพลาดนี้บน mac ของฉันเพราะมันรันเซิร์ฟเวอร์ apache โดยค่าเริ่มต้นโดยใช้พอร์ตเดียวกับที่ใช้โดยเซิร์ฟเวอร์โหนดซึ่งในกรณีของฉันคือพอร์ต 80 สิ่งที่ฉันต้องทำคือหยุดด้วย sudo apachectl stop

หวังว่านี่จะช่วยใครซักคน


2

ฉันได้รับข้อผิดพลาดนี้บน mac ของฉันด้วย ฉันใช้npm run devเพื่อเรียกใช้แอพ Nodejs ใน Windows และใช้งานได้ดี แต่ผมมีข้อผิดพลาดนี้บน mac ของฉัน error given was: Error: bind EACCES null:80-

วิธีหนึ่งในการแก้ไขปัญหานี้คือเรียกใช้ด้วยการเข้าถึงรูท คุณอาจใช้sudo npm run devและจะต้องให้คุณใส่รหัสผ่านของคุณ

โดยทั่วไปแล้วจะดีกว่าที่จะให้บริการแอปพลิเคชันของคุณบนพอร์ตที่ไม่มีสิทธิพิเศษเช่น 3000 ซึ่งจะทำงานโดยไม่มีสิทธิ์รูท

การอ้างอิง: ข้อผิดพลาด Node.js EACCES เมื่อฟังพอร์ต http 80 (ปฏิเสธสิทธิ์)


2

ฉันมีปัญหาที่คล้ายคลึงกันซึ่งปฏิเสธที่จะทำงานบนพอร์ต 8080 แต่ก็มีปัญหาอื่นเช่นกัน

ปรากฎว่าเป็นเพราะenv.localไฟล์ที่อ่านมีความคิดเห็นหลังจากชื่อตัวแปรเช่น:

PORT=8080 # The port the server runs at

และมันตีความเช่นนั้นพยายามใช้พอร์ต " 8080 # The port the server runs at" ซึ่งเห็นได้ชัดว่าเป็นพอร์ตที่ไม่ถูกต้อง (-1) การลบความคิดเห็นทั้งหมดได้แก้ไขแล้ว

ใช้ Windows 10 และ Git Bash โดยวิธีการ


ฉันรู้ว่ามันไม่ได้ว่าปัญหาที่อธิบายไว้ที่นี่ แต่มันอาจจะช่วยให้คนที่ออกมี ฉันลงจอดที่คำถามนี้เพื่อค้นหาปัญหาสำหรับคำตอบของฉันดังนั้น ... อาจจะ?


ใช่ฉันมีประสบการณ์นี้ ความคิดเห็นหลังจากค่าในไฟล์. env อาจทำให้เกิดสิ่งนี้
Danoz

1

จำไว้ว่าถ้าคุณใช้ sudo เพื่อผูกกับพอร์ต 80 และใช้ตัวแปร env PORT & NODE_ENV คุณต้องส่งออก vars เหล่านั้นอีกครั้งเนื่องจากคุณอยู่ภายใต้โปรไฟล์ผู้ใช้รากและไม่ใช่โปรไฟล์ผู้ใช้ของคุณ ดังนั้นเพื่อให้มันทำงานบน Mac ของฉันฉันทำต่อไปนี้:

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


1

ลองตรวจสอบอัตโนมัติ:

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

หลังจากติดตั้งคุณสามารถเพิ่มไฟล์ที่มีชื่อหมายเลขพอร์ตที่คุณต้องการใช้ในโฟลเดอร์ต่อไปนี้: / etc / authbind / byport /

ให้สิทธิ์ 500 ครั้งโดยใช้ chmod และเปลี่ยนความเป็นเจ้าของให้กับผู้ใช้ที่คุณต้องการเรียกใช้โปรแกรมภายใต้

หลังจากนั้นทำ "authbind node ... " เป็นผู้ใช้ในโครงการของคุณ


1

ข้อผิดพลาดของฉันได้รับการแก้ไขเพียงแค่เปลี่ยนหมายเลขพอร์ตใน server.js พิเศษในบรรทัดนี้

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

ฉันเปลี่ยนหมายเลขพอร์ตของฉันเป็น 8085 จาก 8080

หวังว่ามันจะช่วย


0

หลังจากลองวิธีการต่าง ๆ มากมายการติดตั้ง IIS บน windows ของฉันอีกครั้งช่วยแก้ปัญหาได้


0

ข้อผิดพลาดของฉันได้รับการแก้ไขโดยใช้ (บน Windows)

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

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

อนุญาตให้แอป NodeJS เข้าถึงเครือข่ายในไฟร์วอลล์ Windows


0

รีสตาร์ทไม่พอ! วิธีเดียวที่จะแก้ไขปัญหาได้ดังต่อไปนี้:

คุณต้องฆ่าบริการที่ทำงานที่พอร์ตนั้น

ที่ cmd ให้รันในฐานะผู้ดูแลระบบจากนั้นพิมพ์: netstat -aon | ค้นหา / ฉัน "ฟัง"

จากนั้นคุณจะได้รับรายการที่มีบริการที่ใช้งานค้นหาพอร์ตที่ทำงานที่ 4200 และใช้รหัสกระบวนการซึ่งเป็นคอลัมน์สุดท้ายที่จะฆ่ามันโดย

: taskkill / F / PID 2652

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.