https và SSL
Bài đăng này đã không được cập nhật trong 3 năm
Tổng quan
Http và https là 2 protocol chúng ta thường gặp khi truy cập vào một trang web. Hầu hết chúng ta đều hiểu https bảo mật hơn http. Hôm nay mình sẽ giải thích bản chất, cơ chế và cách config một trang web https.
Http và https
http
là tên viết tắt của HyperText Transfer Protocol (giao thức truyền tải siêu văn bản), là một giao thức cơ bản dùng cho World Wide Web (www) để truyền tải dữ liệu dưới dạng văn bản, hình ảnh, video, âm thanh và các tập tin khác từ Web server đến các trình duyệt web và ngược lại.https
là viết tắt của từ HyperText Transfer Protocol Secure và chính là giao thức HTTP có sử dụng thêm các chứng chỉ SSL (Secure Sockets Layer) giúp mã hóa dữ liệu truyền tải nhằm gia bảo mật giữa Web sever đến các trình duyệt web. Nói cách kháchttps
là phiên bảnhttp
nhưng an toàn hơn, bảo mật hơn. Việc bảo mật thông tin riêng tư, cá nhân là rất quan trọng. Do đó có rất nhiều website đã sử dụnghttps
thayhttp
. Các trình duyệt web như Firefox, Chrome và IE như hiện nay đều hiển thị biểu tượng ổ khóa ở thanh địa chỉ để cho biết giao thứchttps
có hoạt động trên trang web bạn truy cập vào hay không.
Cơ chế của SSL ứng dụng trong HTTPS.
SSL là gì?
Việc kết nối giữa một Web browser tới bất kỳ điểm nào trên mạng Internet đi qua rất nhiều các hệ thống độc lập mà không có bất kỳ sự bảo vệ nào với các thông tin trên đường truyền. Không một ai kể cả người sử dụng lẫn Web server có bất kỳ sự kiểm soát nào đối với đường đi của dữ liệu hay có thể kiểm soát được liệu có ai đó thâm nhập vào thông tin trên đường truyền.
Để bảo vệ những thông tin mật trên mạng Internet hay bất kỳ mạng TCP/IP nào, SSL đã kết hợp những yếu tố sau để thiết lập được một giao dịch an toàn:
- Xác thực: đảm bảo tính xác thực của trang mà khách hàng sẽ làm việc ở đầu kia của kết nối. Cũng như vậy, các trang Web cũng cần phải kiểm tra tính xác thực của người sử dụng.
- Mã hoá: đảm bảo thông tin không thể bị truy cập bởi đối tượng thứ ba. Để loại trừ việc nghe trộm những thông tin “nhạy cảm” khi nó được truyền qua Internet, dữ liệu phải được mã hoá để không thể bị đọc được bởi những người khác ngoài người gửi và người nhận.
- Toàn vẹn dữ liệu: đảm bảo thông tin không bị sai lệch và nó phải thể hiện chính xác thông tin gốc gửi đến.Với việc sử dụng SSL, các Web site có thể cung cấp khả năng bảo mật thông tin, xác thực và toàn vẹn dữ liệu đến người dùng. SSL được tích hợp sẵn vào các browser và Web server, cho phép người sử dụng làm việc với các trang Web ở chế độ an toàn.
Giao thức SSL là gì?
SSL được phát triển bởi Netscape, ngày nay giao thức SSL đã được sử dụng rộng rãi trên World Wide Web trong việc xác thực và mã hoá thông tin giữa client và server. Tổ chức IETF (Internet Engineering Task Force ) đã chuẩn hoá SSL và đặt lại tên là TLS (Transport Layer Security). Mặc dù là có sự thay đổi về tên nhưng TSL chỉ là một phiên bản mới của SSL. Phiên bản TSL 1.0 tương đương với phiên bản SSL 3.1. Tuy nhiên SSL là thuật ngữ được sử dụng rộng rãi hơn
SSL được thiết kế như là một giao thức riêng cho vấn đề bảo mật có thể hỗ trợ cho rất nhiều ứng dụng. Giao thức SSL hoạt động bên trên TCP/IP và bên dưới các giao thức ứng dụng tầng cao hơn như là HTTP, IMAP và FTP.
SSL không phải là một giao thức đơn lẻ, mà là một tập các thủ tục đã được chuẩn hoá để thực hiện các nhiệm vụ bảo mật sau:
-
Xác thực server: Cho phép người sử dụng xác thực được server muốn kết nối. Lúc này, phía browser sử dụng các kỹ thuật mã hoá công khai để chắc chắn rằng certificate và public ID của server là có giá trị và được cấp phát bởi một CA (certificate authority) trong danh sách các CA đáng tin cậy của client. Điều này rất quan trọng đối với người dùng. Ví dụ như khi gửi mã số credit card qua mạng thì người dùng thực sự muốn kiểm tra liệu server sẽ nhận thông tin này có đúng là server mà họ định gửi đến không.
-
Xác thực Client: Cho phép phía server xác thực được người sử dụng muốn kết nối. Phía server cũng sử dụng các kỹ thuật mã hoá công khai để kiểm tra xem certificate và public ID của server có giá trị hay không và được cấp phát bởi một CA (certificate authority) trong danh sách các CA đáng tin cậy của server không. Điều này rất quan trọng đối với các nhà cung cấp. Ví dụ như khi một ngân hàng định gửi các thông tin tài chính mang tính bảo mật tới khách hàng thì họ rất muốn kiểm tra định danh của người nhận.
-
Mã hoá kết nối: Tất cả các thông tin trao đổi giữa client và server được mã hoá trên đường truyền nhằm nâng cao khả năng bảo mật. Điều này rất quan trọng đối với cả hai bên khi có các giao dịch mang tính riêng tư. Ngoài ra, tất cả các dữ liệu được gửi đi trên một kết nối SSL đã được mã hoá còn được bảo vệ nhờ cơ chế tự động phát hiện các xáo trộn, thay đổi trong dữ liệu. (đó là các thuật toán băm – hash algorithm).
Giao thức SSL bao gồm 2 giao thức con:
- Giao thức SSL record: xác định các định dạng dùng để truyền dữ liệu.
- Giao thức SSL handshake: sử dụng SSL record protocol để trao đổi một số thông tin giữa server và client vào lấn đầu tiên thiết lập kết nối SSL
Một số thuật toán dùng trong SSL
Các thuật toán mã hoá và xác thực của SSL được sử dụng bao gồm:
- DES (Data Encryption Standard): là một thuật toán mã hoá có chiều dài khoá là 56 bit.
- 3-DES (Triple-DES): là thuật toán mã hoá có độ dài khoá gấp 3 lần độ dài khoá trong mã hoá DES.
- DSA (Digital Signature Algorithm): là một phần trong chuẩn về xác thực số đang được được chính phủ Mỹ sử dụng.
- KEA (Key Exchange Algorithm): là một thuật toán trao đổi khoá đang được chính phủ Mỹ sử dụng.
- MD5 (Message Digest algorithm): được phát thiển bởi Rivest.
- RSA: là thuật toán mã hoá công khai dùng cho cả quá trình xác thực và mã hoá dữ liệu được Rivest, Shamir, and Adleman phát triển.
- RSA key exchange: là thuật toán trao đổi khoá dùng trong SSL dựa trên thuật toán RSA.
- RC2 and RC4: là các thuật toán mã hoá được phát triển bởi Rivest dùng cho RSA Data Security.
- SHA-1 (Secure Hash Algorithm): là một thuật toán băm đang được chính phủ Mỹ sử dụng.
Khi một client và server trao đổi thông tin trong giai đoạn bắt tay (handshake), họ sẽ xác định bộ mã hoá mạnh nhất có thể và sử dụng chúng trong phiên giao dịch SSL.
Cách hoạt động giữa client và server sử dụng SSL.
Đơn giản chúng ta có ví dụ: A cần bán hàng cho anh B sẽ có các thủ tục sau:
- B yêu cầu A gửi cho mình chứng minh thư
- A đưa chứng minh thư cho B
- B mang lên cơ quan công an nhờ xác nhận xem có phải là đúng là ông A không?
- Nếu xác nhận ok, thì B báo cho A biết là ok
- A gửi cho B một key
- B và A sẽ dùng key này để mã hóa thông tin trao đổi với nhau
Qua ví dụ trên thì:
- A là server, B là client
- Chứng minh thư là chính chỉ SSL
- Cơ quan công an là tổ chức CA (Certification Authority); là một tổ chứng mà 2 ông A, B đều tin cậy, là người cấp SSL
- Nếu ông C mà nghe lén được thông tin của A, B thì cũng không giải mã được vì không có key
Có 2 cách tạo SSL:
- Nhờ một tổ chức CA cấp, là tổ chức có độ tin cậy cao, được quyền cấp và chứng nhận SSL. Tất nhiên là chúng ta phải mất tiền để mua chứng chỉ SSL.
- Self-signed SSL: là tự server cấp, tự kí, tự xác thực (ko an toàn và tin tưởng bằng nhờ bên thứ 3)
Phần demo mình tạo self-signed SSL trên môi trường Nginx và Ubuntu 16.04.
Cấu hình HTTPS
Step 1: Tạo một chứng chỉ SSL
TLS/SSL hoạt động dựa vào sự kết hợp giữa một public certificate
và một private key
. SSL key
được giữ bí mật ở trên server. Nó được sử dụng để mã hóa nội dung gửi tới clients.
Còn SSL certificate
được chia sẻ rộng rãi với bất cứ ai yêu cầu nội dung. Nó được sử dụng để giải mã nội dung được ký bởi SSL key
.
Chúng ta sẽ tạo một self-signed key
và một cặp chứng chỉ với câu lệnh OpenSSL
:
sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/ssl/private/nginx-selfsigned.key -out /etc/ssl/certs/nginx-selfsigned.crt
Chắc hẳn sẽ có một số câu hỏi về đống loằng ngoằng kia là cái gì vậy? Mình sẽ giải thích ngay và luôn:
openssl
là một command để tạo vào quản lý chứng chỉOpenSSL
,keys
và các file khác.req
là mộtsubcommand
chỉ định rõ chúng ta mún sử dụng X.509 CSR (certificate signing request) : chứng chỉ yêu cầu ký. X.509 là một chuẩn public key của SSL và TLS.nodes
chỉ rõOpenSSL
bỏ qua việc bảo mặt chứng chỉ của chúng ta bằng một chuỗi mật khẩu (passphrase). Nếu để mật khẩu này thìnginx
của chúng ta luôn phải nhập mật khẩu này mỗi khi khởi động nên rất là bất tiện.days 365
là tham số xác định thời hạn sử dụng chứng chỉ là 365 ngày (1 năm).newkey rsa:2048
là tham số chỉ định chúng ta muốn sinh ra một chứng chỉ mới và một key mới tại cùng câu lệnh với key RSA có độ dài 2048 bít.keyout
chỉ định nơi chứng ta lưu trữprivate key
được sinh ra lúc tạoout
chỉ định nơi chứng chỉ được lưu trữ sau khi tạo
Khi chúng ta sử dụng câu lệnh ở trên, nó sẽ tạo ra 2 file : 1 file key và một file chứng chỉ. Sẽ có một số câu hỏi về server để thêm đúng thông tin vào chứng chỉ. Chúng ta cần điền đầy đủ các thông tin như sau:
Chú ý là dòng Common Name (e.g. server FQDN or YOUR name)
chúng ta cần nhập đúng tên domain hoặc IP của server.
Country Name (2 letter code) [AU]: VN
State or Province Name (full name) [Some-State]: Ha Noi
Locality Name (eg, city) []: Ha Noi
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Test company
Organizational Unit Name (eg, section) []: Test company
Common Name (e.g. server FQDN or YOUR name) []: IP hoặc test.com
Email Address []:admin@test.com
Cả 2 file được tạo trong thư mục /etc/ssl
Để tăng tính bảo mật, chúng ta cũng nên tạo một Diffie-Hellman group:
sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048
Kết thúc chúng ta sẽ có một group DH đủ mạnh trong tại file /etc/ssl/certs/dhparam.pem
.
Step 2: Cấu hình Nginx để sử dụng SSL
Bước tiếp theo là chúng ta sẽ config lại nginx
.
Đầu tiên chúng ta sẽ tạo một Nginx configuration snippet tên là self-signed.conf
trong thư mục /etc/nginx/snippets
.
Cấu hình ssl_certificate
và ssl_certificate_key
có đường dẫn tới certificate và key chúng ta đã tạo.
sudo nano /etc/nginx/snippets/self-signed.conf
# /etc/nginx/snippets/self-signed.conf
ssl_certificate /etc/ssl/certs/nginx-selfsigned.crt;
ssl_certificate_key /etc/ssl/private/nginx-selfsigned.key;
Chúng ta tạo thêm một file snippet khác, định nghĩa vài cài đặt SSL. Nó sẽ tăng tính bảo mật của SSL.
sudo nano /etc/nginx/snippets/ssl-params.conf
Chúng ta sẽ sử dụng mã hóa được recommend trên trang https://cipherli.st/. Ở đây chúng ta chọn cấu hình cho Nginx. Setting được gợi ý ở trang này tạo ra sự bảo mật tốt nhất cho từng web server. Chúng ta sẽ sửa lại vài chỗ trong cấu hình này cho phù hợp:
- Thêm
preferred DNS resolver
cho upstream request là DNS của Google. Thêm ssl_dhparam tới file Diffie-Hellman đã được tạo ra từ bước trước. - Chúng ta sẽ tắt chức năng
preload
HSTS vì hơi phức tạp để hiểu và cấu hình.
# /etc/nginx/snippets/ssl-params.conf
# from https://cipherli.st/
# and https://raymii.org/s/tutorials/Strong_SSL_Security_On_nginx.html
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH";
ssl_ecdh_curve secp384r1;
ssl_session_cache shared:SSL:10m;
ssl_session_tickets off;
ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 5s;
# Disable preloading HSTS for now. You can use the commented out header line that includes
# the "preload" directive if you understand the implications.
#add_header Strict-Transport-Security "max-age=63072000; includeSubdomains; preload";
add_header Strict-Transport-Security "max-age=63072000; includeSubdomains";
add_header X-Frame-Options DENY;
add_header X-Content-Type-Options nosniff;
ssl_dhparam /etc/ssl/certs/dhparam.pem;
Cấu hình Nginx sử dụng SSL
- Trước khi cấu hình, chúng ta cần backup lại config default của
nginx
-sudo cp /etc/nginx/sites-available/default /etc/nginx/sites-available/default.bak
- Mở file cấu hình nginx lên và chỉnh sửa:
-
sudo nano /etc/nginx/sites-available/default
Ban đầu nội dung file sẽ như thế này:
# /etc/nginx/sites-available/default
server {
listen 80 default_server;
listen [::]:80 default_server;
# SSL configuration
# listen 443 ssl default_server;
# listen [::]:443 ssl default_server;
- Trước hết, chúng ta sẽ bắt các request
http
sẽ redirect vềhttps
. Nghĩa là khi người dùng truy cập bằnghttp
thì server tự động chuyển sanghttps
.
# /etc/nginx/sites-available/default
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name server_domain_or_IP;
return 302 https://$server_name$request_uri;
}
# SSL configuration
# listen 443 ssl default_server;
# listen [::]:443 ssl default_server;
- Tiếp theo chúng ta cấu hình SSL listen ở cổng 443 vào block thứ 2. Thêm cấu hình 2 file snippets vào như sau:
# /etc/nginx/sites-available/default
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name server_domain_or_IP;
return 302 https://$server_name$request_uri;
}
server {
# SSL configuration
listen 443 ssl http2 default_server;
listen [::]:443 ssl http2 default_server;
include snippets/self-signed.conf;
include snippets/ssl-params.conf;
}
Chúng ta đã cấu hình xong Nginx SSL. Tiếp đến cần bật firewall
cho HTTPS.
Step 3: Chỉnh sửa Firewall
Nếu ufw
firewall được bật, thì chúng tá sẽ cần chỉnh sửa cài đặt cho phép SSL (HTTPS).
Xem danh sách các profiles firewall:
sudo ufw app list
Output
Available applications:
Nginx Full
Nginx HTTP
Nginx HTTPS
OpenSSH
Xem trạng thái settings hiện tại thì dùng command:
sudo ufw status
Chúng ta có thể thấy chỉ cóHTTP
được cho phép.
Output
Status: active
To Action From
-- ------ ----
OpenSSH ALLOW Anywhere
Nginx HTTP ALLOW Anywhere
OpenSSH (v6) ALLOW Anywhere (v6)
Nginx HTTP (v6) ALLOW Anywhere (v6)
Để thêm HTTPS traffic, chúng ta cần cho phép Nginx Full
profile và xóa Nginx HTTP
profile:
sudo ufw allow 'Nginx Full'
sudo ufw delete allow 'Nginx HTTP'
Xem lại trạng thái firewall:
sudo ufw status
Status: active
To Action From
-- ------ ----
OpenSSH ALLOW Anywhere
Nginx Full ALLOW Anywhere
OpenSSH (v6) ALLOW Anywhere (v6)
Nginx Full (v6) ALLOW Anywhere (v6)
Step 4: Cấu hình Nginx
Để kiểm tra lõi cũ pháp trong cấu hình nginx
thì dùng command sau:
sudo nginx -t
Nếu config ok thì sẽ get được kết quả như sau:
nginx: [warn] "ssl_stapling" ignored, issuer certificate not found
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
Nếu không bị lỗi gì, thì restart lại nginx
:
sudo systemctl restart nginx
Step 5: Test Encryption
Vậy là chúng ta đã cấu hình xong SSL cho domain.
Mở trình duyệt và đánh https
để kiểm tra. Kết quả chúng ta sẽ thấy có cái biểu tượng khóa ở trên trình duyệt:
https://server_domain_or_IP
- Kết quả sẽ có warning như hình dưới:
Tổng kết
Cơ chế của https và SSL tương đối dễ hiểu và có tính thực tiễn cao. Nếu là các trang web cần bảo mât thông tin thì chúng ta nên sử dụng https.
All rights reserved