Tường lửa là công cụ quan trọng có thể cấu hình để bảo vệ máy chủ và hạ tầng. Trong hệ sinh thái Linux, iptables
là một công cụ tường lửa phổ biến, hoạt động cùng với framework lọc gói netfilter
của kernel. Việc tạo các chính sách tường lửa đáng tin cậy có thể gây khó khăn do cú pháp phức tạp và nhiều thành phần liên quan.
Trong hướng dẫn này, bạn sẽ tìm hiểu kiến trúc của IPTables và Netfilter để dễ dàng xây dựng chính sách tường lửa riêng, đồng thời thấy rõ cách các thành phần phối hợp để hình thành hệ thống lọc toàn diện.
IPTables và Netfilter là gì?
Phần mềm tường lửa phổ biến nhất trên Linux trong những năm qua là iptables
. Trong một số bản phân phối, nó đã được thay thế bằng công cụ mới có tên là nftables
, nhưng cú pháp iptables
vẫn thường được dùng làm chuẩn cơ bản. Tường lửa iptables
hoạt động bằng cách tương tác với các hook lọc gói trong ngăn xếp mạng của kernel Linux. Các hook của kernel này được gọi là framework netfilter
.
Mỗi gói tin đi qua tầng mạng (dù vào hay ra) sẽ kích hoạt các hook này, cho phép chương trình can thiệp vào lưu lượng ở các điểm quan trọng. Các mô-đun kernel gắn với iptables
đăng ký cùng các hook này để bảo đảm lưu lượng tuân thủ đúng các điều kiện trong quy tắc tường lửa.
Các hook của Netfilter
Có 5 hook của netfilter
mà chương trình có thể đăng ký. Khi gói tin đi qua ngăn xếp mạng, các mô-đun kernel gắn với những hook này sẽ được kích hoạt. Gói tin sẽ kích hoạt hook nào phụ thuộc vào việc đó là gói vào hay ra, đích đến của gói tin, và liệu gói đó đã bị loại bỏ hoặc từ chối tại một điểm trước đó hay chưa.
Các hook sau đây đại diện cho những điểm được xác định rõ trong ngăn xếp mạng:
NF_IP_PRE_ROUTING
: Kích hoạt với mọi lưu lượng vào ngay khi đi vào ngăn xếp mạng, được xử lý trước khi có bất kỳ quyết định định tuyến nào được đưa ra về nơi gửi gói tin.NF_IP_LOCAL_IN
: Kích hoạt sau khi gói tin vào đã được định tuyến và có đích đến hệ thống cục bộ.NF_IP_FORWARD
: Kích hoạt sau khi gói tin vào đã được định tuyến và cần chuyển tiếp đến host khác.NF_IP_LOCAL_OUT
: Kích hoạt với mọi lưu lượng đi ra được tạo cục bộ ngay khi đi vào ngăn xếp mạng.NF_IP_POST_ROUTING
: Kích hoạt với lưu lượng đi ra hoặc chuyển tiếp sau khi định tuyến xong và ngay trước khi gửi ra ngoài.
Các mô-đun kernel khi đăng ký với những hook này cần cung cấp thêm một mức ưu tiên để xác định thứ tự được gọi khi hook kích hoạt. Nhờ đó, nhiều mô-đun (hoặc nhiều phiên bản của cùng một mô-đun) có thể gắn vào cùng một hook theo trật tự rõ ràng. Sau khi xử lý, từng mô-đun sẽ lần lượt được gọi và trả về quyết định cho framework netfilter
, chỉ định hành động cần thực hiện với gói tin.
Bảng và Chain trong IPTables
Tường lửa iptables
sử dụng các bảng để tổ chức tập quy tắc. Các bảng này phân loại quy tắc dựa trên loại quyết định cần thực hiện.
Ví dụ, nếu quy tắc liên quan đến dịch địa chỉ mạng (Network Address Translation) thì nó sẽ nằm trong bảng nat
. Nếu quy tắc quyết định cho phép gói tin tiếp tục đến đích hay không thì thường được thêm vào bảng filter
.
Trong mỗi bảng iptables
, các quy tắc lại được sắp xếp thành những chain riêng biệt. Bảng phản ánh mục đích tổng quát của quy tắc, còn các chain dựng sẵn đại diện cho hook của netfilter
kích hoạt chúng. Chain sẽ quyết định thời điểm quy tắc được đánh giá.
Tên của các chain dựng sẵn tương ứng trực tiếp với tên các hook netfilter
liên quan:
PREROUTING
: Kích hoạt bởi hookNF_IP_PRE_ROUTING
.INPUT
: Kích hoạt bởi hookNF_IP_LOCAL_IN
.FORWARD
: Kích hoạt bởi hookNF_IP_FORWARD
.OUTPUT
: Kích hoạt bởi hookNF_IP_LOCAL_OUT
.POSTROUTING
: Kích hoạt bởi hookNF_IP_POST_ROUTING
.
Chain cho phép quản trị viên xác định vị trí trong đường đi của gói tin nơi quy tắc sẽ được áp dụng. Mỗi bảng chứa nhiều chain khác nhau, nhờ đó một bảng có thể tác động đến nhiều giai đoạn trong quá trình xử lý. Tuy vậy, một số loại quyết định chỉ phù hợp tại những điểm nhất định trong ngăn xếp mạng, vì thế không phải bảng nào cũng có chain gắn với mọi hook của kernel.
Trong netfilter
chỉ tồn tại 5 hook kernel, và tại mỗi hook thường có chain từ nhiều bảng cùng đăng ký.
Chẳng hạn, có 3 bảng đều sở hữu chain PREROUTING
. Khi được gắn với hook NF_IP_PRE_ROUTING
, các chain này sẽ khai báo mức ưu tiên để xác định thứ tự thực thi. Toàn bộ quy tắc trong chain PREROUTING
có ưu tiên cao nhất sẽ được xử lý trước, sau đó mới đến các chain kế tiếp.
Ngay phần sau, chúng ta sẽ tìm hiểu chi tiết thứ tự của từng chain.
Những bảng nào khả dụng?
Hãy dừng lại đôi chút để cùng xem các bảng khác nhau mà iptables
hỗ trợ. Mỗi bảng đại diện cho một tập quy tắc riêng, được tổ chức theo từng phạm vi xử lý, nhằm đánh giá gói tin.
Bảng Filter
Bảng filter
là một trong những bảng được dùng nhiều nhất trong iptables
. Nó đảm nhận việc quyết định gói tin có được phép tiếp tục đến đích hay sẽ bị từ chối. Trong ngữ cảnh tường lửa, đây chính là quá trình “lọc” gói tin. Phần lớn chức năng mà mọi người gắn liền với khái niệm tường lửa đều nằm trong bảng này.
Bảng NAT
Bảng nat
được sử dụng để thiết lập các quy tắc dịch địa chỉ mạng. Khi gói tin đi vào ngăn xếp mạng, các quy tắc trong bảng sẽ xác định cách thay đổi địa chỉ nguồn hoặc đích của gói tin, từ đó tác động đến cách định tuyến gói tin và lưu lượng phản hồi. Cơ chế này thường được áp dụng để định tuyến gói tin đến các mạng khác khi không thể truy cập trực tiếp.
Bảng Mangle
Bảng mangle
cho phép điều chỉnh tiêu đề IP của gói tin theo nhiều cách khác nhau. Chẳng hạn như bạn có thể điều chỉnh giá trị TTL (Time to Live) của gói tin nhằm kéo dài hoặc rút ngắn số bước nhảy mạng mà gói tin có thể đi qua. Các trường IP header khác cũng có thể được chỉnh sửa tương tự.
Ngoài ra, bảng này có thể gắn một “dấu hiệu” nội bộ của kernel vào gói tin để phục vụ xử lý tiếp theo trong những bảng hoặc các công cụ mạng khác. Dấu hiệu này không làm thay đổi gói tin thực tế mà chỉ thêm thông tin vào bản sao đại diện của gói trong kernel.
Bảng Raw
Tường lửa iptables
hoạt động theo trạng thái, nghĩa là việc đánh giá gói tin dựa trên mối liên hệ với các gói trước đó. Tính năng theo dõi kết nối (connection tracking) được xây dựng trên framework netfilter
cho phép iptables
xem gói tin như một phần của phiên giao tiếp đang diễn ra thay vì các gói rời rạc độc lập. Logic theo dõi kết nối này thường được áp dụng ngay sau khi gói tin đi vào giao diện mạng.
Bảng raw
có phạm vi chức năng hẹp, chủ yếu dùng để gắn nhãn cho gói tin nhằm loại trừ khỏi cơ chế theo dõi kết nối.
Bảng Security
Bảng security
được dùng để gắn nhãn ngữ cảnh bảo mật SELinux lên gói tin. Những nhãn này ảnh hưởng trực tiếp đến cách SELinux hoặc các hệ thống khác có khả năng hiểu ngữ cảnh bảo mật SELinux xử lý gói tin. Nhãn có thể áp dụng riêng cho từng gói hoặc toàn bộ một kết nối.
Mối quan hệ giữa Chain và Bảng
Nếu có 3 bảng có chain PREROUTING
, thứ tự xử lý sẽ như thế nào?
Bảng dưới đây cho thấy các chain có trong mỗi bảng iptables
khi đọc từ trái sang phải.
Ví dụ, chúng ta có thể thấy bảng raw
có cả chain PREROUTING
và OUTPUT
. Khi đọc từ trên xuống dưới, bảng này cũng thể hiện thứ tự mà mỗi chain được gọi khi hook netfilter
tương ứng được kích hoạt.
Có một số điểm cần lưu ý:
Trong bảng minh họa dưới đây, bảng nat
đã được tách riêng giữa các thao tác DNAT
(những thao tác thay đổi địa chỉ đích của gói tin) và SNAT
(những thao tác thay đổi địa chỉ nguồn) để hiển thị thứ tự xử lý rõ ràng hơn. Ngoài ra, bảng còn có thêm các hàng mô tả thời điểm hệ thống đưa ra quyết định định tuyến và bật chức năng theo dõi kết nối, để có cái nhìn tổng thể hơn về toàn bộ quá trình đang diễn ra:
Bảng↓/Chain→ | PREROUTING | INPUT | FORWARD | OUTPUT | POSTROUTING |
---|---|---|---|---|---|
(quyết định định tuyến) | ✓ | ||||
raw | ✓ | ✓ | |||
(theo dõi kết nối được bật) | ✓ | ✓ | |||
mangle | ✓ | ✓ | ✓ | ✓ | ✓ |
nat (DNAT) | ✓ | ✓ | |||
(quyết định định tuyến) | ✓ | ✓ | |||
filter | ✓ | ✓ | ✓ | ||
security | ✓ | ✓ | ✓ | ||
nat (SNAT) | ✓ | ✓ |
Khi một gói tin kích hoạt hook netfilter
, các chain tương ứng trong bảng trên sẽ được xử lý theo thứ tự từ trên xuống dưới. Các hook (cột) mà gói tin sẽ đi qua phụ thuộc vào việc đó là gói tin đi vào hay đi ra, quyết định định tuyến được đưa ra như thế nào, và liệu gói tin có vượt qua tiêu chí lọc hay không.
Một số sự kiện nhất định sẽ khiến chain của một bảng bị bỏ qua trong quá trình xử lý. Ví dụ, chỉ gói tin đầu tiên trong một kết nối mới được đánh giá dựa trên các quy tắc NAT
. Bất kỳ quyết định nat
nào được áp dụng cho gói tin đầu tiên cũng sẽ được áp dụng cho tất cả các gói tin tiếp theo trong cùng kết nối mà không cần đánh giá lại. Các phản hồi của kết nối đã NAT sẽ tự động áp dụng các quy tắc NAT đảo ngược để định tuyến chính xác.
Thứ tự duyệt Chain
Giả sử máy chủ biết cách định tuyến gói tin và các quy tắc tường lửa cho phép truyền tải, các luồng sau đây thể hiện đường đi mà gói tin sẽ đi qua trong các tình huống khác nhau:
- Gói tin đi vào và hướng đến hệ thống cục bộ:
PREROUTING -> INPUT
- Gói tin đi vào và hướng đến một host khác:
PREROUTING -> FORWARD -> POSTROUTING
- Gói tin được tạo từ nội bộ:
OUTPUT -> POSTROUTING
Nếu chúng ta kết hợp thông tin trên với thứ tự trong bảng trước đó, có thể thấy rằng một gói tin đi vào và hướng đến hệ thống cục bộ sẽ lần lượt được xử lý qua các chain PREROUTING
của bảng raw
, mangle
, và nat
. Sau đó, nó sẽ đi qua các chain INPUT
của bảng mangle
, filter
, security
, và nat
trước khi được chuyển tới socket cục bộ ở bước cuối cùng.
Quy tắc IPTables
Mỗi quy tắc được đặt trong một chain thuộc một bảng cụ thể. Khi chain được gọi, gói tin sẽ lần lượt được so khớp với từng quy tắc trong chain. Mỗi quy tắc bao gồm phần điều kiện so khớp và phần hành động.
Điều kiện khớp
Phần so khớp của quy tắc chỉ định tiêu chí mà gói tin phải đáp ứng để thực thi hành động tương ứng (hay còn gọi là “target”).
Hệ thống so khớp rất linh hoạt và có thể mở rộng đáng kể thông qua các phần mở rộng của iptables
. Quy tắc có thể được xây dựng để so khớp theo loại giao thức, địa chỉ đích hoặc nguồn, cổng đích hoặc nguồn, mạng đích hoặc nguồn, giao diện vào hoặc ra, tiêu đề gói tin, trạng thái kết nối cùng nhiều tiêu chí khác. Các tiêu chí này có thể kết hợp với nhau để tạo ra tập hợp quy tắc phức tạp nhằm phân biệt nhiều loại lưu lượng khác nhau.
Đích hành động
Một “target” là phần hành động sẽ được kích hoạt khi gói tin đáp ứng tiêu chí so khớp của quy tắc. Targets thường được chia thành 2 loại:
- Target kết thúc: Thực hiện một hành động kết thúc quá trình đánh giá trong chain và trả quyền kiểm soát về cho hook
netfilter
. Tùy thuộc vào giá trị trả về, hook có thể loại bỏ gói tin hoặc cho phép gói tin tiếp tục đến bước xử lý tiếp theo. - Target không kết thúc: Thực hiện một hành động nhưng quá trình đánh giá vẫn tiếp tục với các quy tắc còn lại trong chain. Cuối cùng, mỗi chain đều phải đưa ra một quyết định kết thúc, nhưng trước đó có thể thực thi nhiều target không kết thúc.
Khả năng sử dụng target trong các quy tắc còn phụ thuộc vào ngữ cảnh. Ví dụ, loại bảng và chain có thể quyết định target nào khả dụng. Các phần mở rộng được kích hoạt trong quy tắc và các điều kiện so khớp cũng có thể ảnh hưởng đến tính khả dụng của target.
Nhảy đến Chain do người dùng định nghĩa
Có một loại đặc biệt của target không kết thúc là target “nhảy” (jump
). Target này làm cho quá trình đánh giá chuyển sang một chain khác để xử lý bổ sung. Trước đây chúng ta đã đề cập đến các chain dựng sẵn được gắn với các hook netfilter
thực thi chúng. Tuy nhiên, iptables
cũng cho phép quản trị viên tạo ra các chain riêng nhằm phục vụ mục đích tổ chức.
Quy tắc có thể được đặt trong chain do người dùng định nghĩa giống như trong chain dựng sẵn. Điểm khác biệt là chain do người dùng định nghĩa chỉ có thể được truy cập thông qua một target “nhảy” từ quy tắc khác, vì chúng không được đăng ký trực tiếp với hook netfilter
.
Chain do người dùng định nghĩa hoạt động như phần mở rộng của chain đã gọi nó. Chẳng hạn, trong một chain như vậy, quá trình đánh giá sẽ quay lại chain gốc nếu đi hết danh sách quy tắc hoặc khi một target RETURN
được kích hoạt bởi quy tắc phù hợp. Quá trình đánh giá cũng có thể “nhảy” tiếp sang các chain do người dùng định nghĩa khác.
Cơ chế này giúp tổ chức quy tắc tốt hơn và cung cấp nền tảng cần thiết để xây dựng nhánh xử lý mạnh mẽ hơn.
IPTables và theo dõi kết nối
Chúng ta đã giới thiệu hệ thống theo dõi kết nối được triển khai trên nền tảng framework netfilter
khi bàn về bảng raw
và tiêu chí so khớp trạng thái kết nối.
Theo dõi kết nối cho phép iptables
đưa ra quyết định về các gói tin khi một kết nối đang diễn ra. Hệ thống theo dõi kết nối cung cấp cho iptables
các chức năng cần thiết để thực hiện các thao tác “có trạng thái”.
Theo dõi kết nối được áp dụng ngay sau khi gói tin đi vào ngăn xếp mạng. Các chain của bảng raw
và một số kiểm tra tính hợp lệ là các bước duy nhất được thực hiện trên gói tin trước khi liên kết gói tin với một kết nối.
Hệ thống sẽ kiểm tra từng gói tin với tập hợp các kết nối đã tồn tại. Nó sẽ cập nhật trạng thái kết nối trong kho dữ liệu nếu cần, và sẽ thêm kết nối mới vào hệ thống khi cần thiết. Các gói tin được đánh dấu với target NOTRACK
trong một chain của bảng raw
sẽ bỏ qua cơ chế theo dõi kết nối.
Các trạng thái khả dụng
Hệ thống theo dõi kết nối phân loại kết nối theo các trạng thái sau:
NEW
: Khi gói tin đầu tiên hợp lệ xuất hiện và không gắn với bất kỳ kết nối nào, hệ thống sẽ tạo kết nối mới với nhãn này. Điều này áp dụng cho cả giao thức có kết nối như TCP và không kết nối như UDP.ESTABLISHED
: Một kết nối được chuyển từNEW
sangESTABLISHED
khi nó nhận được phản hồi hợp lệ theo chiều ngược lại. Với TCP, điều này tương ứng với góiSYN/ACK
, còn với UDP và ICMP thì là phản hồi có địa chỉ nguồn và đích đảo ngược so với gói tin gốc.RELATED
: NhãnRELATED
dành cho những gói tin không trực tiếp thuộc về một kết nối hiện có nhưng có quan hệ với một kết nối đã được ghi nhận trong hệ thống. Ví dụ, đó có thể là kết nối phụ trợ, như khi truyền dữ liệu FTP, hoặc cũng có thể là các phản hồi ICMP đối với nỗ lực kết nối từ những giao thức khác.INVALID
: Gói tin được gán nhãnINVALID
khi không gắn với kết nối hiện có, không hợp lệ để mở kết nối mới, không thể xác định hoặc không thể định tuyến vì nhiều nguyên nhân khác.UNTRACKED
: Gói tin có thể bị đánh dấuUNTRACKED
nếu đã được target trong một chain của bảngraw
để bỏ qua theo dõi.SNAT
: Đây là trạng thái ảo được gán khi địa chỉ nguồn bị thay đổi bởi thao tác NAT. Hệ thống theo dõi kết nối dùng trạng thái này để biết cần khôi phục địa chỉ nguồn trong các gói phản hồi.DNAT
: Đây là trạng thái ảo được gán khi địa chỉ đích bị thay đổi bởi thao tác NAT. Hệ thống theo dõi kết nối dùng trạng thái này để biết cần khôi phục địa chỉ đích khi định tuyến các gói phản hồi.
Các trạng thái được theo dõi trong hệ thống theo dõi kết nối cho phép quản trị viên xây dựng quy tắc nhắm đến các điểm cụ thể trong vòng đời của một kết nối. Điều này mang lại khả năng cần thiết để tạo ra các quy tắc chặt chẽ và an toàn hơn.
Kết luận
Framework lọc gói tin netfilter
cùng với tường lửa iptables
tạo thành nền tảng cho hầu hết các giải pháp tường lửa trên máy chủ Linux.
Các hook của netfilter
trong kernel nằm rất gần với ngăn xếp mạng, nhờ đó có thể kiểm soát mạnh mẽ quá trình xử lý gói tin. Tường lửa iptables
tận dụng đặc điểm này để cung cấp một cơ chế linh hoạt và có thể mở rộng nhằm truyền tải các yêu cầu chính sách đến kernel.
Hiểu rõ cách các thành phần này kết hợp sẽ giúp chúng ta khai thác chúng hiệu quả hơn trong việc kiểm soát và bảo mật hệ thống máy chủ.
Nếu muốn tìm hiểu thêm về cách xây dựng chính sách iptables
hiệu quả, bạn có thể tham khảo hướng dẫn này.
Những hướng dẫn sau có thể giúp bạn bắt đầu triển khai quy tắc tường lửa iptables
:
- Cách thiết lập tường lửa bằng Iptables
- Những điều cần biết về Iptables: Các quy tắc và lệnh tường lửa phổ biến
- Cách thiết lập tường lửa với UFW trên Ubuntu 22.04
- Cách thiết lập tường lửa bằng firewalld trên Rocky Linux 8
- Cách thiết lập tường lửa Iptables để bảo vệ lưu lượng giữa các máy chủ