Thời gian gần đây, hệ thống bên mình liên tục nhận được các cuộc tấn công DDoS SYN Flood Spoofed Source IP (Fake – giả mạo địa chỉ IP) với tần số hơn 1 triệu SYN packet mỗi giây. Đặc biệt, các gói SYN tấn công mang theo Payload Random và có “Total Length” không cố định, gây khá nhiều khó khăn trong việc viết rule. Để đối phó với tình trạng này, trong bài viết hôm nay mình sẽ chia sẻ tới bạn kinh nghiệm chống DDoS SYN Flood bằng iptables u32 module thông qua những ví dụ cụ thể nhất.
Điểm chính cần nắm
Trong quá trình tìm hiểu cách chống DDoS SYN Flood bằng iptables u32 module, bạn cần nắm được những nội dung chính sau:
- Khái niệm về iptables u32 module và cú pháp, toán tử hỗ trợ của nó.
- Hướng dẫn bạn cách sử dụng iptables u32 module, bao gồm việc xác định vị trí “Start” và tính toán giá trị.
- Giả lập một cuộc tấn công SYN Flood Spoofed Source IP với gói SYN có payload và hướng dẫn bạn phân tích, nhận diện chi tiết về cuộc tấn công này.
- Hướng dẫn bạn cách viết rule chống DDoS sử dụng module u32 của iptables với 4 bước chính.
- Biết đến giải pháp chống DDoS SYN Flood hiệu quả – Firewall Anti DDoS Vietnix.
Giới thiệu về iptables u32 module
u32 là module iptables cho phép chúng ta có thể lấy ra byte/bit nào ở bất kỳ vị trí nào trong gói tin để tính toán và kiểm tra giá trị. Sở dĩ có tên là u32 vì mỗi lần lấy data, u32 sẽ lấy 4 byte, tương đương 32bit. Cú pháp của u32 như sau:
Start&Mask=Value|RangeValue
Cú pháp trên có nghĩa:
- Lấy 4 byte dữ liệu từ vị trí “Start”, thực hiện phép toán “AND” với một bit “Mask” (một dãy bit) và so sánh giá trị của kết quả vừa tính toán có bằng với “Value” hoặc nằm trong “RangeValue” hay không.
- Nếu bằng thì rule match, ngược lại rule được xem là không match.
- Nếu vị trí “Start” nằm cuối hoặc gần cuối gói tin khiến cho việc lấy 4 byte tiếp theo vượt ra khỏi phạm vi gói tin thì mặc định kết quả sẽ là False.
Các toán tử hỗ trợ:
Toán tử | Mô tả |
---|---|
& | Phép toán AND hai dãy bit với nhau |
>> | Shift Left (dịch bit sang trái) |
@ | Jump (Nhảy đến vị trí của kết quả vừa tính toán nằm phía trước dấu @) |
&& | Combining tests – AND nhiều điều kiện test lại với nhau |
Với các phiên bản cũ, u32 hỗ trợ phép toán -
để lùi ngược về vị trí byte trước đó (negative offset), tuy nhiên các phiên bản sau này không còn hỗ trợ phép toán này nữa.
Cách sử dụng iptables u32 module
Xác định vị trí “Start”
Do đặc điểm mỗi lần lấy dữ liệu, u32 sẽ lấy 4 byte tính từ vị trí “Start” nên vị trí “Start” của chúng ta sẽ bằng vị trí cần lấy trừ đi 3.
Ví dụ:
- Bạn muốn lấy giá trị của byte 13, vị trí “Start” sẽ là: 13-3=10. Lúc này, tính từ vị trí “Start” (byte 10), u32 sẽ lấy 4 byte bao gồm: byte 10 + byte 11 + byte 12 + byte 13 (byte chúng ta cần lấy)
- Nếu bạn muốn lấy các byte ở vị trí đầu của gói tin như byte 1, byte 2 thì kết quả trừ đi 3 sẽ ra số âm, đây là vị trí không hợp lệ và chúng ta sẽ “Start” ở vị trí 0 và kết hợp với dịch bit (>>) để tính toán giá trị.
Tính toán giá trị
Từ vị trí “Start“, iptables u32 module sẽ lấy 4 byte và trả về cho chúng ta kết quả là một dãy bit gồm 32bit, chúng ta cần điều chỉnh (Mask/Shift) 32bit này và chuyển đối giá trị cuối cùng qua dạng thập phân hoặc hex để so sánh với “Value“.
Ví dụ 1: Giá trị cần giữ lại kiểm tra có chiều dài 2 byte: kiểm tra xem giá trị của trường IPID có nằm trong khoảng từ 2 đến 256:
Chọn vị trí Start: IPID nằm ở byte 4 và byte 5 của IP Header, vậy nên vị trí start của chúng ta sẽ là 5-3=2.
Lúc này kết quả trả về sẽ là 4 byte, bao gồm byte 2 + byte 3 + byte 4 + byte 5, trong đó ta chỉ quan tâm byte 4 + byte 5, các byte còn lại ta cần “zero out” để không còn ảnh hưởng đến giá trị tính toán cuối cùng.
Để “zero out” các giá trị không mong muốn, ta thực hiện phép toán AND các vị trí đó với 0 (vì bit 0 hay bit 1 khi AND với 0 đều bằng 0), các vị trí cần giữ lại sẽ AND với 1 (vì nếu giá trị của bit hiện tại là 1 thì AND với 1 sẽ là 1, giá trị của bit hiện tại là 0 khi AND với 1 cũng vẫn là 0).
Lúc này, “Mask” chúng ta sẽ sử dụng:
0000 0000 | 0000 0000 | 1111 1111 | 1111 1111
- Tương ứng dạng hex:
0x0000FFFF
- Viết gọn lại:
0xFFFF
Zero out 2 byte đầu trong 4 byte kết quả lấy được, giữ nguyên giá trị của 2 byte cuối (trường IPID).
Kết quả cuối cùng chúng ta có:
iptables -m u32 --u32 "2&0xFFFF=0x02:0x100"
Áp dụng tương tự với trường hợp byte cần lấy có chiều dài 1 byte, 3 byte hay 4 byte.
Ví dụ 2: Byte cần lấy nằm ở đầu header: lấy giá trị của trường IP Header Length, trường này gồm 4 bit cuối của byte đầu tiên (byte số 0)
Do vị trí byte cần lấy là byte 0, nếu trừ 3 sẽ ra số âm nên vị trí Start sẽ là 0.
u32 sẽ lấy 4 byte từ vị trí bắt đầu bao gồm byte 0 + byte 1 + byte 2 + byte 3.
Kết quả trả về 1 là dãy gồm 32 bit, trong đó có chứa 4 bit ta cần quan tâm nằm ở byte số 0.
Giả sử dãy bit được trả về có giá trị như sau:
0100 0101 | 0000 1101 | 0010 1111 | 0010 1101
Để tính toán, ta cần đưa 4 bit mình quan tâm về vị trí sát góc bên phải (right most) bằng phép toán dịch bit. Ta cần dịch qua bên phải 3 byte (24 bit).
0>>24
Kết quả:
0000 0000 | 0000 0000 | 0000 0000 | 0100 0101
Tuy nhiên, theo RFC của TCP/IP, muốn tính chiều dài của IP Header, ta cần lấy giá trị này nhân với 4, tương đương với việc dịch giá trị hiện tại qua trái 2 bit. Vậy nên thay vì dịch 24 bit qua phải rồi sau đó dịch lại 2 bit qua trái, ta chỉ cần dịch giá trị ban đầu 22 bit qua phải.
Kết quả: 0000 0000 | 0000 0000 | 0000 0010 | 0001 0100
.
Bước tiếp theo, “zero out” các byte ta không quan tâm, sử dụng Mask:
0000 0000 | 0000 0000 | 0000 0000 | 0011 1100
- Tương đương:
0x0000003C
- Rút gọn:
0x3C
Kết quả cuối cùng nhận được dãy bit có giá trị:
0000 0000 | 0000 0000 | 0000 0010 | 0001 0100
Quy đổi ra thập phân = 20
. Đây chính là chiều dài của IP Header.
Biểu thức cuối cùng:
iptables -m u32 --u32 "0>>22&0x3C=20"
Ví dụ 3: Giá trị cần kiểm tra là 1 bit: Kiểm tra giá trị của cờ SYN có được bật hay không.
Cờ SYN trong byte thứ 13 của TCP header. Muốn lấy được byte này, việc đầu tiên ta cần làm là nhảy qua khỏi chiều dài của IP Header và đến byte đầu tiên của TCP Header, tiếp theo chọn byte thứ 10 (13-3=10) từ vị trí vừa nhảy tới. Thực hiện việc này bằng cách sử dụng toán tử @
:
0>>22&0x3C@10
Trong byte 13, cờ SYN nằm ở bit thứ 2 từ phải sang, do đó dịch sang phải 1 bit để đưa bit của cờ SYN vào đúng bị trí right most:
0>>22&0x3C@10>>1
zero out tất cả những giá trị ta không qua tâm, chính là 31 bit nằm phía trước. Sử dụng Mask:
0000 0000 | 0000 0000 | 0000 0000 | 0000 0001
- Tương đương:
0x00000001
- Rút gọn:
0x01
Kiểm tra xem giá trị có bằng 1 hay không (cờ SYN đang được bật):
0>>22&0x3C@10>>1&0x1=0x1
Biểu thức cuối cùng:
iptables -m u32 --u32 "0>>22&0x3C@10>>1&0x1=0x1"
Đến đây, mình đã chia sẻ xong phần lý thuyết của iptables u32 module, tiếp theo sẽ đến phần thực hành áp dụng vào cuộc tấn công SYN Flood Spoofed Source IP với gói SYN có payload.
Giả lập lại cuộc tấn công
Trước tiên, mình giả lập lại cuộc tấn công để có traffic, tiện cho việc kiểm tra lại xem các rule mình viết đã hoạt động đúng yêu cầu hay chưa. Nhắc lại 1 vài đặc điểm của cuộc tấn công:
- Kiểu tấn công: SYN Flood.
- Source IP: Giả mạo và Random.
- Đặc biệt, các gói SYN có mang theo Payload từ 4-22 bytes.
- Tần số tấn công: > 1 triệu packet/s.
Với các đặc điểm trên, mình sử dụng công cụ hping3 để giả lập lại traffic tấn công, dựng mô hình LAB ở local sử dụng card Host Only với topo như sau:
- Máy tạo traffic tấn công (attacker – nguồn tấn công): 192.168.56.1
- Server: 192.168.56.20
Thử nghiệm tấn công:
Trên máy attacker, chạy lệnh:
$ hping3 --flood --rand-source -S -p 80 --data 4 192.168.56.20
Trên server, kiểm tra traffic bằng vnstat, thấy server đang nhận vào 200,000 packet/s. Traffic tấn công đã gửi thành công đến mục tiêu:
Kiểm tra các gói tin xem có giống với đặc điểm của cuộc tấn công hay chưa:
$ tcpdump -i eth0 -nnn -vvv -X -c 10 -P in port 80
Các điều kiện đã được đáp ứng, bắt tay vào xử lý.
Phân tích tấn công DDoS SYN flood
Bắt 1000 gói tin để phân tích source IP xem đây là kiểu tấn công SYN FLood bằng Botnet hay bằng tool Fake Random IP:
$ tcpdump -i eth0 -nnn -c 1000 -P in port 80 | awk '{print $3}' | cut -d"." -f-4 | sort | uniq -c | sort -rn | more
- Địa chỉ Source có prefix trải đều một cách tuần tự (93.x.x.x, 94.x.x.x, 95.x.x.x, 96.x.x.x, 97.x.x.x, 98.x.x.x, 99.x.x.x …).
- Mỗi IP gửi gói tin đến server với tần số thấp.
- Cấu trúc gói tin gần như là giống nhau.
Từ các dữ kiện trên, có thể xác định đây là kiểu tấn công Random Source IP với các gói tin được tạo ra từ cùng một nguồn. Với đặc điểm trên:
- Số lượng Source IP là vô hạn, vì tool có thể tạo gói tin SYN với source IP bất kỳ => Việc chặn IP sẽ không giải quyết được vấn đề.
- Tần số từ mỗi IP sẽ thấp => Đặt rate limiting cũng sẽ không có tác dụng.
- Dấu hiệu bất thường là các gói tin SYN có mang theo Payload, ta sẽ dựa vào đây và viết rule DROP bỏ các gói tin có đặc điểm này.
Kết luận: Điều kiện để các tin bị xem là không hợp lệ là gói tin mang tất cả các đặc điểm sau:
- Gói tin sử dụng giao thức TCP.
- Gói tin có cờ SYN được bật.
- Gói tin có mang theo payload.
Viết rule chống DDoS SYN Flood bằng iptables u32 module
Kiểm tra gói tin có phải giao thức là TCP hay không
Để kiểm tra gói tin có phải là TCP hay không, ta cần kiểm tra trường Protocol trong IP Header (byte thứ 9). Nếu giá trị của trường này bằng 6 thì là TCP:
- Start Value: 9 -3 = 6.
- Mask:
0xFF
. - Value: 6.
- Biểu thức cuối cùng:
6&0xFF=6
.
Kiểm tra có phải gói SYN hay không
Để kiểm tra xem có phải là gói SYN hay không, bạn cần kiểm tra cờ SYN trong TCP mang giá trị 0 (cờ SYN không bật) hay 1 (cờ SYN được bật).
Cờ SYN trong byte thứ 13 của TCP header: Muốn lấy được byte này, việc đầu tiên ta cần làm là nhảy qua khỏi chiều dài của IP Header và đến byte đầu tiên của TCP Header, tiếp theo chọn byte thứ 10 (13-3=10) từ vị trí vừa nhảy tới. Thực hiện việc này bằng cách sử dụng toán tử @
:
0>>22&0x3C@10
Trong byte 13, cờ SYN nằm ở bit thứ 2 từ phải sang, do đó dịch sang phải 1 bit để đưa bit của cờ SYN vào đúng bị trí right most:
0>>22&0x3C@10>>1
zero out tất cả những giá trị ta không qua tâm, chính là 31 bit nằm phía trước. Sử dụng Mask:
0000 0000 | 0000 0000 | 0000 0000 | 0000 0001
Tương đương: 0x00000001
Rút gọn: 0x01
Kiểm tra xem giá trị có bằng 1 hay không (cờ SYN đang được bật):
0>>22&0x3C@10>>1&0x1=0x1
Trong đó:
0>>22&0x3C@
: Tính chiều dài của IP Header và nhảy đến vị trí byte vừa tính toán10>>1&0x1=0x1
: Lấy byte số 10-13, dịch qua phải 1 bit để đưa cờ SYN vào vị trí Right Most, loại bỏ 31 bit phía trước và kiểm tra giá trị cuối cùng có bằng 1 hay không.
Kiểm tra gói tin có Payload hay không
Để kiểm tra gói tin có Payload hay không, ta cần “nhảy” qua khỏi IP Header, TCP Header và đến byte đầu tiên của phần Data, kiểm tra xem có mang giá trị hay không. Biểu thức:
0>>22&0x3C@12>>26&0x3C@0>>24=0:255
Trong đó:
0>>22&0x3C@
: Tính toán chiều dài của IP Header, nhảy đến vị trí của byte vừa tính toán (chính là vị trí bắt đầu của TCP Header)12>>26&0x3C@
: Tính toán chiểu dài của TCP Header và nhảy đến vị trí của byte vừa tính toán (chính là vị trí bắt đầu của Data)0>>24=0:255
: Từ vị trí đầu tiên của Data, lấy 4 byte bắt đầu từ vị trí số 0, dịch qua phải 24 bit để đưa byte đầu tiên vào vị trí right most, kiểm tra giá trị của byte này có nằm trong khoảng từ 0:255 hay không.
Kết quả cuối cùng
Kết hợp các điều kiện lại sử dụng toán tử &&
, ta có rule như sau:
$ iptables -I INPUT -m u32 --u32 "6&0xFF=6 && 0>>22&0x3C@10&0x02=2 && 0>>22&0x3C@12>>26&0x3C@0>>24=0:255" -j DROP
Chống DDoS SYN Flood hiệu quả với Firewall Anti DDoS từ Vietnix
Với hơn 12 năm nghiên cứu và phát triển, Vietnix đã cho ra đời giải pháp Firewall Anti DDoS độc quyền, tích hợp các thuật toán thông minh chuyên biệt cho việc chống lại các cuộc tấn công DDoS, trong đó có SYN Flood. Sản phẩm được thiết kế với 6 lớp bảo vệ hoạt động liên tục và tự động, giúp ngăn chặn hiệu quả các cuộc tấn công DDoS SYN Flood phức tạp và quy mô lớn. Firewall Anti DDoS sử dụng các kỹ thuật tiên tiến như:
- Phát hiện và phân tích lưu lượng tự động: Hệ thống sẽ liên tục giám sát và phân tích lưu lượng truy cập để phát hiện các dấu hiệu bất thường của tấn công DDoS.
- Lọc và loại bỏ gói tin tấn công: Các gói tin không hợp lệ và các giao thức không được phép sẽ bị loại bỏ khỏi lưu lượng truy cập, đảm bảo chỉ có các yêu cầu hợp lệ được gửi đến hệ thống.
- Linh hoạt và tùy biến: Firewall Anti DDoS của Vietnix cho phép người dùng tùy chỉnh các rule và cấu hình để phù hợp với nhu cầu bảo mật của từng hệ thống.
- Bảo vệ đa lớp: Giải pháp này cung cấp khả năng bảo vệ tới 6 lớp, bao gồm cả lớp ứng dụng, mạng, giúp ngăn chặn các cuộc tấn công từ nhiều phía.
- Công nghệ thiết kế dựa trên các cuộc tấn công tại Việt Nam: Giải pháp được tối ưu hóa để chống lại các loại tấn công phổ biến tại Việt Nam.
Thông tin liên hệ:
- Hotline: 18001093
- Email: sales@vietnix.com.vn
- Địa chỉ: 265 Hồng Lạc, Phường 10, Quận Tân Bình, Thành Phố Hồ Chí Minh.
Có nhiều cách để chặn gói SYN mang payload nhưng hôm nay mình đã hướng dẫn bạn ứng dụng thành công u32 để chặn kiểu tấn công này. Tuy nhiên, trong quá trình làm việc với u32, mình phát hiện u32 vẫn có 1 hạn chế là không thể chặn được gói tin SYN có payload nếu payload < 4 byte. Trong bài tiếp theo, mình sẽ hướng dẫn các bạn cách khác để chặn SYN Flood có payload < 4 byte.