netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* Is TCP over IPsec broken in 2.6.18?
@ 2006-09-22 11:29 Evgeniy Polyakov
  2006-09-22 11:35 ` Evgeniy Polyakov
  2006-09-22 12:19 ` Evgeniy Polyakov
  0 siblings, 2 replies; 45+ messages in thread
From: Evgeniy Polyakov @ 2006-09-22 11:29 UTC (permalink / raw)
  To: netdev

Hello.

I've found strange behaviour of transport mode IPsec in 2.6.18 tree.
After key daemons exchanged keys (I use racoon) I try following command
on 2.6.18 machine: telnet 192.168.4.79 22 (telnet from 2.6.18 to 2.6.17 based one)
and get very slow response, here is related tcpdump output:

15:15:47.396925 IP 192.168.4.78 > 192.168.4.79: ESP(spi=0x027181f9,seq=0x21), length 84
15:15:47.397391 IP 192.168.4.79 > 192.168.4.78: ESP(spi=0x0961a360,seq=0x18), length 84
15:15:47.397025 IP 192.168.4.78 > 192.168.4.79: ESP(spi=0x027181f9,seq=0x22), length 84
15:15:47.404166 IP 192.168.4.79.ssh > 192.168.4.78.47256: P 2541002438:2541002458(20) ack 1601271418 win 91 
15:15:48.279375 IP 192.168.4.79.ssh > 192.168.4.78.47256: P 0:20(20) ack 1 win 91 
15:15:50.031487 IP 192.168.4.79.ssh > 192.168.4.78.47256: P 0:20(20) ack 1 win 91 
15:15:53.535710 IP 192.168.4.79.ssh > 192.168.4.78.47256: P 0:20(20) ack 1 win 91 
15:16:00.544154 IP 192.168.4.79.ssh > 192.168.4.78.47256: P 0:20(20) ack 1 win 91 
15:16:14.561064 IP 192.168.4.79 > 192.168.4.78: ESP(spi=0x0961a360,seq=0x19), length 100
15:16:14.561218 IP 192.168.4.78 > 192.168.4.79: ESP(spi=0x027181f9,seq=0x23), length 84

Unencrypted packets somehow sneaked into the wire.

ping works ok:
15:15:37.919617 IP 192.168.4.78 > 192.168.4.79: ESP(spi=0x027181f9,seq=0x1c), length 116
15:15:37.919858 IP 192.168.4.79 > 192.168.4.78: ESP(spi=0x0961a360,seq=0x13), length 116
15:15:38.920772 IP 192.168.4.78 > 192.168.4.79: ESP(spi=0x027181f9,seq=0x1d), length 116
15:15:38.920823 IP 192.168.4.79 > 192.168.4.78: ESP(spi=0x0961a360,seq=0x14), length 116
15:15:39.920823 IP 192.168.4.78 > 192.168.4.79: ESP(spi=0x027181f9,seq=0x1e), length 116
15:15:39.920883 IP 192.168.4.79 > 192.168.4.78: ESP(spi=0x0961a360,seq=0x15), length 116
15:15:40.920848 IP 192.168.4.78 > 192.168.4.79: ESP(spi=0x027181f9,seq=0x1f), length 116
15:15:40.920893 IP 192.168.4.79 > 192.168.4.78: ESP(spi=0x0961a360,seq=0x16), length 116

It was introduced somewhere in 2.6.18 development cycle and as far as I
recall not at the beginning of it (I found it porting IPsec acrypto to 2.6.18,
unfortunately I do not have version which works anymore, except 2.6.17
tree which works ok with both acrypto and vanilla trees), likely after
transport/tunnel modules introduction by Herbert Xu.

telnet from 2.6.17 tree to 2.6.18 tree works ok too:

15:24:33.428978 IP 192.168.4.79 > 192.168.4.78: ESP(spi=0x0961a360,seq=0x1b), length 84
15:24:33.429130 IP 192.168.4.78 > 192.168.4.79: ESP(spi=0x027181f9,seq=0x2d), length 84
15:24:33.429236 IP 192.168.4.79 > 192.168.4.78: ESP(spi=0x0961a360,seq=0x1c), length 84
15:24:33.436885 IP 192.168.4.78 > 192.168.4.79: ESP(spi=0x027181f9,seq=0x2e), length 100
15:24:33.436962 IP 192.168.4.79 > 192.168.4.78: ESP(spi=0x0961a360,seq=0x1d), length 84
15:24:35.293140 IP 192.168.4.79 > 192.168.4.78: ESP(spi=0x0961a360,seq=0x1e), length 84
15:24:35.293259 IP 192.168.4.78 > 192.168.4.79: ESP(spi=0x027181f9,seq=0x2f), length 84
15:24:35.293315 IP 192.168.4.78 > 192.168.4.79: ESP(spi=0x027181f9,seq=0x30), length 100
15:24:35.293365 IP 192.168.4.79 > 192.168.4.78: ESP(spi=0x0961a360,seq=0x1f), length 84
15:24:35.293372 IP 192.168.4.78 > 192.168.4.79: ESP(spi=0x027181f9,seq=0x31), length 84
15:24:35.293514 IP 192.168.4.79 > 192.168.4.78: ESP(spi=0x0961a360,seq=0x20), length 84
15:24:35.293639 IP 192.168.4.78 > 192.168.4.79: ESP(spi=0x027181f9,seq=0x32), length 84

All tcpdumps were obtained on 2.6.17 machine.
On the same machine I frequently get following logs in syslog:

Sep 22 15:10:52 kano racoon: INFO: ISAKMP-SA established 192.168.4.79[500]-192.168.4.78[500] spi:9865a72e87784e17:cb2af1cfc436bd13 
Sep 22 15:10:52 kano racoon: ERROR: none message must be encrypted
Sep 22 15:10:53 kano racoon: INFO: respond new phase 2 negotiation: 192.168.4.79[500]<=>192.168.4.78[500]
Sep 22 15:10:53 kano racoon: INFO: IPsec-SA established: ESP/Transport 192.168.4.78[0]->192.168.4.79[0] spi=40993273(0x27181f9)
Sep 22 15:10:53 kano racoon: INFO: IPsec-SA established: ESP/Transport 192.168.4.79[0]->192.168.4.78[0] spi=157393760(0x961a360)
Sep 22 15:11:02 kano racoon: ERROR: none message must be encrypted
Sep 22 15:11:12 kano racoon: INFO: IPsec-SA expired: ESP/Transport 192.168.4.78[0]->192.168.4.79[0] spi=3540507(0x36061b)
Sep 22 15:11:12 kano racoon: WARNING: the expire message is received but the handler has not been established.
Sep 22 15:11:12 kano racoon: ERROR: 192.168.4.78 give up to get IPsec-SA due to time up to wait.

I do not recall if they existed when 2.6.17<->2.6.17 communication was
established.

I can use git bisect to track bug down if someone will show me simple tutorial.

-- 
	Evgeniy Polyakov

^ permalink raw reply	[flat|nested] 45+ messages in thread
* RE: [PATCH] Fix for IPsec leakage with SELinux enabled
@ 2006-10-01 20:55 Venkat Yekkirala
  2006-10-02  1:44 ` James Morris
  0 siblings, 1 reply; 45+ messages in thread
From: Venkat Yekkirala @ 2006-10-01 20:55 UTC (permalink / raw)
  To: James Morris, David S. Miller, Herbert Xu
  Cc: netdev, Stephen Smalley, Evgeniy Polyakov, Venkat Yekkirala,
	Paul Moore, Chad Hanson

> The way I was seeing the problem was when connecting via IPsec to a 
> confined service on an SELinux box (vsftpd), which did not have the 
> appropriate SELinux policy permissions to send packets via IPsec.
> 
> The first SYNACK would be blocked,

Given that the resolver fails to find a policy here, I am trying to
understand what exactly is blocking it (the first SYNACK) from
proceeding without IPSec.

> because of an uncached lookup via 
> flow_cache_lookup(), which would fail to resolve an xfrm 
> policy because 
> the SELinux policy is checked at that point via the resolver.
> 
> However, retransmitted SYNACKs would then find a cached flow 
> entry when 
> calling into flow_cache_lookup() with a null xfrm policy, which is 
> interpreted by xfrm_lookup() as the packet not having any associated 
> policy and similarly to the first case, allowing it to pass without 
> transformation.

^ permalink raw reply	[flat|nested] 45+ messages in thread
* RE: [PATCH] Fix for IPsec leakage with SELinux enabled
@ 2006-10-02 17:09 Venkat Yekkirala
  2006-10-02 18:39 ` James Morris
  0 siblings, 1 reply; 45+ messages in thread
From: Venkat Yekkirala @ 2006-10-02 17:09 UTC (permalink / raw)
  To: James Morris, Venkat Yekkirala
  Cc: David S. Miller, Herbert Xu, netdev, Stephen Smalley,
	Evgeniy Polyakov, Paul Moore, Chad Hanson

> On Sun, 1 Oct 2006, Venkat Yekkirala wrote:
> 
> > > The way I was seeing the problem was when connecting via 
> IPsec to a 
> > > confined service on an SELinux box (vsftpd), which did 
> not have the 
> > > appropriate SELinux policy permissions to send packets via IPsec.
> > > 
> > > The first SYNACK would be blocked,
> > 
> > Given that the resolver fails to find a policy here, I am trying to
> > understand what exactly is blocking it (the first SYNACK) from
> > proceeding without IPSec.
> 
> You're right.  My explanation there was for the case where 
> I'd modified 
> the code to propagate the SELinux denial back to 
> xfrm_lookup(), and not 
> for the original issue (sorry, it's been a long week).
> 
> In the original case, all packets originating from a confined 
> domain will 
> bypass ipsec.  During xfrm_lookup, flow_cache_lookup() returns NULL 
> policy:
> 
> xfrm_lookup()
> {
> 	...
> 
> 	if (!policy) {
>                 /* To accelerate a bit...  */
>                 if ((dst_orig->flags & DST_NOXFRM) ||
>                     !xfrm_policy_count[XFRM_POLICY_OUT])
>                         return 0;
> 
>                 policy = flow_cache_lookup(fl, dst_orig->ops->family,
>                                            dir, xfrm_policy_lookup);
>         }
> 
>         if (!policy)
>                 return 0;  <- bad
> 	...
> }
> 
> The call chain is:
> 
> flow_cache_lookup()
>   xfrm_policy_lookup()
>    xfrm_policy_lookup_bytype()
>      xfrm_policy_match() {
>        xfrm_selector_match => returns true, then
>          security_xfrm_policy_lookup => returns -EACCESS
>      }
> 
> then
>      
> xfrm_policy_match() => returns 0
> xfrm_policy_lookup_bytype => returns 0
> xfrm_policy_lookup() => sets obj to NULL w/ void return
> flow_cache_lookup() => returns NULL
> xfrm_lookup => returns 0
> 
> and the packet proceeds without error and with no transform 
> applied (i.e. 
> leaked as cleartext).

This is indeed the "designed" and expected (for me) behavior. But I am
beginning to see where this is perhaps NOT in line with the user
expectation when the users have an IPSec policy rule that does NOT use
labels.

IOW, if they have their policy like (NO LABELS):

spdadd 192.168.4.79 192.168.4.78 any -P out ipsec
        esp/transport//require;

spdadd 192.168.4.78 192.168.4.79 any -P in ipsec
        esp/transport//require;

currently, EACH flow needing to use this rule MUST
have SELinux policy "polmatch"ing the flow context (ftpd_t)
to unlabeled_t (the implied in the absence of an explicit
context on the IPSec policy rule) or the traffic would flow
in clear text ("leaks" in user perception).

What I propose we do is to do the polmatch check ONLY when
there's an explicit label associated with the spd rule. Does
this sound reasonable and correct in the larger SELinux context?

In cases where there's an explicit label on an spd rule like:

spdadd 192.168.4.79 192.168.4.78 any -ctx 1 1
"system_u:object_r:labeled_ipsec_t:s2-s4"
	-P out ipsec
        esp/transport//require;

spdadd 192.168.4.78 192.168.4.79 any -ctx 1 1
"system_u:object_r:labeled_ipsec_t:s2-s4"
	-P in ipsec
        esp/transport//require;

then the current behavior (prior to this proposed patch) would be the
desired behavior, i.e., a polmatch denial in the SELinux module just
means that the flow isn't expected to undergo IPSec xfrms. IOW, there's
no need to propagate -EACCES all the way back up. We could still propagate
errors other than -EACCES if we like.

> 
> The first component of the fix is to propagate errors back up 
> to callers 
> via the flow cache resolver, and handle them correctly, as 
> this is where 
> we can experience security module denials.

This will cause problems with the case where we may have multiple
"labeled" spd rules, each of which should be attempted to be polmatched
against before letting the flow out in clear text, as would be expected
by the user as well.

> 
> The second component is to then ensure that, on failure,

-EACCES in this case is perceived as a failure since the
designed behavior doesn't seem to be in line with the user
expectation. Otherwise, with the above proposed change to
the design, there won't be a polmatch check in this case and
hence no failure.

It's probably still a good idea to propagate non-EACCES failures
back up the chain though.

> we 
> kill the new 
> flow cache entry created during lookup, so that it is not 
> subsequently 
> looked up with a null policy (i.e. allowing future packets to 
> leak) and to 
> force the security hook to be called again in case the policy 
> has changed.  
> 
> Hope that clarifies.
>     
> 
> - James
> -- 
> James Morris
> <jmorris@namei.org>
> 

^ permalink raw reply	[flat|nested] 45+ messages in thread
* RE: [PATCH] Fix for IPsec leakage with SELinux enabled
@ 2006-10-02 18:59 Venkat Yekkirala
  0 siblings, 0 replies; 45+ messages in thread
From: Venkat Yekkirala @ 2006-10-02 18:59 UTC (permalink / raw)
  To: James Morris, Venkat Yekkirala
  Cc: David S. Miller, Herbert Xu, netdev, Stephen Smalley,
	Evgeniy Polyakov, Paul Moore, Chad Hanson

> > This is indeed the "designed" and expected (for me) behavior.
> 
> This is a security hole.  SELinux denies all access by 
> default, so the 
> default behavior of this code is to allow all traffic to bypass IPsec.
> 
> You should not need to add a rule to 'allow' increased security.

You are right. Currently working on a patch (should be out
tonight/tomorrow).

<snip>

> This needs to be handled within SELinux as far as possible, 
> and errors 
> will generally need to be propagated back to the callers, as 

Agreed here as well. I have yet to review your patch in depth,
but it definitely makes sense to do what you say here. Thanks.

> we don't know 
> what other LSMs might do, and errors unrelated to access 
> control can be 
> returned.
> 
> 
> - James
> -- 
> James Morris
> <jmorris@namei.org>
> 

^ permalink raw reply	[flat|nested] 45+ messages in thread

end of thread, other threads:[~2006-10-05 21:04 UTC | newest]

Thread overview: 45+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-09-22 11:29 Is TCP over IPsec broken in 2.6.18? Evgeniy Polyakov
2006-09-22 11:35 ` Evgeniy Polyakov
2006-09-22 12:19 ` Evgeniy Polyakov
2006-09-22 12:23   ` Patrick McHardy
2006-09-22 14:03     ` Evgeniy Polyakov
2006-09-22 15:15       ` James Morris
2006-09-22 15:47         ` James Morris
2006-09-23  4:29         ` Evgeniy Polyakov
2006-09-24  5:11           ` James Morris
2006-09-24  9:08             ` Patrick McHardy
2006-09-24 14:33               ` James Morris
2006-09-24 23:54                 ` Herbert Xu
     [not found]                   ` <20060925103836.GA13966@2ka.mipt.ru>
2006-09-25 11:27                     ` Herbert Xu
2006-09-25 12:05                       ` Evgeniy Polyakov
2006-09-25 12:55                         ` jamal
2006-09-30  5:06                         ` James Morris
2006-09-30  5:14                           ` James Morris
2006-09-30  7:41                             ` James Morris
2006-09-30 11:15                             ` Evgeniy Polyakov
2006-09-30 14:36                               ` James Morris
2006-09-30 14:40                                 ` Evgeniy Polyakov
2006-09-30 14:42                                   ` Evgeniy Polyakov
2006-09-30 14:44                                   ` James Morris
2006-10-01  6:27                                     ` [PATCH] Fix for IPsec leakage with SELinux enabled James Morris
2006-10-02 11:20                                       ` Evgeniy Polyakov
2006-10-02 13:31                                         ` James Morris
2006-10-02 13:42                                           ` Evgeniy Polyakov
2006-10-02 14:05                                             ` James Morris
2006-10-02 14:27                                               ` [PATCH] Fix for IPsec leakage with SELinux enabled - V.02 James Morris
2006-10-02 16:00                                                 ` Evgeniy Polyakov
2006-10-02 16:13                                                   ` James Morris
2006-10-02 16:30                                                     ` Evgeniy Polyakov
2006-10-02 16:41                                                       ` James Morris
2006-10-04  5:08                                                         ` Evgeniy Polyakov
2006-10-04 13:00                                                           ` James Morris
2006-10-03 23:18                                                 ` David Miller
2006-10-04  1:33                                                   ` James Morris
2006-10-04 13:41                                                   ` Herbert Xu
2006-10-05 20:58                                                   ` James Morris
2006-10-05 21:04                                                     ` David Miller
  -- strict thread matches above, loose matches on Subject: below --
2006-10-01 20:55 [PATCH] Fix for IPsec leakage with SELinux enabled Venkat Yekkirala
2006-10-02  1:44 ` James Morris
2006-10-02 17:09 Venkat Yekkirala
2006-10-02 18:39 ` James Morris
2006-10-02 18:59 Venkat Yekkirala

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).