svinota / pyroute2

Python Netlink and PF_ROUTE library — network configuration and monitoring
https://pyroute2.org/
Other
930 stars 244 forks source link

Get conntrack TCP OFFLOAD entries looks broken #1198

Open sever-sever opened 1 month ago

sever-sever commented 1 month ago

Version:

vyos@r4:~$ sudo dpkg -l | grep pyrout
ii  python3-pyroute2                     0.7.2-2                          all          Python3 Netlink library - full package
vyos@r4:~$ 

The script used to get conntrack entries:

#!/usr/bin/env python3

from typing import List, Generator
from pyroute2.conntrack import Conntrack, ConntrackEntry, NFCTAttrTuple

conntrack = Conntrack()
conntrack_dumped_entries: Generator = conntrack.dump_entries(tuple_orig=NFCTAttrTuple())
conntrack_entries: List[ConntrackEntry] = list(conntrack_dumped_entries)

print(conntrack_entries)

If we have entries with offload (fast-path) it seems cannot get info correctly

Without offload entries:

root@r4:/home/vyos# conntrack -L
tcp      6 593 ESTABLISHED src=10.0.0.1 dst=10.0.0.254 sport=59438 dport=179 src=10.0.0.254 dst=10.0.0.1 sport=179 dport=59438 [ASSURED] mark=0 use=1
tcp      6 456 ESTABLISHED src=100.64.0.5 dst=34.107.243.93 sport=45552 dport=443 src=34.107.243.93 dst=192.168.122.222 sport=443 dport=11577 [ASSURED] mark=0 use=1
tcp      6 262 ESTABLISHED src=100.64.0.5 dst=162.159.61.4 sport=50936 dport=443 src=162.159.61.4 dst=192.168.122.222 sport=443 dport=12049 [ASSURED] mark=0 use=1
conntrack v1.4.6 (conntrack-tools): 3 flow entries have been shown.
root@r4:/home/vyos# 
root@r4:/home/vyos# ./my_connatrack_list.py 
[Entry(orig=IPv4(saddr=10.0.0.1, daddr=10.0.0.254, TCP(sport=59438, dport=179)), reply=IPv4(saddr=10.0.0.254, daddr=10.0.0.1, TCP(sport=179, dport=59438)), status=SEEN_REPLY,ASSURED,CONFIRMED,SRC_NAT_DONE,DST_NAT_DONE, protoinfo=TcpInfo(state=ESTABLISHED, orig_flags=WINDOW_SCALE,SACK_PERM,MAXACK_SET, reply_flags=WINDOW_SCALE,SACK_PERM,MAXACK_SET)), Entry(orig=IPv4(saddr=100.64.0.5, daddr=34.107.243.93, TCP(sport=45552, dport=443)), reply=IPv4(saddr=34.107.243.93, daddr=192.168.122.222, TCP(sport=443, dport=11577)), status=SEEN_REPLY,ASSURED,CONFIRMED,SRC_NAT,SRC_NAT_DONE,DST_NAT_DONE, protoinfo=TcpInfo(state=ESTABLISHED, orig_flags=WINDOW_SCALE,SACK_PERM,BE_LIBERAL,MAXACK_SET, reply_flags=WINDOW_SCALE,SACK_PERM,BE_LIBERAL,MAXACK_SET)), Entry(orig=IPv4(saddr=100.64.0.5, daddr=162.159.61.4, TCP(sport=50936, dport=443)), reply=IPv4(saddr=162.159.61.4, daddr=192.168.122.222, TCP(sport=443, dport=12049)), status=SEEN_REPLY,ASSURED,CONFIRMED,SRC_NAT,SRC_NAT_DONE,DST_NAT_DONE, protoinfo=TcpInfo(state=ESTABLISHED, orig_flags=WINDOW_SCALE,SACK_PERM,BE_LIBERAL,DATA_UNACKNOWLEDGED,MAXACK_SET, reply_flags=WINDOW_SCALE,SACK_PERM,BE_LIBERAL,MAXACK_SET))]
root@r4:/home/vyos# 

With offload entries:

root@r4:/home/vyos# conntrack -L && echo "" && ./my_connatrack_list.py
tcp      6 595 ESTABLISHED src=10.0.0.1 dst=10.0.0.254 sport=59438 dport=179 src=10.0.0.254 dst=10.0.0.1 sport=179 dport=59438 [ASSURED] mark=0 use=1
udp      17 src=100.64.0.1 dst=34.206.168.146 sport=41989 dport=123 src=34.206.168.146 dst=192.168.122.222 sport=123 dport=4519 [OFFLOAD] mark=0 use=2
tcp      6 428 ESTABLISHED src=100.64.0.5 dst=34.107.243.93 sport=45552 dport=443 src=34.107.243.93 dst=192.168.122.222 sport=443 dport=11577 [ASSURED] mark=0 use=1
tcp      6 src=100.64.0.5 dst=162.159.61.4 sport=50936 dport=443 src=162.159.61.4 dst=192.168.122.222 sport=443 dport=12049 [OFFLOAD] mark=0 use=2
conntrack v1.4.6 (conntrack-tools): 4 flow entries have been shown.

Traceback (most recent call last):
  File "/home/vyos/./my_connatrack_list.py", line 13, in <module>
    conntrack_entries: List[ConntrackEntry] = list(conntrack_dumped_entries)
                                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/pyroute2/conntrack.py", line 225, in dump_entries
    yield ConntrackEntry(
          ^^^^^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/pyroute2/conntrack.py", line 100, in __init__
    self.protoinfo = NFCTATcpProtoInfo.from_netlink(cta_protoinfo)
                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/pyroute2/conntrack.py", line 52, in from_netlink
    cta_tcp = ndmsg.get_attr('CTA_PROTOINFO_TCP')
              ^^^^^^^^^^^^^^
AttributeError: 'NoneType' object has no attribute 'get_attr'
root@r4:/home/vyos# 

root@r4:/home/vyos# conntrack -L && echo "" && ./my_connatrack_list.py
tcp      6 599 ESTABLISHED src=10.0.0.1 dst=10.0.0.254 sport=59438 dport=179 src=10.0.0.254 dst=10.0.0.1 sport=179 dport=59438 [ASSURED] mark=0 use=1
udp      17 src=100.64.0.5 dst=8.8.8.8 sport=41510 dport=53 src=8.8.8.8 dst=192.168.122.222 sport=53 dport=12100 [OFFLOAD] mark=0 use=2
udp      17 src=100.64.0.1 dst=34.206.168.146 sport=41989 dport=123 src=34.206.168.146 dst=192.168.122.222 sport=123 dport=4519 [OFFLOAD] mark=0 use=2
tcp      6 417 ESTABLISHED src=100.64.0.5 dst=34.107.243.93 sport=45552 dport=443 src=34.107.243.93 dst=192.168.122.222 sport=443 dport=11577 [ASSURED] mark=0 use=1
tcp      6 57 TIME_WAIT src=100.64.0.5 dst=185.125.190.97 sport=41674 dport=80 src=185.125.190.97 dst=192.168.122.222 sport=80 dport=12142 [ASSURED] mark=0 use=1
tcp      6 src=100.64.0.5 dst=162.159.61.4 sport=50936 dport=443 src=162.159.61.4 dst=192.168.122.222 sport=443 dport=12049 [OFFLOAD] mark=0 use=2
conntrack v1.4.6 (conntrack-tools): 6 flow entries have been shown.

Traceback (most recent call last):
  File "/home/vyos/./my_connatrack_list.py", line 13, in <module>
    conntrack_entries: List[ConntrackEntry] = list(conntrack_dumped_entries)
                                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/pyroute2/conntrack.py", line 225, in dump_entries
    yield ConntrackEntry(
          ^^^^^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/pyroute2/conntrack.py", line 100, in __init__
    self.protoinfo = NFCTATcpProtoInfo.from_netlink(cta_protoinfo)
                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/pyroute2/conntrack.py", line 52, in from_netlink
    cta_tcp = ndmsg.get_attr('CTA_PROTOINFO_TCP')
              ^^^^^^^^^^^^^^
AttributeError: 'NoneType' object has no attribute 'get_attr'
root@r4:/home/vyos# 

UDP offload etnries looks good:

root@r4:/home/vyos# conntrack -L && echo "" && ./my_connatrack_list.py
tcp      6 597 ESTABLISHED src=10.0.0.1 dst=10.0.0.254 sport=59438 dport=179 src=10.0.0.254 dst=10.0.0.1 sport=179 dport=59438 [ASSURED] mark=0 use=1
udp      17 src=100.64.0.5 dst=8.8.8.8 sport=41510 dport=53 src=8.8.8.8 dst=192.168.122.222 sport=53 dport=12100 [OFFLOAD] mark=0 use=2
udp      17 src=100.64.0.1 dst=34.206.168.146 sport=41989 dport=123 src=34.206.168.146 dst=192.168.122.222 sport=123 dport=4519 [OFFLOAD] mark=0 use=2
tcp      6 400 ESTABLISHED src=100.64.0.5 dst=34.107.243.93 sport=45552 dport=443 src=34.107.243.93 dst=192.168.122.222 sport=443 dport=11577 [ASSURED] mark=0 use=1
tcp      6 40 TIME_WAIT src=100.64.0.5 dst=185.125.190.97 sport=41674 dport=80 src=185.125.190.97 dst=192.168.122.222 sport=80 dport=12142 [ASSURED] mark=0 use=1
tcp      6 266 ESTABLISHED src=100.64.0.5 dst=162.159.61.4 sport=50936 dport=443 src=162.159.61.4 dst=192.168.122.222 sport=443 dport=12049 [ASSURED] mark=0 use=1
conntrack v1.4.6 (conntrack-tools): 6 flow entries have been shown.

[Entry(orig=IPv4(saddr=10.0.0.1, daddr=10.0.0.254, TCP(sport=59438, dport=179)), reply=IPv4(saddr=10.0.0.254, daddr=10.0.0.1, TCP(sport=179, dport=59438)), status=SEEN_REPLY,ASSURED,CONFIRMED,SRC_NAT_DONE,DST_NAT_DONE, protoinfo=TcpInfo(state=ESTABLISHED, orig_flags=WINDOW_SCALE,SACK_PERM,MAXACK_SET, reply_flags=WINDOW_SCALE,SACK_PERM,MAXACK_SET)), Entry(orig=IPv4(saddr=100.64.0.5, daddr=8.8.8.8, UDP(sport=41510, dport=53)), reply=IPv4(saddr=8.8.8.8, daddr=192.168.122.222, UDP(sport=53, dport=12100)), status=SEEN_REPLY,CONFIRMED,SRC_NAT,SRC_NAT_DONE,DST_NAT_DONE,OFFLOAD), Entry(orig=IPv4(saddr=100.64.0.1, daddr=34.206.168.146, UDP(sport=41989, dport=123)), reply=IPv4(saddr=34.206.168.146, daddr=192.168.122.222, UDP(sport=123, dport=4519)), status=SEEN_REPLY,CONFIRMED,SRC_NAT,SRC_NAT_DONE,DST_NAT_DONE,OFFLOAD), Entry(orig=IPv4(saddr=100.64.0.5, daddr=34.107.243.93, TCP(sport=45552, dport=443)), reply=IPv4(saddr=34.107.243.93, daddr=192.168.122.222, TCP(sport=443, dport=11577)), status=SEEN_REPLY,ASSURED,CONFIRMED,SRC_NAT,SRC_NAT_DONE,DST_NAT_DONE, protoinfo=TcpInfo(state=ESTABLISHED, orig_flags=WINDOW_SCALE,SACK_PERM,BE_LIBERAL,MAXACK_SET, reply_flags=WINDOW_SCALE,SACK_PERM,BE_LIBERAL,MAXACK_SET)), Entry(orig=IPv4(saddr=100.64.0.5, daddr=185.125.190.97, TCP(sport=41674, dport=80)), reply=IPv4(saddr=185.125.190.97, daddr=192.168.122.222, TCP(sport=80, dport=12142)), status=SEEN_REPLY,ASSURED,CONFIRMED,SRC_NAT,SRC_NAT_DONE,DST_NAT_DONE, protoinfo=TcpInfo(state=ESTABLISHED,SYN_SENT, orig_flags=WINDOW_SCALE,SACK_PERM,BE_LIBERAL,MAXACK_SET, reply_flags=WINDOW_SCALE,SACK_PERM,CLOSE_INIT,BE_LIBERAL,MAXACK_SET)), Entry(orig=IPv4(saddr=100.64.0.5, daddr=162.159.61.4, TCP(sport=50936, dport=443)), reply=IPv4(saddr=162.159.61.4, daddr=192.168.122.222, TCP(sport=443, dport=12049)), status=SEEN_REPLY,ASSURED,CONFIRMED,SRC_NAT,SRC_NAT_DONE,DST_NAT_DONE, protoinfo=TcpInfo(state=ESTABLISHED, orig_flags=WINDOW_SCALE,SACK_PERM,BE_LIBERAL,DATA_UNACKNOWLEDGED,MAXACK_SET, reply_flags=WINDOW_SCALE,SACK_PERM,BE_LIBERAL,MAXACK_SET))]
root@r4:/home/vyos# 
root@r4:/home/vyos# 

Example of the firewall:

root@r4:/home/vyos# sudo nft -s list table ip vyos_filter
table ip vyos_filter {
    set I_IPOE {
        type ifname
        flags interval
        auto-merge
        elements = { "ipoe*" }
    }

    flowtable VYOS_FLOWTABLE_OFFLOAD {
        hook ingress priority filter
        devices = { eth0, eth1 }
        counter
    }

    chain VYOS_FORWARD_filter {
        type filter hook forward priority filter; policy accept;
        ct state { established, related } counter flow add @VYOS_FLOWTABLE_OFFLOAD comment "ipv4-FWD-filter-5"
        ct state { established, related } counter queue flags bypass to 25 comment "ipv4-FWD-filter-10"
        iifname "eth1" counter accept comment "ipv4-FWD-filter-1000"
        iifname @I_IPOE counter accept comment "ipv4-FWD-filter-1010"
        counter drop comment "ipv4-FWD-filter-9000"
        counter drop comment "FWD-filter default-action drop"
    }
}