Phiên bản trước của hướng dẫn này được viết bởi Sergey Zhukaev.
Nginx là một máy chủ web mã nguồn mở nhanh và đáng tin cậy. Nó trở nên phổ biến do dung lượng bộ nhớ thấp, khả năng mở rộng cao, dễ cấu hình và hỗ trợ nhiều loại giao thức.
HTTP/2 là phiên bản mới hơn của Hypertext Transport Protocol, được sử dụng trên Web để phân phối các trang từ máy chủ đến trình duyệt. HTTP/2 là bản cập nhật lớn đầu tiên của HTTP trong gần hai thập kỷ: HTTP1.1 được giới thiệu với công chúng vào năm 1999, khi các trang web có kích thước nhỏ hơn nhiều. Internet đã thay đổi đáng kể kể từ đó và hiện chúng ta đang phải đối mặt với những hạn chế của HTTP 1.1. Giao thức giới hạn tốc độ truyền tiềm năng đối với hầu hết các trang web hiện đại, vì nó tải các phần của trang trong hàng đợi - phần trước phải tải xuống hoàn toàn trước khi bắt đầu tải phần tiếp theo - và một trang web hiện đại trung bình tải xuống hàng chục CSS, javascript riêng lẻ, và nội dung hình ảnh.
HTTP/2 giải quyết vấn đề này vì nó mang lại một số thay đổi cơ bản:
Mặc dù HTTP/2 không yêu cầu mã hóa, các nhà phát triển của hai trình duyệt phổ biến nhất, Google Chrome và Mozilla Firefox, đã tuyên bố rằng vì lý do bảo mật, họ sẽ chỉ hỗ trợ HTTP/2 cho các kết nối HTTPS. Do đó, nếu bạn quyết định thiết lập máy chủ có hỗ trợ HTTP/2, bạn cũng phải bảo mật chúng bằng HTTPS.
Hướng dẫn này sẽ giúp bạn thiết lập máy chủ Nginx nhanh chóng và an toàn với hỗ trợ HTTP/2.
Trước khi bắt đầu, bạn sẽ cần một số điều sau:
80
sang cổng 443
, điều này sẽ được đề cập trong các điều kiện tiên quyết trước đó.Nếu bạn đã làm theo bước thiết lập server block trong hướng dẫn cài đặt Nginx, bạn sẽ có một server block cho miền của mình tại /etc/nginx/sites-available/your_domain
với chỉ thị server_name
đã được đặt thích hợp. Thay đổi đầu tiên mà chúng ta sẽ thực hiện là sửa đổi server block miền của bạn để sử dụng HTTP/2.
Mở tệp cấu hình cho miền của bạn bằng nano
hoặc trình chỉnh sửa ưa thích của bạn:
- sudo nano /etc/nginx/sites-enabled/your_domain
Trong tệp, xác định vị trí các biến listen
được liên kết với cổng 443
:
...
listen [::]:443 ssl ipv6only=on;
listen 443 ssl;
...
Cái đầu tiên dành cho các kết nối IPv6. Cái thứ hai dành cho tất cả các kết nối IPv4. Chúng ta sẽ bật HTTP/2 cho cả hai.
Sửa đổi từng chỉ thị listen
để bao gồm http2
:
...
listen [::]:443 ssl http2 ipv6only=on;
listen 443 ssl http2;
...
Điều này yêu cầu Nginx sử dụng HTTP/2 với các trình duyệt được hỗ trợ.
Lưu tệp cấu hình và thoát khỏi trình soạn thảo văn bản. Nếu bạn đang sử dụng nano
, hãy nhấn Ctrl + X
, sau đó, khi được nhắc, hãy nhấn Y
rồi nhấn Enter
.
Bất cứ khi nào bạn thực hiện thay đổi đối với tệp cấu hình Nginx, bạn nên kiểm tra cấu hình để tìm lỗi, sử dụng cờ -t
, chạy lệnh kiểm tra cú pháp tích hợp của Nginx:
- sudo nginx -t
Nếu cú pháp không có lỗi, bạn sẽ nhận được kết quả như sau:
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
Tiếp theo, bạn sẽ thiết lập cấu hình máy chủ Nginx của mình để sử dụng danh sách mật mã hạn chế hơn nhằm cải thiện tính bảo mật của máy chủ.
HTTP/2 có một danh sách chặn các mật mã cũ và không an toàn cần tránh. Bộ mật mã là các thuật toán mật mã mô tả cách mã hóa dữ liệu được truyền.
Phương pháp bạn sẽ sử dụng để xác định mật mã tùy thuộc vào cách bạn đã thiết lập cấu hình chứng chỉ TLS / SSL của mình cho Nginx.
Nếu bạn đã sử dụng Certbot để lấy chứng chỉ của mình, nó cũng tạo ra tệp /etc/letsencrypt/options-ssl-nginx.conf
chứa các mật mã không đủ an toàn cho HTTP/2. Tuy nhiên, việc sửa đổi tệp này sẽ ngăn Certbot áp dụng các bản cập nhật trong tương lai, vì vậy, chúng ta sẽ yêu cầu Nginx không sử dụng tệp này và chúng ta sẽ chỉ định danh sách mật mã của riêng mình.
Mở tệp cấu hình server block cho miền của bạn:
sudo nano /etc/nginx/sites-enabled/your_domain
Tìm dòng bao gồm tệp options-ssl-nginx.conf
và nhận xét nó bằng cách thêm ký tự #
vào đầu dòng:
# include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
Bên dưới dòng đó, thêm dòng này để xác định các mật mã được phép:
ssl_ciphers EECDH+CHACHA20:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5;
Lưu tệp và thoát khỏi trình chỉnh sửa.
Nếu bạn đã sử dụng chứng chỉ tự ký hoặc sử dụng chứng chỉ từ bên thứ ba và thiết lập cấu hình nó theo các điều kiện tiên quyết, hãy mở tệp /etc/nginx/snippets/ssl-params.conf
trong trình soạn thảo văn bản của bạn:
- sudo nano /etc/nginx/snippets/ssl-params.conf
Xác định vị trí dòng sau:
...
ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384;
...
Sửa đổi nó để sử dụng danh sách mật mã sau:
[label /etc/nginx/snippets/ssl-params.conf
]
...
ssl_ciphers EECDH+CHACHA20:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5;
Lưu tệp và thoát khỏi trình chỉnh sửa của bạn.
Một lần nữa, hãy kiểm tra cấu hình để tìm lỗi cú pháp bằng lệnh nginx -t
:
- sudo nginx -t
Nếu bạn gặp bất kỳ lỗi nào, hãy giải quyết chúng và kiểm tra lại.
Khi cấu hình của bạn vượt qua kiểm tra cú pháp, hãy khởi động lại Nginx bằng lệnh systemctl
:
- sudo systemctl reload nginx.service
Khi máy chủ được khởi động lại, hãy xác minh rằng nó hoạt động.
Hãy đảm bảo máy chủ đang chạy và hoạt động với HTTP/2.
Sử dụng lệnh curl
để đưa ra yêu cầu đối với trang web của bạn và xem các tiêu đề:
- curl -I -L --http2 https://your_domain
Bạn sẽ nhận được đầu ra như sau:
HTTP/2 200
server: nginx/1.18.0 (Ubuntu)
date: Wed, 10 Nov 2021 17:53:10 GMT
content-type: text/html
content-length: 612
last-modified: Tue, 09 Nov 2021 23:18:37 GMT
etag: "618b01cd-264"
accept-ranges: bytes
Bạn cũng có thể xác minh rằng HTTP/2 đang được sử dụng trong Google Chrome. Mở Chrome và điều hướng đến https: //your_domain
. Mở Chrome Developer Tools (View -> Developer -> Developer Tools) và tải lại trang (View -> Reload This Page). Điều hướng đến tab Network, nhấp chuột phải vào hàng tiêu đề bảng bắt đầu bằng Name và chọn tùy chọn Protocol từ menu bật lên.
Bạn sẽ có một cột Protocol mới chứa h2
(viết tắt của HTTP/2), cho biết rằng HTTP/2 đang hoạt động.
Tại thời điểm này, bạn đã sẵn sàng phân phát nội dung thông qua giao thức HTTP/2. Hãy cải thiện hiệu suất và bảo mật bằng cách bật HSTS.
Mặc dù các yêu cầu HTTP của bạn chuyển hướng đến HTTPS, bạn có thể bật Bảo mật truyền tải nghiêm ngặt HTTP (HTTP Strict Transport Security - HSTS) để tránh phải thực hiện các chuyển hướng đó. Nếu trình duyệt tìm thấy tiêu đề HSTS, nó sẽ không cố gắng kết nối lại với máy chủ qua HTTP thông thường trong một khoảng thời gian nhất định. Nếu không có vấn đề gì, nó sẽ trao đổi dữ liệu chỉ bằng cách sử dụng kết nối HTTPS được mã hóa. Tiêu đề này cũng bảo vệ chúng ta khỏi các cuộc tấn công hạ cấp giao thức.
Mở lại tệp cấu hình server block cho miền của bạn:
sudo nano /etc/nginx/your_domain
Thêm dòng này vào cùng một khối của tệp chứa mật mã SSL để kích hoạt HSTS:
server {
...
ssl_ciphers EECDH+CHACHA20:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5;
add_header Strict-Transport-Security "max-age=15768000" always;
}
...
max-age
được đặt bằng giây. Giá trị 15768000
tương đương 6 tháng.
Theo mặc định, tiêu đề này không được thêm vào các yêu cầu tên miền phụ. Nếu bạn có tên miền phụ và muốn HSTS áp dụng cho tất cả chúng, bạn nên thêm biến includeSubDomains
vào cuối dòng, như sau:
add_header Strict-Transport-Security "max-age=15768000; includeSubDomains" always;
Lưu tệp và thoát khỏi trình chỉnh sửa.
Một lần nữa, hãy kiểm tra cấu hình để tìm lỗi cú pháp:
- sudo nginx -t
Cuối cùng, khởi động lại máy chủ Nginx để áp dụng các thay đổi.
- sudo systemctl reload nginx.service
Máy chủ Nginx của bạn hiện đang cung cấp các trang HTTP/2. Nếu bạn muốn kiểm tra độ bền của kết nối SSL của mình, vui lòng truy cập Qualys SSL Lab và chạy thử nghiệm trên máy chủ của bạn. Nếu mọi thứ được cấu hình đúng cách, bạn sẽ nhận được điểm A + để bảo mật.
Để tìm hiểu thêm về cách Nginx phân tích cú pháp và triển khai các quy tắc khối máy chủ, hãy thử đọc Tìm hiểu về Máy chủ Nginx và Các thuật toán lựa chọn Location Block.