Re: Labeled IPSec trying to match policy for peer label?

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Sat, Jul 06, 2013 at 08:39:52AM +0200, Sven Vermeulen wrote:
> On Fri, Jul 05, 2013 at 04:50:41PM -0400, Paul Moore wrote:
> > > spdadd 10.1.2.0/24 10.1.3.0/24 any -ctx 1 1
> > >   "system_u:object_r:ipsec_spd_t:s0" -P out ipsec
> > >   esp/tunnel/192.168.100.152-192.168.100.153/require;
> > >
> > > spdadd 10.1.3.0/24 10.1.2.0/24 any -ctx 1 1
> > >   "system_u:object_r:ipsec_spd_t:s0" -P in ipsec
> > >   esp/tunnel/192.168.100.153-192.168.100.152/require;
> [...]
> > Is the server side running the same SELinux policy as the client?  Does the
> > server have a SPD entry that is labeled, e.g. '-ctx 1 1
> > "system_u:object_r:ipsec_spd_t:s0"'?
>
> Yes, both sides have the same setkey instructions (only the in/out is
> switched) and are running the same SELinux policy & type. The racoon
> configurations are also the same (of course each one with the right
> addresses in the remote { ... } and sainfo { ... } definitions.

I tried with ipsec-tools 0.8.1 but no difference; I started racoon with
debugging on to see what I could have done wrong. Here is my analysis and
output:

At a certain point in time, isakmp_quick.c's get_proposal_r() method is
called, where the policy is eventually queried for:

#v+
/* get inboud policy */
sp_in = getsp_r(&spidx);
if (sp_in == NULL) {
  ...
  plog(LLV_ERROR, LOCATION, NULL, "no policy found: %s\n", spidx2str(&spidx));
}
#v-

The error I get at the end (no policy found) is triggered when getsp_r
doesn't return any policy. I enabled generate_policy in racoon just to make
sure it is here in the code that getsp_r returns no matches (as racoon then
tries to generate code and I see additional logging events).

So I take a look at the getsp_r() code, which traverses the &sptree list and
does two checks:

#v+
for (p = TAILQ_FIRST(&sptree); p; p = TAILQ_NEXT(p, chain)) {
        if (!cmpspidxstrict(spidx, &p->spidx))
                return p;

        if (!found && !cmpspidxwild(spidx, &p->spidx))
                found = p;
}
#v-

So the spidx one is the information from the packet, while &p->spidx is the
one from the database, right?

The cmpspidxstrict() method checks if the entries match (dir,
prefs, prefd, ul_proto) and if the socket addresses (?) match.

The cmpspidxwild() method checks similar stuff on the dir(ection), protocol,
family, and then it checks the differences on the socket level.

Now, considering the following output:

#v+
Jul  6 13:24:06 test racoon: DEBUG: sub:0x3f88b6e2c58: 10.1.3.0/24[0]
10.1.2.0/24[0] proto=any dir=in
sec_ctx:doi=1,alg=1,len=36,str=root:sysadm_r:ping_t:s0-s0:c0.c1023
Jul  6 13:24:06 test racoon: DEBUG: db :0x7e2229aca0: 10.1.3.0/24[0]
10.1.2.0/24[0] proto=any dir=fwd
sec_ctx:doi=1,alg=1,len=45,str=system_u:object_r:ipsec_spd_t:s0-s0:c0.c1023

Jul  6 13:24:06 test racoon: DEBUG: sub:0x3f88b6e2c58: 10.1.3.0/24[0]
10.1.2.0/24[0] proto=any dir=in
sec_ctx:doi=1,alg=1,len=36,str=root:sysadm_r:ping_t:s0-s0:c0.c1023
Jul  6 13:24:06 test racoon: DEBUG: db: 0x7e2229aca0: 10.1.3.0/24[0]
10.1.2.0/24[0] proto=any dir=fwd
sec_ctx:doi=1,alg=1,len=45,str=system_u:object_r:ipsec_spd_t:s0-s0:c0.c1023
#v-

No match; I get the entries twice (once for cmpspidxstrict() and one for
cmpspidxwild()).

#v+
Jul  6 13:24:06 test racoon: DEBUG: sub:0x3f88b6e2c58: 10.1.3.0/24[0]
10.1.2.0/24[0] proto=any dir=in
sec_ctx:doi=1,alg=1,len=36,str=root:sysadm_r:ping_t:s0-s0:c0.c1023
Jul  6 13:24:06 test racoon: DEBUG: db :0x7e2229af60: 10.1.3.0/24[0]
10.1.2.0/24[0] proto=any dir=in
sec_ctx:doi=1,alg=1,len=45,str=system_u:object_r:ipsec_spd_t:s0-s0:c0.c1023
Jul  6 13:24:06 test racoon: DEBUG: sub:0x3f88b6e2c58: 10.1.3.0/24[0]
10.1.2.0/24[0] proto=any dir=in
sec_ctx:doi=1,alg=1,len=36,str=root:sysadm_r:ping_t:s0-s0:c0.c1023
Jul  6 13:24:06 test racoon: DEBUG: db: 0x7e2229af60: 10.1.3.0/24[0]
10.1.2.0/24[0] proto=any dir=in
sec_ctx:doi=1,alg=1,len=45,str=system_u:object_r:ipsec_spd_t:s0-s0:c0.c1023
Jul  6 13:24:06 test racoon: DEBUG: 0x3f88b6e2c58 masked with /24: 10.1.3.0[0]
Jul  6 13:24:06 test racoon: DEBUG: 0x7e2229af60 masked with /24: 10.1.3.0[0]
Jul  6 13:24:06 test racoon: DEBUG: 0x3f88b6e2c58 masked with /24: 10.1.2.0[0]
Jul  6 13:24:06 test racoon: DEBUG: 0x7e2229af60 masked with /24: 10.1.2.0[0]
#v-

Here, I get the same entries again, but now with the "masked" stuff as well.
These masked stuff entries come from cmspidxwild(), so the earlier checks
all match (which we can see from the output).

Also, because I see two sets of "masked with" events, the first check
succeeds:

#v+
        mask_sockaddr((struct sockaddr *)&sa1, (struct sockaddr *)&a->src,
                b->prefs);
        mask_sockaddr((struct sockaddr *)&sa2, (struct sockaddr *)&b->src,
                b->prefs);
        plog(LLV_DEBUG, LOCATION, NULL, "%p masked with /%d: %s\n",
                a, b->prefs, saddr2str((struct sockaddr *)&sa1));
        plog(LLV_DEBUG, LOCATION, NULL, "%p masked with /%d: %s\n",
                b, b->prefs, saddr2str((struct sockaddr *)&sa2));
        if (cmpsaddr((struct sockaddr *)&sa1, (struct sockaddr *)&sa2)
> CMPSADDR_WILDPORT_MATCH)
                return 1;
#v-

But the second check seems to fail, because after the second check I would
expect information on the range checking:

#v+
        mask_sockaddr((struct sockaddr *)&sa1, (struct sockaddr *)&a->dst,
                b->prefd);
        mask_sockaddr((struct sockaddr *)&sa2, (struct sockaddr *)&b->dst,
                b->prefd);
        plog(LLV_DEBUG, LOCATION, NULL, "%p masked with /%d: %s\n",
                a, b->prefd, saddr2str((struct sockaddr *)&sa1));
        plog(LLV_DEBUG, LOCATION, NULL, "%p masked with /%d: %s\n",
                b, b->prefd, saddr2str((struct sockaddr *)&sa2));
        if (cmpsaddr((struct sockaddr *)&sa1, (struct sockaddr *)&sa2)
> CMPSADDR_WILDPORT_MATCH)
                return 1;
#v-

What is it trying to do here? Why are the checks on b->prefd in both
cases (and not on a->prefd first and then b->prefd)?

When I don't add the contexts, I don't even get to this location. It
nicely matches (I think the match then is in cmpspidxstrict()),
doesn't show the "masked with" information.

#v+
Jul  6 14:32:01 test racoon: DEBUG: sub:0x3a74d3e2418: 10.1.3.0/24[0]
10.1.2.0/24[0] proto=any dir=in
Jul  6 14:32:01 test racoon: DEBUG: db :0x7fde6a2f30: 10.1.3.0/24[0]
10.1.2.0/24[0] proto=any dir=fwd
Jul  6 14:32:01 test racoon: DEBUG: sub:0x3a74d3e2418: 10.1.3.0/24[0]
10.1.2.0/24[0] proto=any dir=in
Jul  6 14:32:01 test racoon: DEBUG: db: 0x7fde6a2f30: 10.1.3.0/24[0]
10.1.2.0/24[0] proto=any dir=fwd
Jul  6 14:32:01 test racoon: DEBUG: sub:0x3a74d3e2418: 10.1.3.0/24[0]
10.1.2.0/24[0] proto=any dir=in
Jul  6 14:32:01 test racoon: DEBUG: db :0x7fde6a31f0: 10.1.3.0/24[0]
10.1.2.0/24[0] proto=any dir=in
#v-

Here it has found a match, because the next check uses an outgoing "sub":

#v+
Jul  6 14:32:01 test racoon: DEBUG: sub:0x3a74d3e2418: 10.1.2.0/24[0]
10.1.3.0/24[0] proto=any dir=out
Jul  6 14:32:01 test racoon: DEBUG: db :0x7fde6a2f30: 10.1.3.0/24[0]
10.1.2.0/24[0] proto=any dir=fwd
Jul  6 14:32:01 test racoon: DEBUG: sub:0x3a74d3e2418: 10.1.2.0/24[0]
10.1.3.0/24[0] proto=any dir=out
Jul  6 14:32:01 test racoon: DEBUG: db: 0x7fde6a2f30: 10.1.3.0/24[0]
10.1.2.0/24[0] proto=any dir=fwd
Jul  6 14:32:01 test racoon: DEBUG: sub:0x3a74d3e2418: 10.1.2.0/24[0]
10.1.3.0/24[0] proto=any dir=out
Jul  6 14:32:01 test racoon: DEBUG: db :0x7fde6a31f0: 10.1.3.0/24[0]
10.1.2.0/24[0] proto=any dir=in
Jul  6 14:32:01 test racoon: DEBUG: sub:0x3a74d3e2418: 10.1.2.0/24[0]
10.1.3.0/24[0] proto=any dir=out
Jul  6 14:32:01 test racoon: DEBUG: db: 0x7fde6a31f0: 10.1.3.0/24[0]
10.1.2.0/24[0] proto=any dir=in
Jul  6 14:32:01 test racoon: DEBUG: sub:0x3a74d3e2418: 10.1.2.0/24[0]
10.1.3.0/24[0] proto=any dir=out
Jul  6 14:32:01 test racoon: DEBUG: db :0x7fde6a35f0: 10.1.2.0/24[0]
10.1.3.0/24[0] proto=any dir=out
Jul  6 14:32:01 test racoon: DEBUG: suitable SP found:10.1.2.0/24[0]
10.1.3.0/24[0] proto=any dir=out
#v-

Wkr,
Sven Vermeulen

--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@xxxxxxxxxxxxx with
the words "unsubscribe selinux" without quotes as the message.




[Index of Archives]     [Selinux Refpolicy]     [Linux SGX]     [Fedora Users]     [Fedora Desktop]     [Yosemite Photos]     [Yosemite Camping]     [Yosemite Campsites]     [KDE Users]     [Gnome Users]

  Powered by Linux