DDoS là gì? Cách ứng phó với DDoS trên server Linux bằng iptables

Bài viết hướng dẫn sử dụng iptables trên server cài HĐH nhân Linux phần nào ứng phó trước các cuộc tấn công DDoS.

DDoS là gì?

DoS (Denial of Service) là cuộc tấn công mang tính chất phá hoại bằng cách làm ngập lụt (flood) đến mức quá tải hạ tầng mạng của Server đích bằng dòng dữ liệu khổng lồ, khiến cho các máy client bình thường khác không thể kết nối với server.

DDoS (Distributed Denial of Service) là cuộc tấn công DoS có quy mô lớn với traffic phá hoại đến từ nhiều nguồn, có thể là từ hệ thống rất nhiều máy client bị điều khiển (botnet).

Ta thường gặp nhất là DDoS tấn công từ Layer 3, nhằm vào hạ tầng các Website với mục đích “hạ gục” nguồn thông tin và công cụ kinh doanh của đối phương.

Khi đối diện với cuộc tấn công DDoS quy mô lớn thì rất khó để phân biệt đâu là request tấn công và đâu là request từ người dùng thật. Việc phân loại này nếu automate thì cũng cực kỳ tốn kém tài nguyên.

Vì thế nếu ta cung cấp các dịch vụ công cộng thì DDoS hầu như không thể ngăn chặn hoàn toàn mà chỉ có thể tìm cách “chống chọi” mà thôi.

Để chống chọi với DDoS cần có một hạ tầng cực kỳ mạnh mẽ và đồng bộ từ Layer 1 đến Layer 7 trong mô hình OSI – vô cùng tốn kém.

Vì vậy DDoS thực sự là một loại hình tội phạm phá hoại tài sản, và Anti-DDoS là “key” cạnh tranh hàng đầu giữa các dịch vụ Hosting.

Có khá nhiều phương pháp DDoS, và dưới đây là hướng dẫn sử dụng iptables để ứng phó với một số loại hình tấn công, phần nào làm giảm mức độ ảnh hưởng ngay tại server Linux.

Cấu hình giảm hậu quả DDoS ở mức kernel

Thêm đoạn cấu hình sau vào cuối file /etc/sysctl.conf để tối ưu hiệu năng của kernel trước các cuộc tấn công DDoS và hỗ trợ cho các cấu hình ngừa DDoS bằng iptables phía sau.

kernel.printk = 4 4 1 7 
kernel.panic = 10 
kernel.sysrq = 0 
kernel.shmmax = 4294967296 
kernel.shmall = 4194304 
kernel.core_uses_pid = 1 
kernel.msgmnb = 65536 
kernel.msgmax = 65536 
vm.swappiness = 20 
vm.dirty_ratio = 80 
vm.dirty_background_ratio = 5 
fs.file-max = 2097152 
net.core.netdev_max_backlog = 262144 
net.core.rmem_default = 31457280 
net.core.rmem_max = 67108864 
net.core.wmem_default = 31457280 
net.core.wmem_max = 67108864 
net.core.somaxconn = 65535 
net.core.optmem_max = 25165824 
net.ipv4.neigh.default.gc_thresh1 = 4096 
net.ipv4.neigh.default.gc_thresh2 = 8192 
net.ipv4.neigh.default.gc_thresh3 = 16384 
net.ipv4.neigh.default.gc_interval = 5 
net.ipv4.neigh.default.gc_stale_time = 120 
net.netfilter.nf_conntrack_max = 10000000 
net.netfilter.nf_conntrack_tcp_loose = 0 
net.netfilter.nf_conntrack_tcp_timeout_established = 1800 
net.netfilter.nf_conntrack_tcp_timeout_close = 10 
net.netfilter.nf_conntrack_tcp_timeout_close_wait = 10 
net.netfilter.nf_conntrack_tcp_timeout_fin_wait = 20 
net.netfilter.nf_conntrack_tcp_timeout_last_ack = 20 
net.netfilter.nf_conntrack_tcp_timeout_syn_recv = 20 
net.netfilter.nf_conntrack_tcp_timeout_syn_sent = 20 
net.netfilter.nf_conntrack_tcp_timeout_time_wait = 10 
net.ipv4.tcp_slow_start_after_idle = 0 
net.ipv4.ip_local_port_range = 1024 65000 
net.ipv4.ip_no_pmtu_disc = 1 
net.ipv4.route.flush = 1 
net.ipv4.route.max_size = 8048576 
net.ipv4.icmp_echo_ignore_broadcasts = 1 
net.ipv4.icmp_ignore_bogus_error_responses = 1 
net.ipv4.tcp_congestion_control = htcp 
net.ipv4.tcp_mem = 65536 131072 262144 
net.ipv4.udp_mem = 65536 131072 262144 
net.ipv4.tcp_rmem = 4096 87380 33554432 
net.ipv4.udp_rmem_min = 16384 
net.ipv4.tcp_wmem = 4096 87380 33554432 
net.ipv4.udp_wmem_min = 16384 
net.ipv4.tcp_max_tw_buckets = 1440000 
net.ipv4.tcp_tw_recycle = 0 
net.ipv4.tcp_tw_reuse = 1 
net.ipv4.tcp_max_orphans = 400000 
net.ipv4.tcp_window_scaling = 1 
net.ipv4.tcp_rfc1337 = 1 
net.ipv4.tcp_syncookies = 1 
net.ipv4.tcp_synack_retries = 1 
net.ipv4.tcp_syn_retries = 2 
net.ipv4.tcp_max_syn_backlog = 16384 
net.ipv4.tcp_timestamps = 1 
net.ipv4.tcp_sack = 1 
net.ipv4.tcp_fack = 1 
net.ipv4.tcp_ecn = 2 
net.ipv4.tcp_fin_timeout = 10 
net.ipv4.tcp_keepalive_time = 600 
net.ipv4.tcp_keepalive_intvl = 60 
net.ipv4.tcp_keepalive_probes = 10 
net.ipv4.tcp_no_metrics_save = 1 
net.ipv4.ip_forward = 0 
net.ipv4.conf.all.accept_redirects = 0 
net.ipv4.conf.all.send_redirects = 0 
net.ipv4.conf.all.accept_source_route = 0 
net.ipv4.conf.all.rp_filter = 1

Áp dụng ngay cấu hình trên bằng lệnh sysctl như sau.

sudo sysctl -p

Ngăn ngừa DDoS bằng iptables

Do các cuộc tấn công DDoS có cường độ rất cao, ta không nên sử dụng INPUT chain để ngăn chặn các gói tin này vì sẽ ảnh hưởng đến giảm hiệu năng của hệ thống, do gói tin trước khi đến INPUT chain phải đi qua PREROUTINGFORWARD chain.

Vì thế ta hãy dùng mangle table để xử lý gói tin tại PREROUTING chain.

Chặn các gói tin không hợp lệ

Chặn các gói tin không phải là SYN và không thuộc các gói TCP đã bắt tay (ESTABLISHED) thành công.

iptables -t mangle -A PREROUTING -m conntrack --ctstate INVALID -j DROP

Chặn các gói tin mới nhưng không phải là SYN

Chặn các gói tin mới (kết nối chưa ở trạng thái ESTABLISHED) nhưng không có cờ SYN. Cái này tương tự cái trên nhưng vì lý do nào đó rule phía trên để lọt vài gói kiểu như thế này.

iptables -t mangle -A PREROUTING -p tcp ! --syn -m conntrack --ctstate NEW -j DROP

Chặn các gói SYN có kích thước bất thường

Ngăn ngừa SYN flood bằng cách chặn các gói SYN có giá trị TCP MSS (Maximum segment size) lớn bất thường ví dụ từ 536 – 65535.

iptables -t mangle -A PREROUTING -p tcp -m conntrack --ctstate NEW -m tcpmss ! --mss 536:65535 -j DROP

Chặn các gói tin có trạng thái không hợp lý

Ngăn chặn các gói tin chứa một số cờ mà các gói tin hợp lệ không bao giờ được set.

iptables -t mangle -A PREROUTING -p tcp --tcp-flags FIN,SYN FIN,SYN -j DROP
iptables -t mangle -A PREROUTING -p tcp --tcp-flags SYN,RST SYN,RST -j DROP
iptables -t mangle -A PREROUTING -p tcp --tcp-flags FIN,RST FIN,RST -j DROP
iptables -t mangle -A PREROUTING -p tcp --tcp-flags FIN,ACK FIN -j DROP
iptables -t mangle -A PREROUTING -p tcp --tcp-flags ACK,URG URG -j DROP
iptables -t mangle -A PREROUTING -p tcp --tcp-flags ACK,PSH PSH -j DROP
iptables -t mangle -A PREROUTING -p tcp --tcp-flags ALL NONE -j DROP

Ngăn các gói tin giả mạo (spoofing) là từ mạng riêng

Nếu máy chủ không có liên hệ gì với mạng nội bộ thì ta nên có thiết lập này để loại bỏ các gói tin ‘giả vờ’ như đến từ các máy trong cùng mạng LAN.

iptables -t mangle -A PREROUTING -s 224.0.0.0/3 -j DROP 
iptables -t mangle -A PREROUTING -s 169.254.0.0/16 -j DROP 
iptables -t mangle -A PREROUTING -s 172.16.0.0/12 -j DROP 
iptables -t mangle -A PREROUTING -s 192.0.2.0/24 -j DROP 
iptables -t mangle -A PREROUTING -s 192.168.0.0/16 -j DROP 
iptables -t mangle -A PREROUTING -s 10.0.0.0/8 -j DROP 
iptables -t mangle -A PREROUTING -s 0.0.0.0/8 -j DROP 
iptables -t mangle -A PREROUTING -s 240.0.0.0/5 -j DROP 
iptables -t mangle -A PREROUTING -s 127.0.0.0/8 ! -i lo -j DROP

Chặn các gói tin ICMP

ICMP thường dùng để ping và vì thế dễ bị lợi dụng để thực hiện đòn Ping of Death (ping flood), ICMP flood hoặc ICMP fragmentation flood. Nếu cảm thấy việc sử dụng ping là không cần thiết thì nên bật thiết lập này.

iptables -t mangle -A PREROUTING -p icmp -j DROP

Không cho client tạo quá nhiều kết nối

Rule dưới đây ngăn không cho client tạo quá 80 kết nối (connection) đến server. Điều này giúp ngăn chặn tấn công kiểu tạo kết nối (connection attack).

Con số 80 chỉ là ví dụ, ta cần điều chỉnh tùy theo hoạt động của ứng dụng trên server.

iptables -A INPUT -p tcp -m connlimit --connlimit-above 80 -j REJECT --reject-with tcp-reset

Giới hạn số kết nối TCP mới từ một client trong khoảng thời gian ngắn

Giới hạn không cho nhiều hơn 60 kết nối TCP mới từ một client trong mỗi giây. Con số 60 cũng chỉ là ví dụ trong tham số –limit.

Cách này nói chung cũng không hiệu quả lắm trong việc ngăn DDoS vì kẻ gian thường tấn công bằng số lượng lớn client hoặc giả mạo vô hạn IP nguồn.

iptables -A INPUT -p tcp -m conntrack --ctstate NEW -m limit --limit 60/s --limit-burst 20 -j ACCEPT 
iptables -A INPUT -p tcp -m conntrack --ctstate NEW -j DROP

Ngăn các gói fragment

Ngăn chặn các gói fragment với mục đích ngăn ngừa UDP fragmentation flood.

Tuy nhiên trước một cuộc tấn công UDP fragment flood vũ bão thì phía network card là physical layer cũng sẽ bị quá tải và nhiều khả năng gói tin không có cơ hội gặp rule này. Vì thế nó cũng không cần thiết lắm.

iptables -t mangle -A PREROUTING -f -j DROP

Giảm thiểu số lượng TCP RST trong khoảng thời gian ngắn

Mục đích của việc giảm thiểu này (ví dụ dưới đây là chỉ cho 2 gói RST trong 1 giây) là để ngăn chặn kiểu tấn công TCP RST floods. Tuy nhiên hiệu quả của phương pháp này vẫn còn là dấu hỏi.

iptables -A INPUT -p tcp --tcp-flags RST RST -m limit --limit 2/s --limit-burst 2 -j ACCEPT 
iptables -A INPUT -p tcp --tcp-flags RST RST -j DROP

Ngăn ngừa port scanning

Port scanning không hẳn là một hành vi DDoS nhưng nó là một trong những sự chuẩn bị của ‘tội ác’ này bằng việc phát hiện những cổng TCP nào đang mở trên server.

Rule dưới đây nhận biết dấu hiệu của port scanning dựa trên các cờ và tần suất của gói TCP đến và chặn hành vi này.

/sbin/iptables -N port-scanning 
/sbin/iptables -A port-scanning -p tcp --tcp-flags SYN,ACK,FIN,RST RST -m limit --limit 1/s --limit-burst 2 -j RETURN
/sbin/iptables -A port-scanning -j DROP

Ngăn tấn công brute-force

Rule dưới đây giảm thiểu tấn công brute-force để dò mật khẩu truy cập, bằng cách hạn chế số lượng những kết nối mới tạo trong khoảng thời gian ngắn tại một cổng dịch vụ nào đó.

Ví dụ sau là dành cho SSH – một trong những service phổ biến và can thiệp sâu trên server (SHH port= 22). Ta có thể thay bằng cổng dịch vụ khác.

/sbin/iptables -A INPUT -p tcp --dport ssh -m conntrack --ctstate NEW -m recent --set 
/sbin/iptables -A INPUT -p tcp --dport ssh -m conntrack --ctstate NEW -m recent --update --seconds 60 --hitcount 10 -j DROP

Phản hồi về bài viết

Cùng thảo luận chút nhỉ!

This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.