2014-10-26 32 views
6

Tôi đang tạo một máy chủ HTTPS lần đầu tiên trong Node và mã (xem bên dưới) hoạt động cho một cổng ngẫu nhiên như 6643 nhưng trên cổng 443, nó sẽ không hoạt động. Tôi gặp lỗi này:Máy chủ https của Node.js: Không thể nghe cổng 443 - Tại sao?

[Debug][Server]: Initialized... 
[Debug][Control Center]: Application initialized... 

events.js:72 
     throw er; // Unhandled 'error' event 
      ^
Error: listen EACCES 
    at errnoException (net.js:904:11) 
    at Server._listen2 (net.js:1023:19) 
    at listen (net.js:1064:10) 
    at Server.listen (net.js:1138:5) 
    at Object.module.exports.router (/home/ec2-user/Officeball/Versions/officeball_v0.0.5/server/custom_modules/server.js:52:5) 
    at Object.<anonymous> (/home/ec2-user/Officeball/Versions/officeball_v0.0.5/server/control_center.js:15:59) 
    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) 

Đây là máy chủ Amazon Linux EC2. Đó là sự hiểu biết của tôi rằng khi tôi đặt DNS A Name Record của miền của mình thành IP của máy chủ, khi người dùng tìm kiếm https://mydomain.com, trình duyệt sẽ tra cứu IP của máy chủ của tôi tại cổng 443, được cho là cổng chuẩn cho lưu lượng HTTPS.

Vì vậy, hiểu biết của tôi là tôi cần phải phục vụ https nội dung qua cổng 443.

Tôi đang làm gì sai?


Đây là mã máy chủ của tôi:

control_center.js (init)

/* Control Center */ 

//DEFINE GLOBALS 

preloaded = {}; 

//GET DIRECT WORKING PATH 

var dirPath = process.cwd(); 

//REQUIRE CUSTOM MODULES 

var debug = new (require(dirPath + 
     "/custom_modules/debug"))("Control Center"); 
var socket = require(dirPath + 
     "/custom_modules/socket")(4546); 

// ! this is the relevant line 
var server = require(dirPath + "/custom_modules/server").router(443); 

//APP INITIALIZE 

debug.log("Application initialized..."); 

server.js

/* Server */ 

//REQUIRE NPM MODULES 

var fs  = require('fs'), 
    https = require('https'), 
    url  = require('url'), 
    path = require('path'); 

//GET DIRECT WORKING PATH 

var dirPath = process.cwd(); 

//REQUIRE CUSTOM MODULES 

//Snip! 

var debug = new (require(dirPath + 
     "/custom_modules/debug"))("Server"); 

//Preload requests 

var preload = require(dirPath + 
     '/custom_modules/preload').init(); 

//INIT MODULE 

debug.log("Initialized..."); 

//DEFINE MODULE VARIABLES 

var options = { 
    key: fs.readFileSync('SSL/evisiion_private_key.pem'), 
    cert: fs.readFileSync('SSL/evisiion_ssl_cert.pem') 
}; 

//LISTEN FOR PATH REQUESTS 

//route requests to server 
module.exports.router = function(port) { 
    https.createServer(options, function(req, res) { 

     //Snip! 

    }).listen(port); 
}; 
+0

Có lẽ không phải là mã, hãy xem [ở đây] (http://stackoverflow.com/questions/5004159/opening-port-80-ec2-amazon-web-services/10454688#10454688). –

+0

@BrendanAshworth khi nó đơn giản đến nỗi đau ... –

+0

lý do duy nhất tôi biết là bởi vì tôi đã trả lời cùng một câu hỏi trước :) cũng có thể phải làm với người dùng root riêng nếu câu trả lời không sửa chữa nó –

Trả lời

24

Trên Linux (và, tôi tin rằng, hầu hết các hệ điều hành giống Unix khác), một dịch vụ phải chạy dưới dạng root để có thể liên kết với một cổng được đánh số nhỏ hơn 1024.

Tôi vừa xác minh nó trên một Ứng dụng nút Tôi đã nằm xung quanh, và tôi thấy chính xác cùng một lỗi, dòng cho dòng giống hệt nhau chặn đường dẫn tệp, khi tôi đã thay đổi cổng từ 5000 thành 443.

Trong quá trình phát triển, hầu hết mọi người sẽ chạy máy chủ dev trên cổng cao hơn như 8080. Trong sản xuất, bạn cũng có thể muốn sử dụng một máy chủ web thích hợp như Nginx để phục vụ nội dung tĩnh và đảo ngược proxy mọi thứ khác với ứng dụng Node của bạn, điều này khiến cho nó ít vấn đề hơn vì Nginx có thể khá hạnh phúc chạy như người chủ.

EDIT: Vì trường hợp sử dụng của bạn yêu cầu cung cấp một số nội dung tĩnh, bạn có thể muốn sử dụng máy chủ web như Nginx hoặc Apache để xử lý các tệp tĩnh và proxy ngược lại sang cổng khác cho nội dung động của bạn. proxy ngược lại là khá đơn giản với Nginx - đây là một tập tin mẫu cấu hình:

server { 
    listen 443; 
    server_name example.com; 
    client_max_body_size 50M; 

    access_log /var/log/nginx/access.log; 
    error_log /var/log/nginx/error.log; 

    location /static { 
     root /var/www/mysite; 
    } 

    location/{ 
     proxy_pass http://127.0.0.1:8000; 
    } 
} 

này giả định ứng dụng web của bạn là để có thể truy cập trên cổng 443, và đang chạy trên cổng 8000. Nếu vị trí phù hợp với thư mục/tĩnh, nó được phục vụ từ/var/www/mysite/static. Nếu không, Nginx sẽ chuyển nó sang ứng dụng đang chạy tại cổng 8000, có thể là một ứng dụng Node.js, hoặc một ứng dụng Python hoặc bất kỳ thứ gì.

Điều này cũng khá gọn gàng giải quyết vấn đề của bạn vì ứng dụng sẽ có thể truy cập được trên cổng 443, mà không phải thực sự liên kết với cổng đó.

+0

Bạn đã đúng, chỉ cần ném vào từ ma thuật và nó làm việc ngay lập tức. Gotta yêu 'sudo' –

+3

@ jt0dd - thường là một thực tế tồi để chạy máy chủ web của bạn tại quyền truy cập root vì nó nhân số lỗ hổng bảo mật mà bạn có thể phải chịu. Xem hai bài viết trong bình luận của tôi về câu hỏi của bạn cho các cách thay thế nghe trên một cổng thấp mà không cần chạy quá trình nút của bạn như là người chủ. Cá nhân tôi đang sử dụng giải pháp iptable. – jfriend00

+0

@ jfriend00 Chỉ cần đánh tôi với nó! Giải pháp iptables là giải pháp tốt nhất miễn là bạn không cần phải phân phát bất kỳ tệp tĩnh nào. Nếu bạn làm thế, tôi nghĩ tốt hơn là nên làm những gì tôi đã đề cập - phục vụ chúng với Nginx và đảo ngược mọi thứ khác với cổng mà ứng dụng Node.js đang chạy. –

Các vấn đề liên quan