SIP connection tracking SIP connection tracking/NAT and related problems Patrick McHardy <kaber@trash.net> Netfilter Workshop 2007
Overview - Used for locating endpoints and negotiation of session parameters - Conntrack/NAT helper in mainline since 2.6.18. Only supports very basic set of features, doesn't handle many cases - Large patchset queued for 2.6.25 solving many of the problems. Some hard ones remain ...
General problems - Very firewall and NAT unfriendly protocol: doesn't care about ports and address at all, responses to requests may be sent on different ports, to different IP addresses, ... Some clients seem to consider it elegant to make use of even the most absurd things allowed by the specification.
General problems - Hard to parse: continuation lines, strange whitespace rules, lots of special cases. Seems to be aimed at human readability, not parsability. - Patches fix parsing to be mostly RFC-compliant. Replies on different ports than the request not handled properly.
Registration - User-Agent sends REGISTER request to registrar containing its Contact address, where requests directed at the UA should be sent to. - Need to create expectation for Contact address before seeing response from registrar to perform NAT on the expectation and avoid clashes.
Registration - Would be preferable to wait for confirmation, allows to put trust purely in the registrar: use of inactive expectations only for reservation purposes, activated on response indicating success. - Requests may arrive from anywhere, not just the registrar. Need wildcard as source for expectation.
Registration - Expectations for incoming requests not only need to be unique among expectations, also must not clash with other conntrack entries:
Registration UA1:5061 -> Registrar:5060 REGISTER Contact: UA1:5061 UA2:5061 -> Registrar:5060 REGISTER Contact: UA2:5061 After NAT: NAT:5061 -> Registrar:5060 REGISTER Contact: NAT:5062 Expect * -> NAT:5062 NAT:5062 -> Registrar:5060 REGISTER Contact: NAT:5063 Expect * -> NAT:5063 - Requests from the Registrar to UA1's Contact address will match the existing connection from UA2 in the reply direction and go to the wrong UA.
Registration - Contact address must match the address used for registration to avoid clashes: UA1:5061 -> Registrar:5060 REGISTER Contact: UA1:5061 After NAT: NAT:5061 -> Registrar:5060 REGISTER Contact: NAT:5062 Expect: * -> NAT:5062
Registration - Incoming requests from the registrar to the SNATed contact address are DNATed to the internal host, making them look exactly like the reply of the connection used for registration => clash Registrar:5060 -> NAT:5062 INVITE <sip:user@nat:5062> DNATed to original Contact address: UA1:5061 Registrar:5060 -> UA1:5061 Clash with UA1:5061 -> Registrar:5060
Registration - In conclusion: need to make sure each UA uses the same, unique port for both communication and signaling expectations. Port must not only be unique for all connections to the registrar, but for all SIP connections because of wildcard expectations.
Registration - Helpers currently not able to remap the “helped” connection, NAT setup is completed before helper gets first packet. - Even if it were possible, choosing a unique port requires scanning entire conntrack table.
Registration - after choosing the port (must be done on first packet) and before setting up the signaling expectation (done on REGISTER request), other expectations may be created that still clash. Hard to avoid at expectation creation time because of wildcards (would require to scan entire conntrack table). Possible solution is to create an inactive expectation for reserving the tuple.
- INVITE requests are used to negotiate and establish sessions Invitations - INVITE requests are used to negotiate and establish sessions
Invitations - Invite request may also contain Contact address. Further requests may arrive at the new Contact address. Can't create expectations since the connection the INVITE arrives on may already be expected. Would allow to create deep expectation hierarchy: stack explodes at conntrack destruction time. Also no expiration time like in REGISTER requests.
Invitations - INVITE request contains address and port numbers for media streams. Media streams in both directions may not be symmetrical and may arrive from unknown third parties. Expectations must use a wildcard for the source.
Invitations - Media may arrive as soon as the media information is sent (early media), can't wait for confirmation from registrar. Allows to create full-blown expectations with wildcards using just a single UDP packet. - Maybe at least make sure the expected connection looks like valid RTP?
Invitations - When multiple endpoints sharing the same user ID are located behind the firewall, the same media information may be received multiple times on different connection. Must perform a lookup before registering the expectation to avoid clashes.
Invitations - Problem: the media expectation “belongs” to the first connection it was seen on. If that endpoint rejects the call, the expectation will get cleaned up. It is still needed for the other endpoints though.
Invitations - Media expectations should not cause signaling expectations to get evicted: helpers can define “expectation classes”, eviction prefers expectations of the same class.