[redhat-lspp] [PATCH 1/2] Leveraging IPSec for MAC of Linux network communications

Joy Latten latten at austin.ibm.com
Tue Mar 21 17:00:33 UTC 2006


By means of yesterday's LSPP call, here are the ipsec-tools patches.
I am in the process of working on the policy required for nethooks to
work as well as a how-to. Will post these as soon as I am completed.

Regards,
Joy Latten
----------------------------------------------------------------------
A feature using IPSec security associations to implicitly label network
packets has been accepted into the 2.6.16 kernel. This feature
integrates IPSec with SELinux to extend SELinux's mandatory access
control support from a single system to a network of systems via network
communications. This feature will also be used for acquiring LSPP
certification. The modifications consisted of a patch to the kernel and
to the userspace ipsec-tools. 

This submission contains the modifications made to ipsec-tools.
The patch has been divided into two parts to make for quick and easier
reviewing. The first part contains the modifications made to the setkey
utility allowing for the inclusion of an access control label when
adding a security policy and/or a security association. The second part
contains the modification made to racoon to allow negotiations to
include an access control label. 

Setkey has been modified to parse the security context and use the
SADB_X_EXT_SEC_CTX extension in pfkey. Racoon has been modified to
negotiate security context as well as use the SADB_X_EXT_SEC_CTX
extension. A security context is entered as a parameter when configuring
the security policy with setkey. The security context is also entered as
a parameter when configuring security association with setkey or it is
negotiated when racoon determines security association. The initiating
racoon uses the security context associated with the policy, that was
delivered in the acquire message, for negotiating. The responding racoon
peeks into the proposal for the security context so that he can include
it as a selector to retrieve corresponding policy. When examining the
initiator and responder proposals, if security contexts are used, they
must match exactly, otherwise racoon's negotiations fail and an SA will
not be established. 

The defines, HAVE_SECCTX and SADB_X_EXT_SEC_CTX in the code contain the
changes made to ipsec-tools.

For those interested in more information about the design, the following
text was taken from Trent's write-up for kernel submission.

This patch series implements per packet access control 
        via the extension of the Linux Security Modules (LSM) 
        interface by hooks in the XFRM and pfkey subsystems that
        leverage IPSec security associations to label packets. 
        Extensions to the SELinux LSM are included that leverage 
        the patch for this purpose.
        
        This kernel patch implements the changes necessary to 
        the XFRM subsystem, pfkey interface, ipv4/ipv6, and 
        xfrm_user interface to restrict a socket to use only 
        authorized security associations (or no security association) 
        to send/receive network packets.

        Patch Purpose:
        The patch is designed to enable access control per 
        packets based on the strongly authenticated IPSec security
        association. Such access controls augment the existing ones
        based on network interface and IP address. The former
        are very coarse-grained, and the latter can be spoofed. By 
        using IPSec, the system can control access to remote
        hosts based on cryptographic keys generated using the IPSec
        mechanism. This enables access control on a per-machine 
        basis or per-application if the remote machine is running 
        the same mechanism and trusted to enforce the access 
        control policy.

        Patch design approach:
        
        The overall approach is that policy (xfrm_policy) entries 
        set by user-level programs (e.g., setkey for ipsec-tools) 
        are extended with a security context that is used at policy
        selection time in the XFRM subsystem to restrict the sockets
        that can send/receive packets via security associations
        (xfrm_states) that are built from those policies.  
        
        A presentation available at
      
www.selinux-symposium.org/2005/presentations/session2/2-3-jaeger.pdf
        from the SELinux symposium describes the overall approach.
        
        Patch implementation details: 
        On output, the policy retrieved (via xfrm_policy_lookup
        or xfrm_sk_policy_lookup) must be authorized for the 
        security context of the socket and the same security 
        context is required for resultant security association
        (retrieved or negotiated via racoon in ipsec-tools).  
        This is enforced in xfrm_state_find. On input, the policy
        retrieved must also be authorized for the socket
        (at __xfrm_policy_check), and the security context of
        the policy must also match the security association 
        being used.
        
        The patch has virtually no impact on packets that do not 
        use IPSec. The existing Netfilter (outgoing) and 
        LSM rcv_skb hooks are used as before.
        
        Also, if IPSec is used without security contexts, the 
        impact is minimal. The LSM must allow such policies to be
        selected for the combination of socket and remote machine, 
        but subsequent IPSec processing proceeds as in the original
        case.
        
        Testing:
        The pfkey interface is tested using the ipsec-tools.
        Ipsec-tools have been modified that supports assignment of
        xfrm_policy entries and security associations with security
        contexts via setkey and the negotiation using the security
        contexts via racoon.

Regards,
Joy Latten

------------------------------------------------------------------------

diff -urpN ipsec-tools-0.6.5.orig/configure.ac
ipsec-tools-0.6.5.p1/configure.ac
--- ipsec-tools-0.6.5.orig/configure.ac	2006-03-02 12:15:22.000000000
-0600
+++ ipsec-tools-0.6.5.p1/configure.ac	2006-03-02 14:43:59.000000000
-0600
@@ -588,6 +588,41 @@ AC_CHECK_TYPE([ipsec_policy_t], 
 	      	#include <netinet6/ipsec.h>
 	      ])
 
+# Check if kernel support is available for Security Context, defaults
to no.
+kernel_secctx="no"
+
+AC_MSG_CHECKING(kernel Security Context support)
+case $host_os in
+linux*)
+# Linux kernel Security Context check
+AC_EGREP_CPP(yes,
+[#include <linux/pfkeyv2.h>
+#ifdef SADB_X_EXT_SEC_CTX
+yes
+#endif
+], [kernel_secctx="yes"])
+	;;
+esac
+AC_MSG_RESULT($kernel_secctx)
+
+AC_MSG_CHECKING(whether to support Security Context)
+AC_ARG_ENABLE(security-context,
+	[  --enable-security-context    enable Security
Context(yes/no/kernel)],
+	[if test "$enable_security-context" = "kernel"; then
+		enable_security_context=$kernel_secctx; fi],
+	[enable_security_context=$kernel_secctx])
+AC_MSG_RESULT($enable_security_context)
+
+if test "$enable_security_context" = "yes"; then
+	if test "$kernel_secctx" = "no" ; then
+		AC_MSG_ERROR([Security Context requested, but no kernel support!
Aborting.])
+	else
+		AC_DEFINE([HAVE_SECCTX], [], [Enable Security Context])
+		SECCTX_OBJS="security.o"
+		AC_SUBST(SECCTX_OBJS)
+	fi
+fi
+
 CFLAGS="$CFLAGS $CFLAGS_ADD"
 CPPFLAGS="$CPPFLAGS $CPPFLAGS_ADD"
 
diff -urpN ipsec-tools-0.6.5.orig/src/libipsec/pfkey.c
ipsec-tools-0.6.5.p1/src/libipsec/pfkey.c
--- ipsec-tools-0.6.5.orig/src/libipsec/pfkey.c	2006-03-02
12:15:22.000000000 -0600
+++ ipsec-tools-0.6.5.p1/src/libipsec/pfkey.c	2006-03-02
15:03:10.000000000 -0600
@@ -1969,6 +1969,9 @@ pfkey_align(msg, mhp)
 #ifdef SADB_X_EXT_PACKET
 		case SADB_X_EXT_PACKET:
 #endif
+#ifdef SADB_X_EXT_SEC_CTX
+		case SADB_X_EXT_SEC_CTX:
+#endif
 
 			mhp[ext->sadb_ext_type] = (void *)ext;
 			break;
diff -urpN ipsec-tools-0.6.5.orig/src/libipsec/pfkey_dump.c
ipsec-tools-0.6.5.p1/src/libipsec/pfkey_dump.c
--- ipsec-tools-0.6.5.orig/src/libipsec/pfkey_dump.c	2006-03-02
12:15:22.000000000 -0600
+++ ipsec-tools-0.6.5.p1/src/libipsec/pfkey_dump.c	2006-03-02
14:45:44.000000000 -0600
@@ -243,6 +243,9 @@ pfkey_sadump1(m, withports)
 	struct sadb_ident *m_sid, *m_did;
 	struct sadb_sens *m_sens;
 #endif
+#ifdef SADB_X_EXT_SEC_CTX
+	struct sadb_x_sec_ctx *m_sec_ctx;
+#endif
 #ifdef SADB_X_EXT_NAT_T_TYPE
 	struct sadb_x_nat_t_type *natt_type;
 	struct sadb_x_nat_t_port *natt_sport, *natt_dport;
@@ -279,6 +282,9 @@ pfkey_sadump1(m, withports)
 	m_did = (void *)mhp[SADB_EXT_IDENTITY_DST];
 	m_sens = (void *)mhp[SADB_EXT_SENSITIVITY];
 #endif
+#ifdef SADB_X_EXT_SEC_CTX
+	m_sec_ctx = (struct sadb_x_sec_ctx *)mhp[SADB_X_EXT_SEC_CTX];
+#endif
 #ifdef SADB_X_EXT_NAT_T_TYPE
 	natt_type = (void *)mhp[SADB_X_EXT_NAT_T_TYPE];
 	natt_sport = (void *)mhp[SADB_X_EXT_NAT_T_SPORT];
@@ -433,6 +439,19 @@ pfkey_sadump1(m, withports)
 			0 : m_lfts->sadb_lifetime_allocations));
 	}
 
+#ifdef SADB_X_EXT_SEC_CTX
+	if (m_sec_ctx != NULL) {
+		printf("\tsecurity context doi: %u\n",
+					m_sec_ctx->sadb_x_ctx_doi);
+		printf("\tsecurity context algorithm: %u\n",
+					m_sec_ctx->sadb_x_ctx_alg);
+		printf("\tsecurity context length: %u\n",
+					m_sec_ctx->sadb_x_ctx_len);
+		printf("\tsecurity context: %s\n",
+			(char *)m_sec_ctx + sizeof(struct sadb_x_sec_ctx));
+	}
+#endif
+
 	printf("\tsadb_seq=%lu pid=%lu ",
 		(u_long)m->sadb_msg_seq,
 		(u_long)m->sadb_msg_pid);
@@ -470,6 +489,9 @@ pfkey_spdump1(m, withports)
 #endif
 	struct sadb_x_policy *m_xpl;
 	struct sadb_lifetime *m_lftc = NULL, *m_lfth = NULL;
+#ifdef SADB_X_EXT_SEC_CTX
+	struct sadb_x_sec_ctx *m_sec_ctx;
+#endif
 	struct sockaddr *sa;
 	u_int16_t sport = 0, dport = 0;
 
@@ -492,6 +514,9 @@ pfkey_spdump1(m, withports)
 	m_lftc = (void *)mhp[SADB_EXT_LIFETIME_CURRENT];
 	m_lfth = (void *)mhp[SADB_EXT_LIFETIME_HARD];
 
+#ifdef SADB_X_EXT_SEC_CTX
+	m_sec_ctx = (struct sadb_x_sec_ctx *)mhp[SADB_X_EXT_SEC_CTX];
+#endif
 #ifdef __linux__
 	/* *bsd indicates per-socket policies by omiting src and dst 
 	 * extensions. Linux always includes them, but we can catch it
@@ -596,6 +621,18 @@ pfkey_spdump1(m, withports)
 			(u_long)m_lfth->sadb_lifetime_usetime);
 	}
 
+#ifdef SADB_X_EXT_SEC_CTX
+	if (m_sec_ctx != NULL) {
+		printf("\tsecurity context doi: %u\n",
+					m_sec_ctx->sadb_x_ctx_doi);
+		printf("\tsecurity context algorithm: %u\n",
+					m_sec_ctx->sadb_x_ctx_alg);
+		printf("\tsecurity context length: %u\n",
+					m_sec_ctx->sadb_x_ctx_len);
+		printf("\tsecurity context: %s\n",
+			(char *)m_sec_ctx + sizeof(struct sadb_x_sec_ctx));
+	}
+#endif
 
 	printf("\tspid=%ld seq=%ld pid=%ld\n",
 		(u_long)m_xpl->sadb_x_policy_id,
diff -urpN ipsec-tools-0.6.5.orig/src/setkey/parse.y
ipsec-tools-0.6.5.p1/src/setkey/parse.y
--- ipsec-tools-0.6.5.orig/src/setkey/parse.y	2006-03-02
12:15:22.000000000 -0600
+++ ipsec-tools-0.6.5.p1/src/setkey/parse.y	2006-03-02
14:47:06.000000000 -0600
@@ -78,6 +78,15 @@ const char *p_key_auth;
 time_t p_lt_hard, p_lt_soft;
 size_t p_lb_hard, p_lb_soft;
 
+struct security_ctx {
+        __u8 doi;
+        __u8 alg;
+        __u16 len;
+        char *buf;
+};
+
+struct security_ctx sec_ctx;
+
 static u_int p_natt_type;
 static struct addrinfo * p_natt_oa = NULL;
 
@@ -124,6 +133,7 @@ static int setkeymsg_add __P((unsigned i
 %token F_POLICY PL_REQUESTS
 %token F_AIFLAGS
 %token TAGGED
+%token SECURITY_CTX
 
 %type <num> prefix protocol_spec upper_spec
 %type <num> ALG_ENC ALG_ENC_DESDERIV ALG_ENC_DES32IV ALG_ENC_OLD
ALG_ENC_NOKEY
@@ -533,12 +543,18 @@ extension
 	|	F_LIFETIME_SOFT DECSTRING { p_lt_soft = $2; }
 	|	F_LIFEBYTE_HARD DECSTRING { p_lb_hard = $2; }
 	|	F_LIFEBYTE_SOFT DECSTRING { p_lb_soft = $2; }
+	|       SECURITY_CTX DECSTRING DECSTRING QUOTEDSTRING {
+		sec_ctx.doi = $2;
+		sec_ctx.alg = $3;
+		sec_ctx.len = $4.len+1;
+		sec_ctx.buf = $4.buf;
+	}
 	;
 
 	/* definition about command for SPD management */
 	/* spdadd */
 spdadd_command
-	:	SPDADD ipaddropts STRING prefix portstr STRING prefix portstr
upper_spec upper_misc_spec policy_spec EOT
+	:	SPDADD ipaddropts STRING prefix portstr STRING prefix portstr
upper_spec upper_misc_spec context_spec policy_spec EOT
 		{
 			int status;
 			struct addrinfo *src, *dst;
@@ -570,7 +586,7 @@ spdadd_command
 				return -1;
 			}
 
-			status = setkeymsg_spdaddr(SADB_X_SPDADD, $9, &$11,
+			status = setkeymsg_spdaddr(SADB_X_SPDADD, $9, &$12,
 			    src, $4, dst, $7);
 			freeaddrinfo(src);
 			freeaddrinfo(dst);
@@ -589,7 +605,7 @@ spdadd_command
 	;
 
 spddelete_command
-	:	SPDDELETE ipaddropts STRING prefix portstr STRING prefix portstr
upper_spec upper_misc_spec policy_spec EOT
+	:	SPDDELETE ipaddropts STRING prefix portstr STRING prefix portstr
upper_spec upper_misc_spec context_spec policy_spec EOT
 		{
 			int status;
 			struct addrinfo *src, *dst;
@@ -617,7 +633,7 @@ spddelete_command
 				return -1;
 			}
 
-			status = setkeymsg_spdaddr(SADB_X_SPDDELETE, $9, &$11,
+			status = setkeymsg_spdaddr(SADB_X_SPDDELETE, $9, &$12,
 			    src, $4, dst, $7);
 			freeaddrinfo(src);
 			freeaddrinfo(dst);
@@ -792,6 +808,16 @@ upper_misc_spec
 		}
 	;
 
+context_spec
+	:	/* NOTHING */
+	|	SECURITY_CTX DECSTRING DECSTRING QUOTEDSTRING {
+			sec_ctx.doi = $2;
+			sec_ctx.alg = $3;
+			sec_ctx.len = $4.len+1;
+			sec_ctx.buf = $4.buf;
+		}
+	;
+
 policy_spec
 	:	F_POLICY policy_requests
 		{
@@ -939,7 +965,27 @@ setkeymsg_spdaddr(type, upper, policy, s
 
 			setvarbuf(buf, &l, (struct sadb_ext *)&m_addr,
 			    sizeof(m_addr), sa, salen);
-
+#ifdef SADB_X_EXT_SEC_CTX
+			/* Add security context label */
+			if (sec_ctx.doi) {
+				struct sadb_x_sec_ctx m_sec_ctx;
+				u_int slen = sizeof(struct sadb_x_sec_ctx);
+
+				memset(&m_sec_ctx, 0, slen);
+
+				m_sec_ctx.sadb_x_sec_len =
+				PFKEY_UNIT64(slen + PFKEY_ALIGN8(sec_ctx.len));
+
+				m_sec_ctx.sadb_x_sec_exttype = 
+					SADB_X_EXT_SEC_CTX;
+				m_sec_ctx.sadb_x_ctx_len = sec_ctx.len;/*bytes*/
+				m_sec_ctx.sadb_x_ctx_doi = sec_ctx.doi;
+				m_sec_ctx.sadb_x_ctx_alg = sec_ctx.alg;
+				setvarbuf(buf, &l, 
+					  (struct sadb_ext *)&m_sec_ctx, slen, 
+					  (caddr_t)sec_ctx.buf, sec_ctx.len);
+			}
+#endif
 			msg->sadb_msg_len = PFKEY_UNIT64(l);
 
 			sendkeymsg(buf, l);
@@ -1268,6 +1314,25 @@ setkeymsg_add(type, satype, srcs, dsts)
 		l += slen;
 	}
 
+#ifdef SADB_X_EXT_SEC_CTX
+	/* Add security context label */
+	if (sec_ctx.doi) {
+		struct sadb_x_sec_ctx m_sec_ctx;
+		u_int slen = sizeof(struct sadb_x_sec_ctx);
+
+		memset(&m_sec_ctx, 0, slen);
+
+		m_sec_ctx.sadb_x_sec_len = PFKEY_UNIT64(slen +
+					PFKEY_ALIGN8(sec_ctx.len));
+		m_sec_ctx.sadb_x_sec_exttype = SADB_X_EXT_SEC_CTX;
+		m_sec_ctx.sadb_x_ctx_len = sec_ctx.len; /* bytes */
+		m_sec_ctx.sadb_x_ctx_doi = sec_ctx.doi;
+		m_sec_ctx.sadb_x_ctx_alg = sec_ctx.alg;
+		setvarbuf(buf, &l, (struct sadb_ext *)&m_sec_ctx, slen,
+			  (caddr_t)sec_ctx.buf, sec_ctx.len); 
+	}
+#endif
+
 	len = sizeof(struct sadb_sa);
 	m_sa.sadb_sa_len = PFKEY_UNIT64(len);
 	m_sa.sadb_sa_exttype = SADB_EXT_SA;
@@ -1513,6 +1578,8 @@ parse_init()
 	p_lt_hard = p_lt_soft = 0;
 	p_lb_hard = p_lb_soft = 0;
 
+	memset(&sec_ctx, 0, sizeof(struct security_ctx));
+
 	p_aiflags = 0;
 	p_aifamily = PF_UNSPEC;
 
diff -urpN ipsec-tools-0.6.5.orig/src/setkey/setkey.8
ipsec-tools-0.6.5.p1/src/setkey/setkey.8
--- ipsec-tools-0.6.5.orig/src/setkey/setkey.8	2006-03-02
12:15:22.000000000 -0600
+++ ipsec-tools-0.6.5.p1/src/setkey/setkey.8	2006-03-02
14:46:18.000000000 -0600
@@ -218,7 +218,7 @@ on the command line achieves the same fu
 .It Xo
 .Li spdadd
 .Op Fl 46n
-.Ar src_range Ar dst_range Ar upperspec Ar policy
+.Ar src_range Ar dst_range Ar upperspec Ar label Ar policy
 .Li ;
 .Xc
 Add an SPD entry.
@@ -368,6 +368,20 @@ Specify hard/soft life time duration of 
 .It Fl bh Ar bytes
 .It Fl bs Ar bytes
 Specify hard/soft life time duration of the SA measured in bytes
transported.
+.\"
+.It Fl ctx Ar doi Ar algorithm Ar context-name
+Specify an access control label. The access control label is
interpreted 
+by the LSM (e.g., SELinux). Ultimately, it enables MAC on network 
+communications. 
+.Bl -tag -width Fl -compact
+.It Ar doi
+The domain of interpretation, which is used by the
+IKE daemon to identify the domain in which negotiation takes place. 
+.It Ar algorithm
+Indicates the LSM for which the label is generated (e.g., SELinux).
+.It Ar context-name 
+The string representation of the label that is interpreted by the LSM.
+.El
 .El
 .\"
 .Pp
@@ -488,6 +502,27 @@ to use with IPsec.
 You have to consider carefully what to use.
 .\"
 .Pp
+.It Ar label
+.Ar label 
+is the access control label for the policy. This label is interpreted
+by the LSM (e.g., SELinux). Ultimately, it enables MAC on network
+communications. When a policy contains an access control label, SAs
+negotiated with this policy will contain the label. It's format:
+.Bl -tag -width Fl -compact
+.\"
+.It Fl ctx Ar doi Ar algorithm Ar context-name
+.Bl -tag -width Fl -compact
+.It Ar doi
+The domain of interpretation, which is used by the
+IKE daemon to identify the domain in which negotiation takes place.
+.It Ar algorithm
+Indicates the LSM for which the label is generated (e.g., SELinux).
+.It Ar context-name
+The string representation of the label that is interpreted by the LSM.
+.El
+.El
+.\"
+.Pp
 .It Ar policy
 .Ar policy
 is in one of the following three formats:
@@ -796,6 +831,14 @@ spdadd 10.0.11.41/32[21] 10.0.11.33/32[a
 	-P out ipsec esp/tunnel/192.168.0.1-192.168.1.2/require ;
 
 add 10.1.10.34 10.1.10.36 tcp 0x1000 -A tcp-md5 "TCP-MD5 BGP secret" ;
+
+add 10.0.11.41 10.0.11.33 esp 0x10001
+	-ctx 1 1 "system_u:system_r:unconfined_t:SystemLow-SystemHigh"
+	-E des-cbc 0x3ffe05014819ffff;
+
+spdadd 10.0.11.41 10.0.11.33 any
+	-ctx 1 1 "system_u:system_r:unconfined_t:SystemLow-SystemHigh"
+	-P out ipsec esp/transport//require ;
 .Ed
 .\"
 .Sh SEE ALSO
diff -urpN ipsec-tools-0.6.5.orig/src/setkey/token.l
ipsec-tools-0.6.5.p1/src/setkey/token.l
--- ipsec-tools-0.6.5.orig/src/setkey/token.l	2006-03-02
12:15:22.000000000 -0600
+++ ipsec-tools-0.6.5.p1/src/setkey/token.l	2006-03-02
14:46:53.000000000 -0600
@@ -236,6 +236,7 @@ nocyclic-seq	{ return(NOCYCLICSEQ); }
 {hyphen}ls	{ return(F_LIFETIME_SOFT); }
 {hyphen}bh	{ return(F_LIFEBYTE_HARD); }
 {hyphen}bs	{ return(F_LIFEBYTE_SOFT); }
+{hyphen}ctx	{ return(SECURITY_CTX); }
 
 	/* ... */
 any		{ return(ANY); }




More information about the redhat-lspp mailing list