TLS/SSL đóng vai trò như một “lớp vỏ” mã hóa, bao bọc toàn bộ lưu lượng truy cập thông thường, đảm bảo rằng mọi thông tin trao đổi giữa máy chủ và client đều được bảo vệ và mã hóa.
Nhờ công nghệ này, các máy chủ có thể gửi dữ liệu một cách an toàn mà không lo bị tin tặc nghe lén. Hơn nữa, hệ thống chứng chỉ còn giúp người dùng xác minh danh tính của trang web mà họ đang kết nối, chống lại các cuộc tấn công lừa đảo (phishing).
Trong bài hướng dẫn này, chúng ta sẽ cùng nhau thiết lập một chứng chỉ SSL tự ký (self-signed) để sử dụng với máy chủ web Apache trên hệ điều hành CentOS 7.
Lưu ý quan trọng: Một chứng chỉ tự ký sẽ mã hóa giao tiếp giữa máy chủ của bạn và mọi client. Tuy nhiên, vì nó không được ký bởi bất kỳ tổ chức cấp chứng chỉ (Certificate Authority – CA) đáng tin cậy nào (những CA này thường được tích hợp sẵn trong các trình duyệt web), người dùng sẽ không thể tự động xác thực danh tính của máy chủ của bạn. Kết quả là, người dùng sẽ thấy một cảnh báo bảo mật khi truy cập trang web của bạn.
Do hạn chế này, các chứng chỉ tự ký không phù hợp cho môi trường production phục vụ công khai. Chúng thường chỉ được sử dụng để thử nghiệm, phát triển, hoặc để bảo mật các dịch vụ không quan trọng, được sử dụng bởi một người dùng duy nhất hoặc một nhóm nhỏ người dùng có thể xác lập sự tin cậy vào tính hợp lệ của chứng chỉ thông qua các kênh liên lạc khác.
Để có một giải pháp chứng chỉ sẵn sàng cho môi trường production , bạn nên cân nhắc sử dụng Let’s Encrypt, một tổ chức cấp chứng chỉ miễn phí. Bạn có thể tìm hiểu cách tải xuống và cấu hình chứng chỉ Let’s Encrypt trong các tài liệu hướng dẫn chuyên sâu hơn.
Chuẩn bị
Trước khi bắt đầu với hướng dẫn này, có một vài bước bạn cần hoàn thành trước:
- Một máy chủ CentOS 7 với một người dùng không phải
root
có quyềnsudo
. - Cài đặt Apache
Sau khi hoàn thành các bước này, bạn có thể đăng nhập bằng tài khoản người dùng không phải root
qua SSH và tiếp tục với bài hướng dẫn.
Bước 1: Cài đặt mod_ssl
Để thiết lập chứng chỉ tự ký, trước tiên bạn phải đảm bảo rằng module mod_ssl
của Apache cung cấp hỗ trợ mã hóa SSL đã được cài đặt trên máy chủ. Bạn có thể cài đặt mod_ssl
bằng lệnh yum
:
sudo yum install mod_ssl
Module này sẽ tự động được kích hoạt trong quá trình cài đặt và Apache sẽ có thể bắt đầu sử dụng chứng chỉ SSL sau khi nó được khởi động lại.
Bước 2: Tạo một chứng chỉ mới
Giờ thì Apache đã sẵn sàng để sử dụng mã hóa, bạn có thể chuyển sang bước tạo một chứng chỉ SSL mới. TLS/SSL hoạt động bằng cách sử dụng kết hợp giữa một chứng chỉ công khai (public certificate) và một khóa riêng (private key). Khóa SSL được giữ bí mật trên máy chủ và được dùng để giải mã hóa nội dung mà client gửi đến. Trong khi đó, chứng chỉ SSL được chia sẻ công khai với bất kỳ ai yêu cầu nội dung.
Thư mục /etc/ssl/certs
, nơi có thể chứa chứng chỉ công khai, đã tồn tại trên máy chủ. Bạn sẽ cần tạo thêm thư mục /etc/ssl/private
để chứa tệp khóa riêng. Vì tính bí mật của khóa này là rất quan trọng, bạn cần phải thêm khóa quyền truy cập để ngăn chặn sự truy cập trái phép:
sudo mkdir /etc/ssl/private
sudo chmod 700 /etc/ssl/private
Bây giờ, bạn có thể tạo một cặp khóa và chứng chỉ tự ký bằng OpenSSL chỉ với một lệnh duy nhất:
sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/ssl/private/apache-selfsigned.key -out /etc/ssl/certs/apache-selfsigned.crt
Bạn sẽ được hỏi một loạt các câu hỏi.
openssl
: Đây là công cụ dòng lệnh cơ bản để tạo và quản lý các chứng chỉ, khóa và các tệp OpenSSL khác.req
: Lệnh con này chỉ định rằng bạn muốn sử dụng quản lý yêu cầu ký chứng chỉ X.509 (CSR). “X.509” là một tiêu chuẩn cơ sở hạ tầng khóa công khai mà SSL và TLS tuân thủ để quản lý khóa và chứng chỉ của chúng. Bạn muốn tạo một chứng chỉ X.509 mới, vì vậy bạn đang sử dụng lệnh con này.x509
: Điều này sửa đổi thêm lệnh con trước đó bằng cách cho tiện ích biết rằng bạn muốn tạo một chứng chỉ tự ký thay vì tạo một yêu cầu ký chứng chỉ, như thường lệ.nodes
: Lệnh này cho OpenSSL biết bỏ qua tùy chọn bảo mật chứng chỉ của bạn bằng một cụm mật khẩu (passphrase). Bạn cần Apache có thể đọc tệp mà không cần sự can thiệp của người dùng khi máy chủ khởi động. Một cụm mật khẩu sẽ ngăn điều này xảy ra vì bạn sẽ phải nhập nó sau mỗi lần khởi động lại.days 365
: Tùy chọn này đặt thời gian chứng chỉ sẽ được coi là hợp lệ. Chúng ta đặt là một năm ở đây.newkey rsa:2048
: Điều này chỉ định rằng bạn muốn tạo một chứng chỉ và một khóa mới cùng một lúc. Bạn chưa tạo khóa cần thiết để ký chứng chỉ ở bước trước, vì vậy bạn cần tạo nó cùng với chứng chỉ. Phầnrsa:2048
cho biết tạo khóa RSA dài 2048 bit.keyout
: Dòng này cho OpenSSL biết nơi đặt tệp khóa riêng đã tạo mà bạn đang tạo.out
: Điều này cho OpenSSL biết nơi đặt chứng chỉ mà bạn đang tạo.
Như đã nói ở trên, các tùy chọn này sẽ tạo ra cả tệp khóa và chứng chỉ. Bạn sẽ được hỏi một vài câu hỏi về máy chủ của bạn để nhúng thông tin chính xác vào chứng chỉ.
Hãy điền các thông tin được yêu cầu một cách phù hợp.
Lưu ý: Điều quan trọng là bạn phải nhập tên miền hoặc địa chỉ IP công cộng của máy chủ của bạn khi được nhắc nhập Common Name (e.g. server FQDN or YOUR name). Giá trị ở đây phải khớp với cách người dùng truy cập máy chủ của bạn.
Toàn bộ các câu hỏi sẽ trông giống như sau:
OutputCountry Name (2 letter code) [XX]:US
State or Province Name (full name) []:Example
Locality Name (eg, city) [Default City]:Example
Organization Name (eg, company) [Default Company Ltd]:Example Inc
Organizational Unit Name (eg, section) []:Example Dept
Common Name (eg, your name or your server's hostname) []:your_domain_or_ip
Email Address []:webmaster@example.com
Cả hai tệp bạn đã tạo sẽ được đặt trong các thư mục con thích hợp của thư mục /etc/ssl
.
Khi bạn đang sử dụng OpenSSL, bạn cũng nên tạo một nhóm Diffie-Hellman mạnh mẽ, được sử dụng trong việc trao đổi (Perfect Forward Secrecy) với các client.
Bạn có thể thực hiện điều này bằng cách gõ:
sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048
Quá trình này có thể mất vài phút, nhưng khi hoàn thành, bạn sẽ có một nhóm DH mạnh mẽ tại /etc/ssl/certs/dhparam.pem
mà bạn có thể sử dụng trong cấu hình của mình.
Bước 3: Cấu hình chứng chỉ cho Apache
Bạn đã có tất cả các thành phần cần thiết. Việc tiếp theo cần làm là thiết lập các virtual host để hiển thị chứng chỉ mới.
Mở một tệp mới trong thư mục /etc/httpd/conf.d
:
sudo vi /etc/httpd/conf.d/your_domain_or_ip.conf
Dán cấu hình VirtualHost
tối thiểu sau:
<VirtualHost *:443>
ServerName your_domain_or_ip
DocumentRoot /var/www/html
SSLEngine on
SSLCertificateFile /etc/ssl/certs/apache-selfsigned.crt
SSLCertificateKeyFile /etc/ssl/private/apache-selfsigned.key
</VirtualHost>
Hãy đảm bảo cập nhật dòng ServerName
thành cách bạn dự định truy cập máy chủ của mình. Đây có thể là tên máy chủ (hostname), tên miền đầy đủ (full domain name) hoặc địa chỉ IP. Đảm bảo bất cứ điều gì bạn chọn khớp với Common Name mà bạn đã chọn khi tạo chứng chỉ.
Thiết lập các tham số SSL bảo mật
Tiếp theo, bạn sẽ thêm một số tùy chọn SSL bổ sung để tăng cường bảo mật cho trang web của bạn. Các tùy chọn bạn sẽ sử dụng là các khuyến nghị từ Cipherlist.eu. Trang web này được thiết kế để cung cấp các cài đặt mã hóa dễ hiểu cho các phần mềm phổ biến.
Lưu ý: Các cài đặt mặc định được đề xuất trên Cipherlist.eu cung cấp bảo mật mạnh mẽ. Đôi khi, điều này phải trả giá bằng khả năng tương thích với client thấp hơn. Nếu bạn cần hỗ trợ các client cũ hơn, có một danh sách thay thế có thể truy cập bằng cách nhấp vào liên kết có nhãn “Yes, give me a ciphersuite that works with legacy / old software.”
Danh sách tương thích có thể được sử dụng thay vì các đề xuất mặc định trong cấu hình trên giữa hai khối comment. Việc lựa chọn cấu hình nào bạn sử dụng sẽ phụ thuộc phần lớn vào những gì bạn cần hỗ trợ.
Có một vài phần của cấu hình mà bạn có thể muốn sửa đổi. Đầu tiên, bạn có thể thêm trình phân giải DNS ưa thích của mình cho các yêu cầu ngược dòng vào chỉ thị resolver
. Trong hướng dẫn này, chúng ta sử dụng của Google.
Cuối cùng, bạn nên dành một chút thời gian để đọc về HTTP Strict Transport Security, hay HSTS, và đặc biệt là về chức năng “preload”. Việc tải trước HSTS cung cấp bảo mật tăng cường, nhưng có thể có những hậu quả sâu rộng nếu vô tình kích hoạt hoặc kích hoạt không chính xác. Trong hướng dẫn này, chúng ta sẽ không tải trước các cài đặt, nhưng bạn có thể sửa đổi điều đó nếu bạn chắc chắn hiểu các ý nghĩa.
Các thay đổi khác bạn sẽ thực hiện là xóa +TLSv1.3
và bỏ comment các chỉ thị SSLSessionTickets
và SSLOpenSSLConfCmd
, vì những thứ này không có sẵn trong phiên bản Apache được cung cấp cùng CentOS 7.
Dán các cài đặt từ trang web sau khi kết thúc khối VirtualHost
:
. . .
</VirtualHost>
. . .
# Begin copied text
# from <https://cipherli.st/>
SSLCipherSuite EECDH+AESGCM:EDH+AESGCM
# Requires Apache 2.4.36 & OpenSSL 1.1.1
SSLProtocol -all +TLSv1.2
# SSLOpenSSLConfCmd Curves X25519:secp521r1:secp384r1:prime256v1
# Older versions
# SSLProtocol All -SSLv2 -SSLv3 -TLSv1 -TLSv1.1
SSLHonorCipherOrder On
# Disable preloading HSTS for now. You can use the commented out header line that includes
# the "preload" directive if you understand the implications.
#Header always set Strict-Transport-Security "max-age=63072000; includeSubdomains; preload"
Header always set Strict-Transport-Security "max-age=63072000; includeSubdomains"
# Requires Apache >= 2.4
SSLCompression off
SSLUseStapling on
SSLStaplingCache "shmcb:logs/stapling-cache(150000)"
# Requires Apache >= 2.4.11
# SSLSessionTickets Off
Khi bạn hoàn tất các thay đổi này, bạn có thể lưu và đóng tệp.
Tạo Redirect từ HTTP sang HTTPS (Tùy chọn)
Với cấu hình hiện tại, máy chủ sẽ cung cấp cả lưu lượng HTTP không mã hóa và HTTPS được mã hóa. Để tăng cường bảo mật, trong hầu hết các trường hợp, việc chuyển hướng tự động HTTP sang HTTPS là điều nên làm. Nếu bạn không muốn hoặc không cần chức năng này, bạn có thể bỏ qua phần này.
Để chuyển hướng tất cả lưu lượng truy cập sang dạng mã hóa SSL, hãy tạo và mở một tệp có phần mở rộng .conf
trong thư mục /etc/httpd/conf.d
:
sudo vi /etc/httpd/conf.d/non-ssl.conf
Bên trong, tạo một khối VirtualHost
để khớp các yêu cầu trên cổng 80. Bên trong đó, sử dụng chỉ thị ServerName
để khớp lại tên miền hoặc địa chỉ IP của bạn. Sau đó, sử dụng Redirect
để khớp bất kỳ yêu cầu nào và gửi chúng đến VirtualHost
SSL. Đảm bảo bao gồm dấu gạch chéo ngược (trailing slash):
<VirtualHost *:80>
ServerName your_domain_or_ip
Redirect "/" "https://your_domain_or_ip/"
</VirtualHost>
Lưu và đóng tệp này khi bạn hoàn tất.
Bước 4: Áp dụng thay đổi cấu hình Apache
Đến đây, bạn đã tạo một chứng chỉ SSL và cấu hình máy chủ web của mình để áp dụng nó cho trang web. Để áp dụng tất cả các thay đổi này và bắt đầu sử dụng mã hóa SSL, bạn có thể khởi động lại máy chủ Apache để tải lại các cấu hình và module của nó.
Đầu tiên, kiểm tra tệp cấu hình của bạn để tìm lỗi cú pháp bằng cách gõ:
sudo apachectl configtest
Miễn là đầu ra kết thúc bằng Syntax OK
, bạn có thể yên tâm để tiếp tục. Nếu điều này không phải là một phần của đầu ra của bạn, hãy kiểm tra cú pháp của các tệp của bạn và thử lại:
Output. . .
Syntax OK
Khởi động lại máy chủ Apache để áp dụng các thay đổi của bạn bằng cách gõ:
sudo systemctl restart httpd.service
Tiếp theo, đảm bảo cổng 80 và 443 đã được mở trong tường lửa của bạn. Nếu bạn không chạy tường lửa, bạn có thể bỏ qua phần này.
Nếu bạn có tường lửa firewalld
đang chạy, bạn có thể mở các cổng này bằng cách gõ:
sudo firewall-cmd --add-service=http
sudo firewall-cmd --add-service=https
sudo firewall-cmd --runtime-to-permanent
Nếu bạn có tường lửa iptables
đang chạy, các lệnh bạn cần chạy phụ thuộc rất nhiều vào bộ quy tắc hiện tại của bạn. Đối với một bộ quy tắc cơ bản, bạn có thể thêm quyền truy cập HTTP và HTTPS bằng cách gõ:
sudo iptables -I INPUT -p tcp -m tcp --dport 80 -j ACCEPT
sudo iptables -I INPUT -p tcp -m tcp --dport 443 -j ACCEPT
Bước 5: Kiểm tra mã hóa
Giờ thì, bạn đã sẵn sàng để kiểm tra máy chủ SSL của mình.
Mở trình duyệt web của bạn và gõ https://
theo sau là tên miền hoặc địa chỉ IP của máy chủ của bạn vào thanh địa chỉ:
https://your_domain_or_ip
Vì chứng chỉ bạn đã tạo không được ký bởi một trong các tổ chức cấp chứng chỉ đáng tin cậy của trình duyệt của bạn, bạn có thể sẽ thấy một cảnh báo trông như sau:
Thao tác này là hoàn toàn bình thường và được mong đợi. Bạn chỉ quan tâm đến khía cạnh mã hóa của chứng chỉ, chứ không phải xác thực bên thứ ba về tính xác thực của máy chủ của bạn. Nhấp vào “ADVANCED” (hoặc “Nâng cao”) và sau đó là liên kết được cung cấp để tiếp tục truy cập máy chủ của bạn:
Bạn sẽ được đưa đến trang web của mình. Nếu bạn nhìn vào thanh địa chỉ của trình duyệt, bạn sẽ thấy một số dấu hiệu về bảo mật một phần. Đây có thể là một biểu tượng khóa có dấu “x” trên đó hoặc một hình tam giác có dấu chấm than. Trong trường hợp này, điều này chỉ có nghĩa là chứng chỉ không thể được xác thực. Nó vẫn đang mã hóa kết nối của bạn.
Nếu bạn đã cấu hình Apache để chuyển hướng các yêu cầu HTTP sang HTTPS, bạn cũng có thể kiểm tra xem việc chuyển hướng có hoạt động chính xác không:
http://your_domain_or_ip
Nếu điều này cho kết quả cùng một biểu tượng, điều đó có nghĩa là việc chuyển hướng của bạn đã hoạt động chính xác.
Kết luận
Như đã đề cập xuyên suốt bài viết, bạn cần nắm vững điểm mấu chốt: chứng chỉ tự ký (self-signed certificate) rất hữu ích cho các môi trường thử nghiệm, phát triển nội bộ hoặc các dịch vụ không quá nhạy cảm. Chúng cung cấp khả năng mã hóa dữ liệu mạnh mẽ, nhưng không đi kèm với sự xác thực danh tính từ một bên thứ ba đáng tin cậy. Điều này có nghĩa là người dùng bên ngoài sẽ nhận được cảnh báo bảo mật khi truy cập trang của bạn.
Nếu bạn đang có kế hoạch sử dụng SSL cho một trang web công cộng, phục vụ số lượng lớn người dùng, bạn nên cân nhắc mua một chứng chỉ SSL từ một tổ chức cấp chứng chỉ đáng tin cậy (như DigiCert, Sectigo, GlobalSign…) hoặc sử dụng các dịch vụ miễn phí như Let’s Encrypt để tránh các cảnh báo đáng sợ hiển thị cho mỗi khách truy cập của bạn. Việc này sẽ giúp website của bạn trông chuyên nghiệp và đáng tin cậy hơn rất nhiều trong mắt người dùng cuối.
Hy vọng bài viết này đã cung cấp cho bạn cái nhìn rõ ràng và các bước thực hành cụ thể để làm chủ việc cấu hình SSL cơ bản trên Apache.