Trưa 4/4/2005
Mấy ngày vừa qua (từ ngày 28/3/2005) các trận DoS tấn công HVA "thưa dần rồi tắt hẳn", hay nói một cách khác, "thưa dần rồi tạm tắt".
Trưa nay, với mấy phút còn lại của giờ nghỉ trưa, tôi log vào HVA diễn đàn để xem qua và thấy truy cập diễn đàn thật chậm. Một trận tấn công mới? Tôi vội log vào HVA xuyên qua SSH và vất vả lắm (3 lần log vào) mới vào được. Tôi thật ngạc nhiên khi thấy server load khá thấp:
# w
load average: 4.25, 5.52, 4.96
Nhưng tại sao chậm thế này nhỉ? Tôi không tin đường dây sử dụng Internet của công ty có sự cố và bị chậm. Tuy nhiên, để xác thực tình hình, tôi gọi điện nhờ một người bạn kiểm tra dùm và như tôi dự đoán, tay bạn cho biết là vào HVA cực kỳ chậm. Tôi thử kiểm tra tình hình của web service bằng lệnh:
Code: # ps -ef | grep httpd | wc -l
257
Ôi chao, apache đã dùng tới mức tối đa cho phép của "MaxClients" là 256 processes và rõ ràng những processes này hoàn toàn bị chiếm hết và liên tục được sử dụng. Tôi mở một cái "tail" đến log file của apache và ngay lập tức, hàng loạt các cú GET có dạng:
/forum/?file=hvaonline_net&url=http%3A%2F%2Fhvaonline%2Enet%2Fforum%2F%3Ffile%3Dhvaonline%5Fnet&t=3660%260%2E372
đang hối hả "dội" đến HVA. Điều đáng chú ý ở đây là tính đơn giản nhưng cụ thể của request URL. Rõ ràng các cú GET này được tạo ra để tấn công cụ thể đến HVA.
Sau vài phút, tôi thử kiểm tra lại số lượng httpd process đang chạy, vẫn 257. Điều này chứng tỏ các process này đã bị "max out" tối đa nhưng lại không tạo ảnh hưởng mấy đến database server. Có lẽ ứng dụng trên mod_security của lần trước đã "bao" luôn trường hợp này. Tôi mở cấu hình của apache ra và chỉnh sửa lại giá trị "Keep-alive" timeout ngắn bớt lại chỉ còn 1/3 giá trị nguyên thuỷ với mục đích "ép" các cú GET này đang dùng "keep-alive" phải chấm dứt sau một khoảng thời gian nào đó để tạo điều kiện cho người dùng khác có thể vào. Sau khi restart lại apache và tiếp tục theo dõi, tôi nhận thấy tình hình không cải thiện được bao nhiêu. Khi duyệt HVA forum, có quá nhiều khoảng đứt đoạn và vẫn rất chậm. Tôi phóng ngay một cú tcpdump để lấy thông tin phân tích xem sự thể ra sao.
Trong khi tcpdump đang chạy, tôi trầm ngâm suy nghĩ
"nếu những cú GET này có thể đi xuyên qua được bức cản connection limit và rate limit thì có nghĩa số lần gởi phải thấp hơn quy định cản trên firewall không thì chúng đã bị firewall DROP ngay từ bên ngoài." Sau 2 phút, tôi dừng tcpdump, nén kết quả sniff được và tải về máy của tôi. Tôi nhận thấy cú GET với URL kia chưa rõ nội dung là gì như rõ ràng nó không thuộc một URI hợp lệ nào của HVA cả. Chắc chắn nó sẽ được "wwwect" về trang mặc định của HVA và làm như thế, số query đến server vẫn xảy ra --> tạo server load. Tôi quyết định lập thêm một rule trên mod_security để cản cú GET mới này.
Vẫn chưa thoả mãn với tình trạng bị "maxed out", tôi bắt tay ngay vào điều chỉnh số "MaxClients" được "hardcoded" trong httpd.h là 256 (vì tôi không thể gia tăng quá con số này trên cấu hình httpd.conf) và biên dịch lại apache. Công việc này chỉ mất chưa tới 5 phút trên HVA server (xeon CPU có khác!). Tôi điều chỉnh lại giá trị MaxClients thành 512 và restart lại apache. Lần này, khi theo dõi số lượng child process được apache tạo ra tôi thấy nó không gia tăng quá nhanh chóng sau khi vượt khỏi con số 257. Cứ mỗi 5 phút lại có thêm chừng 2 child process mới. Điều này chứng tỏ số lượng IP dùng để tạo các cú GET không gia tăng (hoặc gia tăng rất ít). Hy vọng người dùng có thể tiếp tục vào được diễn đàn HVA ở tình trạng tạm thời "cầm cự" thế này cho đến tối, khi tôi rảnh rỗi hơn để có thể điều chỉnh xác thực hơn.
Mới đó mà đã hết giờ ăn trưa và trước mắt tôi là một mớ công việc kinh khủng cần phải giải quyết. Tôi thở dài, chỉnh lại firewall để hạn chế số lượng connection. Khởi động lại firewall, tôi hy vọng với hạn chế này cộng với rule mới cho mod_security sẽ giảm thiểu tác hại của các cú GET tai quái (nhưng hợp lệ) kia. Tôi phải quay lại với mớ công việc đang bề bộn ở sở làm.
Chiều 4/4/2005
Đã gần đến giờ tan sở, tôi vào thử HVA lần nữa. Tình hình vẫn không khá hơn bao nhiêu. Tôi thử log vào HVA server bằng SSH, kẹt cứng! không vào được. Tôi thử đi thử lại cả chục lần cũng không được. Chẳng lẽ lão JAL đã rút dây cắm luôn sao?
. Từ SSH console tôi dùng để tunnel từ nhà, tôi thử nmap HVA và biết chắc nó vẫn còn online. Tuy nhiên có quá nhiều packets bị hủy (lost). Tôi chậc lưỡi "không lẽ trận DoS này đã saturate luôn cả đường dây Internet của HVA sao?". Còn 10 phút nữa tan sở, tôi quyết định tạo tunnel từ sở về máy ở nhà và tạo đường ra để connect với YIM (xuyên qua tunnel). Tôi log on YIM và lão JAL đang "vàng khè" trên danh sách YIM. Tôi gởi vội cho lão một thông điệp vào báo rằng tôi không vào SSH được. Cả hai chúng tôi đều đoán rằng có lẽ đường dẫn Internet của HVA đã bị saturate hoặc máy chủ HVA quá bận rộn (ít nhất là trên socket) nên tôi không log vào được. Tôi đề nghị lão JAL tắt bỏ apache, tắt bỏ luôn monit để tránh không cho nó tự động restart lại apache. Tôi vẫn vào không được! JAL đã thử restart lại server hai lần và ngưng hẳn apache nhưng tôi vẫn không thể vào được. Dường như ngay khi máy chủ HVA online, đường dẫn của nó bị ngập ngụa các packets tấn công hoặc có thể nó đang bị tấn công bởi một dạng khác. Tiếc thay tôi không thể làm gì được lúc này.
Tình hình xem ra gay go. Tôi than thầm
"hèm, trúng ngay một ngày bận rộn mà chơi thật ác". Trước khi rời sở, tôi đề nghị JAL điều chỉnh lại trọn bộ chế độ logging của firewall để giảm thiểu số lượng logs đang được tạo ra với cơn lũ DDoS đang ập vào HVA server. Tôi đề nghị JAL tạm ngưng ở đó, khi tôi về đến nhà tối nay, tôi sẽ liên lạc với JAL qua YIM và tiếp tục xử lý. Tôi xếp laptop lại, phóng nhanh ra cửa để kịp chuyến tàu.
Trên tàu, trên đường về nhà, tôi mở mảnh tcpdump lấy được lúc trưa để xem xét. Tôi thấy ngay một lượng GET khổng lồ đã ập vào HVA server từ hàng trăm IP (từ VN và nhiều nơi khác trên thế giới). Cú get có nội dung và header như sau:
Code: GET /forum/?file=hvaonline_net&url=http%3A%2F%2Fhvaonline%2Enet%2Fforum%2F%3Ffile%3Dhvaonline%5Fnet&t=3660%260%2E37203 HTTP/1.1
Accept: */*
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)
Host: hvaonline.net
Connection: Keep-Alive
Cookie: session_id=74814b8ff967ad0d282ed5945d39276a
Đoạn trên cho chúng ta những thông tin gì? quả là không nhiều. Trước tiên ta thấy cú GET này hoàn toàn không có thông tin nào về x-flash cả. Đây là lý do tại sao chúng đi xuyên qua firewall và không hề bị cản trở (ngoài số requests vi phạm luật connection limit). Kế tiếp, giá trị request được "pass" qua URL hoàn toàn không vi phạm luật bảo mật đã được áp đặt trên HVA server (cho các vấn đề thuộc về xss, buffer overflow, sql inject....). Các giá trị request được "urlencoded" hoàn toàn đúng quy cách. Decode đoạn request trên cho kết quả như sau:
/forum/?file=hvaonline_net&url=http://hvaonline.net/forum/?file=hvaonline_net&t=3660&0.37203
Đây là lý do tại sao chúng lại tiếp tục đi xuyên qua các cơ chế cản lọc ở tầng application và "tàn phá". Có lẽ sau khi tôi áp dụng một rule mới trên mod_security đã giảm thiểu loại GET này nhưng server tiếp tục bị tấn công bằng phương thức khác. Lúc nãy JAL cho tôi biết cổng 25 (SMTP) của HVA server cũng có hàng đống request nhưng không chắc phải do DoS hay không.
Tôi tiếp tục duyệt qua đoạn tcpdump, đoạn này chỉ chạy trong 2 phút lúc trưa nhưng sau khi liệt kê thông tin trong đoạn này, tôi tổng kết có khoảng trên 75 ngàn cú GET đến HVA server trong 2 phút ngắn ngủi và đi từ ít nhất 400 IP khác nhau. Tôi trầm ngâm nghĩ ngợi và hình thành 2 trường hợp có thể xảy ra với HVA từ trưa nay:
1) loại GET ở trên bị loại trừ và một (hoặc nhiều loại khác) đang tấn công HVA mà tôi chưa rõ là dạng nào.
2) lối cản bằng mod_security đã tạo ra "phản ứng phụ" như tôi đã trình bày trong phần cuối của bài ký sự lần trước.
Cả hai giả định này đều có thể xảy hoặc có thể đang cùng xảy ra.
Hãy thử phân tích trường hợp 1 trước.
- Nếu HVA đang bị tấn công bằng một dạng (hoặc nhiều dạng GET) khác thì có nghĩa là màng lưới phòng thủ trên HVA không cản lọc hết hoặc không hề cản lọc.
- Nếu các cú GET ở dạng khác dạng GET ở trên và không hề mang thông tin gì chứng tỏ nó là x-flash thì chắc chắn nó được đi xuyên qua firewall và tất nhiên snort cũng chẳng có gì để thông báo.
- Nếu các cú GET này không hề vi phạm các luật cản lọc của mod_security, chúng sẽ tiếp tục đi vào.
Điều này cho thấy nếu mod_security định chỉnh định chặt chẽ hơn và sâu sát hơn cho cấu trúc của web application chạy trên HVA, trường hợp những cú GET "đen tối" nhưng "hợp lệ" sẽ giảm thiểu. Đây là điều mà thôi đã đề cập trong bài "ký sự" lần trước về việc sắp xếp và chỉnh định lại web application của HVA để loại bỏ phần lớn những khả năng tấn công "một cách hợp lệ" của DDoS. Nói cho cùng, mod_security đã không phải là một tấm màn che cốt lõi trong các tầng phòng thủ của HVA. Tôi vẫn rất e ngại khi phải dùng các hệ thống cản lọc trên application layer vì lý do hiệu xuất nhưng nếu cần phải dùng đến nó để gia tăng độ chặt chẽ của "vòng đai phòng thủ" thì cũng phải dùng vậy. Nhưng có lẽ phải tối ưu dạng ứng dụng này đến mức tối đa có thể được. Thực tế lúc này tôi chưa dùng mod_security cho mục đích bảo vệ ở bình diện DoS và sự thể đã quá hiển nhiên.
Với trường hợp 2, tôi e rằng ứng dụng mod_security hồi trưa nay đã tạo những "phản ứng phụ". Phản ứng phụ ở đây là hàng loạt các cú FIN mà mod_security tạo ra để kết thúc những cú GET "đen tối" tạo ra. Như đã phân tích ở cuối bài "ký sự" lần trước, bởi mod_security thực thi các bước cần thiết và đúng quy định trên giao thức TCP nên chính nó đã bị sức ép về mặt tài nguyên để thực thi. Tôi hình dung ra hàng ngàn sockets đang ở tình trạng FIN-WAIT-1, FIN-WAIT-2 và TIME-WAIT đang hiện diện trên HVA server lúc này. Nói về mặt tài nguyên (như memory, disk space, bandwidth) thì HVA server đủ sức để chống chọi ít nhất vài giờ nhưng tình trạng sẽ trở nên tệ hại nếu như số lần mod_security thực thi để kết liễu các cú GET kia càng tăng. Quả thật, đây là điều tôi lo ngại hơn hết bởi vì sức ép của tình trạng dần dần cạn kiệt tài nguyên chắc chắn sẽ xảy ra nếu như không có một phương pháp nào giải quyết nhanh chóng hơn là phó mặc vào cơ chế triệt bỏ các cú GET của mod_security. Tuy những cú GET này không thể đi sâu hơn vào hệ thống để tạo server load nhưng nói về mặt tác dụng của mục đích DoS, nó có tác dụng hơn những cú POST chậm chạp kia. Những cú POST có thể đạt được ở mức tối đa và có thể đụng tới giới hạn số connection database server cho phép rồi dừng lại ở đó (vì không thể đi xa hơn). Với những cú GET kia và với số lượng IP dày đặc nhằm dung hoà đường dẫn của HVA thì tình hình nằm trên phương diện hoàn toàn khác.
Trước mắt tôi e rằng số lượng "MaxClients" trên apache có thể đã "maxed out". Điều này có nghĩa rất ít cơ hội người dùng hợp lệ có thể vào được diễn đàn HVA vì số lượng "MaxClients" đã tới giới hạn và gần như bị những cú GET tai quái kia chiếm giữ. Vậy, điểm cốt lõi ở đây là làm sao giải toả tình trạng bị "maxed out" ở trên, làm sao "discard" được những cú GET đi vào nhanh như vũ bão kia. Từ khoá "discard" đã cho tôi ngay một đáp án. Tôi chưa hình thành ngay được phương pháp cụ thể làm thế nào để giải toả nhưng tôi tự gật gù sau khi nảy ra cho mình một hướng giải quyết.
Tối 4/4/2005
Cơm nước xong, tôi phải dành nửa giờ để kiểm soát bài vở của thằng cu con. Khi mọi chuyện đâu vào đó thì đã 8 giờ tối nơi tôi cư ngụ, chừng 6 giờ chiều giờ máy chủ. Đối với người dùng, diễn đàn HVA đã offline hơn 2 giờ.
Tôi thử log vào HVA server bằng SSH. Vẫn không vào được! Mở YIM lên, JAL đang online, có lẽ lão đang sẵn sàng tác chiến
. Tôi gởi JAL một thông điệp đề nghị chỉnh firewall để block luôn cổng 80, không cho phép bất cứ request nào đi vào được trong máy. JAL thực hiện ngay việc này nhưng... tôi vẫn không thể log vào cổng SSH trên HVA server. Cha chả, tôi ngầm đoán lần này HVA bị tấn công với số lượng IP chưa từng có. Cứ cho mỗi IP chỉ gởi 3 request trong một giây và có 5, 7 trăm hoặc cả ngàn IP cùng gởi một lượt thì có thể đường dây Internet của HVA bị dung hoà (saturated).
Tôi lại đề nghị JAL đóng luôn cổng SMTP và cổng SSH nhưng mở lại SSH trên một cổng hoàn toàn khác xem sao. Sau một phút, JAL hồi báo cho biết là đã thực hiện xong đề nghị của tôi. Tôi thử log vào HVA xuyên qua cổng SSH "mới" và quả nhiên, tôi log vào được. Vẫn còn rất chậm nhưng điều quan trọng là tôi đã có thể vào HVA server. Tôi thử bắt đầu điều chỉnh HVA server nhưng nhận ra ngay là không thể làm việc trong tình trạng như thế này để khắc phục nhanh chóng tình trạng hiện thời của HVA bởi vì những gì tôi gõ hoặc duyệt trên console mất quá nhiều thời gian để thực thi. Tôi quyết định nhờ JAL triển khai dùm các bước (vì lão ngồi ngay trước server nên không bị tình trạng chậm như tôi).
Trong khi trao đổi thông tin với JAL để lão điều chỉnh trên server, tôi tranh thủ điều chỉnh một số chi tiết khác. Tôi mất hơn 20 phút để điều chỉnh lại cấu hình của apache, thêm 15 phút để điều chỉnh lại firewall và kiểm tra chế độ log. JAL đã hoàn tất các điểm tôi đề nghị JAL chỉnh sửa từ lâu, còn tôi phải gần 1 giờ trôi qua mới kết thúc mọi việc. Trong lúc tôi kiểm tra và điều chỉnh lại những điểm quan trọng trên HVA server, JAL signed off YIM nhưng trở lại sau vài phút.
Tôi bảo JAL:
"bồ sẵn sàng chưa? hãy khởi động lại các dịch vụ!"
JAL cười, đáp lại:
"có tự tin không đó lão?"
Tôi đáp:
"cùng lắm là rút dây ra đi ngủ cho ngon giấc thôi ".
Và... thế là chúng tôi khởi động lại các dịch vụ cần thiết. Thật tuyệt! server load không những giảm xuống mà giảm thật nhanh. Giá trị lấy từ
# netstat -nat | grep TIME_WAIT tụt xuống từ trên 4000 ngàn còn lại vài chục trong mấy phút đồng hồ. Nhìn trên cái stats của server, tôi tủm tỉm cười một mình vì từ khoá "discard" tôi nảy ra trong đầu khi đang ở trên tàu lửa chiều nay quả thật ứng hiệu ngoài ý muốn. Điều đáng chú ý là ngay lúc apache khởi động lại, tôi phát hiện ra hàng loạt "x-flash" ở dạng GET (phối hợp với vài dạng x-flash khác) và có request rất ngắn gọn như sau:
GET /forum/index.php?
Tuy nhiên, những cú GET này đã được chuyển hướng đến một nơi khác và không có cơ hội đi vào HVA forum. Bạn có thể thắc mắc tại sao các request ở dạng
/forum/index.php? lại không thể đi vào HVA forum, nếu thế thì cả những request từ người dùng hợp lệ cũng sẽ bị "hoá giải" cả sao? Điều tôi có thể tiết lộ ở đây là một request thiếu hợp lệ được gởi từ "x-flash" có tính chất khác biệt so với request gởi từ trình duyệt bình thường (như Internet Explorer hoặc FireFox...). Nếu bạn dùng packet sniffer để bắt lấy một đoạn thông tin và thử phân tích kỹ lưỡng, bạn sẽ nhận ra điều này. Sự khác biệt không những từ thông tin biểu thị x-flash (nếu có) mà còn ở một số thông tin khác trên HTTP header. Tính đặc biệt này đã không được ứng dụng để "cản" các cú "x-flash" ở tầng IP (trên iptables) bởi vì dẫu có nhận ra, iptables cũng không thể xử lý được chúng (ngoại trừ có một iptables module chuyện dụng cho vấn đề này, nhưng tôi e rằng nó không tuyệt đối hiệu quả). Sau khi ứng dụng mod_security, các gói tin đi đến tầng HTTP và mang tính chất đặc biệt này đã bị xử lý một cách dễ dàng vì chúng ở trên cùng một tầng giao thức.
Rất tiếc tôi không / (chưa) có thể tiết lộ chi tiết kỹ thuật của phương pháp ứng dụng lúc này vì nhiều lý do nhạy cảm. Tuy nhiên, tôi có thể gợi ý một điểm cốt lõi: nếu bạn phải cản một nguồn lực đẩy vào, bạn sẽ hao tổn sức lực. Nhưng nếu bạn cho phép nó vào và dẫn nguồn lực này đến một nơi không gây tác hại, không gây "phản ứng phụ" thì bạn không còn bị hao tổn. Nguyên tắc này hoá giải hàng ngàn sockets ở dạng "orphans" trên HVA server. Chẳng những thế, sau đó nó không còn bất cứ cơ hội để tạo thêm "orphan" nào trên socket vì "4 bước kết thúc" xuất truy cập hoàn toàn không xảy ra đối với các gói tin vi phạm. Tất nhiên các xuất truy cập hợp lệ vẫn hoạt động bình thường và đúng quy định của giao thức.
Mười lăm phút trôi qua, server load của HVA xuống còn 0.5 trong khi mớ log của snort vẫn tường trình các cú x-flash đổ vào như nước. Ngay lúc các dịch vụ trên HVA khởi động lại, tôi và JAL cùng log vào diễn đàn HVA (bằng FireFox). Có lẽ JAL cũng như tôi, cũng nhẹ nhõm khi thấy vận tốc duyệt diễn đàn có phần nhanh hơn trước. Phải chăng tôi tưởng tượng?
Tôi gởi JAL một thông điệp:
"thôi, tớ đi ngủ đây!" và logoff.
Các bạn có thể theo dõi tiếp phần 18 tại http://hvaonline.net/hvaonline/posts/list/508.html