* Understanding Netfilter and IPSec Transport Mode over NAT @ 2006-02-07 19:40 Chinh Nguyen 2006-02-09 18:44 ` Chinh Nguyen 0 siblings, 1 reply; 3+ messages in thread From: Chinh Nguyen @ 2006-02-07 19:40 UTC (permalink / raw) To: netfilter-devel Hi, I realize that this is a devel mailing-list. My apologies. I am having problem with Racoon and Transport Mode over NAT (for TCP traffic) for kernel 2.6.16-rc1. I'm trying to understand how Netfilter works and I'm stumped. I've embedded some printk statements but I'll probably have to do some live debugging unless someone can point out what's going on. When I modify Racoon to NOT push an sadb_x_policy (in/out bypass) for the IKE/IKE-NAT ports via setsockopt, UDP-encap ESP carrying UDP data is rejected in __xfrm_policy_check. The standard Racoon which pushes an in/out bypass per-socket policy accepts encrypted UDP traffic. After decap, the associated skb has a security path. As such, the post_input function (ie, esp4_post_input) sets the skb->ipsummed to ignore checksum. The result is that UDP traffic is accepted as shown below: Feb 7 13:29:30 localhost kernel: [17179776.692000] esp_input begin Feb 7 13:29:30 localhost kernel: [17179776.692000] esp_input encap block Feb 7 13:29:30 localhost kernel: [17179776.692000] esp_input decap_type block Feb 7 13:29:30 localhost kernel: [17179776.692000] esp_input end Feb 7 13:29:30 localhost kernel: [17179776.692000] xfrm4_rcv_encap: skb->sp != NULL = 1 Feb 7 13:29:30 localhost kernel: [17179776.692000] xfrm_pol_check: skb->sp != NULL? = 1 Feb 7 13:29:30 localhost kernel: [17179776.692000] esp_post_input begin Feb 7 13:29:30 localhost kernel: [17179776.692000] props.mode = 0, ip_summed = 2 (CHECKSUM_UNNECESSARY) Feb 7 13:29:30 localhost kernel: [17179776.692000] xfrm_pol_check: pol != NULL? = 1 Feb 7 13:29:30 localhost kernel: [17179776.692000] xfrm_pol_check: accept The first question is more academic. How does a per-socket bypass policy equals "accept transport mode ESP"? The second question is more pragmatic. Why doesn't this work for TCP? With encrypted TCP traffic, the skb->sp is NULL, therefore esp_post_input is not called. Why? However, the decrypted TCP packet itself seems to be sent up the stack since netstat reveals that bad TCP segments are being received. Feb 7 13:37:08 localhost kernel: [17180234.228000] esp_input begin Feb 7 13:37:08 localhost kernel: [17180234.228000] esp_input encap block Feb 7 13:37:08 localhost kernel: [17180234.228000] esp_input decap_type block Feb 7 13:37:08 localhost kernel: [17180234.228000] esp_input end Feb 7 13:37:11 localhost kernel: [17180234.228000] xfrm4_rcv_encap: skb->sp != NULL = 1 Feb 7 13:37:11 localhost kernel: [17180234.228000] xfrm_pol_check: skb->sp != NULL? = 0 Feb 7 13:37:11 localhost kernel: [17180237.256000] xfrm_pol_check: pol != NULL? = 1 Feb 7 13:37:11 localhost kernel: [17180237.256000] xfrm_pol_check: accept Chinh ^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: Understanding Netfilter and IPSec Transport Mode over NAT 2006-02-07 19:40 Understanding Netfilter and IPSec Transport Mode over NAT Chinh Nguyen @ 2006-02-09 18:44 ` Chinh Nguyen 2006-02-10 9:23 ` Balazs Scheidler 0 siblings, 1 reply; 3+ messages in thread From: Chinh Nguyen @ 2006-02-09 18:44 UTC (permalink / raw) To: netfilter-devel Chinh Nguyen wrote: > Hi, > The first question is more academic. How does a per-socket bypass policy equals > "accept transport mode ESP"? > > The second question is more pragmatic. Why doesn't this work for TCP? With > encrypted TCP traffic, the skb->sp is NULL, therefore esp_post_input is not > called. Why? However, the decrypted TCP packet itself seems to be sent up the > stack since netstat reveals that bad TCP segments are being received. I discovered that the "bug" is in the function tcp_v4_rcv for kernel 2.6.16-rc1. After the ESP packet is decapped and decrypted in xfrm4_rcv_encap_finish, the unencrypted packet is pushed back through ip_local_deliver. For a UDP packet, it goes (back) to function udp_queue_rcv_skb. The first thing this function does is called xfrm4_policy_check. As noted previously, in xfrm4_policy_check, if the skb->sp != NULL, the esp_post_input function is called. The post input function sets skb->ip_summed to CHECKSUM_UNNECESSASRY if we are in transport mode. Therefore, further down in udp_queue_rcv_skb, we skip the checksum check and the packet is passed up the stack. However, for a decrypted TCP packet, the packet goes to tcp_v4_rcv. This function does the checksum check right away if skb->ip_summed != CHECKSUM_UNNECESSARY while xfrm4_policy_check is called a little later in the function. Therefore, the esp post input has not yet set the ip_summed to unnecessary. The decrypted packet fails the checksum and is discarded. To confirm this, I added another call to xfrm4_policy_check before the checksum check in tcp_v4_rcv (to call esp post input). Once patched, my systems were able to initiate TCP connections using Transport Mode/NAT. printk(KERN_INFO "tcp_v4_rcv: tcp patch\n"); if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb)) goto discard_it; nf_reset(skb); printk(KERN_INFO "tcp_v4_rcv: skb = %08x, skb->ip_summed = %d\n", skb, skb->ip_summed); /* An explanation is required here, I think. * Packet length and doff are validated by header prediction, * provided case of th->doff==0 is eliminated. * So, we defer the checks. */ if ((skb->ip_summed != CHECKSUM_UNNECESSARY && tcp_v4_checksum_init(skb))) goto bad_packet; printk(KERN_INFO "tcp_v4_rcv: sum ok\n"); I don't consider this a real patch because it's inefficient to have 2 calls to xfrm4_policy_check in tcp_v4_rcv. Is this the right list to bring up this issue or should I go to some other list (e.g., linux-kernel, etc)? Regards, Chinh ^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: Understanding Netfilter and IPSec Transport Mode over NAT 2006-02-09 18:44 ` Chinh Nguyen @ 2006-02-10 9:23 ` Balazs Scheidler 0 siblings, 0 replies; 3+ messages in thread From: Balazs Scheidler @ 2006-02-10 9:23 UTC (permalink / raw) To: Chinh Nguyen; +Cc: netfilter-devel On Thu, 2006-02-09 at 13:44 -0500, Chinh Nguyen wrote: > Chinh Nguyen wrote: > > Hi, > > The first question is more academic. How does a per-socket bypass policy equals > > "accept transport mode ESP"? > > > > The second question is more pragmatic. Why doesn't this work for TCP? With > > encrypted TCP traffic, the skb->sp is NULL, therefore esp_post_input is not > > called. Why? However, the decrypted TCP packet itself seems to be sent up the > > stack since netstat reveals that bad TCP segments are being received. > > I discovered that the "bug" is in the function tcp_v4_rcv for kernel 2.6.16-rc1. > > After the ESP packet is decapped and decrypted in xfrm4_rcv_encap_finish, the > unencrypted packet is pushed back through ip_local_deliver. For a UDP packet, it > goes (back) to function udp_queue_rcv_skb. The first thing this function does is > called xfrm4_policy_check. As noted previously, in xfrm4_policy_check, if the > skb->sp != NULL, the esp_post_input function is called. The post input function > sets skb->ip_summed to CHECKSUM_UNNECESSASRY if we are in transport mode. > Therefore, further down in udp_queue_rcv_skb, we skip the checksum check and the > packet is passed up the stack. > > However, for a decrypted TCP packet, the packet goes to tcp_v4_rcv. This > function does the checksum check right away if skb->ip_summed != > CHECKSUM_UNNECESSARY while xfrm4_policy_check is called a little later in the > function. Therefore, the esp post input has not yet set the ip_summed to > unnecessary. The decrypted packet fails the checksum and is discarded. > > To confirm this, I added another call to xfrm4_policy_check before the checksum > check in tcp_v4_rcv (to call esp post input). Once patched, my systems were able > to initiate TCP connections using Transport Mode/NAT. > > printk(KERN_INFO "tcp_v4_rcv: tcp patch\n"); > if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb)) > goto discard_it; > nf_reset(skb); > > printk(KERN_INFO "tcp_v4_rcv: skb = %08x, skb->ip_summed = %d\n", skb, > skb->ip_summed); > /* An explanation is required here, I think. > * Packet length and doff are validated by header prediction, > * provided case of th->doff==0 is eliminated. > * So, we defer the checks. */ > if ((skb->ip_summed != CHECKSUM_UNNECESSARY && > tcp_v4_checksum_init(skb))) > goto bad_packet; > > printk(KERN_INFO "tcp_v4_rcv: sum ok\n"); > > > I don't consider this a real patch because it's inefficient to have 2 calls to > xfrm4_policy_check in tcp_v4_rcv. > > Is this the right list to bring up this issue or should I go to some other list > (e.g., linux-kernel, etc)? > I think the proper place is netdev and maybe Cc Patrick McHardy as he wrote the IPSec NAT patches, even though he is reading netfilter-devel as well. -- Bazsi ^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2006-02-10 9:23 UTC | newest] Thread overview: 3+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2006-02-07 19:40 Understanding Netfilter and IPSec Transport Mode over NAT Chinh Nguyen 2006-02-09 18:44 ` Chinh Nguyen 2006-02-10 9:23 ` Balazs Scheidler
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.