some things to discuss about MAC

Robert Watson rwatson at FreeBSD.org
Sat Dec 29 14:21:21 GMT 2001


On Sat, 29 Dec 2001, Ilmar S. Habibulin wrote:

> On Fri, 28 Dec 2001, Robert Watson wrote:
> 
> > My temptation would be instead to process based on the mbuf MAC label, and
> > simply make sure CIPSO processing happened before the packets were fed
> > into ipfw.  This would mean we could process packets not using CIPSO, and
> ipfw deals with ip packet header only. and parses it independently from
> ip_dooptions(m), which i use to label mbuf with packet label, if it
> exists. So we can teach ipfirewall to parse, understand and make access
> control decision based on CIPSO, because CIPSO is one of the IP packet
> header options. nothing more from ipfw point of view.

Hmm.  Right now, each mbuf contains a label as part of the mbuf header. 
Currently, that label is initialized either from the socket the packet is
sent from, or the interface from which it originates.  In a couple of
weird cases, the mbuf label is generated as a result of another message
without interaction with either an interface or a socket, in which case I
currently generate the label based on the packet it is a response to.  In
all of these cases, before merging your CIPSO code, the packet label is
part of the mbuf and not actually in the explicit packet contents.  As
such, even before the CIPSO code, it should be possible to teach ipfw to
look at the mbuf label, in the style of the 'via' ipfw rules that look at
the similar mbuf ifp field for the source interface.

Originally, I was looking at it in the following way:

- Some interfaces would be single-level interfaces, where packets would be
  implicitly labled as they came in based on the label assigned to the
  interface, and packets would only be allowed out the interface if the
  policy permitted it.  This is what is currently implemented: ioctl is
  used to configure an 'incoming' label and an 'outgoing' label on the
  interface: one is used as the default label for incoming packets, and
  the other is compared to permit the packet go out.  Until the interface
  policies become more sophisticated, that's actually redundant since they
  are always the same.  With TE, they can differ.

Once we have CIPSO,...

- Some interfaces will be multi-level 'trusted' interfaces, which will
  be assumed to connect to a network of other trusted systems with which
  exchanging CIPSO labels makes sense.  For unlabeled packets, a default
  label will be applied to the mbuf as it comes in, but it is expected
  that many (most?) packets will already be labeled using CIPSO.  As the
  packet enters the IP stack (ip_input()), CIPSO would be processed and
  the mbuf label of the packet updated from the interface value to the
  value extracted from CIPSO.  If we're using IPFW to process the packet
  based on the CIPSO label, ordering here doesn't matter, but if we're
  using IPFW to process the mbuf label, we'll need to process CIPSO before
  IPFW on the input path.  Multi-level interfaces might also have policy
  about the label ranges for CIPSO that they were willing to accept --
  i.e., hierarchal A-M is permitted from fxp0, but don't permit CIPSO
  labels in the N-Z range from that interface.  This might permit a host
  to sit between two multi-level networks and gate appropriately. 

- In addition, IPsec tunnel mode might play a role: as part of IPsec
  negotiation of IPsec tunnels, a virtual interface is assigned to the
  tunnel.  Ioctls can be used to set labels on those virtual interfaces,
  or to enable CIPSO processing.  This is handled the same as the previous
  two cases, only IPsec provides some assurance that the CIPSO label is
  generated by the intended host.

- IPsec transport mode might also be interesting, although I have not yet
  thought about it much.  My guess is that we'd assign labels based on the
  SA, but since I think IP options are not covered by AH, we might not be
  able to use CIPSO with it.  Not sure yet, but it's worth exploring.

> > avoid modifying packets without CIPSO (such as those popping out of an
> > IPsec tunnel with an assigned label) in order to allow them to be
> > processed.  That doesn't mean we shouldn't also support filtering based on
> > CIPSO, but this route might be simpler.
> So there would be no packet modifications, because ipfw didn't deal with
> mbuf of the packet. It would not assign any label on mbuf. It would only
> check existence of CIPSO, parse it, if exists, and match the rule.
> That's my proposal.

Hmm.  I think we should try both, and see what happens.  The reason to
support mbuf labels, I think, would be for use with single-level
interfaces: rather than add CIPSO to packets that don't have it on the
input or output paths, simply use the mbuf label.

Another idea that I believe is supported by some of the Argus stuff is to
relabel packets using firewall rules: not just permit patching, but also
rules that update the label.  On an isolated system attached only to a
single-level interface, using ipfw rules to modify the specific labels on
certain packets might have utility.  For example, all traffic coming in
from the interface might (by default) get a low integrity label.  Some
traffic might be relabeled using ipfw to get a higher integrity label.
This would allow the administrator to reduce the exposure of applications
based on packet type in a mandatory way.  This has some downsides too due
to potential issues with ICMP for protocol-based rules, but for IP-based
rules it is a reasonable approach.

> > Filtering based on IP using this type of filtering sounds relatively
> > straight forward -- however, things are slightly more complex for
> > filtering based on (say) UDP port number, because UDP errors are reported
> > out of band using ICMP, making them harder to match.
> Well, maybe i'm looking at this problem in a more simple way. I think,
> that if we decide to implement such functionality, then the first step
> maybe implementing simple cipso based filter. As i understand you are
> talking about dynamic rules? I haven't looked at them yet, so can't say
> anything.

I wasn't thinking of dynamic rules, just a different approach to the ipfw
rules.

> > I'm actually running into an interesting problem involving TCP right now.
> > Currently, I don't polyinstantiate the port space, I just do access
> > control.  When a TCP response is sent to a packet, and there's an
> > associated socket, the socket's label is used for the response packet.
> You are using the label of associated socket even if it is a negative
> reply (RST)?

Actually, what I was trying to say was this: when a packet originates from
an interface, it gets the interface default label.  When it originates
from a socket, it gets the socket labl (even negative replies, right now,
although that may be wrong).  And when it originates from neither, it gets
the label of the packet it is replying to.  Arguably, in the case you
describe (RST on a port that is real), maybe it should be based on the
label of the packet it is responding to. This would, for one thing, reduce
the opportunity for a covert channel.

> > However, when there's no socket, the original query's label is used.  The
> > result is that if a port is accepting connections, but the socket is
> > labeled such that you are not permitted to talk to it, you get a
> > connection timed out.  But if you try to connect to a port that is not
> Well, then use the querys' label for outgoing packet when access is
> denied.

I'll have to look through tcp_respond() and see how easy it would be to
identify when to reject due to MAC and yet keep that label.  The current
implementation is certainly the easiest, but I think we can improve the
behavior with a bit of hacking.

> > open (unless interface rules restrict it) you get the connection refused
> > RST.  Not a huge problem but something to resolve at some point.  The good
> > news is that access control on raw sockets, UDP sockets, and TCP sockets
> > all now appears to be working correctly (I fixed a few more bugs last
> > night), and interface-based access control works correctly.  Right now,
> Cool. Today i cvsuped the rest of your commit and will try to compile
> kernel.

Make sure to set the following in loader.conf:

kern.security.mac.te.enabled="0"

You might also want to do:

kern.security.mac.enforce_network="0"
kern.security.mac.enforce_socket="0"

Right now the TE code may cause problems, otherwise.  Both Biba and MLS
seem generally to be doing the right thing, modulo being purely
hierarchal, and VFS and pipe layering being wrong.  Right now, NFS booting
can be broken due to NFS mounts using the wrong credential to open
sockets, especially on TCP.  I have patches in a local p4 tree to fix
credential handling in NFS, but it's not merged yet.  The problem is that
when the socket connect() call is done for NFS, it uses the credential of
the process that is making the NFS VFS call that results in the socket
opening.  Since TCP supports closing and reopening, this can be a big
problem if a process with the wrong MAC label is generating the VFS call. 
My patches cache the credential used to mount the file system and use that
to authorize the socket reopening, which should fix it.

I also need to add a VFS call to modify the per-fs label used for
single-level filesystems. 

> > I'm focussing a bit of time on getting a basic TE implementation working,
> > and then will move back to the network stack to integrate your CIPSO code,
> > and broaden support for access control on interfaces (support label ranges
> > not just equality tests for outgoing packets).
> So i have to read TE docs, that Tim sent me a year ago, to fresh my memory
> about that policy.

There's useful TE documentation on www.nsa.gov/selinux, and useful DTE
documentation on ftp.tislabs.com.  Right now, I'm doing pure TE, although
at some point in the future we might want to investigate doing DTE.  TE's
labeling scheme matches the current labeling we support, making it easier
to fit in.

> Happy New year to everybody! 

You too.


To Unsubscribe: send mail to majordomo at trustedbsd.org
with "unsubscribe trustedbsd-discuss" in the body of the message



More information about the trustedbsd-discuss mailing list