Một packet IP (áp dụng cả với IPv4 và IPv6) thông thường sẽ có trong header của nó thông tin về địa chỉ nguồn, địa chỉ đích của packet, loại protocol, và tùy protocol sẽ có hoặc không có thêm các thông tin khác như options, codes, cổng nguồn cổng đích (với các protocol UDP và TCP quen thuộc). Trong rất nhiều trường hợp, chỉ cần những thông tin này của một packet, kết hợp với bảng routes của router (bảng chứa các dải địa chỉ đích, interface và gateway (không bắt buộc) tương ứng, cùng với số distance (1 dạng giúp sắp xếp thứ tự ưu tiên)) là đủ để router có thể chuyển tiếp những packet đơn lẻ này đến đích cần đến (qua gateway ở 1 interface, hay vào thẳng layer 2 của 1 interface). Thậm chí thông tin lưu trong packet đơn lẻ này trong rất nhiều trường hợp cũng đủ để viết các rules firewall để lọc các packet này, có cho qua hay không dựa vào các thông tin có trong packet đơn lẻ này.
Điều gì xảy ra nếu bác cần dùng NAT. NAT bao gồm cả address translation, lẫn port translation, và tất nhiên là cả tính năng port forwarding. Với NAT thì 1 packet khi chạy qua tường lửa có thể có địa chỉ nguồn và/hoặc địa chỉ đích, cũng như cổng nguồn và/hoặc cổng đích của nó bị sửa đổi bởi các rules. Thí dụ từ trong LAN PC 192.168.0.5 bác gửi 1 packet UDP ra ngoài internet, vào cổng 53 của địa chỉ đích 8.8.8.8, cổng nguồn từ PC là 49300. Với NAT (thường là rule masquerade) router của bác sẽ tìm được gateway ứng với địa chỉ đích 8.8.8.8, thường là gateway ra WAN với route tới 0.0.0.0/0. Interface này là interface WAN với rule masquerade, router của bác sẽ áp dụng srcnat, sửa địa chỉ nguồn của packet từ 192.168.0.5 thành địa chỉ public của router trên cái interface, có thể phải sửa cả cổng source 49300 nếu đã có kết nối khác dùng cổng này của router. Packet UDP với đích 8.8.8.8:53 và nguồn là địa chỉ IP và cổng mới này sẽ được gửi qua gateway vào internet. Giờ google dns trả lời và gửi packet trở lại, source address và port bây giờ là 8.8.8.8:53 destination address là địa chỉ WAN của router và cái cổng đích là 49300 hoặc có thể là cổng đã bị thay thế ở trên. Với thông tin từ cái packet duy nhất này, và mỗi cái bảng routes, làm thế nào mà router biết cách chuyển tiếp gói trả lời này tới cái PC gốc?
Tương tự với port forwarding. Giả sử bác cấu hình forward cổng 8080 TCP của router tới cổng 80 của máy 192.168.0.10 trong LAN. Khi từ ngoài gửi packet vào cổng 8080 của router, router sẽ sửa địa chỉ đích của packet thành 192.168.0.10 và cổng đích thành 80. Sau đó khi thiết bị 192.168.0.10 gửi packet trả lời. Vì chỉ có thông tin từ mỗi packet này, router sẽ không biết đây là packet trả lời cho 1 packet trước. Router phải làm thế nào đó để biết rằng bây giờ phải sửa cổng nguồn của packet thành 8080 (và địa chỉ nguồn của packet thành địa chỉ WAN của router)?
Hay giả sử bác không dùng NAT, tức là địa chỉ IP trong LAN của bác là địa chỉ từ bên ngoài internet trỏ vào được (là trường hợp với IPv6), thế nhưng bác lại có 2 đường WAN 1 & 2 kết nối ra internet. Trong bảng routes của bác có 2 entry tới ::0/0 (hoặc 0.0.0.0/0) với 2 gateway của 2 đường WAN tương ứng, nhưng WAN1 có distance nhỏ hơn. Giờ bác nhận được 1 packet từ địa chỉ ngoài internet, đến qua đường WAN2 với địa chỉ đích là thiết bị trong LAN. Router của bác chỉ dùng thông tin trong packet này dễ dàng chuyển tiếp nó đến được thiết bị. Thiết bị sau đó gửi packet trả lời, với địa chỉ đích là địa chỉ từ ngoài internet kia. Với thông tin duy nhất từ packet, router chỉ biết cách chọn dòng route đầu tiên ứng với cái gateway của WAN1 vì distance nhỏ hơn, và nhờ gateway đó chuyển tiếp, trong khi lẽ ra nó phải dùng gateway của WAN2. Có cách nào để nó biết dùng gateway của WAN2?
Hoặc nếu các rules tường lửa của bác cần các điều kiện dựa trên các trạng thái của 1 kết nối TCP như số bytes đã truyền, hay tốc độ hiện thời. Nếu chỉ có thông tin từ packet đơn lẻ thì không làm được điều này.
Hay có những giao thức đặc biệt như FTP, cần 2 kết nối, một cho command, một để truyền dữ liệu. FTP ở chế độ passive thì client nối vào cổng 21 của server để gửi lệnh, khi cần truyền file thì server sẽ gửi thông tin về cổng và địa chỉ IP để client tạo kết nối thứ 2 dùng để truyền dữ liệu. Giờ giả sử bác muốn cấu hình firewall để chỉ cho phép tạo kết nối để truyền file qua FTP. Bác sẽ có rule nghiêm ngặt block packet đi ra ngoài chỉ cho đến cổng 21 của server đích. Nhưng giờ làm thế nào để có rule ngoại lệ cho các packet gửi đến cái đường truyền data kia, khi cổng và địa chỉ đích không biết trước được?
Câu trả lời cho tất cả những cái này là tính năng connection tracking
Connection tracking - RouterOS - MikroTik Documentation (https://help.mikrotik.com/docs/display/ROS/Connection+tracking) trong cấu hình tường lửa. Có thể bật tắt ở đây:
Nếu Enabled=No thì firewall chỉ sử dụng thông tin từ các packet đơn lẻ. Để auto tương đương với disabled khi không có rule nào trong các bảng của cấu hình tường lửa, khi có 1 rule bất kỳ thì auto sẽ tương đương với Enabled=Yes, bật connection tracking. Phải bật connection tracking thì NAT và những properties sau mới sử dụng được trong các rules của tường lửa:
Khi bật connection tracking thì RouterOS sẽ cấp phát bộ nhớ để lưu các entries chứa thông tin về các kết nối (connections). Các entries này chính là nội dụng bác nhìn thấy ở bảng Connections trong cửa sổ tường lửa IPv4 và IPv6. Số lượng entries tối đa phụ thuộc vào kích thước RAM của router, ghi ở dòng status Max Entries bên dưới cửa sổ.
Với mỗi một packet được firewall xử lý, trước tiên firewall sẽ tìm xem có thể gán packet đó với 1 cái connection entry sẵn có nào không. Nếu không được thì 1 entry mới sẽ được tạo ra, ứng với connection mới. connection-state của packet sẽ là "new". Khi nhận được packet trả lời cho packet này , nếu có, packet đó cũng sẽ được gán với cái connection entry này, và sẽ có connection-state là established. Tương tự với packet trả lời cho packet trả lời này. Tóm lại các packet sau gửi đi gửi lại giữa 2 đầu kết nối sẽ được gán với cái connection entry này và có connection-state=established.
Trong trường hợp sử dụng NAT thì sau khi packet đầu (connection-state=new) đi qua các rules NAT (scrnat (gồm cả masquerade), dstnat) khi các địa chỉ và cổng nguồn đích bị các rules chỉnh sửa, thì thông tin các địa chỉ và cổng đã bị chỉnh sửa từ cái gì sang cái gì sẽ được nhớ lại trong cái connection entry này, và thuộc tính connection-nat-state sẽ có giá trị dstnat hoặc srcnat tương ứng. Với những thông tin được lưu lại này, firewall sẽ biết cách khôi phục lại giá trị cổng và địa chỉ ban đầu khi tiếp nhận và chuyển tiếp các packets trả lời. Như vậy giải quyết được vấn đề ở trên với NAT và port forwarding.
Trong kết nối cũng có field để lưu thông tin connection-mark, mà bác có thể dùng các rules mangle để đặt và sửa. Với cách này với trường hợp multi-WAN bác có thể viết rules để "nhớ" packet đầu của connection đến từ đường WAN nào, và đánh dấu lên connection (connection-mark) để sau này tường lửa route các packets trả lời của cùng kết nối đi ra đúng bằng đường WAN đó. Đây là cấu hình thường gặp khi load balancing nhiều đường WAN.
Và với thông tin lưu lại, tường lửa cũng có thể đếm số packets và bytes đã gửi nhận của các packets gắn với kết nối này, cũng như tốc độ hiện thời (rate) đường gửi và nhận. Ngoài ra trạng thái hiện thời của 1 kết nối TCP (
established, time-wait, close, syn-sent, syn-received) cũng có thể được biết (thuộc tính tcp-state) vì các packet kiểu SYN, SYN ACK, FIN, FIN ACK v.v... của kết nối được đọc và ghi nhận.
Vấn đề của giao thức như giao thức FTP ở trên cũng được giải quyết. Các packet của kết nối data được tạo thêm kia cũng sẽ được ghép với cái connection entry của kết nối command tới cổng 21 của server kia, khác biệt là connection-state của chúng sẽ là "related". Với rule accept connection-state="related" ở trên đỉnh như với cấu hình firewall của bác thì khi kết nối đường truyền lệnh cổng 21 kia đã được tường lửa cho phép đi qua thì các packet của kết nối data cũng mặc định được cho qua.
Và vì trong cùng 1 kết nối, ngoại trừ packet đầu tiên có connection-state=new, hầu hết các packet còn lại sẽ có state=established hoặc related, nêu nếu trong tường lửa của bác có rules accept với connection-state=established,related và đặt ở tít trên đầu, thì hầu hết các packets sẽ được xử lý ngay bằng 1 rule này ngay lập tức, và sau khi đã được accept thì các rules phức tạp và nhiều hơn bên dưới sẽ được bỏ qua không cần phải xử lý. Nói cách khác là đa số các rules tường lửa phức tạp của bác bên dưới sẽ chỉ cần phải mang ra áp dụng với packet đầu tiên, packet có connection-state=new, mà thôi. Nếu packet đầu được accept thì các packet sau đó không cần phải chạy qua hầu hết các rules đó nữa, giảm tải CPU đi rất nhiều.