Analysing TCP Header Options

Giới thiệu
TCP Options (MSS, Window Scaling, Selective Acknowledgements, Time Stamps, Nop) có vị trí nằm ở cuối TCP Header.
Truyền thông dữ liệu càng ngày càng trở nên phức tạp hơn, ít chấp nhận sai sót và độ trễ, rõ ràng là các tính năng mới này đã được tích hợp cho TCP transport để giúp khắc phục nhiều vấn đề.
Ví dụ, Window Scaling, đã được đề cập đến ở bài trước và được giới thiệu ở đây, có thể sử dụng trường TCP Options bởi vì trường Window nguyên thủy của nó chỉ dài có 16 bits, cho phép một số thập phân tối đa là 65.535. Rõ ràng đây là con số quá nhỏ so với việc chúng ta muốn biểu thị giá trị 'Window Size' sử dụng những con số trong phạm vi kích thước hàng ngàn đến 1 triệu như 400.000 hay 950.000.
Trước khi đi phân tích chi tiết, chúng ta hãy xem qua trường TCP Options ở dưới hình sau:


Nằm ở cuối Header và ngay trước phần dữ liệu, nó cho phép chúng ta sử dụng những cải tiến mới được khuyến nghị bởi các kỹ sư đã giúp thiết kế nên các giao thức mà chúng ta đang sử dụng trong truyền thông dữ liệu ngày nay.


TCP Options
Hầu hết các TCP Options mà chúng ta chuẩn bị phân tích sẽ chỉ xuất hiện trong các pha Initial SYN và SYN/ACK của quá trình bắt tay 3 bước (thực hiện để thiết lập 1 kết nối ảo trước khi truyền dữ liệu). Tuy nhiên, có 1 vài Options khác, có thể được sử dụng theo ý muốn, trong TCP Session.
Một chú ý quan trọng là TCP Options có thể chiếm không gian ở cuối TCP Header và độ dài của nó là 1 bội số của 8 bits. Điều này có nghĩa là nếu chúng ta sử dụng 1 TCP Option có chiều dài là 4 bits, thì nó sẽ phải tự động thêm vào 4 bits padding nữa để phù hợp (đúng tiêu chuẩn) với TCP RFC. Vì vậy, chiều dài của TCP Options phải là bội số của 8 bits (8, 16, 24, 32,...).
Dưới đây là các TCP Options mà chúng ta sẽ đi vào phân tích:
- Maximum Segment Size (MSS).
- Window Scaling.
- Selective Acknowledgements (SACK).
- Time Stamps.
- Nop.

Maximum Segment Size (MSS)
Maximum Segment Size được sử dụng để xác định Segment lớn nhất được sử dụng trong suốt quá trình kết nối giữa 2 máy. Vì vậy, bạn sẽ chỉ nhìn thấy được Option này được sử dụng trong các pha SYN và SYN/ACK của quá trình bắt tay 3 bước. MSS chiếm 4 bytes (32 bits) chiều dài.
Nếu bạn đã nghe qua về thuật ngữ MTU (Maximum Transfer Unit), bạn sẽ hài lòng khi biết rằng MSS giúp xác định MTU được sử dụng trên mạng.
Nếu bạn còn phải gãi đầu vì chưa rõ ràng lắm với MSS và MTU, đừng lo lắng, hãy thử xem mô hình dưới đây:


Bạn có thể nhìn thấy Maximum Segment Size bao gồm Data Segment, trong khi Maximum Transfer Unit bao gồm cả TCP Header, MSS và IP Header.
Nó cũng có lợi cho chúng ta nhận ra thuật ngữ chính xác tương ứng với mỗi cấp độ của mô hình OSI: TCP Header và Data được gọi là 1 Segment (tầng 4) trong khi IP Header và Segment được gọi là 1 IP Datagram (tầng 3).
Hơn nữa, bất kể kích thước MTU như nào, thì vẫn sẽ có 18 bytes được gán bởi tầng Data Link ở đầu. 18 bytes gán thêm này gồm có địa chỉ MAC nguồn, địa chỉ MAC đích, loại giao thức, tiếp theo là Frame Check Sequence nằm ở cuối Frame.
Đây cũng chính là lý do tại sao mà chúng ta chỉ có thể có 1 MTU tối đa là 1500 bytes. Vì kích thước tối đa của 1 Frame Ethernet II là 1518 bytes, trừ đi 18 bytes được gán vào bởi tầng Data Link, vì thế chỉ còn lại 1500 bytes tối đa cho MTU.
TCP thường tính toán giá trị MSS để cho phù hợp với MTU. Trên thực tế thì với giá trị MSS như vậy, nếu chúng ta thêm phần IP Header vào thì IP Datagram sẽ tương đương với MTU, hay là:
MTU = IP Header + TCP Header + Data
Nếu MSS Option bị bỏ qua bởi 1 hoặc cả 2 đầu của kết nối, thì giá trị 536 bytes sẽ được sử dụng. Giá trị 536 bytes của MSS được định nghĩa bởi RFC 1122 và được tính bằng cách lấy giá trị mặc định của 1 IP Datagram, 576 bytes, trừ đi độ dài tiêu chuẩn của IP và TCP Header (40 bytes) sẽ cho chúng ta giá trị 536 bytes.
Nói chung, việc sử dụng giá trị MSS tốt nhất có thể cho mạng của bạn là rất quan trọng bởi vì hiệu suất mạng của bạn có thể rất kém nếu giá trị này quá lớn hay quá nhỏ.

Window Scaling
Chúng ta đã đề cập đến vấn đề này trong bài trước. Chủ đề này là khá rộng và đòi hỏi phải có sự chú ý.
Chúng ta đã biết được cờ Window Size, thì Window Scaling, bản chất của nó thực sự là 1 extension của cờ Window Size. Bởi vì giá trị lớn nhất có thể trong cờ Window Size là 65.535 bytes (64 kb), rõ ràng là giá trị này là quá bé so với những gì chúng ta yêu cầu trong ngày nay -> Window Scaling được sinh ra.
Window Scaling Option có kích thước tối đa là 30 bits, bao gồm 16 bits của trường Window Size. Bởi vậy, 16 (Original Window Field) + 14 (TCP Option 'Window Scaling') = 30 bits.
Nếu bạn đang tự hỏi trên Trái Đất này liệu có ai đang sử dụng 1 giá trị Window Size rất lớn, hãy nghĩ lại. Window Scaling được tạo ra cho những đường truyền WAN độ trễ cao, băng thông lớn có Window Size bị giới hạn có thể gây ra vấn đề hiệu suất nghiêm trọng.
Hãy xem ví dụ dưới đây:


Ví dụ trên giả định là chúng ta đang sử dụng Window Size tối đa là 64 kbs và vì đường truyền WAN có độ trễ rất cao, nên các gói tin sẽ phải mất 1 thời gian để đi đến đích của chúng, là máy B. Do độ trễ cao, máy A sẽ ngừng truyền dữ liệu kể từ khi 64 kbs dữ liệu được chuyển và máy A chưa nhận được báo nhận.
Với Time = 4, máy B đã nhận được dữ liệu và gửi báo nhận cho máy A để máy A có thể tiếp tục gửi dữ liệu, nhưng báo nhận sẽ chỉ được chuyển đến máy A trong khoảng Time = 6.
Vì vậy, từ Time = 1 cho đến Time = 6, máy A ngồi và chờ đợi. Bạn có thể tưởng tượng hiệu suất của việc truyền dữ liệu trong trường hợp này nghèo nàn đến mức nào. Nếu chúng ta truyền 1 tập tin khoảng 10 Mb, nó sẽ rất mất thời gian.
Bây giờ chúng ta cũng sử dụng ví dụ trên, nhưng với Window Scaling:


Như bạn có thể thấy, với việc sử dụng Window Scaling, Window Size đã tăng lên 256 kb. Vì giá trị khá lớn, có thể dịch chuyển nhiều dữ liệu hơn trong quá trình vận chuyển, máy B đã nhận được những gói đầu tiên, trong khi máy A vẫn gửi Window đầu tiên cho máy B.
Tại thời điểm Time = 2, máy B gửi 1 báo nhận đến máy A, trong khi máy A vẫn đang còn bận rộn với việc chuyển dữ liệu. Máy A sẽ nhận được báo nhận trước khi hoàn thành xong việc chuyển hết Window có kích thước 256 kbs và sẽ tiếp tục gửi dữ liệu mà không cần tạm dừng bởi vì nó sẽ sớm nhận được báo nhận từ máy B.
Rõ ràng sự khác biệt mà 1 giá trị Window Size lớn đã được thể hiện rõ, tăng hiệu suất mạng và giảm thiểu thời gian chờ đợi cho các máy gửi.
Window Scaling Option được định nghĩa trong RFC 1072, cho phép 1 hệ thống sử dụng giá trị Window Size có kích thước 30 bits, với 1 kích thước buffer tối đa là 1 GB. Option này đã được làm rõ và định nghĩa lại trong RFC 1323.

Selective Acknowledgements (SACK)
TCP đã được thiết kế để trở thành 1 giao thức khá mạnh mẽ, tuy nhiên nó vẫn có 1 số nhược điểm, trong đó có vấn đề liên quan đến Acknowledgements, đó cũng là lý do tại sao Selective Acknowledgements được giới thiệu trong RFC 1072.
Vấn đề đối với Acknowledgements chính là không có cơ chế cho 1 người nhận để biểu thị trạng thái: "Tôi vẫn đang chờ đợi những bytes dữ liệu từ 20 đến 25, nhưng đã nhận được các bytes từ 30 đến 35". Và nếu bạn tự hỏi liệu điều này có thể diễn ra hay không, thì câu trả lời là có.
Nếu các Segment đến không theo thứ tự và có 1 lỗ hổng trong hàng đợi của người nhận, sau đó người nhận sử dụng báo nhận 'cổ điển' được hỗ trợ bởi TCP, và người nhận chỉ có thể nói: "Tôi đã nhận được mọi thứ cho đến bytes thứ 20". Người gửi sau đó cần phải nhận ra rằng có 1 cái gì đó đã sai và tiếp tục gửi từ thời điểm đó trở đi (byte thứ 20).
Bạn có thể kết luận, tình trạng trên là không thể chấp nhận được. Do đó, 1 dịch vụ mạnh mẽ hơn đã được tạo ra, đó là Selective Acknowledgements.
Đầu tiên, khi 1 kết nối ảo được thiết lập bằng cách sử dụng quá trình bắt tay 3 bước cổ điển, các máy phải gửi "Selective Acknowledgements Permitted" trong TCP Options để chỉ ra rằng họ có thể sử dụng SACK của nhau. Từ thời điểm này trở đi, SACK Option được gửi bất cứ khi nào Selective Acknowledgement là cần thiết.
Ví dụ, chúng ta có 1 máy Windows 98 đang chờ đợi byte thứ 4268, nhưng SACK Options cho thấy máy này cũng đã nhận được các bytes từ 7080 cho đến 8468, rõ ràng là nó thiếu các bytes từ 4268 cho đến 7079, vì thế Server nên gửi lại 2810 bytes còn thiếu, chứ không phải truyền lại tất cả các bytes từ byte thứ 4268.
Cuối cùng, chúng ta nên lưu ý rằng trường SACK trong TCP Options sử dụng 2 trường 16 bits, tổng lại là 32 bits. Lý do có 2 trường là bởi vì người nhận phải có khả năng xác định phạm vi các bytes đã nhận được, giống như ví dụ ở trên. Trong trường hợp Window Scaling cũng được sử dụng, 2 trường 16 bits này có thể được mở rộng lên thành 2 trường 24 bits hoặc 32 bits.

Timestamps
Một khía cạnh khác của các dịch vụ điều khiển luồng và độ tin cậy của TCP là roud trip times của 1 mạch ảo. Round trip time sẽ xác định chính xác TCP sẽ chờ đợi bao lâu trước khi cố gắng truyền lại 1 Segment không có báo nhận.
Bởi vì mỗi mạng có những đặc điểm độ trễ riêng, nên TCP phải hiểu được những đặc điểm này để thiết lập giá trị ngưỡng cho bộ đếm thời gian báo nhận. Mạng LAN thường có thời gian trễ rất thấp, và như vậy TCP có thể sử dụng các giá trị thấp cho bộ đếm thời gian báo nhận. Nếu 1 Segment không được báo nhận 1 cách nhanh chóng, thì người gửi có thể truyền lại dữ liệu xảy ra vấn đề 1 cách nhanh chóng. Do đó giảm thiểu sự mất mát băng thông và giảm độ trễ.
Mặt khác, sử dụng 1 giá trị ngưỡng thấp trên 1 mạng WAN chắc chắn sẽ gây ra vấn đề đơn giản bởi vì bộ đếm thời gian báo nhận sẽ hết hạn trước khi dữ liệu đến đích.
Vì vậy, để cho TCP thiết lập giá trị ngưỡng chính xác cho bộ đếm thời gian báo nhận, nó có thể đo round trip time cho các Segment khác nhau. Cuối cùng, nó phải theo dõi các Segment khác trong suốt quá trình kết nối để theo kịp với những thay đổi trong mạng. Đây là nơi mà Timestamp Option được sử dụng.
Tương tự như phần lớn các TCP Options khác, Timestamp Option phải được gửi trong quá trình bắt tay 3 bước để cho phép sử dụng trong bất kỳ Segment nào tiếp theo.
Trường Timestamp bao gồm 1 trường Timestampt Echo và 1 trường Timestamp Reply, cả 2 trường đều được thiết lập giá trị 0 bởi người gửi và được hoàn thành bởi người nhận sau khi nó được gửi trả lại người gửi. Cả 2 trường Timestamp đều có độ dài là 4 bytes.

Nop
Nop TCP Option có nghĩa là "No Option" và được sử dụng để tách các Option khác nhau được sử dụng trong trường TCP Options. Việc thực hiện trường Nop tùy thuộc vào hệ điều hành được sử dụng. Ví dụ, nếu các Options MSS và SACK được sử dụng, Windows XP sẽ thường đặt 2 trường  Nop ở giữa chúng, chúng ta có thể nhìn thấy điều này qua hình ảnh đầu tiên của bài.
Cuối cùng, chúng ta nên lưu ý rằng, Nop Option chỉ chiếm 1 byte. Trong ví dụ ở đầu trang, nó sẽ chiếm 2 bytes bởi vì nó được sử dụng 2 lần. Bạn cũng nên lưu ý rằng trường này thường được kiểm tra bởi các hacker khi họ đang cố gắng xác định hệ điều hành của các remote host.

Lược dịch từ bài gốc: Click Here

Bài tiếp theo: TCP Data






3 nhận xét:

  1. KHông biết bài này là anh dịch hay là tự viết, kiến thức rất bổ ích. Anh có nguồn tài liệu nào chia sẻ em với :)

    Trả lờiXóa
    Trả lời
    1. Hi bạn, cám ơn bạn đã feed back về bài viết trên blog của mình, loạt bài về TCP này mình đều dịch lại từ trang firewall.cx, ở trên web đó cũng có nhiều bài rất bổ ích.
      Ngoài ra, mình có upload 1 vài ebooks mà mình thấy hay, bạn có thể down về xem, link đây bạn nhé: http://dhngoc.blogspot.com/p/tai-lieu.html

      Xóa
  2. giữ rừng internet, đến giờ mới tình cờ thấy blog này, quá hay... quá thực tế... nắm được cái này thì rất hữu ích, có thể chặn kiểu tấn công sql brute force đơn giản bằng 1 code ngắn từ google, code chạy trên máy chủ - nếu ip là nước ngoài + cổng truy cập là sql server thì dùng window firewall block ngay ip đó,... cám ơn tác giả nhiều.

    Trả lờiXóa