Query TCP states/connection tracking table in Linux Kernel Module
Hi, I'm developing a proxy system for TCP handshakes. Essentially, it's a similar system to a TRAP server where SYN packets will be handled by a proxy server and once the handshake completes, the connection gets handed off to the actual server. In my implementation, I have a few extra functionalities I'm adding in which require me to notify a third party once a valid handshake ACK is received. However, I'm unable to find a way to verify an incoming ACK packet. My initial implementation was using NFQueue and IPtables in user space, where I'll simply intercept ACK packets with the ESTABLISHED state (iptables --tcp-flags SYN,ACK,... ACK -m state --state ESTABLISHED) and queue them to one of the netfilter queues where I then ensure that they don't have a payload (therefore, confirming it is a handshake packet with ACK flag. Currently ignoring things like TCP Fast Open where the payload is included in the handshake ACK packet). If IPtables can access the connection tracking tables, then that means it is possible from a netfilter kernel module. I'm just not sure how? I've got a general concept of how networking works in the Linux kernel but a bit clueless on the actual implementation. Any help? -- Swarm
On Thu, 19 Sep 2019 06:12:46 -0000, Yadunandan Pillai said:
I'm developing a proxy system for TCP handshakes.
The programmer's version of "I'm writing the Great American Novel". :)
However, I'm unable to find a way to verify an incoming ACK packet.
That will depend on exactly what you mean by "verify". Are you just concerned with the TCP 4-tuple (source/dest port, source/dest address)? Or are you also checking that things like the sequence number match? (Bonus points for doing the right thing on a kernel that has syncookies enabled, and still work correctly if syncookies aren't in use)
I then ensure that they don't have a payload (therefore , confirming it is a handshake packet with ACK flag.
Note that ACK packets with no payload don't mean they're handshake packets. Look at any FTP transfer - you'll see packets going one way with data, and just ACK going back the other way. You need both SYN and ACK for it to be a handshake packet. iptables --tcp-flags SYN,ACK,... ACK <- isn't doing what you think it does. I'm wondering if you may be in over your head on this one...
Alright so check it out. I definitely don't think I'm over my head because I'm almost there at solving this stupid problem. I basically did two things for researching: looked at the packet capture for an HTTP request to a basic `python -m http.server` and saw exactly what you said, both handshake ACK packets and ACK packets to acknowledge requests from either side of the flow. However, I noticed that the sequence number of the ACK handshake packet was SEQ number in SYNACK plus 1, and this was unique from any other data packet. So one on hand, I have the possibility of somehow accessing the state table in the kernel to see if the ACK matches any of the SYNACKs SEQ number plus 1. Alternatively, I could conntrack in userspace and communicate via netlink. Other way is to use TCP states and watch for when the state for any connection to port 8000 changes to TCP_ESTABLISHED. This seems like a more viable solution because the work of determining whether the connection is established has already been completed. However, I'm not sure how to do this with either netfilter or eBPF. Swarm ‐‐‐‐‐‐‐ Original Message ‐‐‐‐‐‐‐ On Thursday, September 19, 2019 8:20 PM, Valdis Klētnieks <valdis.kletnieks@vt.edu> wrote:
On Thu, 19 Sep 2019 06:12:46 -0000, Yadunandan Pillai said:
I'm developing a proxy system for TCP handshakes.
The programmer's version of "I'm writing the Great American Novel". :)
However, I'm unable to find a way to verify an incoming ACK packet.
That will depend on exactly what you mean by "verify". Are you just concerned with the TCP 4-tuple (source/dest port, source/dest address)? Or are you also checking that things like the sequence number match? (Bonus points for doing the right thing on a kernel that has syncookies enabled, and still work correctly if syncookies aren't in use)
I then ensure that they don't have a payload (therefore , confirming it is a handshake packet with ACK flag.
Note that ACK packets with no payload don't mean they're handshake packets.
Look at any FTP transfer - you'll see packets going one way with data, and just ACK going back the other way.
You need both SYN and ACK for it to be a handshake packet.
iptables --tcp-flags SYN,ACK,... ACK <- isn't doing what you think it does.
I'm wondering if you may be in over your head on this one...
participants (2)
-
Valdis Klētnieks -
Yadunandan Pillai