- Giao tiếp Internet có cấu trúc trong đó packet được nhiều tầng chia nhau xử lý; nhờ giao thức phân tầng, lập trình viên không cần trực tiếp xử lý chi tiết triển khai về truyền tải, định tuyến hay bảo mật
- Một HTTP request đi theo luồng từng bước, bắt đầu từ việc trình duyệt tạo message, rồi tra cứu DNS, TCP 3-way handshake, đi qua router và nhận phản hồi từ server
- HTTP cơ bản gửi header và body dưới dạng plaintext, nên dễ bị nghe lén và giả mạo server; để bù đắp hạn chế này, một tầng bảo mật được thêm vào
- HTTPS là HTTP được bổ sung mã hóa và xác thực bằng TLS; TLS handshake là quá trình thống nhất version, cipher suite, certificate và thông tin trao đổi khóa để tạo symmetric session key
- TLS 1.3 loại bỏ RSA cùng các cipher suite và tham số yếu, đồng thời thu hẹp lựa chọn, tạo ra một handshake đơn giản hơn, nhanh hơn và an toàn hơn so với cách cũ
Mô hình phân tầng để nhìn vào giao tiếp Internet
- Internet là mạng của các mạng máy tính được kết nối với nhau, và “Internet” theo nghĩa đen là “giữa các mạng”
- Hoạt động như một mạng mesh dùng packet switching, với cấu trúc best-effort delivery không bảo đảm packet có được chuyển đi hay thời điểm đến nơi
- Internet trông như hoạt động trơn tru vì nhiều tầng trừu tượng xử lý phía sau các việc như thử lại, bảo đảm thứ tự, loại bỏ trùng lặp và bảo mật
- Mỗi tầng cung cấp một chức năng cụ thể, và nhiều giao thức khác nhau có thể triển khai chức năng đó
- Nhờ tính mô-đun này, việc thay đổi giao thức ở một tầng có thể không ảnh hưởng đến giao thức ở các tầng khác
Vai trò theo từng tầng mạng
- Application layer xử lý logic theo từng ứng dụng; đơn vị giao tiếp là message, HTTP là ví dụ tiêu biểu
- Security layer cung cấp mã hóa và xác thực; đơn vị giao tiếp là record, TLS là ví dụ
- Transport layer chịu trách nhiệm truyền dữ liệu đáng tin cậy; dùng TCP segment hoặc UDP datagram và được nhận diện bằng số port
- Network layer định tuyến packet xuyên Internet; dùng địa chỉ IP làm định danh
- Link layer quản lý giao tiếp gần với môi trường vật lý; dùng frame và được nhận diện bằng địa chỉ MAC
- Physical layer truyền bit giữa các thiết bị ở mức vật lý; ví dụ là cáp quang hoặc Ethernet cable
Luồng của một HTTP request
Packet đi đến server như thế nào
- Khi client gửi request, data packet không đi thẳng đến server mà tìm đường đến gateway của mạng server thông qua nhiều thiết bị mạng và router
- Sau đó Link layer đảm nhiệm việc truyền trong đoạn cục bộ
-
Các bước để văn bản băng qua Internet
- Thiết bị client đóng gói dữ liệu HTTP request thành TCP segment, rồi bọc tiếp thành IP packet
- Nếu là kết nối có dây, nó được đóng gói thêm một lần nữa thành Link layer frame như Ethernet frame
- Frame được gửi qua mạng cục bộ đến router của client
- Router cục bộ nhận frame, loại bỏ Link layer header rồi xử lý IP packet
- Router nhìn địa chỉ IP đích để quyết định hop tiếp theo
- Packet được chuyển sang mạng tiếp theo thông qua một hoặc nhiều router trung gian, và mỗi router lặp lại quá trình xác định hop tiếp theo rồi chuyển tiếp
- Cuối cùng packet đến router nằm trong cùng mạng với server đích
- Router này đưa ra quyết định định tuyến cuối cùng và gửi packet đến thiết bị cục bộ tương ứng với server
- Router của server chuyển packet đến server qua network segment cục bộ
- Link layer bảo đảm frame được chuyển đúng đến network interface của server
- Server nhận frame, trích xuất IP packet, rồi xử lý TCP segment được đóng gói để tái tạo HTTP request ban đầu
- Quá trình Network layer gửi packet xuyên Internet cũng được dùng trong các bước trước đó như phân giải tên miền hoặc TCP handshake
Server response và trình duyệt render
- Server xử lý HTTP request rồi gửi HTTP response về client
- Response gồm phiên bản HTTP đang dùng, status code như
200 hoặc 404, response header, và body như HTML của trang được yêu cầu hoặc dữ liệu JSON
HTTP/1.1 200 OK
Date: Sat, 26 May 2023 10:00:00 GMT
Server: Apache/2.4.41 (Ubuntu)
Content-Type: text/html
Content-Length: 3456
Example Page
Hello, world!
- Client nhận và xử lý HTTP response
- Trình duyệt phân tích HTML và render nội dung lên màn hình
- Nếu response có thêm tài nguyên như hình ảnh, CSS, JavaScript, trình duyệt sẽ gửi thêm HTTP request theo cùng quy trình
Vấn đề bảo mật của HTTP và HTTPS
- HTTP cơ bản hoàn toàn không có bảo mật
- Người nghe lén kết nối có thể thấy 100% dữ liệu được trao đổi
- Nếu ai đó giả làm server, client có thể gửi thông tin quan trọng đến sai đối tượng
- HTTPS là HTTP được bổ sung mã hóa và xác minh
- Có nhiều cách làm cho giao tiếp HTTP an toàn, nhưng cách triển khai hiện được dùng phổ biến là TLS
- TLS cho phép client và server xác minh danh tính của nhau, đồng thời mã hóa payload theo cách mà cả hai phía đều có thể giải mã
- Luồng HTTPS request giống luồng HTTP request đã thấy ở trên, nhưng có thêm Security layer giữa Application layer và Transport layer
- TLS handshake thường dùng TCP
TLS handshake thống nhất những gì
- TLS handshake là quá trình client và server thống nhất nhiều yếu tố sẽ dùng cho giao tiếp
- Các nội dung cần thống nhất gồm tập hợp thuật toán dùng cho xác minh message, nén và mã hóa
- Tập hợp thuật toán này được gọi là cipher suite
- Nói chính xác, phần còn lại sau khi loại trừ compression algorithm mới là cipher suite, nhưng trong bài viết này toàn bộ tập hợp được gọi là cipher suite
- Các thành phần ví dụ như sau
- Compression algorithm: cách nén dữ liệu trên đường truyền; ví dụ là Gzip và Brotli, hiện nay chủ yếu dùng Brotli
- Key exchange algorithm: cách trao đổi khóa mã hóa một cách an toàn trên kênh công khai; ví dụ là ECDHE-RSA và ECDHE-ECDSA, hiện nay chủ yếu dùng ECDHE
- Authentication algorithm: cách xác thực danh tính của các bên trong handshake; ví dụ là RSA và ECDSA, RSA được dùng rộng rãi còn ECDSA cũng đang trở nên phổ biến
- Symmetric encryption algorithm: cách mã hóa dữ liệu giữa client và server; ví dụ là AES-128-GCM và AES-256-GCM, AES-GCM cung cấp bảo mật mạnh và hiệu quả
- MAC algorithm: cách bảo đảm tính toàn vẹn và tính xác thực của message; ví dụ là HMAC-SHA256 và HMAC-SHA384, trong đó HMAC-SHA256 và GCM mode của các cipher suite hiện đại được sử dụng
- Client và server thống nhất cipher suite, trao đổi random seed và thông tin SSL certificate để có thể tạo symmetric key dùng cho mã hóa và xác minh message
- Nguồn tài liệu về TLS handshake là Cloudflare
Các bước TLS handshake truyền thống
-
Client Hello
- Client gửi đến server một TCP message chứa các cipher suite được hỗ trợ, TLS version được hỗ trợ và một số ngẫu nhiên gọi là Client Random
-
Server Hello
- Server phản hồi bằng một TCP message chứa TLS version được chọn, thuật toán cipher suite được chọn và Server Random
-
Certificate Verification
- Client xác minh SSL certificate của server thông qua Certificate Authority và lấy public key của server
-
Premaster Secret Generation
- Client tạo premaster secret, mã hóa bằng public key của server rồi gửi cho server
-
Decryption
- Server dùng private key để giải mã premaster secret
-
Session Key Creation
- Client và server dùng Client Random, Server Random và premaster secret để tạo session key
-
Client Ready
- Client gửi message
finished được mã hóa bằng session key
-
Server Ready
- Server gửi message
finished được mã hóa bằng session key
-
Secure HTTP Communication
- Sau đó hai bên giao tiếp bằng mã hóa đối xứng an toàn sử dụng session key
Những điểm thay đổi trong TLS 1.3
- TLS handshake được mô tả ở trên là quy trình dành cho các phiên bản TLS trước đây, và đã là cách cũ theo chuẩn TLS 1.3 mới nhất
- TLS 1.3 trở lên không hỗ trợ RSA và nhiều cipher suite vì lý do bảo mật
- Phiên bản mới giảm đáng kể số lựa chọn, nên đơn giản hơn, an toàn hơn và nhanh hơn
- Trong TLS 1.3, các khái niệm cốt lõi vẫn được giữ nguyên
- Thông qua handshake, hai bên thống nhất cách nén, xác thực server và trao đổi khóa
- Tạo khóa mã hóa đối xứng để bảo vệ dữ liệu packet được trao đổi qua TCP
- TLS 1.3 không hỗ trợ các cipher suite và tham số dễ bị tấn công, đồng thời rút gọn handshake để tạo handshake nhanh hơn và an toàn hơn
-
Các bước cơ bản của TLS 1.3 handshake
- Client hello: client gửi phiên bản giao thức, Client Random và danh sách cipher suite
- TLS 1.3 loại bỏ hỗ trợ các cipher suite không an toàn, nên số cipher suite khả dụng giảm mạnh
- Client hello cũng chứa các tham số sẽ dùng để tính premaster secret
- Client giả định rằng mình biết key exchange method mà server ưu tiên, và điều này có khả năng đúng hơn nhờ danh sách cipher suite đã được rút gọn
- Cấu trúc này rút ngắn tổng độ dài so với handshake của TLS 1.0, 1.1 và 1.2
- Server generates master secret: server đã nhận Client Random, tham số của client và cipher suite, đồng thời có thể tự tạo Server Random nên có thể tạo master secret
- Server hello and
Finished: Server hello gồm server certificate, digital signature, Server Random và cipher suite được chọn
- Vì server đã có master secret, nó cũng gửi kèm message
Finished
- Final steps and client
Finished: client xác minh signature và certificate, tạo master secret rồi gửi message Finished
- Secure symmetric encryption achieved: sau đó mã hóa đối xứng an toàn được thiết lập
1 bình luận
Các ý kiến trên Hacker News
Với tư cách là người không chuyên, tôi thắc mắc vì sao khi không truy cập được một website cụ thể hoặc toàn bộ Internet, lại khó biết sự cố xảy ra ở đoạn nào đến vậy
Thường không rõ đó là lỗi cấu hình mạng trên máy cục bộ của tôi, vấn đề kết nối Wi‑Fi tới router, vấn đề cáp giữa router và ISP, sự cố diện rộng của ISP, hay lỗi của website tôi đang muốn truy cập
Tôi từng nghe lời giải thích mơ hồ rằng đó là vì yêu cầu được định tuyến qua các đường đi không xác định, nhưng nghe chưa thuyết phục lắm. Tôi thắc mắc liệu khi một liên kết nào đó trên đường đi bị đứt, liên kết cuối cùng còn hoạt động bình thường có thể báo ngược lại rằng “tin nhắn của bạn đã đến được đây, nhưng khi cố gửi sang bước tiếp theo thì thất bại” hay không
Cấu hình mỗi nơi một khác, không thể biết cấu hình nào là có chủ đích, và sẽ rất nguy hiểm nếu dựa trên các nguyên nhân phổ biến để giả định rồi đưa ra một câu trả lời hoàn toàn sai
Ví dụ, nếu cả máy chủ DNS lẫn host đích đều không phản hồi, có thể nói đó là lỗi cấu hình router hoặc sự cố ISP, nhưng nguyên nhân thực tế có thể là một VPN client đã thay đổi bảng định tuyến cục bộ và máy chủ DNS rồi khi thoát không khôi phục lại. Vấn đề là làm sao bộ chẩn đoán biết được đó là thay đổi tạm thời hay cấu hình vĩnh viễn
Ứng dụng sẽ không thấy thông điệp ICMP nếu socket không được thiết lập như vậy. Những thứ này được xem là lỗi “tạm thời”, và trên Linux được cấu hình bằng tùy chọn socket
IP_RECVERRKhi làm việc ở tầng 7, việc thu thập lỗi ở tầng này không có nhiều giá trị. Lỗi Destination Unreachable lộ lên phía trên sẽ được đưa vào logic xử lý lỗi mà bạn vốn sẽ có sẵn, và trong trường hợp này các tầng khác sẽ thử lại với đích không thể tới được, nên có lẽ nó sẽ trông giống như hết thời gian chờ
Các RFC này hữu ích để hiểu tầng TCP xử lý lỗi ICMP như thế nào: https://www.rfc-editor.org/rfc/rfc1122#page-103
Mục 4.2.3.9 nói rằng thông điệp Unreachable là điều kiện soft error, nên TCP không được ngắt kết nối và phải cung cấp thông tin cho ứng dụng. TCP có thể đẩy lên tầng ứng dụng qua routine ERROR_REPORT, hoặc ghi lại thông điệp rồi chỉ báo cho ứng dụng khi kết nối TCP hết thời gian chờ
Cũng có một tài liệu đi sâu hơn về cách các stack tương tác để nghiên cứu ICMP như một vector tấn công TCP: https://www.rfc-editor.org/rfc/rfc5927
Nếu không thể tới được chính máy chủ DNS thì đó là lỗi mạng nào đó giữa người dùng và máy chủ ấy. Thông thường người ta chẩn đoán bằng cách tự thực hiện từng bước. Kiểm tra xem có ping được địa chỉ máy chủ DNS không, có phân giải được host đó bằng máy chủ DNS ấy không, và với máy chủ DNS khác thì thế nào. Một số tên cũng có thể bị loại trừ do chính sách công ty
Nếu muốn đào sâu hơn, các công cụ dòng lệnh như
ping,traceroute,digsẽ hữu íchMTR giống như ping + traceroute chạy liên tục theo thời gian thực, và từng hop được hiển thị riêng
Ngay cả khi lần đầu nhận ra một node trên mạng Xfinity bị chết, trong cùng MTR tôi vẫn thấy ít nhất từ mạng của tôi tới modem là bình thường, nên kết quả khá nhất quán. Tôi chưa thấy nhiều công cụ nào hiển thị tốt như MTR việc độ trễ tăng thêm hàng trăm ms ở một hop nào đó bên ngoài ISP
Nó không giải quyết được mọi vấn đề, nhưng vì cung cấp độ trễ tách theo từng hop nên đáng để kiểm tra
Để nói “vấn đề nằm ở đây”, cần có các giả định về cách hệ điều hành, phần cứng và mạng được cấu hình
Khi truy cập một website, trước tiên phải lấy địa chỉ IP của web server từ DNS, nhưng việc trình duyệt lấy IP DNS từ đâu đã phức tạp rồi. Nó có thể được cấu hình trong trình duyệt, hệ điều hành, router, modem; nếu không cấu hình thì sẽ nhận từ máy chủ DHCP mà router kết nối tới. Đó có thể là máy chủ DHCP của ISP, hoặc một router khác trong nội bộ tổ chức
Nếu DNS có vẻ bất thường thì dễ biết IP bị sai, nhưng khó nói IP đó đến từ đâu. SSL cũng vậy: có thể chứng chỉ của máy chủ sai, hoặc chứng chỉ trên máy tính của tôi sai
Có thể liên quan: cũng có ví dụ tương tác theo dõi chi tiết từng byte cho TLSv1.2 và TLSv1.3
Nếu muốn học thêm về TLS, đây là tài liệu tôi rất thích và rất khuyến nghị
[0]: https://tls12.xargs.org/
[1]: https://tls13.xargs.org/
Tôi tò mò không biết còn ví dụ bài viết nào khác được viết theo góc nhìn này không. Tôi thích những bài diễn giải kiểu “giải thích cho một kỹ sư tầm tầm”, bất kể trình độ ra sao
Nhìn chung rất hữu ích, vì có thể học thêm những mảnh kiến thức trước đây chưa hoàn toàn rõ ràng, hoặc có thêm ví dụ để dùng khi giải thích cho người khác
Ví dụ:
https://www.cloudflare.com/learning/dns/what-is-dns/
https://www.cloudflare.com/learning/ssl/transport-layer-secu...
https://www.cloudflare.com/learning/performance/what-is-http...
Cách giải thích “client tạo premaster secret, mã hóa bằng khóa công khai của server rồi gửi cho server” đã không còn đúng từ lâu rồi
Nó cũng nói thêm rằng quy trình vừa mô tả là quy trình của các phiên bản TLS đời đầu, đã lỗi thời so với TLS 1.3 hiện đại
Câu “các phiên bản TLS hiện tại (>1.3) không hỗ trợ RSA và nhiều cipher suite vì lý do bảo mật” là đúng ở phần trao đổi khóa. Lý do là RSA không cung cấp forward secrecy
RSA vẫn được dùng cho chữ ký, và có lẽ là loại phổ biến nhất trong chứng chỉ x509
Theo tôi biết, Safari gần đây cũng đã nâng yêu cầu khóa 2048-bit đối với chữ ký RSA
Bài này đọc giống như AI tóm tắt một bài giải thích HTTPS thực sự. Thuật ngữ xuất hiện mà không có ngữ cảnh
Không giải thích chứng chỉ là gì, chuỗi tin cậy hoạt động ra sao, và giả định rằng người đọc biết mật mã khóa công khai. Nó giải thích 6 trong 7 tầng OSI nhưng lại không nói đến chính thuật ngữ đó, và bỏ qua tầng trình diễn
Tất nhiên ngay từ tiêu đề đã nói là mediocre rồi
Viết lách không phải thế mạnh của tôi nên tôi cảm ơn các phê bình. Việc bài của tôi đi từ “dở” sang “có phải AI không?” cũng là tiến bộ rồi
Tôi đã suy nghĩ nên dừng phần giải thích ở đâu, và xem mật mã khóa công khai là một ranh giới hợp lý vì nó có thể được giải thích tốt hơn ở nơi khác. Nhiều tầng OSI cũng tương tự
Tôi thừa nhận rằng đáng lẽ nên đề cập đến chứng chỉ và có lẽ cả toàn bộ chuỗi tin cậy
Tôi không tìm được đoạn code minh họa việc xác minh chữ ký của
SHA256(client_hello_random + server_hello_random + curve_info + public_key)Tôi hiểu lý thuyết, nhưng khi triển khai thì lại gặp vấn đề gì đó. Sẽ rất tốt nếu có link tới một chương trình đồ chơi cho thấy thực tế làm như thế nào
Mong là đừng có kiểu diễn đạt “khóa riêng nằm trong chứng chỉ SSL của server”. Dù sao tiêu đề cũng là “Mediocre Engineer”
TLS <1.3 cũng không hoạt động theo cách bài viết mô tả, vậy mà bài lại cố trộn thêm các yếu tố mới hơn của 1.3. Phần DNS giải thích recursive resolver, nhưng client không làm như vậy, có lẽ nó sẽ giao tiếp với stub resolver
Các lỗi cứ tiếp tục xuất hiện như “Internet Layer”, ngụ ý rằng brotli là thuật toán được dùng rộng rãi trong nén TLS hoặc cipher suite, hay “các phiên bản TLS hiện tại (>1.3) không hỗ trợ RSA”
Những thứ blogspam như thế này đôi khi khiến tôi ước có downvote. Quảng cáo không khó chịu đến mức phải flag, nhưng chất lượng thì thấp. Có lẽ tôi nên viết một bài bớt mediocre hơn rồi đưa lên trang nhất HN. Nếu kiếm được lương $300K thì chắc tôi đã có thêm thời gian
Nội dung bài nhìn chung hơi cũ. Ngày nay 30% request web là HTTP/3, và còn có CORS nữa, nhưng không có ngày đăng
Tôi thường phát triển các hệ thống SaaS được triển khai trong mạng nội bộ doanh nghiệp, nên request CORS gần như 0%. HTTP/3 cũng vậy