eBPF & XDP tích hợp trong Bizfly Cloud CDN giúp xử lý hiệu năng cao và phòng chống tấn công DDoS L3/4
Theo tốc độ phát triển chóng mặt của công nghệ số, lượng dữ liệu cần xử lý cũng tăng lên không ngừng. Điều này đòi hỏi các hệ thống phải nâng cao năng lực xử lý, nhiều hệ thống đã áp dụng các công nghệ chuyên sâu để ứng phó với bài toán hiệu năng cao.
Bên cạnh các giải pháp tăng cấu hình, sử dụng phần cứng có hiệu năng cao, hiện một giải pháp đang được áp dụng hiệu quả tại nhiều hãng công nghệ lớn, đó là tận dụng khả năng xử lý hiệu năng cao trong lõi hệ điều hành với công nghệ eBPF. Cùng Bizfly Cloud tìm hiểu về công nghệ này qua bài phân tích sau đây.
Tìm hiểu eBPF là gì?
Berkeley Packet Filter (BPF) là một công nghệ được sử dụng trong các chương trình chạy trong nhân hệ điều hành cho phép phân tích lưu lượng mạng (phiên bản eBPF là một phiên bản mở rộng của BPF (extended BPF) JIT và máy ảo trong nhân Linux).
Về cBPF (classic BPF)
BPF là một máy ảo nhỏ có độ linh hoạt và hiệu năng cao ở trong nhân của hệ điều hành Linux. Công nghệ cho phép chạy các chương trình được đưa vào từ phía người dùng (userspace) một cách an toàn và đính kèm các chương trình đó tại các điểm hook được chỉ định trong nhân hệ điều hành. BPF có thể phân biệt và đưa ra các quyết định để thực hiện hành động tiếp theo dựa trên các gói tin nhận được từ mạng. BPF đã được ứng dụng trên Linux trong nhiều năm để làm bộ lọc gói tin, ví dụ điển hình là tcpdump.
BPF phiên bản ban đầu đã được đổi tên thành cBPF hay classic BPF. Máy ảo BPF ban đầu sử dụng 2 thanh ghi 32 bit và hiểu được 22 lệnh khác nhau, ngoài ra còn sử dụng 16 thanh ghi 32 bit làm bộ nhớ lưu trữ ban đầu. Hiện tại, cBPF đang được sử dụng trên các kiến trúc 32 bit, trong khi đó các hệ thống hỗ trợ 64 bit thực hiện biên dịch JIT từ tập lệnh (instructions set) của eBPF.
Về eBPF (extended BPF)
Về cơ bản thì eBPF vẫn là BPF, eBPF được tạo ra để giúp BPF có thể được ứng dụng trong nhiều bài toán lớn hơn. Cụ thể là tăng lên 11 thanh ghi 64 bit. Các thanh ghi 64 bit ánh xạ một-một với thanh ghi trong phần cứng trên kiến trúc 64 bit được hỗ trợ bởi nhân hệ điều hành.
Tập lệnh của eBPF phong phú hơn so với cBPF khi thêm vào các lệnh (instruction) sử dụng thuật toán và logic phù hợp với thanh ghi có kích cỡ lớn hơn, cũng như một lệnh call cho lời gọi hàm.
Sau đây là các thành phần chính tham gia vào hoạt động của một chương trình BPF.
Hook
Ngoài các hook thường thấy trong kernel space, eBPF thêm vào một hook mới trong driver space, hook này gọi là eXpress DataPath (XDP). XDP là nơi cắm chương trình BPF vào driver tương ứng, cho phép người dùng lựa chọn loại bo, chuyển hướng, hoặc gửi về nơi đến trước khi các gói tin này được cấp socket buffer metadata.
eBPF Verifier + JIT
Sau khi chương trình BPF được biên dịch sang eBPF bytecode bằng trình biên dịch LLVM Clang và xác định được hook mà ta muốn tải chương trình vào, ta có thể tiến hành tải chương trình vào nhân.
Khi chương trình được tải vào nhân Linux, eBPF sẽ phải tuân thủ một quá trình (thông qua lời gọi hệ thống bpf()), nó sẽ trải qua hai bước trước khi được cắm vào hook được yêu cầu.
Quá trình kiểm tra:
Bước kiểm tra đảm bảo rằng chương trình eBPF chạy an toàn. Nó xác nhận rằng chương trình đáp ứng một số điều kiện nhất định:
- Chương trình không được sử dụng biến chưa được khai báo trước hoặc truy cập một vùng nhớ quá giới hạn.
- Chương trình phải phù hợp với kích thước vùng nhớ mà hệ thống yêu cầu. Ta sẽ không thể load một chương trình eBPF lớn bất thường.
- Chương trình luôn chạy đến khi kết thúc (tức là chương trình không chạy trong một vòng lặp mãi mãi, hoặc chờ một chương trình khác để tiếp tục tiến trình. Chương trình eBPF có các vòng lặp giới hạn, nó chỉ có thể được chấp nhận nếu như verifier có thể chắc chắn rằng vòng lặp này có chứa một điều kiện thoát và có thể chắc chắn rằng điều kiện này sẽ xảy ra).
- Chương trình phải có độ phức tạp nhất định. Verifier sẽ đánh giá tất cả các trường hợp hoạt động của chương trình và phải có khả năng hoàn thành việc đánh giá trong giới hạn độ phức tạp đã cấu hình.
Trình biên dịch JIT:
Bước biên dịch Just-in-Time (JIT) chuyển đổi bytecode được biên dịch từ LLVM Clang thành mã opcodes để tối ưu hóa tốc độ thực thi của chương trình trong nhân. Nhờ vậy các chương trình eBPF có thể chạy hiệu quả tương tự với biên dịch nguyên bản code của nhân hoặc code được tải vào như một module của nhân.
BPF Map
Một đặc tính quan trọng cần nhắc đến của các chương trình eBPF là khả năng chia sẻ và lưu trữ dữ liệu đã thu thập. Với mục đích này, các chương trình eBPF có thể tận dụng các BPF maps để lưu trữ và truy xuất dữ liệu trong một tập hợp nhiều cấu trúc dữ liệu. BPF maps có thể được truy cập từ các chương trình eBPF cũng như từ các ứng dụng userspace thông qua lời gọi hệ thống.
BPF map là tập các cặp key/value được xác định khi tải chương trình eBPF, và những map này có thể được tham chiếu từ trong code eBPF. BPF map có thể tồn tại ở kiểu toàn cục hoặc kiểu per-CPU. BPF map có thể được chia sẻ qua lại giữa các chương trình BPF chạy ở các vùng khác nhau của nhân hoặc giữa chương trình eBPF và userspace.
BPF map có thể mang kiểu hash maps, array, radix tree, cũng như còn có các kiểu đặc biệt hơn như map chứa con trỏ trỏ đến các chương trình eBPF (kiểu map này được áp dụng cho tail call).
Tìm hiểu về XDP
eXpress Data Path (XDP) cung cấp cho BPF một framework cho phép xử lý gói tin ở tốc độ cao bên trong nhân Linux. XDP sẽ chạy chương trình BPF ở thời điểm sớm nhất có thể, có thể là ngay thời khắc driver mạng nhận được gói tin.
XDP return code
Khi chương trình được gọi, nó sẽ nhận được context của gói tin và từ đó chương trình có thể đọc nội dung gói tin bằng con trỏ trỏ đến dữ liệu của gói tin, qua đó có thể cập nhật một số bộ đếm và có khả năng sửa đổi gói tin. Sau cùng chương trình cần kết thúc bằng một trong 5 hành động XDP, các return code của chương trình BPF sẽ chỉ cho driver nên thực hiện hành động nào với gói tin:
XDP_DROP: Đây là hành động loại bỏ gói tin và thường được sử dụng cho các chương trình BPF có cơ chế nhằm giảm thiểu tấn công Ddos hoặc tường lửa nói chung.
XDP_ABORTED: Tương tự như DROP, hành động này cho biết đã xảy ra lỗi khi xử lý. Hành động này không nên được sử dụng làm mã trả về.
XDP_PASS: Hành động này sẽ giải phóng gói tin và chuyển tiếp nó đến network stack của nhân để tiếp tục xử lý. Đây có thể là gói tin gốc hoặc phiên bản sửa đổi của nó.
XDP_TX: Hành động này dẫn đến việc trả lại gói tin đã nhận ra khỏi cùng một NIC (Network interface card) mà nó đã đến. Hành động này thường kết hợp với việc sửa đổi nội dung gói tin, ví dụ như viết lại địa chỉ IP và MAC.
XDP_REDIRECT: Hành động chuyển hướng cho phép một chương trình BPF chuyển hướng gói tin đến một nơi khác, một CPU khác hoặc NIC khác.
Các chế độ hoạt động của XDP
XDP có 3 chế độ hoạt động trong đó chế độ ‘native’ XDP là chế độ mặc định.
Native XDP
Đây là chế độ mặc định trong đó chương trình XDP BPF được chạy trực tiếp trên driver sẽ nhận gói tin.
Offloaded XDP
Trong chế độ offloaded XDP, chương trình XDP BPF được offload trực tiếp vào NIC thay vì được chạy từ CPU. Nhờ đó, chi phí xử lý mỗi gói tin vốn đã cực kỳ thấp giờ được đưa ra khỏi CPU và được chạy trên NIC, giúp tăng hiệu suất rất lớn so với native XDP
Generic XDP
Đối với các driver chưa được triển khai native XDP hoặc offloaded XDP, nhân hệ điều hành cung cấp một lựa chọn không yêu cầu bất kỳ thay đổi nào liên quan đến driver. Chế độ này áp dụng cho các bên muốn cài đặt và thử nghiệm các chương trình dựa trên API XDP của nhân và sẽ không hoạt động với hiệu suất tương đương với chế độ native XDP hoặc offloaded XDP. Khi áp dụng XDP trong production environment, chế độ native XDP hoặc offloaded XDP sẽ phù hợp và nên được sử dụng hơn khi chạy XDP
Ưu, nhược điểm của chế độ Native XDP so với Offloaded XDP:
Nhược điểm
Chế độ offloaded XDP sẽ đem đến hiệu suất lớn hơn so với chế độ native XDP do chương trình XDP BPF đã được tách ra khỏi CPU và chạy trên NIC
Ưu điểm
Hầu hết các NIC sử dụng 10G hoặc cao hơn đều đã có hỗ trợ chế độ native XDP. Chế độ offload thường được triển khai trên các SmartNIC có xử lý đa luồng, đa lõi
Chỉ các chương trình XDP không yêu cầu truy cập đến các hàm hỗ trợ của BPF mới có thể offload ra phần cứng của mạng. Vậy nên các driver sử dụng chế độ offload sẽ thường đi kèm chế độ native để có thể truy cập vào các hàm hỗ trợ chỉ khả dụng với chế độ native.
Các ứng dụng của eBPF và XDP
eBPF và XDP có thể áp dụng vào rất nhiều bài toán cụ thể nhờ khả năng có thể lập trình và dễ sử dụng, dưới đây ta có danh sách một số các bài toán cụ thể mà ta có thể dễ dàng giải quyết khi ứng dụng eBPF và XDP.
Phòng chống Ddos và tường lửa
Một trong những tính năng cơ bản của XDP BPF là ta có thể ra lệnh cho driver loại bỏ một gói tin bằng giá trị trả về XDP_DROP tại thời điểm rất sớm, đây là điều kiện lý tưởng để đối phó với tấn công Ddos. Ngoài ra, XDP BPF còn cho phép thực hiện mọi loại chính sách tường lửa với gần như không tiêu tốn tài nguyên trong BPF.
Chuyển tiếp gói tin và cân bằng tải
Ứng dụng khác của XDP là chuyển tiếp gói tin và cân bằng tải bằng các giá trị trả về XDP_TX hoặc XDP_REDIRECT. Trong tầng XDP ta có thể tùy ý chỉnh sửa gói tin bằng chương trình BPF, trong tập các hàm hỗ trợ của BPF cũng có các hàm giúp tăng giảm kích cỡ gói tin để có thể tùy ý đóng gói hoặc mở gói tin trước khi lại gửi chúng ra ngoài. Với XDP_TX và XDP_REDIRECT, ta có thể áp dụng trong cài đặt bộ cân bằng tải để điều hướng gói tin.
Lọc/xử lý gói tin trước khi vào ngăn xếp
XDP cũng có thể được sử dụng để tăng cường an toàn ngăn xếp mạng của nhân bằng cách áp dụng XDP_DROP, nó có thể loại bỏ các gói tin không cần thiết tại điểm sớm nhất có thể trước khi chúng đến ngăn xếp mạng. Lợi ích của việc là các gói tin không cần phải đi qua các thành phần khác nhau của nhân như công cụ GRO, bộ phân tích luồng, … trước khi có thể xác định loại bỏ gói tin đó hay không.
Giám sát, thu thập thông tin lưu lượng mạng
Trong quá trình phân tích gói phức tạp, XDP cung cấp một phương tiện để đẩy các gói tin (đã bị chia ra hoặc đầy đủ) và metadata một cách hiệu quả. Phương tiện này cũng được cho phép trong trường hợp lưu lượng mới, ta chỉ có thể phân tích dữ liệu và sau khi được xác định là lưu lượng không độc hại mới có thể cho vượt qua giám sát.
Ứng dụng eBPF và XDP cho hệ thống CDN Edge Platform của Bizfly Cloud
Công nghệ eBPF và XDP hiện tại đã được nghiên cứu và ứng dụng trên hệ thống CDN Edge Platform của Bizfly Cloud, phục vụ cho nhu cầu phòng chống tấn công DDoS tầng L3/4 đồng thời giám sát liên tục các gói tin vào/ra hệ thống giúp đội ngũ kỹ sư Bizfly Cloud giám sát hiệu quả chất lượng truyền tải dữ liệu, phát hiện kịp thời các bất thường trong lưu lượng mạng từ đó liên tục cải thiện chất lượng dịch vụ CDN, mang tới cho khách hàng dịch vụ ổn định và hiệu quả sử dụng cao nhất.
>>> Có thể bạn quan tâm: Dịch vụ CDN nào tốt nhất Việt Nam?
Bizfly Cloud - Đơn vị hàng đầu cung cấp các giải pháp hạ tầng Cloud IT phục vụ chuyển đổi số cho doanh nghiệp - tiền thân là VCCloud - trực thuộc Công ty Cổ phần VCCorp - Công ty dẫn đầu trong lĩnh vực truyền thông và công nghệ tại Việt Nam.
Trải nghiệm MIỄN PHÍ Bizfly Cloud CDN và nhận ưu đãi hấp dẫn, độc giả đăng ký ngay tại: https://bizflycloud.vn/cdn
Đăng ký dùng thử ngay tại: https://manage.bizflycloud.vn/