Cài đặt SSL và giao thức HTTP/2 cho NGINX trên CentOS 7

Cài đặt SSL và giao thức HTTP/2 cho NGINX trên CentOS 7

Trong tháng 2/2015, một kiểu giao thức web mới vừa được IESG chấp thuận mang nhiều tính năng vượt trội hơn, giúp website tối ưu tốc độ hơn đó là giao thức HTTP/2. Vậy thì HTTP/2 là gì, nó có những ưu điểm nào thì trong bài này, tác giả Công Hải tại AppFast sẽ giới thiệu và hướng dẫn cách cài đặt nó vào máy chủ Linux sử dụng CentOS 7.

Cập nhật 12/2019: vào 01/2020 thì 2 giao thức TLSv1 TLSv1.1 trở nên lỗi thời và không còn đạt điểm bảo mật cao nhất nữa, vì vậy bạn cần phải điều chỉnh lại thiết lập cho phù hợp để đạt điểm A+.

Nội dung chính

HTTP 1.1 và HTTP 2

HTTP (Hypertext Transfer Protocol) là một giao thức truyền chuẩn về mạng (truyền tải siêu văn bản – nói nôm na là giao thức web). HTTP 1.1 ra đời vào năm 1997 và vẫn được sử dụng đến hiện tại mà chưa hề có một nâng cấp nào. Có lẽ đã quá cũ nên vào 12/2014 nhóm phát triển của Hypertext Transfer Protocol đã đề xuất lên IESG xem HTTP/2 như là một tiêu chuẩn mới. Và đã được IESG chấp thuận vào ngày 17/02/2015.

HTTP 2 phát triển dựa trên SPDY (pronounced speedy) một giao thức mạng mở được phát triển bởi Google.

Sự khác biệt thì rất nhiều nhưng mình tóm lại sự khác biệt lớn nhất giữa 2 giao thức là: HTTP2 hỗ trợ các truy vấn ghép, nén nội dung, ưu tiên và quản lý thông minh hơn các luồng dữ liệu. Điều đó gây ra việc giảm độ trễ và tăng tốc tải nội dung web. Xem thêm tại bài HTTP/2 là gì?

HTTPS là gì?

HTTPS (Hypertext Transfer Protocol Secure) là một sự kết hợp giữa giao thức HTTP và giao thức bảo mật SSL hay TLS cho phép trao đổi thông tin một cách bảo mật trên Internet.

Cách cài đặt

Hiện có rất nhiều bài hướng dẫn cài đặt SSL nhưng thật sự rất ít bài làm đúng. Ngay cả tinhte.vn cũng chưa thực sự cài đúng.

Các bạn có thể test SSL của website tại:https://www.ssllabs.com/ssltest/index.html

Kết quả test của https://fullstackstation.com/.

Nên hôm nay, mình sẽ hướng dẫn bạn cài đặt và cấu hình HTTPS với HTTP2 lên chuẩn A+.

Bước 1. Cài NGINX 1.9.5 trở lên và kích hoạt HTTP 2

Ngày 22/09/2015 vừa rồi NGINX đã ra phiên bản mainline 1.9.5 chính thức hỗ trợ HTTP 2, và từ này chính thức say goodbye SDPY một thời hùng hậu. Như vậy, điều này có nghĩa là bạn chỉ có thể sử dụng HTTP 2 trên NGINX phiên bản 1.9.5 trở lên, nếu bạn đang dùng NGINX thì hãy gõ nginx -v để kiểm tra phiên bản NGINX hiện tại của bạn.

Để cài NGINX 1.9.5, bạn cần nạp package vào. Hãy tạo file /etc/yum.repos.d/nginx.repo và chèn đoạn dưới đây vào hoặc nếu có rồi thì sửa nội dung:
[nginx]
name=nginx repo
baseurl=http://nginx.org/packages/mainline/centos/$releasever/$basearch/
gpgcheck=0
enabled=1

Sau đó cập nhật lại gói yum.

yum update -y

Và cài NGINX vào với lệnh sau:

yum install nginx

Sau khi cài đặt bạn kiểm tra lại có phải là version 1.9.5 và có module http 2 (--with-http_v2_module) bằng lệnh sau:

nginx -V

Sau khi cài đặt xong, hãy thiết lập NGINX sử dụng HTTP 2 bằng cách mở tập tin cấu hình NGINX của bạn tại /etc/nginx/conf.d và đổi phần listen 80 thành thế này:

server {
 listen 443 ssl http2;
 server_name domain.com www.domain.com;
 .....
}

Bước 2: Cấu hình SSL cho NGINX

Thiết lập chứng thực vùng nhớ (Session cache)

Điều này là khá quan trọng vì khi truy cập giao thức SSL thì lần đầu sẽ xử lý rất nặng và nhiều (Nên khi truy cập vào trang web https lần đầu tiên thường lâu hơn so với lần sau). Thiết lập này sẽ giúp NGINX nhớ session của user và  không cần chứng thực cho request kế tiếp.

ssl_session_cache shared:SSL:20m;
ssl_session_timeout 180m;

Ý nghĩa dòng 1 là tạo vùng nhớ 20MB cho chứng thực SSL. Theo tài liệu của NGINX thì 1MB chứ 4000 session. Vậy 20MB tương đương với 80.000 Session (bạn có thể điều chỉnh cho phù hợp với nhu cầu server bạn).

Dòng thứ 2 là lưu nó trong 180 phút (3 tiếng) con số này phù hợp với khoảng thời gian User truy cập website bạn. Nếu website bạn cần bảo mật hơn thì có thể giảm con số này xuống nhưng KHÔNG NÊN giảm dưới 10 phút.

Vô hiệu hóa SSL

Có thể là bạn nói tôi khùng, đang setup SSL giờ là vô hiệu hóa nó.

Nói vậy thôi, chứ thực ra là thay thế SSL (Secure Sockets Layer) bằng TLS(Transport Layer Security). Vì thực tế là SSL còn nhiều điểm yếu hơn là TLS. Tuy nhiên IE6 không hỗ trợ TLS (nhưng chắc là IE6 đã quá cổ rồi, tìm cũng chẳng còn đâu).

Thêm dòng sau tiếp theo 2 dòng trên:

ssl_protocols TLSv1.2;
# từ 02/2020 thì TLSv1 TLSv1.1 đưa vào danh sách lạc hậu, bạn cần chỉnh lại giá trị này

Tối ưu hóa Cipher Suites (Bộ mã hóa)

Trung tâm xử lý, mã hóa, giải mã của SSL/TLS là chổ này (tạm hiểu vậy vì mình không phân tích sâu vào cơ chế hoạt động của nó).

Khai báo NGINX bật bộ mã hóa:

ssl_prefer_server_ciphers on;

Khai báo danh sách các cơ chế mã hóa được chấp nhận:

ssl_ciphers ECDH+AESGCM:ECDH+AES256:ECDH+AES128:DH+3DES:!ADH:!AECDH:!MD5

Tạo ra các thông số DHParam

Tạo file DH (Diffie-Hellman) với 2048 bit (đủ chết cho những thằng muốn hack):

openssl dhparam 2048 -out /etc/nginx/cert/dhparam.pem

Sau đó thêm vào config dòng sau:

ssl_dhparam /etc/nginx/cert/dhparam.pem;

@Lưu ý: Nếu client của bạn dùng JAVA 6 trở xuống thì nên dùng 1024 bit thôi nhé ?

Kích hoạt OCSP

OCSP (Online Certificate Status Protocol) được hiểu như là kiểm tra chứng thức của bạn với nhà cùng cấp SSL (theo bài tạo chứng chỉ SSL đây là COMODO). Tạo ra file Khai báo với NGINX của bạn đây là giấy thức bằng cách sử dụng lệnh sau:

cat AddTrustExternalCARoot.crt PositiveSSLCA2.crt > trustchain.crt

File AddTrustExternalCARoot.crt là file gốc, file PositiveSSLCA2.crt là file chứng thực trung gian có kèm theo trong file zip khi bạn mua SSL hoặc download của COMODO tại đây.

Tiếp theo là cấu hình NGINX stapling

ssl_stapling on;
ssl_stapling_verify on;
ssl_trusted_certificate /etc/nginx/cert/trustchain.crt;
resolver 8.8.8.8 8.8.4.4;

Ở đây là mình dùng qua DNS Google, bạn có thể dùng DNS nào khác mà bạn tin tưởng hoặc nhanh hơn.

Cấu hình Strict Transport Security

Sau khi server đã chứng thực xong thì trả về trình duyệt thời gian chứng thực được chấp nhận, trong thời gian này khi request trình duyệt không cần gửi chứng thực với Server nữa (Dó là lý do tại sao chỉ nặng lúc đầu).

Thêm dòng sau vào config file:

add_header Strict-Transport-Security "max-age=31536000" always;

Trong trường hợp chứng thực này được dùng cho nhiều subdomain thì sửa lại như sau:

add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;

That All, chỉ thế thôi. Bạn save lại file và restart NGINX và có thể kiểm tra xem SSL của bạn được loại gì rồi nào?

Sau khi cấu hình xong bạn sẽ có file cấu hình NGINX của domain như thế này đây:

server {
 listen 443 ssl http2;
 listen [::]:443 ssl http2;
 
 server_name your_domain.com;
 
 ssl_certificate /etc/nginx/cert/your_key.certchain.crt;
 ssl_certificate_key /etc/nginx/cert/your_key.key;
 
 ssl_session_cache shared:SSL:20m;
 ssl_session_timeout 60m;
 
 ssl_prefer_server_ciphers on;
 ssl_ciphers ECDH+AESGCM:ECDH+AES256:ECDH+AES128:DH+3DES:!ADH:!AECDH:!MD5;
 
 ssl_dhparam /etc/nginx/cert/dhparam.pem;
 
 ssl_protocols TLSv1.2;
  
 ssl_stapling on;
 ssl_stapling_verify on;
 ssl_trusted_certificate /etc/nginx/cert/trustchain.crt;
 resolver 8.8.8.8 8.8.4.4;
 
 add_header Strict-Transport-Security "max-age=31536000" always;
 #add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
 
 # Cấu hình của bạn ở dưới này
 …
}

Sau đó bạn có thể kiểm tra server đã dùng HTTP 2 chưa bằng cách cài pluginHTTP/2 and SPDY indicator của Chrome.

Thế thôi, rất đơn giản phải không nào? Nhìn chung cách cài đặt SSL và bật HTTP/2 cũng khá đơn giản, nó cũng giống như mình kích hoạt SPDY mà thôi nhưng chỉ khác là thay spdy thành http2 trong phần listen của tập tin cấu hình mà thôi. Nhưng ngoài việc đó, trong bài này bạn cũng đã biết thêm một vài kỹ thuật quan trọng để cấu hình SSL an toàn hơn để đạt chuẩn A+ tại SSLLabs.

Nguồn: Bài viết được gởi từ tác giả Công Hải từ appfast.io là đối tác của Fullstack Station. Được biên tập và cập nhật bởi Fullstackstation.

Read more