Tại sao tin tặc lại tấn công máy chủ DNS bằng DoS?
Tôi thức dậy sáng nay với một máy chủ được khởi động lại. Máy chủ DNS đang chạy ở mức hơn 100%. Sau một chút làm việc, tôi đã có fail2ban để chặn tất cả các yêu cầu đó.
Bản thân các yêu cầu là hợp lệ, lặp lại hàng trăm lần mỗi giây. Khi khối có nhiều (hàng trăm) IP, tôi có thể thấy rằng tôi đang chặn 1 triệu lượt truy cập UDP vài giờ một lần.
Đó chỉ là một cuộc tấn công [D] DoS? (có thể được coi là động vì nhiều máy tính có liên quan và một khi một máy tính bị chặn đủ lâu thì có vẻ như nó sẽ dừng các yêu cầu)
Một khả năng khác mà tôi có thể nghĩ đến là kẻ tấn công đang cố gắng đánh sập máy chủ DNS và giành quyền truy cập khi nó khởi động lại hoặc làm hỏng toàn bộ máy tính và cố gắng kết nối với các dịch vụ khác. (tức là trong trường hợp bạn không biết cách cài đặt tường lửa trước khi bắt đầu dịch vụ của mình)
Kể từ lần đặt lại tường lửa cuối cùng của tôi, đây là số liệu thống kê của tôi:
Lượt truy cập: 2,346,742
Số lượng IP: 473
Nó diễn ra nhanh chóng. Vài trăm lượt truy cập mỗi giây. Tuy nhiên, số lượng IP không tăng nhiều.
Trả lời
Từ nhận xét của @ Schroeder, tôi đã thực hiện một số tìm kiếm bổ sung và tìm hiểu thêm về kiểu tấn công này.
Tôi là mục tiêu!
Trước hết, có vẻ như tôi là mục tiêu của cuộc tấn công. Tại sao? Bởi vì cuộc tấn công Khuếch đại DNS có nghĩa là cổng nguồn của các yêu cầu DNS được đặt thành 53. Điều này có thể buộc DNS của tôi gửi phản hồi không được yêu cầu đến một máy chủ khác (xem biểu đồ bên dưới). Vì tôi có ít hơn 0,1% số lần truy cập như vậy sử dụng cổng đó, tôi không thực sự nghĩ rằng DNS của tôi đã được sử dụng cho Khuếch đại, mà đúng hơn đó là mục tiêu.
Cuộc tấn công hoạt động như thế nào?
Kẻ tấn công thiết lập một máy tính có phần mềm gửi các gói UDP đến một số máy chủ DNS ngẫu nhiên để yêu cầu tên miền. Gói tin trông bình thường ngoại trừ thực tế là kẻ tấn công đặt địa chỉ IP của một máy tính khác thay vì địa chỉ IP của nó làm nguồn. Kết quả là DNS gửi câu trả lời đến máy tính sai :
10.0.0.1 10.0.0.2 10.0.0.3
+------------+ +------------+ +------------+
| | | | | |
| Attacker +-->| Some DNS +-->| Me |
| | | | | |
+------------+ +--+---------+ +------------+
| ^
v |
+---------+--+ This step is not required, it happens if
| | your DNS is setup to accept recursive
| Master DNS | requests (which is not a good idea)
| |
+------------+
10.0.0.4
Trong ví dụ trên, yêu cầu của kẻ tấn công phải có 10.0.0.1 làm địa chỉ gốc của UDP. Nhưng thay vào đó, kẻ tấn công thay đổi địa chỉ IP của mình bằng 10.0.0.3. Kết quả là, khi DNS tại 10.0.0.2 nhận được gói UDP và sẵn sàng gửi trả lời, nó sẽ gửi dữ liệu đến 10.0.0.3.
DNS chính của miền sẽ được sử dụng nếu DNS tại 10.0.0.2 không biết gì về tên miền đang được truy vấn.
LƯU Ý QUAN TRỌNG: Điều này đúng với tất cả các dịch vụ UDP. DNS có lẽ là kém nhất về khả năng khuếch đại, nhưng NTP, chẳng hạn, cũng có thể được nhắm mục tiêu.
Tại sao không chỉ xác minh Địa chỉ nguồn?
Không thể thực hiện từ 10.0.0.2 vì UDP không có bộ nhớ về nguồn thực của gói tin.
Điều có thể xảy ra là các ISP xác minh rằng tất cả các gói đi ra khỏi một máy tính nhất định có địa chỉ IP của máy tính đó. Tôi nghĩ một số thì có, nhưng có lẽ hầu hết thì không. Nó có một tác động nhỏ về tốc độ ... tất nhiên với khuếch đại DNS là đáng buồn cười (khuếch đại DNS có tác động xấu hơn trên Internet so với việc kiểm tra nguồn gốc gói UDP nhỏ).
Điều khác có thể là người dùng vẫn có thể làm được bằng cách kết nối với Internet theo cách mà anh ta bỏ qua xác minh ISP. Tôi không biết liệu điều đó có thể xảy ra hay không, nhưng tôi sẽ không ngạc nhiên rằng nó có thể được thực hiện.
Trên thực tế, điều này là rất khó khăn vì nguồn gốc của các cuộc tấn công như vậy rất khó theo dõi và đó chắc chắn là lý do tại sao chúng vẫn đang xảy ra hàng loạt.
Tại sao đó là một DDoS?
Gói yêu cầu bản ghi DNS, đó là những gì xảy ra ở đây, rất nhỏ, có thể 300 byte. Vì vậy kẻ tấn công chỉ phải gửi một gói UDP nhỏ.
Tuy nhiên, phản hồi có thể là nhiều kilobyte dữ liệu. Cụ thể, có một miền đang được sử dụng trong các cuộc tấn công này:
peacecorps.gov
và miền đó trả về hơn 3Kb dữ liệu! (Nó xác định nhiều trường 'TXT' được sử dụng trong cuộc tấn công khuếch đại đó.) Đây là lý do tại sao nó được gọi là Cuộc tấn công khuếch đại.
Kết quả là, các yêu cầu từ Kẻ tấn công được chuyển đổi thành các phản hồi lớn hơn gấp 10 lần và máy tính bị tấn công (10.0.0.3) bị tập trung với một số lượng lớn các gói UDP khá lớn.
Ở đây tôi hiển thị mục nhập kết quả trong iptables
. Con số đầu tiên đại diện cho số lần truy cập vào máy tính DNS của tôi sau khoảng 40 phút (vì vậy hơn 10.000 lần truy cập một phút ...):
pkts bytes target prot opt in out source destination
61637 4376227 DROP udp -- eno1 * 0.0.0.0/0 0.0.0.0/0 udp dpt:53 STRING match "|0a7065616365636f72707303676f76|" ALGO name bm TO 65535
Cũng lưu ý cách chuỗi đã được chuyển đổi hoàn toàn thành số thập lục phân.
Một yêu cầu HTTP sẽ không tệ hơn sao ?!
HTTP 0.9 / 1.0 / 1.1 / 2 sử dụng TCP là giao thức hai chiều và không thể tạo khuếch đại với TCP. tức là TCP bị hỏng nếu lần đầu tiên bạn không kết nối đúng cách với quá trình bắt tay đầy đủ.
Tuy nhiên, HTTP / 3 giới thiệu giao thức QUIC là HTTP qua các gói UDP. Cho đến nay tôi chưa nghe nói về các vấn đề lớn với QUIC, nhưng giao thức đã thay đổi rất nhiều trong vòng 6-7 năm qua và nó vẫn chưa được triển khai rộng rãi. Đây là một bài viết về thực tế là QUIC đã tích hợp các tính năng để ngăn chặn các cuộc tấn công khuếch đại, vì vậy hy vọng rằng nó đã được quan tâm.
Một số người đang nói về việc sử dụng HTTP để truy vấn tên miền. (DoH - Tên miền qua HTTP). Hy vọng rằng điều đó sẽ không được thực hiện bằng QUIC ...
Làm cách nào để khắc phục sự cố?
Quá trình khuếch đại xảy ra do DNS của bạn được thiết lập để chấp nhận các yêu cầu tên miền mà bạn không kiểm soát (tức là các miền bạn không phải là chủ sở hữu).
BIND có một tùy chọn cho phép nó khuếch đại, được gọi là đệ quy theo cách nói của DNS. Tính năng này hiện bị tắt theo mặc định, nhưng bạn có thể đã bật nó (do nhầm lẫn?).
Đây là cài đặt sai :
allow-recursion { any; };
Những gì bạn muốn là sử dụng các cài đặt chính xác :
trusted-servers { 192.0.2.4; } // list all your trusted servers
allow-recursion { trusted-servers; };
Điều này sẽ làm cho máy chủ của bạn tự động từ chối tất cả các yêu cầu như vậy. Vì vậy, nếu bạn không peacecorps.gov
và bạn nhận được một yêu cầu như vậy, BIND sẽ chỉ dừng lại ở đó và ghi một ghi chú vào nhật ký DNS của bạn về yêu cầu bị từ chối.
Tôi có thể chặn IP khỏi những yêu cầu đó không?
Đúng. Tôi bắt đầu bằng cách làm điều đó vì máy chủ của tôi đang chạy tốt hơn 100% trong thời gian CPU. Tuy nhiên, có thể không khôn ngoan khi làm như vậy. Từ hình trên, bạn có thể thấy máy chủ DNS của bạn nằm giữa kẻ tấn công và nạn nhân. Nếu bạn chặn địa chỉ IP nguồn, đó không phải là IP của kẻ tấn công mà bạn đang chặn mà đó là của nạn nhân. Điều này có nghĩa là bạn đang thực sự ngăn nạn nhân nhìn thấy tên miền của mình và thực hiện các yêu cầu hợp pháp. Đó có lẽ không phải là điều bạn muốn!
Lúc đầu, tôi tạo một thông báo nhật ký từ tường lửa của mình. Nếu tôi phát hiện 5 yêu cầu trở lên đến cổng 53 (UDP) từ cùng một địa chỉ IP trong một khoảng thời gian ngắn (5 giây), thì tôi sẽ chặn địa chỉ IP đó. Để làm như vậy, tôi đã sử dụng fail2ban
.
Đầu tiên, tôi có một bộ lọc phát hiện các liên kết với UDP và cổng 53 là đích:
# Filter: /etc/fail2ban/filter.d/named-fast-requests.conf
[Definition]
failregex = \sIN=[a-z0-9]+ .* SRC=<HOST> .* PROTO=UDP .* DPT=53\s
Thứ hai, tôi có một nhà tù cung cấp các thông số khác:
# Jail: /etc/fail2ban/jail.d/named-fast-requests.conf
[named-fast-requests]
enabled = true
filter = named-fast-requests
action = named-action[scheme=all,period=year,reason=named fast requests]
logpath = /var/log/iptables/iptables.log
maxretry = 5
findtime = 5
bantime = 1036800
Điểm chính ở đây là maxretry
và findtime
được đặt ở 5 lần trong 5 giây hoặc ít hơn. Khi điều đó xảy ra, tôi chặn <HOST>
.
Bạn sẽ muốn cập nhật hành động với thứ của riêng bạn. Tôi sử dụng iplockcông cụ của riêng tôi ở đây. Lệnh tôi sử dụng trong hành động:
actionban = /usr/sbin/iplock -s named -b <ip>
Theo mặc định, fail2ban sử dụng iptables
trực tiếp. Tìm kiếm hành động của họ để xem nó được thực hiện như thế nào.
Đừng là nguồn khuếch đại
Bạn nên chặn các yêu cầu có cổng UDP nguồn nhỏ hơn 1024. Các yêu cầu này không hợp lệ. Nếu bạn cung cấp một máy chủ, cổng 53 sẽ là một cổng đích chứ không phải nguồn.
iptables -I INPUT 123 -i eth0 -p udp -m udp --sport 0:1023 -j DROP
CẢNH BÁO: thay thế vị trí (123) bằng số chính xác!
Quy tắc này nói rằng đối với bất kỳ gói UDP đến nào eth0
, có cổng nguồn từ 0 đến 1023, hãy bỏ gói đó đi. Điều này ngăn ai đó sử dụng máy chủ DNS của bạn để khuếch đại. Tuy nhiên, nó không bảo vệ máy chủ của bạn khỏi sự khuếch đại từ những người khác. Lưu ý rằng ngay cả với allow-recursion
thiết lập thích hợp , bạn sẽ không ngăn được cuộc tấn công khuếch đại nếu kẻ tấn công chọn đúng một trong các tên miền của bạn để tấn công.
Lưu ý: nếu bạn chỉ định một máy chủ định danh khác để phân giải tên miền trên máy tính của mình, bạn có thể muốn mở các kết nối đó trước khi chặn mọi thứ từ cổng 0 đến 1023. Điều này sẽ giống như sau:
iptables -I INPUT 123 -i eth0 -p udp -m udp --sport 53 -s 8.8.8.8 \
-d <your-static-ip> -j ACCEPT
Đây là dữ liệu trả về từ máy chủ định danh 8.8.8.8, mà bạn có thể muốn nhận. Không có khả năng nhà cung cấp của bạn hoặc một số máy chủ định danh chính thức khác là nguồn trực tiếp của một cuộc tấn công UDP. Nếu bạn không có địa chỉ IP tĩnh, bạn không phải bao gồm -d
tùy chọn.
Tuy nhiên, có lẽ tốt hơn rất nhiều nếu sử dụng ESTABLISHED
tính năng hiện có sẵn cho các tin nhắn UDP (nó đã có một thời gian, nhưng tôi nhớ một thời gian khi nó không khả dụng ...):
iptables -I INPUT 123 -i eth0 -p udp -m state \
--state ESTABLISHED,RELATED -m udp -d <your-static-ip> -j ACCEPT
Điều này có nghĩa là bạn sẽ tự động chấp nhận câu trả lời từ nhà cung cấp máy chủ tên miền của mình vì tường lửa sẽ biết bạn đã gửi yêu cầu và bạn muốn chấp nhận câu trả lời. Quy tắc này phải xuất hiện trước DROP
quy tắc trên.
Thả yêu cầu không mong muốn sớm
Rõ ràng, việc BIND chấp nhận tất cả những yêu cầu peacecorps.gov
đó không phải là điều mà bất cứ ai cũng muốn. Bạn thực sự có thể chặn chúng trực tiếp trong tường lửa của mình. Điều này hoạt động vì các gói UDP không được mã hóa nên tên miền có thể nhìn thấy được.
Đây là một quy tắc người ta có thể sử dụng để chặn các yêu cầu tên miền đó:
sudo iptables -I INPUT 123 -i eno1 -p udp -m udp --dport 53 \
-m string --hex-string "|0A|peacecorps|03|gov|" --algo bm -j DROP
Rõ ràng, nếu DNS của bạn có bất kỳ miền hoặc miền phụ nào bao gồm "peacecorps.gov" thì nó không nên sử dụng iptables
quy tắc đó . Đối với hầu hết chúng ta, mặc dù nó phải là hiếm.
Các --hex-string
tùy chọn cho phép bạn chỉ định một chuỗi. Cách nó được xác định trong gói UDP sử dụng một dạng chuỗi P (kích thước + dữ liệu). Vì "peacecorps" dài 10 ký tự, chúng tôi đặt 0x0A ngay trước nó. Một lần nữa, "gov" là ba chữ cái nên chúng tôi sử dụng 0x03. Nếu chúng ta sử dụng chuỗi "peacecorps.gov", nó sẽ không hoạt động vì dấu chấm không khớp với byte 0x03. Tuy nhiên, kích thước đầu tiên là tùy chọn (mặc dù bạn có thể kết hợp bất kỳ thứ gì trông giống nhau, chẳng hạn như "bestpeacecorps").
Có một quy tắc như vậy sẽ tiết kiệm cho dịch vụ tên miền của bạn rất nhiều lưu lượng truy cập hoàn toàn không mong muốn.
Cập nhật: Mặc dù cuộc tấn công đã dừng khoảng hai tuần sau khi tôi đăng câu hỏi của mình, vấn đề "peacecorps.gov" vẫn xảy ra khoảng 10 lần một ngày.
Nguồn: https://defragged.org/2020/05/20/tips-and-tricks-blocking-dns-requests-via-iptables/
Gỡ lỗi DNS của bạn
Để xem máy chủ DNS của bạn nhận và trả lời truy vấn nào, bạn có thể chạy các lệnh sau trong bảng điều khiển của mình:
sudo rndc querylog
Bây giờ hãy xem các bản ghi, thường là ở đây:
less /var/log/named.log
Nhìn xuống dưới cùng (nhấn Gvào less
) và bạn sẽ bắt đầu thấy các truy vấn từ các IP từ xa. Nhật ký bao gồm tên miền đang được kiểm tra. Nó rất thực tế, đặc biệt nếu bạn đã lỡ nhập một số tên miền của riêng mình vào DNS phụ hoặc cấp ba của bạn.