Logo Zephyrnet

Cách sử dụng SSL / TLS với Node.js

Ngày:

Vào năm 2020, không có lý do gì để trang web của bạn không sử dụng HTTPS. Khách truy cập mong đợi nó, Google sử dụng nó như một yếu tố xếp hạng và các nhà sản xuất trình duyệt sẽ vui vẻ đặt tên và xấu hổ những trang web không sử dụng nó.

Trong hướng dẫn này, tôi sẽ hướng dẫn bạn một ví dụ thực tế về cách thêm Hãy mã hóa–Đã tạo chứng chỉ cho máy chủ Express.js của bạn.

Nhưng bảo vệ các trang web và ứng dụng của chúng tôi bằng HTTPS là chưa đủ. Chúng tôi cũng nên yêu cầu các kết nối được mã hóa từ các máy chủ mà chúng tôi đang nói chuyện. Chúng tôi sẽ thấy rằng các khả năng tồn tại để kích hoạt lớp SSL / TLS ngay cả khi nó không được bật theo mặc định.

Lưu ý: nếu bạn đang tìm hướng dẫn về cách thiết lập SSL với NGINX khi định cấu hình nó hoạt động như một proxy ngược cho ứng dụng Node, hãy xem mẹo nhanh của chúng tôi, “Định cấu hình NGINX và SSL với Node.js".

Hãy bắt đầu bằng một bản đánh giá ngắn về trạng thái hiện tại của HTTPS.

HTTPS Ở khắp mọi nơi

Đặc tả HTTP / 2 được xuất bản dưới dạng RFC 7540 vào tháng 2015 năm 2, có nghĩa là tại thời điểm này, nó là một phần của tiêu chuẩn. Đây là một cột mốc quan trọng. Bây giờ tất cả chúng ta có thể nâng cấp máy chủ của mình để sử dụng HTTP / 1.1. Một trong những khía cạnh quan trọng nhất là khả năng tương thích ngược với HTTP 2 và cơ chế thương lượng để chọn một giao thức khác. Mặc dù tiêu chuẩn không chỉ định mã hóa bắt buộc, nhưng hiện tại không có trình duyệt nào hỗ trợ HTTP / XNUMX không được mã hóa. Điều này mang lại cho HTTPS một sự thúc đẩy khác. Cuối cùng, chúng tôi sẽ nhận được HTTPS ở khắp mọi nơi!

Ngăn xếp của chúng ta thực sự trông như thế nào? Từ quan điểm của một trang web chạy trong trình duyệt (ở cấp ứng dụng), chúng ta phải đi qua các lớp sau để đạt được cấp IP:

  1. Trình duyệt khách hàng
  2. HTTP
  3. SSL / TLS
  4. TCP
  5. IP

HTTPS không khác gì giao thức HTTP trên SSL / TLS. Do đó, tất cả các quy tắc của HTTP vẫn được áp dụng. Lớp bổ sung này thực sự cung cấp cho chúng ta điều gì? Có nhiều lợi thế: chúng tôi nhận được xác thực bằng cách có khóa và chứng chỉ; một loại quyền riêng tư và bí mật nhất định được đảm bảo, vì kết nối được mã hóa theo cách bất đối xứng; và tính toàn vẹn của dữ liệu cũng được bảo toàn, vì dữ liệu đã truyền không thể thay đổi trong quá trình truyền.

Một trong những lầm tưởng phổ biến nhất là sử dụng SSL / TLS tốn kém về mặt tính toán và làm chậm máy chủ. Điều này chắc chắn không còn đúng nữa. Chúng tôi cũng không cần bất kỳ phần cứng chuyên dụng nào với các đơn vị mật mã. Ngay cả đối với Google, lớp SSL / TLS chiếm ít hơn 1% tải CPU và chi phí mạng của HTTPS so với HTTP là dưới 2%. Nói chung, sẽ không có ý nghĩa gì nếu bạn bỏ qua HTTPS chỉ vì một chút chi phí nhỏ.

Như Ilya Grigorik nói, có một vấn đề về hiệu suất:

Phiên bản gần đây nhất là TLS 1.3. TLS là sự kế thừa của SSL, có sẵn trong phiên bản SSL 3.0 mới nhất của nó. Những thay đổi từ SSL sang TLS ngăn cản khả năng tương tác, tuy nhiên, quy trình cơ bản không thay đổi. Chúng tôi có ba kênh được mã hóa khác nhau. Đầu tiên là cơ sở hạ tầng khóa công khai cho chuỗi chứng chỉ. Thứ hai cung cấp mật mã khóa công khai cho các trao đổi khóa. Cuối cùng, cái thứ ba là đối xứng. Ở đây chúng tôi có mật mã để truyền dữ liệu.

TLS 1.3 sử dụng băm cho một số hoạt động quan trọng. Về mặt lý thuyết, có thể sử dụng bất kỳ thuật toán băm nào, nhưng bạn nên sử dụng SHA2 hoặc một thuật toán mạnh hơn. SHA1 đã là một tiêu chuẩn từ lâu nhưng gần đây đã trở nên lỗi thời.

HTTPS cũng đang được khách hàng chú ý nhiều hơn. Các mối quan tâm về quyền riêng tư và bảo mật luôn tồn tại, nhưng với lượng dữ liệu và dịch vụ có thể truy cập trực tuyến ngày càng tăng, mọi người ngày càng quan tâm hơn. Đối với những trang web không triển khai nó, có một tiện ích mở rộng trình duyệt hữu ích - HTTPS mọi nơi từ EFF - mã hóa thông tin liên lạc của chúng tôi với hầu hết các trang web.

HTTPS-ở mọi nơi

Những người sáng tạo nhận ra rằng nhiều trang web chỉ cung cấp HTTPS một phần. Plugin cho phép chúng tôi viết lại các yêu cầu cho những trang web chỉ cung cấp hỗ trợ HTTPS một phần. Ngoài ra, chúng tôi cũng có thể chặn HTTP hoàn toàn (xem ảnh chụp màn hình ở trên).

Giao tiếp cơ bản

Quá trình xác thực chứng chỉ bao gồm việc xác nhận chữ ký chứng chỉ và thời hạn hết hạn. Chúng tôi cũng cần xác minh rằng nó liên kết với một gốc đáng tin cậy. Cuối cùng, chúng ta cần kiểm tra xem nó có bị thu hồi hay không. Có các cơ quan chuyên trách, đáng tin cậy trên thế giới cấp chứng chỉ. Trong trường hợp một trong số này bị xâm phạm, tất cả các chứng chỉ khác từ cơ quan có thẩm quyền nói trên sẽ bị thu hồi.

Biểu đồ trình tự cho một lần bắt tay HTTPS trông như sau. Chúng tôi bắt đầu với việc khởi tạo từ máy khách, sau đó là một thông báo với chứng chỉ và trao đổi khóa. Sau khi máy chủ gửi gói đã hoàn thành, máy khách có thể bắt đầu trao đổi khóa và truyền thông số kỹ thuật mật mã. Tại thời điểm này, khách hàng đã kết thúc. Cuối cùng máy chủ xác nhận lựa chọn thông số kỹ thuật mật mã và kết thúc quá trình bắt tay.

HTTPS-trình tự

Toàn bộ chuỗi được kích hoạt độc lập với HTTP. Nếu chúng tôi quyết định sử dụng HTTPS, chỉ có xử lý ổ cắm được thay đổi. Máy khách vẫn đang đưa ra các yêu cầu HTTP, nhưng socket sẽ thực hiện quá trình bắt tay được mô tả trước đó và mã hóa nội dung (tiêu đề và nội dung).

Vậy chúng ta cần làm gì để SSL / TLS hoạt động với máy chủ Express.js?

HTTPS

Theo mặc định, Node.js cung cấp nội dung qua HTTP. Nhưng cũng có một Mô-đun HTTPS mà chúng tôi phải sử dụng để giao tiếp qua một kênh an toàn với khách hàng. Đây là một mô-đun tích hợp sẵn và cách sử dụng rất giống với cách chúng tôi sử dụng mô-đun HTTP:

const https = require("https"), fs = require("fs"); const options = { key: fs.readFileSync("/srv/www/keys/my-site-key.pem"), cert: fs.readFileSync("/srv/www/keys/chain.pem")
}; const app = express(); app.use((req, res) => { res.writeHead(200); res.end("hello worldn");
}); app.listen(8000); https.createServer(options, app).listen(8080);

Bỏ qua /srv/www/keys/my-site-key.pem và và /srv/www/keys/chain.pem tệp cho thời điểm này. Đó là những chứng chỉ SSL mà chúng tôi cần tạo, chúng tôi sẽ thực hiện một chút sau. Đây là phần thay đổi với Let's Encrypt. Trước đây, chúng tôi phải tạo một cặp khóa riêng tư / công khai, gửi nó đến một cơ quan đáng tin cậy, trả tiền cho họ và có thể đợi một chút để có được chứng chỉ SSL. Ngày nay, Let's Encrypt tạo và xác thực chứng chỉ của bạn ngay lập tức miễn phí!

Tạo chứng chỉ

certbot

Đặc tả TLS yêu cầu một chứng chỉ, được ký bởi một tổ chức phát hành chứng chỉ đáng tin cậy (CA). CA đảm bảo rằng chủ sở hữu chứng chỉ thực sự là người mà họ tuyên bố. Vì vậy, về cơ bản khi bạn nhìn thấy biểu tượng ổ khóa màu xanh lục (hoặc bất kỳ dấu hiệu màu xanh lục nào khác ở phía bên trái của URL trong trình duyệt của bạn), điều đó có nghĩa là máy chủ bạn đang giao tiếp thực sự là máy chủ mà nó tuyên bố. Nếu bạn đang truy cập facebook.com và bạn thấy một ổ khóa màu xanh lục, thì gần như chắc chắn rằng bạn thực sự đang giao tiếp với Facebook và không ai khác có thể nhìn thấy thông tin liên lạc của bạn - hay nói đúng hơn là không ai khác có thể đọc được.

Cần lưu ý rằng chứng chỉ này không nhất thiết phải được xác minh bởi một cơ quan có thẩm quyền như Let's Encrypt. Ngoài ra còn có các dịch vụ trả phí khác. Về mặt kỹ thuật, bạn có thể tự mình ký tên, nhưng sau đó (vì bạn không phải là CA đáng tin cậy) những người dùng truy cập trang web của bạn có thể sẽ thấy một cảnh báo đáng sợ lớn đưa ra để đưa họ trở lại trạng thái an toàn.

Trong ví dụ sau, chúng tôi sẽ sử dụng certbot, được sử dụng để tạo và quản lý chứng chỉ với Let's Encrypt.

Trên trang Certbot bạn có thể tìm thấy hướng dẫn về cách cài đặt certbot cho hầu hết mọi kết hợp hệ điều hành / máy chủ. Bạn nên chọn các tùy chọn có thể áp dụng cho bạn.

Một sự kết hợp phổ biến để triển khai ứng dụng Node là NGINX trên Ubuntu LTS mới nhất và đó là những gì tôi sẽ sử dụng ở đây.

sudo apt-get update
sudo apt-get install software-properties-common
sudo add-apt-repository universe
sudo add-apt-repository ppa:certbot/certbot
sudo apt-get update

Webroot

Webroot là một plugin Certbot rằng, ngoài chức năng mặc định của Certbot (tự động tạo cặp khóa công khai / riêng tư của bạn và tạo chứng chỉ SSL cho chúng), cũng sao chép chứng chỉ vào thư mục webroot của bạn và xác minh máy chủ của bạn bằng cách đặt một số mã xác minh vào thư mục tạm thời ẩn được đặt tên .well-known. Để bỏ qua việc thực hiện một số bước này theo cách thủ công, chúng tôi sẽ sử dụng plugin này. Plugin được cài đặt theo mặc định với certbot. Để tạo và xác minh chứng chỉ của chúng tôi, chúng tôi sẽ chạy như sau:

certbot certonly --webroot -w /var/www/example/ -d www.example.com -d example.com

Bạn có thể phải chạy lệnh này dưới dạng sudo, vì nó sẽ cố gắng ghi vào /var/log/letsencrypt.

Bạn cũng sẽ được yêu cầu cung cấp địa chỉ email của mình. Bạn nên nhập một địa chỉ thực mà bạn thường sử dụng, vì bạn sẽ nhận được thông báo nếu chứng chỉ của bạn sắp hết hạn. Sự đánh đổi để Let's Encrypt phát hành một chứng chỉ miễn phí là nó sẽ hết hạn ba tháng một lần. May mắn thay, việc gia hạn dễ dàng như chạy một lệnh đơn giản, chúng ta có thể giao cho một công việc cron và sau đó không phải lo lắng về việc hết hạn. Ngoài ra, đó là một phương pháp bảo mật tốt để gia hạn chứng chỉ SSL, vì nó giúp kẻ tấn công có ít thời gian hơn để phá mã. Đôi khi các nhà phát triển thậm chí còn thiết lập cron này để chạy hàng ngày, điều này hoàn toàn tốt và thậm chí được khuyến nghị.

Hãy nhớ rằng bạn phải chạy lệnh này trên máy chủ mà miền được chỉ định trong -d cờ (cho miền) giải quyết - nghĩa là máy chủ sản xuất của bạn. Ngay cả khi bạn có giải pháp DNS trong tệp máy chủ lưu trữ cục bộ của mình, điều này sẽ không hoạt động vì miền sẽ được xác minh từ bên ngoài. Vì vậy, nếu bạn đang thực hiện việc này cục bộ, rất có thể nó sẽ không thành công, trừ khi bạn mở một cổng từ máy cục bộ của mình ra thế giới bên ngoài và để nó chạy phía sau một tên miền phân giải cho máy của bạn. Đây là một kịch bản rất khó xảy ra.

Cuối cùng nhưng không kém phần quan trọng, sau khi chạy lệnh này, đầu ra sẽ chứa các đường dẫn đến khóa riêng tư và tệp chứng chỉ của bạn. Sao chép các giá trị này vào đoạn mã trước đó - vào cert tài sản cho chứng chỉ và key thuộc tính cho khóa:

// ... const options = { key: fs.readFileSync("/var/www/example/sslcert/privkey.pem"), cert: fs.readFileSync("/var/www/example/sslcert/fullchain.pem") // these paths might differ for you, make sure to copy from the certbot output
}; // ...

thắt chặt nó lên

HTTP Strict Transport Security

Bạn đã bao giờ có một trang web mà bạn chuyển từ HTTP sang HTTPS và có một số chuyển hướng còn sót lại vẫn chuyển hướng sang HTTP chưa? HTTP Strict Transport Security (HSTS) là một cơ chế chính sách bảo mật web để giảm thiểu các cuộc tấn công hạ cấp giao thức và chiếm quyền điều khiển cookie.

HSTS buộc ứng dụng khách (trình duyệt đang truy cập máy chủ của bạn) điều hướng tất cả lưu lượng truy cập thông qua HTTPS - một hệ tư tưởng “an toàn hoặc hoàn toàn không”!

Express JS không cho phép chúng tôi thêm tiêu đề này theo mặc định, vì vậy chúng tôi sẽ sử dụng Nón bảo hộ, một mô-đun Node cho phép chúng tôi làm điều này. Tải về Nón bảo hộ bằng cách chạy như sau:

npm install helmet

Sau đó, chúng tôi chỉ cần thêm nó làm phần mềm trung gian vào máy chủ Express của chúng tôi:

const https = require("https"), fs = require("fs"), helmet = require("helmet"); const options = { key: fs.readFileSync("/srv/www/keys/my-site-key.pem"), cert: fs.readFileSync("/srv/www/keys/chain.pem")
}; const app = express(); app.use(helmet()); // Add Helmet as a middleware app.use((req, res) => { res.writeHead(200); res.end("hello worldn");
}); app.listen(8000); https.createServer(options, app).listen(8080);

Thông số Diffie – Hellman Strong (er)

Để bỏ qua một số phép toán phức tạp, chúng ta hãy bắt đầu cuộc đuổi bắt. Nói một cách đơn giản, có hai khóa khác nhau được sử dụng để mã hóa: chứng chỉ chúng tôi nhận được từ tổ chức phát hành chứng chỉ và một khóa do máy chủ tạo ra để trao đổi khóa. Khóa mặc định để trao đổi khóa (còn được gọi là Trao đổi khóa Diffie – Hellmanhoặc DH) sử dụng khóa “nhỏ hơn” so với khóa cho chứng chỉ. Để khắc phục điều này, chúng tôi sẽ tạo một khóa DH mạnh và cung cấp nó vào máy chủ an toàn của chúng tôi để sử dụng.

Để tạo khóa dài hơn (2048 bit), bạn sẽ cần openssl, mà bạn có thể đã cài đặt theo mặc định. Trong trường hợp bạn không chắc chắn, hãy chạy openssl -v. Nếu không tìm thấy lệnh, hãy cài đặt openssl bằng cách chạy sudo apt install openssl (hoặc truy cập trang tải xuống của họ tại đây):

openssl dhparam -out /var/www/example/sslcert/dh-strong.pem 2048

Sau đó sao chép đường dẫn đến tệp vào cấu hình của chúng tôi:

// ... const options = { key: fs.readFileSync("/var/www/example/sslcert/privkey.pem"), cert: fs.readFileSync("/var/www/example/sslcert/fullchain.pem"), // these paths might differ for you, make sure to copy from the certbot output dhparam: fs.readFileSync("/var/www/example/sslcert/dh-strong.pem")
}; // ...

Kết luận

Vào năm 2020 và hơn thế nữa, không có lý do gì để loại bỏ HTTPS. Định hướng tương lai có thể nhìn thấy rõ ràng: HTTPS ở khắp mọi nơi! Trong Node.js, chúng tôi có rất nhiều tùy chọn để sử dụng SSL / TLS. Chúng tôi có thể xuất bản các trang web của mình trong HTTPS, chúng tôi có thể tạo các yêu cầu tới các trang web được mã hóa và chúng tôi có thể ủy quyền các chứng chỉ không đáng tin cậy.

Nguồn: https://www.sitepoint.com/how-to-use-ssltls-with-node-js/?utm_source=rss

tại chỗ_img

Tin tức mới nhất

tại chỗ_img