---
title: "Cách thiết lập Nginx với Hỗ trợ HTTP/2 trên Ubuntu 20.04"
description: "Cách thiết lập Nginx với Hỗ trợ HTTP/2 trên Ubuntu 20.04"
url: https://cloudfly.vn/techblog/cach-thiet-lap-nginx-voi-ho-tro-http2-tren-ubuntu-2004
image: https://media.cloudfly.vn/posts/techblog_093I9Rt.png
---

# Cách thiết lập Nginx với Hỗ trợ HTTP/2 trên Ubuntu 20.04

Phiên bản trước của hướng dẫn này được viết bởi Sergey Zhukaev.

## Giới thiệu

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:

* Tất cả các yêu cầu được tải xuống song song, không phải trong hàng đợi
* Tiêu đề HTTP được nén
* Chuyển trang dưới dạng tệp nhị phân, không phải dưới dạng tệp văn bản, hiệu quả hơn
* Máy chủ có thể "đẩy" dữ liệu ngay cả khi không có yêu cầu của user, điều này giúp cải thiện tốc độ cho những người dùng có độ trễ cao

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.

## Điều kiện

Trước khi bắt đầu, bạn sẽ cần một số điều sau:

* Máy chủ Ubuntu 20.04 được cài đặt bằng cách làm theo hướng dẫn thiết lập máy chủ ban đầu Ubuntu 20.04, bao gồm sudo non-root user và tường lửa.
* Nginx được cài đặt trên máy chủ của bạn, bạn có thể thực hiện việc này bằng cách làm theo Cách cài đặt Nginx trên Ubuntu 20.04.
* Tên miền được thiết lập cấu hình để trỏ đến máy chủ của bạn. Bạn có thể mua một cái trên CloudFly hoặc nhận một cái miễn phí trên Freenom. 
* Chứng chỉ TLS / SSL được thiết lập cấu hình cho máy chủ của bạn. Bạn có hai lựa chọn:
1. Bạn có thể nhận chứng chỉ miễn phí từ Let’s Encrypt bằng cách làm theo Cách bảo mật Nginx với Let’s Encrypt trên Ubuntu 20.04.
2. Bạn cũng có thể tạo và thiết lập cấu hình chứng chỉ tự ký bằng cách làm theo Cách tạo chứng chỉ SSL tự ký cho Nginx trong Ubuntu 20.04.

* Nginx được thiết lập cấu hình để chuyển hướng lưu lượng truy cập từ cổng `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 đó.
* Nginx được thiết lập cấu hình để sử dụng khóa Ephemeral Diffie-Hellman (DHE) 2048 bit hoặc cao hơn, khóa này cũng phải được đề cập trong các điều kiện tiên quyết trước đó.

## Bước 1: Bật hỗ trợ HTTP/2

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:
```command
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`:
```nginx
[label /etc/nginx/sites-enabled/your_domain]
...
    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`:
```nginx
[label /etc/nginx/sites-enabled/your_domain]
...
    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:
```command
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
[label Output of sudo nginx -t]
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ủ.

## Bước 2: Xóa bộ mật mã cũ và không an toàn

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:
```custom_prefix()
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:
```nginx
[label /etc/nginx/sites-enabled/your_domain]
<^>#<^> 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:
```nginx
[label /etc/nginx/sites-enabled/your_domain]
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:
```command
sudo nano /etc/nginx/snippets/ssl-params.conf
```

Xác định vị trí dòng sau:
```nginx
[label /etc/nginx/snippets/ssl-params.conf]
...
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:
```nginx
[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`:
```command
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`:
```command
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.

## Bước 3: Xác minh rằng HTTP/2 đã được Bật

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 đề:
```command
curl -I -L --http2 https://<^>your_domain<^>
```

Bạn sẽ nhận được đầu ra như sau:
```custom_prefix()
<^>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.

![description image](https://media.cloudfly.vn/posts/cach-thiet-lap-Nginx-voi-ho-tro-HTTP-2-tren-Ubuntu-20.04_2.png)

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.

## Bước 4: Bật bảo mật truyền tải nghiêm ngặt HTTP (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:
```custom_prefix()
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:
```nginx
[label /etc/nginx/your_domain]
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:
```nginx
[label /etc/nginx/your_domain]
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:
```command
sudo nginx -t
```

Cuối cùng, khởi động lại máy chủ Nginx để áp dụng các thay đổi.
```command
sudo systemctl reload nginx.service
```

## Kết luận

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.
