All of lore.kernel.org
 help / color / mirror / Atom feed
* 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.