Bảo mật dữ liệu là “khẩu hiệu sống còn” của các doanh nghiệp trong thế giới số hóa ngày nay. Chính vì thế việc một website phải có xác thực HTTPS là điều tất yếu. HTTP (Hypertext Transfer Protocol) và HTTPS (Hypertext Transfer Protocol Secure) là hai giao thức được sử dụng để truyền tải dữ liệu qua internet. Tuy cùng chung mục đích, nhưng sự khác biệt giữa chúng có thể được ví như sự chênh lệch giữa “đánh cá trong ao” và “đánh cá trên biển”.
Việc xác thực HTTPS bởi một website công khai đã mua tên miền và mua xác thực SSL thì chắc hẳn rất bình thường, nhưng bạn có biết trong môi trường chúng ta phát triển phần mềm (development environment) thì việc cấu hình https đôi khi là điều rất cần thiết vì có ứng dụng yêu cầu chúng ta phải chạy https mới hoạt động mà không hẳn công ty nào cũng triển khai domain trong môi trường đó. Vậy nên, thông thường trong môi trường đó chỉ có những chiếc máy chủ và IP máy chủ đó vậy làm sao để cấu hình HTTPS “xanh lè” như bỏ tiền ra để mua thì bạn hãy xem bài viết ngắn này để thấy.
Nội dung
Kết quả
Những bước triển khai
- Step 0: Thiết lập ban đầu về dự án.
- Step 1: Tạo file cung cấp các thiết lập và yêu cầu cần thiết để tạo ra một Certificate Authority.
- Step 2: Tạo file định nghĩa các thông tin mở rộng cho chứng chỉ máy chủ.
- Step 3: Tạo một chứng chỉ tự ký và khóa riêng tư cho Certificate Authority.
- Step 4: Tạo ra một yêu cầu chứng chỉ (CSR) và khóa riêng tư cho máy chủ với tên chung.
- Step 5: Ký chứng chỉ cho yêu cầu chứng chỉ của máy chủ bằng Certificate Authority (CA).
- Step 6: Sử dụng chứng chỉ và khóa riêng tư của máy chủ, cùng với chứng chỉ CA, để khởi chạy một máy chủ SSL/TLS.
- Step 7: Cấu hình Nginx reverse proxy để chạy xác thực https dự án.
Triển khai chi tiết xác thực HTTPS
Step 0: Thiết lập ban đầu về dự án
Tôi đã chạy một Server Ubuntu 20.04 có địa chỉ IP là 10.32.4.190.
Nếu bạn chưa có Server hãy xem bài viết Cách dùng Vagrant tạo máy ảo để tạo nhanh một Server chỉ với một câu lệnh.
Tiếp theo, trên server này tôi đã cài docker và chạy một dự án html, css tại địa chỉ http://10.32.4.190:8010 như bạn có thể thấy nó chạy http và cảnh bảo Not secure.
Nếu bạn muốn chạy website giống như tôi có thể thực hiện:
$ docker pull elroydevops/car-serv
pull docker image từ Dockerhub.
$ docker run --name=car-serv -dp 8010:80 elroydevops/car-serv
chạy dự án website.
Step 1: Tạo file cung cấp các thiết lập và yêu cầu cần thiết để tạo ra một Certificate Authority.
Hãy đảm bảo là server của bạn đã cài đặt Nginx và enable port Nginx như dưới đây:
Và chạy được website nginx như dưới đây dĩ nhiên vẫn là HTTP chưa xác thực HTTPS:
$ mkdir /etc/nginx/certs; cd /etc/nginx/certs
tạo thư mục chứa các thông tin về certs và di chuyển đến đó.
Tiếp tục thực hiện tiếp bước sau:
$ vi myAwesomeCA.cnf
tạo file có nội dung:
[ req ] distinguished_name = req_distinguished_name x509_extensions = root_ca [ req_distinguished_name ] countryName = Country Name (2 letter code) countryName_min = 2 countryName_max = 2 stateOrProvinceName = State or Province Name (full name) localityName = Locality Name (eg, city) 0.organizationName = Organization Name (eg, company) organizationalUnitName = Organizational Unit Name (eg, section) commonName = Common Name (eg, fully qualified host name) commonName_max = 64 emailAddress = Email Address emailAddress_max = 64 [ root_ca ] basicConstraints = critical, CA:true
- [req]: Đây là phần đầu tiên trong tệp tin và định nghĩa các yêu cầu chung cho quá trình tạo yêu cầu chứng chỉ (Certificate Signing Request – CSR) từ CA.
-
- distinguished_name: Định nghĩa các trường thông tin cá nhân, tổ chức hoặc cấu trúc liên quan đến yêu cầu chứng chỉ. Đây bao gồm quốc gia, tiểu bang hoặc tỉnh thành, địa phương, tên tổ chức, đơn vị tổ chức, tên phổ biến và địa chỉ email.
- x509_extensions: Định nghĩa các phần mở rộng cho chứng chỉ X.509, trong trường hợp này là phần mở rộng của chứng chỉ gốc (root certificate).
- [req_distinguished_name]: Đây là phần định nghĩa chi tiết cho các trường thông tin trong yêu cầu chứng chỉ (CSR). Các trường thông tin này sẽ được điền vào khi tạo CSR.
- countryName: Đại diện cho tên quốc gia, được yêu cầu nhập vào dưới dạng mã quốc gia 2 ký tự.
- stateOrProvinceName: Đại diện cho tên tiểu bang, tỉnh thành.
- localityName: Đại diện cho tên địa phương, thành phố.
- 0.organizationName: Đại diện cho tên tổ chức hoặc công ty.
- organizationalUnitName: Đại diện cho tên đơn vị tổ chức hoặc phòng ban.
- commonName: Đại diện cho tên chung, thông thường là tên miền hoặc tên máy chủ đầy đủ.
- emailAddress: Đại diện cho địa chỉ email.
- [root_ca]: Đây là phần định nghĩa các phần mở rộng cho chứng chỉ gốc (root certificate).
- basicConstraints: Định nghĩa các ràng buộc cơ bản cho chứng chỉ, trong trường hợp này là ràng buộc cơ bản bắt buộc và xác định rằng đây là một CA (CA:true).
Bạn có thể tham khảo openssl tại: openssl.org – docs
Step 2: Tạo file định nghĩa các thông tin mở rộng cho chứng chỉ máy chủ.
$ vi myAwesomeServer.ext
tạo file có nội dung:
subjectAltName = @alt_names extendedKeyUsage = serverAuth [alt_names] IP.1 = 10.32.4.1 IP.2 = 10.32.4.2
- subjectAltName: Đây là một phần mở rộng của chứng chỉ X.509 và được sử dụng để xác định tên chung (common name) thay thế cho chứng chỉ. Trong trường hợp này, thông tin này được định dạng như sau:
- @alt_names: Đây là một tham chiếu đến phần [alt_names] trong tệp tin, nơi chúng ta sẽ xác định các tên chung (common names) thay thế.
- extendedKeyUsage: Đây là một phần mở rộng khác của chứng chỉ X.509 và xác định mục đích sử dụng của chứng chỉ. Trong trường hợp này, thông tin này được định dạng như sau:
- serverAuth: Đây là một mục đích sử dụng mở rộng cho chứng chỉ, xác định rằng chứng chỉ này được sử dụng để xác thực máy chủ trong quá trình giao tiếp (server authentication).
- [alt_names]: Đây là phần định nghĩa cho danh sách các tên chung (common names) thay thế, được sử dụng trong phần subjectAltName.
- IP.1: Đại diện cho địa chỉ IP thứ nhất, trong trường hợp này là 10.32.4.1
- IP.2: Đại diện cho địa chỉ IP thứ hai, trong trường hợp này là 10.32.4.2
Bạn cũng hãy yên tâm vì chúng ta không hẳn cần fix cứng toàn bộ các IP.
Step 3: Tạo một chứng chỉ tự ký và khóa riêng tư cho Certificate Authority
$ openssl req -x509 -newkey rsa:2048 -out myAwesomeCA.cer -outform PEM -keyout myAwesomeCA.pvk -days 10000 -verbose -config myAwesomeCA.cnf -nodes -sha256 -subj "/CN=MyCompany CA"
openssl req
: Lệnh OpenSSL để tạo yêu cầu chứng chỉ (Certificate Signing Request – CSR) hoặc chứng chỉ tự ký.-x509
: Tùy chọn để tạo chứng chỉ tự ký.-newkey rsa:2048
: Tạo một cặp khóa mới, sử dụng thuật toán RSA với độ dài 2048 bit.-out myAwesomeCA.cer
: Đặt tên tệp chứng chỉ tự ký xuất ra là myAwesomeCA.cer.-outform PEM
: Định dạng tệp xuất ra là PEM (Privacy-Enhanced Mail).-keyout myAwesomeCA.pvk
: Đặt tên tệp khóa riêng tư xuất ra là myAwesomeCA.pvk.-days 10000
: Đặt thời hạn (số ngày) của chứng chỉ là 10,000 ngày.-verbose
: Xuất ra thông tin chi tiết về quá trình tạo chứng chỉ.-config myAwesomeCA.cnf
: Sử dụng tệp cấu hình myAwesomeCA.cnf để thiết lập các thông tin chứng chỉ.-nodes
: Không mã hóa khóa riêng tư khi lưu trữ nó.-sha256
: Sử dụng thuật toán băm SHA-256 cho chứng chỉ.-subj "/CN=MyCompany CA"
: Xác định phần tử chủ (subject) của chứng chỉ, trong trường hợp này, Common Name (CN) được đặt là “MyCompany CA”
hãy chú ý bạn nên đổi tương ứng MyCompany thành tên cert mà bạn muốn hiển thị nhé.
Step 4: Tạo ra một yêu cầu chứng chỉ (CSR) và khóa riêng tư cho máy chủ với tên chung
$ openssl req -newkey rsa:2048 -keyout myAwesomeServer.pvk -out myAwesomeServer.req -subj /CN=localhost -sha256 -nodes
openssl req
: Lệnh OpenSSL để tạo yêu cầu chứng chỉ (CSR).-newkey rsa:2048
: Tạo một cặp khóa mới, sử dụng thuật toán RSA với độ dài 2048 bit.-keyout myAwesomeServer.pvk
: Đặt tên tệp khóa riêng tư xuất ra là myAwesomeServer.pvk.-out myAwesomeServer.req
: Đặt tên tệp yêu cầu chứng chỉ xuất ra là myAwesomeServer.req.-subj /CN=localhost
: Xác định phần tử chủ (subject) của yêu cầu chứng chỉ, trong trường hợp này, Common Name (CN) được đặt là “localhost”.-sha256
: Sử dụng thuật toán băm SHA-256 cho yêu cầu chứng chỉ.-nodes
: Không mã hóa khóa riêng tư khi lưu trữ nó.
Step 5: Ký chứng chỉ cho yêu cầu chứng chỉ của máy chủ bằng Certificate Authority (CA)
$ openssl x509 -req -CA myAwesomeCA.cer -CAkey myAwesomeCA.pvk -in myAwesomeServer.req -out myAwesomeServer.cer -days 10000 -extfile myAwesomeServer.ext -sha256 -set_serial 0x1111
openssl x509
: Lệnh OpenSSL để xử lý chứng chỉ X.509.-req
: Xác định rằng đầu vào là một yêu cầu chứng chỉ (CSR).-CA myAwesomeCA.cer
: Xác định tệp chứng chỉ CA (myAwesomeCA.cer) để ký chứng chỉ.-CAkey myAwesomeCA.pvk
: Xác định tệp khóa riêng tư CA (myAwesomeCA.pvk) để ký chứng chỉ.-in myAwesomeServer.req
: Xác định tệp yêu cầu chứng chỉ (CSR) của máy chủ (myAwesomeServer.req) cần được ký.-out myAwesomeServer.cer
: Đặt tên tệp chứng chỉ ký (signed certificate) xuất ra là myAwesomeServer.cer.-days 10000
: Đặt thời hạn (số ngày) của chứng chỉ là 10,000 ngày.-extfile myAwesomeServer.ext
: Xác định tệp mở rộng (extension) (myAwesomeServer.ext) để thiết lập thông tin mở rộng cho chứng chỉ.-sha256
: Sử dụng thuật toán băm SHA-256 cho chứng chỉ.-set_serial 0x1111
: Đặt số serial cho chứng chỉ là 0x1111 (đây là giá trị ví dụ, bạn có thể chọn giá trị khác).
Step 6: Sử dụng chứng chỉ và khóa riêng tư của máy chủ, cùng với chứng chỉ CA, để khởi chạy một máy chủ SSL/TLS
$ openssl s_server -accept 15000 -cert myAwesomeServer.cer -key myAwesomeServer.pvk -CAfile myAwesomeCA.cer -WWW
openssl s_server
: Lệnh OpenSSL để khởi chạy một máy chủ SSL/TLS.-accept 15000
: Xác định cổng (port) mà máy chủ sẽ lắng nghe kết nối, trong trường hợp này là cổng 15000.-cert myAwesomeServer.cer
: Xác định tệp chứng chỉ máy chủ (myAwesomeServer.cer) được sử dụng để xác thực và bảo mật kết nối.-key myAwesomeServer.pvk
: Xác định tệp khóa riêng tư máy chủ (myAwesomeServer.pvk) được sử dụng để giải mã và bảo mật kết nối.-CAfile myAwesomeCA.cer
: Xác định tệp chứng chỉ CA (myAwesomeCA.cer) được sử dụng để xác thực chứng chỉ máy chủ và thiết lập một chuỗi tin cậy (trust chain).-WWW
: Tạo một máy chủ web đơn giản, sử dụng giao thức HTTP để truyền thông tin.
Step 7: Cấu hình Nginx reverse proxy để chạy xác thực https dự án
$ mv /etc/nginx/sites-available/default /etc/nginx/certs
chuyển file cấu hình Nginx mặc định ra (bạn có thể xóa cũng được)
Hiện tại tổng những thông tin chúng ta có như dưới đây:
$ vi /etc/nginx/sites-available/default
mở file và điền thông tin dưới đây
server { listen 80; server_name 10.32.4.190; return 301 https://$host$request_uri; } server { listen 443 ssl; server_name 10.32.4.190; ssl_certificate /etc/nginx/certs/myAwesomeServer.cer; ssl_certificate_key /etc/nginx/certs/myAwesomeServer.pvk; location / { proxy_pass http://10.32.4.190:8010; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_ssl_verify off; } }
$ nginx -t && systemctl restart nginx
test Nginx và restart lại nginx.
Vậy là hiện tại website có thể chạy HTTPS tuy nhiên lại chưa được xác thực HTTPS nên gặp tình trạng như dưới đây:
Tiếp theo chúng ta cần Copy file myAwesomeCA.cer vào máy cá nhân của chúng ta, tại vì chúng ta sẽ cần phải thêm nó vào web browser như Chrome, Microsort EGDE, Firefox,…
$ exit
thoát khỏi server
$ scp [email protected]:/etc/nginx/certs/myAwesomeCA.cer "D:\Downloads"
copy file chứng chỉ số (digital certificate) vào máy cá nhân của tôi tại thư mục D:\Downloads
Tiếp theo tiến hành thêm chứng chỉ vào web browser:
Chọn sang Trusted Root Certification Authorities tiến hành import
Kiểm tra lại website và đã thành công xác thực HTTPS
Vậy là trong bài viết này mình đã hướng dẫn xong cách tự xác thực HTTPS khi bạn chỉ có chiếc server phù hợp môi trường phát triển phần mềm. Nếu bạn muốn tìm hiểu về DevOps thì có thể theo dõi website của mình, mình luôn hướng tới sự chi tiết, đơn giản, Mình sẽ làm nhiều hướng dẫn hơn về các kỹ năng các tool khác để giúp bạn tối ưu được những tác vụ cũng như tiết kiệm những chi phí khi phát triển phần mềm. Thanks.
Mọi thắc mắc bạn có thể liên hệ:
Email: [email protected]