12/08/2018, 16:58

sử dụng SSL/TLS với note.js

Xin chào các bạn, trong bài viết này, chúng tôi sẽ giới thiệu cho các bạn về cách thêm chứng chỉ Let's Encrypt vào máy chủ Express.js. Tuy nhiên, việc bảo vệ website và ứng dụng của chúng tôi với HTTPS là không đủ. Chúng ta cũng nên yêu cầu kết nối được mã hóa từ các máy chủ mà chúng ta đang nói ...

Xin chào các bạn, trong bài viết này, chúng tôi sẽ giới thiệu cho các bạn về cách thêm chứng chỉ Let's Encrypt vào máy chủ Express.js. Tuy nhiên, việc bảo vệ website và ứng dụng của chúng tôi với HTTPS là không đủ. Chúng ta cũng nên yêu cầu kết nối được mã hóa từ các máy chủ mà chúng ta đang nói chuyện. Chúng ta sẽ thấy rằng vẫn có cách để kích hoạt lớp SSL/TLS ngoại trừ cách mặc định Đầu tiên, hãy bắt đàu với một bài đánh giá ngắn về HTTPS trong thời điểm hiện tại

HTTPS everywhere

Đặc tả HTTP / 2 đã được xuất bản dưới dạng RFC 7540 vào tháng 5 năm 2015, nghĩa là vào thời điểm này nó là một phần của tiêu chuẩn. Đây là một mốc quan trọng. Bây giờ chúng ta có thể nâng cấp các máy chủ của chúng tôi để sử dụng HTTP / 2. 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 1.1 và cơ chế đàm phán để 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, hiện tại không có trình duyệt hỗ trợ HTTP / 2 không được mã hóa. Điều này cho phép HTTPS tăng thêm. Cuối cùng, chúng tôi sẽ nhận được HTTPS ở mọi nơi!

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

  1. Client browser
  2. HTTP
  3. SSL/TLS
  4. TCP
  5. IP

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

Ngày trước, một trong những vẫn đề phổ biến nhất khi sử dụng SSL / TLS đòi hỏi quá nhiều tài nguyên và làm chậm máy chủ. Thơi điểm bây giờ, diề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 để lưu trữ. Ngay cả đối với Google, lớp SSL / TLS cũng chỉ chiếm ít hơn 1% tải CPU. Hơn nữa, chi phí trên mạng của HTTPS so với HTTP thấp hơn 2%. Nói chung tất cả, HTTPS rất đáng để đầu tư và sử dụng.

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

TLS 1.3 sử dụng mảng băm cho một số thao tác 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 rất khuyến khích sử dụng thuật toán SHA2 hoặc một thuật toán mạnh hơn. SHA1 đã được một tiêu chuẩn trong một thời gian dài nhưng gần đây đã trở nên lỗi thời.

HTTPS cũng đang thu hút nhiều sự chú ý hơn từ phía khách hàng. Các mối quan tâm về bảo mật dữ liệu luôn là vấn đề được ưu tiên và quan tâm hàng đầu, nhưng với số lượng ngày càng tăng của dữ liệu và dịch vụ truy cập trực tuyến mà người ta ngày càng quan tâm. Vì sự tiện lơi của browser plugin "HTTPS Everywhere", nên nó hiện đang được sử dụng hầu như trên tấ cả các trang web.

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

Giao tiếp cơ bản

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

Biểu đồ trình tự bắt tay 3 bước cho HTTPS sẽ như sau. Chúng tôi bắt đầu với init từ khách hàng, tiếp theo 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 chỉnh của nó, khách hàng có thể bắt đầu trao đổi khóa và truyền số liệu đặc biệt. Tại thời điểm này, khách hàng đã hoàn tất. Cuối cùng, máy chủ xác nhận lựa chọn đặc tả mật mã và đóng quá trình

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

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

HTTPS

Theo mặc định, Node.js phục vụ nội dung qua HTTP. Nhưng cũng có một module HTTPS mà chúng ta 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 module cài sẵn, và việc sử dụng rất giống với cách chúng ta sử dụng module 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 world
");
});

app.listen(8000);

https.createServer(options, app).listen(8080);

Bây giờ, chúng ta sẽ ignore /srv/www/keys/my-site-key.pem và /srv/www/keys/chain.pem. Đó là các chứng chỉ SSL mà chúng ta cần tạo, chúng ta sẽ làm sau đó. Đây là một phần đã thay đổi với Let's Encrypt. Trước đây, chúng tôi phải tạo ra cặp khóa cá nhân / công khai, gửi tới cơ quan tin cậy, thanh toán và có thể chờ đợi một chút để có được chứng chỉ SSL. Còn bây giờ, hãy mã hóa tạo ra và xác nhận chứng chỉ của bạn miễn phí và ngay lập tức!

Khởi tạo chứng chỉ (Generating Certificates)

Certbot Chứng chỉ được ký bởi một cơ quan chứng nhận đáng tin cậy (CA) được yêu cầu bởi đặc tả TLS. CA đảm bảo rằng người giữ chứng chỉ thực sự là người mà ông 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ây nào khác ở phía bên trái của URL trong trình duyệt của bạn) thì điều đó có nghĩa là máy chủ mà bạn đang giao tiếp thực sự là người mà nó tuyên bố. Nếu bạn đang ở trên facebook.com và bạn thấy một khóa màu xanh lá cây, gần như chắc chắn bạn thực sự đang giao tiếp với Facebook và không ai khác nhìn thấy được giao tiếp của bạn - hoặc đúng hơn, không ai khác có thể đọc nó.

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 như Let's Encrypt. Cũng có các dịch vụ thanh toán khác. Bạn có thể đăng ký kỹ thuật cho chính mình, nhưng sau đó người dùng truy cập trang web của bạn sẽ không nhận được sự chấp thuận từ CA khi truy cập và tất cả các trình duyệt hiện đại sẽ hiển thị một lá cờ cảnh báo lớn cho người dùng và yêu cầu được chuyển hướng "an toàn".

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

Trên trang Certbot, bạn có thể tìm hướng dẫn về cách cài đặt Certbot trên hệ điều hành của bạn. Ở đây chúng ta sẽ làm theo các hướng dẫn macOS. Để cài đặt Certbot, chạy lênh dưới đây:

brew install certbot

Webroot

Webroot là một plugin của Certbot, ngoài chức năng mặc định của Certbot, nó sẽ tự động tạo ra cặp khóa công khai / riêng tư của bạn và tạo ra một chứng chỉ SSL cho những người này cũng sao chép các chứng chỉ vào thư mục webroot của bạn và cũng xác minh máy chủ của bạn bằng cách đặt một số mã xác minh vào một thư mục tạm thời ẩn được đặt tên. nổi tiếng. Để 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 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 lệnh dưới đây:

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 bạn. Bạn nên đặt một địa chỉ thực mà bạn sử dụng thường xuyên vì bạn sẽ nhận được thông báo nếu chứng chỉ của bạn hết hạn sắp hết hạn. Thương mại đi cho Hãy mã hóa là một giấy chứng nhận miễn phí là nó sẽ hết hạn mỗi ba tháng. May mắn, đổi mới dễ dàng như chạy một lệnh đơn giản, mà chúng ta có thể chỉ định cho một cron và sau đó không phải lo lắng về hết hạn. Ngoài ra, đó là một thực tiễn bảo mật tốt để làm mới chứng chỉ SSL, vì nó cho phép kẻ tấn công ít thời gian hơn để phá vỡ mật 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, đó là hoàn toàn tốt đẹp và thậm chí là đề nghị.

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

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 đường dẫn đến khóa cá nhân 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 thuộc tính cert cho chứng chỉ và thuộc tính khóa cho khoá.

// ...

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
};

// ...

Tighetning IT UP

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

HSTS hiệu quả buộc khách hàng (trình duyệt truy cập vào máy chủ của bạn) để chỉ đạo tất cả lưu lượng truy cập thông qua HTTPS - với tư tưởng "secure or not at all"!

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 Helmet, một module cho phép chúng tôi thực hiện việc này. Thiết lập Helmet bằng cách chạy lệnh sau:

npm install --save helmet

Sau đó, chúng ta chỉ cần thêm nó như một 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 world
");
});

app.listen(8000);

https.createServer(options, app).listen(8080);

Thông số Strong (er) của Diffie-Hellman

chúng ta hãy cắt giảm để bỏ qua một số phần phức tạp về toán học. Trong các thuật ngữ rất đơn giản, có hai khóa khác nhau được sử dụng để mã hóa chứng chỉ mà chúng tôi nhận được từ cơ quan cấp chứng chỉ và một chứng chỉ được tạo ra bởi máy chủ để trao đổi khóa. Khóa mặc định cho trao đổi khóa (còn gọi là trao đổi khóa Diffie-Hellman hoặc DH) sử dụng khóa "smaller" so với khoá cho chứng chỉ. Để khắc phục điều này, chúng tôi sẽ tạo ra một strong HD key và cung cấp nó cho máy chủ.

Để tạo ra khóa dài hơn (2048 bit), bạn sẽ cần tệp openssl, có thể bạn đã 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 lệnh không được tìm thấy, hãy cài đặt openssl bằng cách chạy cài đặt Brews openssl:

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

sao chép thông tin dưới đây vào tệp tin cấu hình:

// ...

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")
};

// ...

Phần kết luận

Vào năm 2018 trở lên, không có lý do gì để từ chối HTTPS. Chúng ta có thể rõ ràng thấy được HTTPS EveryWhere! Trong Node.js, chúng ta có rất nhiều lựa chọn để sử dụng SSL / TLS. Với HTTPS, chúng ta có thể publish web một cách an toàn hơn, có thể tạo request API tới các trang web được mã hóa.

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

0