แนวทางปฏิบัติที่ดีที่สุดเมื่อใช้ Node.js ด้วยพอร์ต 80 (Ubuntu / Linode) [ปิด]


260

ฉันกำลังตั้งค่าครั้งแรกของฉันNode.jsเซิร์ฟเวอร์บนและผมค่อนข้างใหม่กับรายละเอียดของcloud Linux node Linux admin(BTW ฉันไม่ได้พยายามใช้ Apache ในเวลาเดียวกัน)

ทุกอย่างถูกติดตั้งอย่างถูกต้อง แต่ฉันพบว่าถ้าฉันใช้root loginฉันไม่สามารถฟังport 80ด้วยโหนด อย่างไรก็ตามฉันไม่ต้องการรันเป็นรูทเพื่อเหตุผลด้านความปลอดภัย

การปฏิบัติที่ดีที่สุดคืออะไร:

  1. ตั้งค่าการอนุญาตที่ดี / ผู้ใช้สำหรับโหนดเพื่อให้ปลอดภัย / แซนด์บ็อกซ์หรือไม่
  2. อนุญาตให้ใช้พอร์ต 80 ภายในข้อ จำกัด เหล่านี้
  3. เริ่มต้นโหนดและรันโดยอัตโนมัติ
  4. จัดการข้อมูลบันทึกที่ส่งไปยังคอนโซล
  5. การบำรุงรักษาทั่วไปและความปลอดภัยอื่น ๆ

ฉันควรส่งต่อการรับส่งข้อมูลพอร์ต 80 ไปยังพอร์ตการรับฟังอื่นหรือไม่

ขอบคุณ

คำตอบ:


532

พอร์ต 80

สิ่งที่ฉันทำบนอินสแตนซ์คลาวด์ของฉันคือฉันเปลี่ยนเส้นทางพอร์ต 80 ไปยังพอร์ต 3000 ด้วยคำสั่งนี้:

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

จากนั้นฉันจะเปิด Node.js ที่พอร์ต 3000 การร้องขอไปที่พอร์ต 80 จะได้รับการแมปกับพอร์ต 3000

นอกจากนี้คุณควรแก้ไขไฟล์และเพิ่มบรรทัดที่ลบ/etc/rc.local sudoที่จะเพิ่มการเปลี่ยนเส้นทางเมื่อเครื่องบูทขึ้น คุณไม่จำเป็นต้องsudoใน/etc/rc.localเพราะคำสั่งที่มีการทำงานเป็นrootเมื่อบูทระบบ

ท่อน

ใช้โมดูลถาวรเพื่อเปิด Node.js ของคุณด้วย จะตรวจสอบให้แน่ใจว่าจะรีสตาร์ทหากเคยเกิดปัญหาและจะเปลี่ยนเส้นทางบันทึกคอนโซลไปยังไฟล์

เปิดตัวใน Boot

เพิ่ม Node.js start script ของคุณไปยังไฟล์ที่คุณแก้ไขเพื่อเปลี่ยนเส้นทางพอร์ต, /etc/rc.local. สิ่งนี้จะเรียกใช้สคริปต์เรียกใช้ Node.js ของคุณเมื่อระบบเริ่มทำงาน

มหาสมุทรดิจิตอลและ VPS อื่น ๆ

สิ่งนี้ไม่เพียงใช้กับ Linode เท่านั้น แต่ Digital Ocean, AWS EC2 และผู้ให้บริการ VPS อื่น ๆ ด้วย อย่างไรก็ตามในระบบ RedHat ตามคือ/etc/rc.local/ect/rc.d/local


3
ขอบคุณสำหรับคำตอบที่ดีและตรงประเด็น
Robotbugs

21
BTW บน Ubuntu เป็น /etc/rc.local
kehers

12
บ่อยครั้งที่แฟล็ก "-i eth0" จะเป็นปัญหาสำหรับเซิร์ฟเวอร์ส่วนตัวเสมือน แทนที่ eth0 ตามต้องการ
JHAWN

7
หากฉันเพิ่มสคริปต์เริ่มต้น Node.js ของฉัน/etc/rc.localมันจะไม่ถูกดำเนินการในขณะrootที่บูตระบบหรือไม่ ที่จะเอาชนะวัตถุประสงค์ของการเปลี่ยนเส้นทางพอร์ต 80
jamix

4
โปรดทราบว่าการเปลี่ยนเส้นทางพอร์ตจะทำงานพอร์ตปลายทางจะต้องเปิดใช้งานไฟร์วอลล์ของคุณด้วย WRT เริ่มต้นอินสแตนซ์ของโหนดในการบูตเราเพียงแค่ใช้ประโยชน์จากไฟล์ init script / systemd ของดิสทริบิวชันที่อนุญาตให้คุณระบุผู้ใช้
bk138

116

ให้สิทธิ์ผู้ใช้อย่างปลอดภัยในการใช้พอร์ต 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 มันจะไม่บ่น

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


9
นี่คือคำตอบที่ดีกว่าง่ายกว่า
Kyle Chadha

2
และเพิ่มคำตอบโดยละเอียดที่นี่stackoverflow.com/questions/23281895/…
พบกับ Mehta

1
เว็บเซิร์ฟเวอร์เช่น NGINX ทำงานบนพอร์ต 80 ได้อย่างไร มันทำอะไรที่คล้ายกันไหม?
Eric Andrew Lewis

1
@EricAndrewLewis: ฉันจะบอกว่ามันขึ้นอยู่กับ ข้อผิดพลาดนี้จะปรากฏขึ้นเมื่อคุณใช้เซิร์ฟเวอร์ในโหมดที่ไม่ใช่รูท ถ้าคุณใช้เซิร์ฟเวอร์ Nginx ในฐานะผู้ใช้รูท! นอกจากนี้หากใช้งานเป็นผู้ใช้ปกติและได้รับข้อผิดพลาด เรียกใช้คำสั่งด้านบนเพื่อให้สิทธิ์ที่ปลอดภัยในการเข้าถึงพอร์ต นอกจากนี้อ้างถึงstackoverflow.com/questions/31369480/…
พบกับ Mehta

16

ปล่อยสิทธิพิเศษของรูทหลังจากที่คุณผูกกับพอร์ต 80 (หรือ 443)

สิ่งนี้อนุญาตให้พอร์ต 80/443 ยังคงได้รับการป้องกันในขณะที่ยังคงป้องกันไม่ให้คุณแสดงคำขอเป็นรูท:

function drop_root() {
    process.setgid('nobody');
    process.setuid('nobody');
}

ตัวอย่างการทำงานเต็มรูปแบบโดยใช้ฟังก์ชั่นด้านบน:

var process = require('process');
var http = require('http');
var server = http.createServer(function(req, res) {
    res.write("Success!");
    res.end();
});

server.listen(80, null, null, function() {
    console.log('User ID:',process.getuid()+', Group ID:',process.getgid());
    drop_root();
    console.log('User ID:',process.getuid()+', Group ID:',process.getgid());
});

ดูรายละเอียดเพิ่มเติมได้ที่นี้อ้างอิงเต็ม


9

สำหรับพอร์ต 80 (ซึ่งเป็นคำถามเดิม) ดาเนียลพูดถูก ฉันเพิ่งย้ายไปhttpsและต้องเปลี่ยนจากiptablesเป็นพร็อกซีแสง nginx ที่จัดการใบรับรอง SSL ฉันพบคำตอบที่เป็นประโยชน์พร้อมกับส่วนสำคัญโดยgabrielhpuglieseเกี่ยวกับวิธีจัดการกับมัน โดยทั่วไปฉัน

หวังว่าจะช่วยให้คนอื่นปวดหัวบ้าง ฉันแน่ใจว่ามีวิธีที่บริสุทธิ์ในการทำเช่นนี้ แต่ nginx นั้นรวดเร็วและทำงานได้

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