On 18 Mar 2022, at 11:46, otr...@employees.org<mailto:otr...@employees.org> wrote:
Klement, Following up on this thread. The changes in 34877 led to some undesired behaviour in the "real world(tm)". In the close pattern below it left sessions in established state, and with a relatively low cps would consume the whole session table. The change here https://gerrit.fd.io/r/c/vpp/+/35692 nat: tweak rfc7857 tcp connection tracking proposes to move the needle somewhat more towards protecting the session table. Views? Miklos, Klement? The RFC7857 state machine introduced in 56c492a is a trade-off. It tries to retain sessions as much as possible and also offers some protection against spurious RST by re-establishing sessions if data is received after the RST. From experience in the wild, this algorithm is a little too liberal, as it leaves too many spurious established sessions in the session table. E.g. a oberserved pattern is: client server <- FIN, ACK ACK -> ACK -> RST, ACK -> So why not just add a new state change where RST+half-closed moves to TRANS instead of throwing everything away? What do you mean by "throwing everything away"? Reset the state flags? Now it goes to transitory, and it will stay in transitory as long as packets are flowing. Assuming the guys writing RFC gave it a thorough thought and that current state tracking is mostly done with RFC in mind, then changing it dramatically feels like it might not cover corner cases which we are currently not aware of. Feels like instead of doing one tweak let’s rewrite the whole thing approach. I wouldn't make too many assumptions about guys writing RFCs, given that I'm one of them. ;-) Oh! When you put it like this … ;-) There is a history here, and initially NATs were viewed as breaking the Internet architecture, and if NATs should be specified at all, the overriding concern was to make them as transparent to applications as possible. Given the centralisation of the Internet and the level of packet mangling/middleboxes we now have, combined with the run-out of IPv4 addresses, applications have been forced to adapt. I don't think you can expect long-lived TCP sessions to survive at all anymore. Wouldn’t it be then easier to just have transitory timeout on for all sessions all the time? Yes, you would have to turn on (tcp) keepalives for your (ssh) sessions … And also Miklos might be a bit unhappy, but you would get a very very simple solution …. The main concern about RST was to recover from a 3rd party sending RSTs into the session. With the current state machine this would leave the session in established state. These proposed changes do: - require 3-way handshake to establish session. How does this help? Would you also need to track sequence numbers as was done before? It helps in the case where someone would spoof a a SYN, then RFC would leave the spurious session in established. The proposed state machine will leave it in transitory (the client to server ACK would never be seen). Ah, so you are assuming a legitimate client is connecting to a nefarious server, which cannot produce it’s own SYN (or ACK) packet, but has the capability to spoof a SYN packet, yes? Or is it a nefarious client which is unable to produce a SYN packet, but capable of spoofing a SYN packet? Neither I think, I'm concerned about a nefarious 3rd party trying to attack the session table. Yes, somewhat depending on how the NAT is configured the attacker has to be on the inside. Depending on the 3-way handshake also ensures the NAT state is better synchronised with the client and server state, than just using the 2-way. Do you see this causing issues? I don’t see any value added besides code being more complex. If I have inside access I can drain the session table with scapy (which is a very slow way of doing things) easily even without keeping any local state and it doesn’t matter if you track 2way or 3way …. (haven’t we had this discussion a couple of times already? feels a bit like beating a dead horse. NAT just sucks - malicious actor on the inside can simply make life miserable for all others UNLESS you implement a limit per inside host). (current requires only to see SYNs from both sides) - Any FIN or RST will move session to transitory without recovery to established Right, so if one side says “FIN” a.k.a. I’m done with sending data to you, while the other party still has data to send, then you just cut it off. Not sure how often this occurs in real world... Agree, I was also concerned about this. No idea how prevalent this is. I could add a counter I suppose that would count number of packets in transitory state. Or packets hitting a non garbage collected entry within the time window between established and transitory. I also have another patch that expands on the syslog session logging, which could be used to do post session analysis to learn better how well the state machine fares. In half-closed packets are still allowed to pass, just with a transitory timeout instead of established. So if one side sends FIN, and the other sends a packet an hour later, that will not work. But if the other side sent it 3 minutes later it would. Assuming default timers. Maybe Miklos can provide some insight into this as they seem to do a lot of “device is rarely communicating”. Yes, that would be good to know. Best regards, Ole
-=-=-=-=-=-=-=-=-=-=-=- Links: You receive all messages sent to this group. View/Reply Online (#21065): https://lists.fd.io/g/vpp-dev/message/21065 Mute This Topic: https://lists.fd.io/mt/88218698/21656 Group Owner: vpp-dev+ow...@lists.fd.io Unsubscribe: https://lists.fd.io/g/vpp-dev/unsub [arch...@mail-archive.com] -=-=-=-=-=-=-=-=-=-=-=-