Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F137869382
D20967.id59909.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
32 KB
Referenced Files
None
Subscribers
None
D20967.id59909.diff
View Options
Index: sys/modules/mac_ipacl/Makefile
===================================================================
--- /dev/null
+++ sys/modules/mac_ipacl/Makefile
@@ -0,0 +1,8 @@
+# $FreeBSD$
+
+.PATH: ${SRCTOP}/sys/security/mac_ipacl
+
+KMOD=mac_ipacl
+SRCS=mac_ipacl.c
+
+.include <bsd.kmod.mk>
Index: sys/netinet/in.c
===================================================================
--- sys/netinet/in.c
+++ sys/netinet/in.c
@@ -72,6 +72,10 @@
#include <netinet/udp.h>
#include <netinet/udp_var.h>
+#ifdef MAC
+#include <security/mac/mac_framework.h>
+#endif
+
static int in_aifaddr_ioctl(u_long, caddr_t, struct ifnet *, struct thread *);
static int in_difaddr_ioctl(u_long, caddr_t, struct ifnet *, struct thread *);
@@ -372,6 +376,15 @@
/*
* See whether address already exist.
*/
+
+#ifdef MAC
+ /*Check if a MAC policy disallows setting the IPv4 address.*/
+ error = mac_inet_check_SIOCAIFADDR(td->td_ucred,
+ &addr->sin_addr, ifp);
+ if (error)
+ return (error);
+#endif
+
iaIsFirst = true;
ia = NULL;
NET_EPOCH_ENTER(et);
Index: sys/netinet6/in6.c
===================================================================
--- sys/netinet6/in6.c
+++ sys/netinet6/in6.c
@@ -112,6 +112,9 @@
#include <netinet6/in6_fib.h>
#include <netinet6/in6_pcb.h>
+#ifdef MAC
+#include <security/mac/mac_framework.h>
+#endif
/*
* struct in6_ifreq and struct ifreq must be type punnable for common members
@@ -556,7 +559,14 @@
{
struct nd_prefixctl pr0;
struct nd_prefix *pr;
-
+
+#ifdef MAC
+ /*Check if a MAC policy disallows setting the IPv6 address.*/
+ error = mac_inet6_check_SIOCAIFADDR(td->td_ucred,
+ &sa6->sin6_addr, ifp);
+ if (error)
+ goto out;
+#endif
/*
* first, make or update the interface address structure,
* and link it to the list.
Index: sys/security/mac/mac_framework.h
===================================================================
--- sys/security/mac/mac_framework.h
+++ sys/security/mac/mac_framework.h
@@ -89,6 +89,9 @@
struct vnode;
struct vop_setlabel_args;
+struct in_addr;
+struct in6_addr;
+
#include <sys/acl.h> /* XXX acl_type_t */
#include <sys/types.h> /* accmode_t */
@@ -153,6 +156,12 @@
int mac_ifnet_ioctl_set(struct ucred *cred, struct ifreq *ifr,
struct ifnet *ifp);
+/*Checks if the IP address is allowed for the interface.*/
+int mac_inet_check_SIOCAIFADDR(struct ucred *cred,
+ const struct in_addr *ia, struct ifnet *ifp);
+int mac_inet6_check_SIOCAIFADDR(struct ucred *cred,
+ const struct in6_addr *ia6, struct ifnet *ifp);
+
int mac_inpcb_check_deliver(struct inpcb *inp, struct mbuf *m);
int mac_inpcb_check_visible(struct ucred *cred, struct inpcb *inp);
void mac_inpcb_create(struct socket *so, struct inpcb *inp);
Index: sys/security/mac/mac_inet.c
===================================================================
--- sys/security/mac/mac_inet.c
+++ sys/security/mac/mac_inet.c
@@ -108,6 +108,18 @@
return (0);
}
+
+/* Check with rules in module if the IPv4 address is allowed.*/
+int
+mac_inet_check_SIOCAIFADDR(struct ucred *cred, const struct in_addr *ia,
+ struct ifnet *ifp)
+{
+ int error;
+
+ MAC_POLICY_CHECK(ip4_check_jail, cred, ia, ifp);
+ return (error);
+}
+
static struct label *
mac_ipq_label_alloc(int flag)
{
Index: sys/security/mac/mac_inet6.c
===================================================================
--- sys/security/mac/mac_inet6.c
+++ sys/security/mac/mac_inet6.c
@@ -173,6 +173,16 @@
q6->ip6q_label);
}
+/* Check with rules in module if the IPv4 address is allowed.*/
+int
+mac_inet6_check_SIOCAIFADDR(struct ucred *cred, const struct in6_addr *ia6,
+ struct ifnet *ifp)
+{
+ int error;
+
+ MAC_POLICY_CHECK(ip6_check_jail, cred, ia6, ifp);
+ return (error);
+}
void
mac_netinet6_nd6_send(struct ifnet *ifp, struct mbuf *m)
{
Index: sys/security/mac/mac_policy.h
===================================================================
--- sys/security/mac/mac_policy.h
+++ sys/security/mac/mac_policy.h
@@ -100,6 +100,9 @@
struct vattr;
struct vnode;
+struct in_addr;
+struct in6_addr;
+
/*
* Policy module operations.
*/
@@ -238,6 +241,12 @@
typedef void (*mpo_ip6q_update_t)(struct mbuf *m, struct label *mlabel,
struct ip6q *q6, struct label *q6label);
+/* Policy ops checking IPv4 and IPv6 address for ipacl.*/
+typedef int (*mpo_ip4_check_jail_t)(struct ucred *cred,
+ const struct in_addr *ia, struct ifnet *ifp);
+typedef int (*mpo_ip6_check_jail_t)(struct ucred *cred,
+ const struct in6_addr *ia6, struct ifnet *ifp);
+
typedef void (*mpo_ipq_create_t)(struct mbuf *m, struct label *mlabel,
struct ipq *q, struct label *qlabel);
typedef void (*mpo_ipq_destroy_label_t)(struct label *label);
@@ -746,6 +755,9 @@
mpo_inpcb_destroy_label_t mpo_inpcb_destroy_label;
mpo_inpcb_init_label_t mpo_inpcb_init_label;
mpo_inpcb_sosetlabel_t mpo_inpcb_sosetlabel;
+
+ mpo_ip4_check_jail_t mpo_ip4_check_jail;
+ mpo_ip6_check_jail_t mpo_ip6_check_jail;
mpo_ip6q_create_t mpo_ip6q_create;
mpo_ip6q_destroy_label_t mpo_ip6q_destroy_label;
Index: sys/security/mac_ipacl/Makefile
===================================================================
--- /dev/null
+++ sys/security/mac_ipacl/Makefile
@@ -0,0 +1,4 @@
+KMOD=mac_ipacl
+SRCS=mac_ipacl.c
+
+.include <bsd.kmod.mk>
Index: sys/security/mac_ipacl/design_notes.txt
===================================================================
--- /dev/null
+++ sys/security/mac_ipacl/design_notes.txt
@@ -0,0 +1,72 @@
+"Simplicity is the ultimate sophistication"
+------------------------
+|mac_ipacl Design Notes|
+------------------------
+
+Design Goals -
+------------
+1. Do we need to check the addresses per interface per vnet-jail or addresses per
+ vnet-jail?
+
+ The first one gives more flexibilty but increases complexity of policy table.
+ The first is more prefered over the second since it gives ability to restrict
+ the particular interface of a jail.
+
+2. Another question which increses complexity here is- Should jails be allowed to
+ create new interface(intefaces created after the policy has been loaded? and,
+ if yes, then how our module will react to the new interface?
+
+ I am not sure about this one. But the new interfaces shall not affect the host
+ until and unless they are connected to the host or other jail. So, they don't
+ have any effect but this issue should be dealt to prevent any design flaw/bugs.
+
+ New interfaces, by default, should not have any rights to set the IP address,
+ new rules(about the new interface) have to be applied by the host to provide
+ those rights.
+
+3. Another important step is to decide whether to allow all IP addresses or reject
+ all IP address when the MAC module is loaded?
+
+ I'm thinking to allow all address when the module is loaded and then tune it with
+ a sysctl variable to disallow all. The host can then specify IP address to allow
+ according to the Policy Table.
+
+4. The "Policy Table" may take-
+ a.) JID(or name of the jail) - the jail id/name for the jail for which the
+ restriction are to be applied, This identifies that jail.
+ b.) Network Interface - The network interface which are allowed to set the IP
+ address and/or which are not?
+ OR we can say, name of the interfaces that are allowed for setting their IP
+ c.) IP address/list of IP address which are allowed for particular interface.
+ d.) Network Prefix(A range of IP address) that is allowed to the jail.
+ e.) label to allow/reject? But depend on whether we started with all IP or NO IP.
+ f.) ?
+
+5. In policy, we may check the jail by passing the credential and where the thread is
+ and also if the thread's vnet and intefaces matches.
+
+6. How to name the jail in the policy?
+
+ I am thinking of using jid to name the jail in the policy. But another question
+ arises is how to find that jail with that jid. Search for the function that find
+ your prison with given jid. check prison_find(int jid), this will solve this problem
+
+7. should we also check for subnet the jail is choosing? If yes, then we also have to pass
+ the prefix to the framework.
+
+Points
+(To be kept in mind) -
+--------------------
+1. ioctl check calls should be kept generic. Although, currently we are only interested
+ in VIMAGE JAILS, but in future might need to extend the MAC module to host system,
+ et cetera.
+ So, the MAC calls should run for all cases, and checks related to jails and VNET
+ should be handled later in the Policy Module
+
+3. vnet should be checked from socket or interface and not from the thread. This means
+ we'd probably have to pass one of those in the policy as well.
+
+ Passing the interface ifnet to the policy will be more easy/appropriate, since only
+ it is available as arguement in in.c(in_aifaddr_ioctl) for our MAC checks. Alternatively
+ we could have moved our check to in_control() for ipv4 case like we have in IPv6 case,
+ for checking the vnet from socket.
Index: sys/security/mac_ipacl/mac_ipacl.c
===================================================================
--- /dev/null
+++ sys/security/mac_ipacl/mac_ipacl.c
@@ -0,0 +1,409 @@
+/* MAC policy module for limiting IP address to a VNET enabled jail. */
+
+#include <sys/param.h>
+#include <sys/module.h>
+#include <sys/errno.h>
+#include <sys/kernel.h>
+#include <sys/mutex.h>
+#include <sys/priv.h>
+#include <sys/queue.h>
+#include <sys/socket.h>
+#include <sys/sysctl.h>
+#include <sys/systm.h>
+#include <sys/types.h>
+#include <sys/ucred.h>
+#include <sys/jail.h>
+
+#include <net/if.h>
+#include <net/if_var.h>
+
+#include <netinet/in.h>
+#include <netinet6/scope6_var.h>
+
+#include <security/mac/mac_policy.h>
+
+SYSCTL_DECL(_security_mac);
+
+static SYSCTL_NODE(_security_mac, OID_AUTO, ipacl, CTLFLAG_RW, 0,
+ "TrustedBSD mac_ipacl policy controls");
+
+//#ifdef INET
+static int ipacl_ipv4 = 1;
+SYSCTL_INT(_security_mac_ipacl, OID_AUTO, ipv4, CTLFLAG_RWTUN,
+ &ipacl_ipv4, 0, "Enforce mac_ipacl for IPv4 addresses");
+//#endif
+
+//#ifdef INET6
+static int ipacl_ipv6 = 1;
+SYSCTL_INT(_security_mac_ipacl, OID_AUTO, ipv6, CTLFLAG_RWTUN,
+ &ipacl_ipv6, 0, "Enforce mac_ipacl for IPv6 addresses");
+//#endif
+
+static MALLOC_DEFINE(M_IPACL, "ipacl_rule", "Rules for mac_ipacl");
+
+#define MAC_RULE_STRING_LEN 1024
+
+struct ipacl_addr {
+ union {
+ struct in_addr ipv4;
+ struct in6_addr ipv6;
+ u_int8_t addr8[16];
+ u_int16_t addr16[8];
+ u_int32_t addr32[4];
+ } ipa; /* 128 bit address*/
+#define v4 ipa.ipv4
+#define v6 ipa.ipv6
+#define addr8 ipa.addr8
+#define addr16 ipa.addr16
+#define addr32 ipa.addr32
+};
+
+struct ip_rule {
+ int jid;
+ bool allow;
+ bool subnet_apply; /*rule applied on whole subnet*/
+ char if_name[IFNAMSIZ]; /*network interface name*/
+ int af; /*address family*/
+ struct ipacl_addr addr;
+ struct ipacl_addr mask;
+ TAILQ_ENTRY(ip_rule) r_entries;
+};
+
+static struct mtx rule_mtx;
+static TAILQ_HEAD(rulehead, ip_rule) rule_head;
+static char rule_string[MAC_RULE_STRING_LEN];
+
+static void
+destroy_rules(struct rulehead *head)
+{
+ struct ip_rule *rule;
+
+ while ((rule = TAILQ_FIRST(head)) != NULL) {
+ TAILQ_REMOVE(head, rule, r_entries);
+ free(rule, M_IPACL);
+ }
+}
+
+static void
+ipacl_init(struct mac_policy_conf *conf)
+{
+
+ mtx_init(&rule_mtx, "rule_mtx", NULL, MTX_DEF);
+ TAILQ_INIT(&rule_head);
+}
+
+static void
+ipacl_destroy(struct mac_policy_conf *conf)
+{
+
+ mtx_destroy(&rule_mtx);
+ destroy_rules(&rule_head);
+}
+
+/*
+ * Note: parsing routines are destructive on the passed string.
+ */
+static int
+parse_rule_element(char *element, struct ip_rule **rule)
+{
+ char *jid, *allow, *if_name, *fam, *ip_addr, *mask, *p;
+ struct ip_rule *new;
+ int error, prefix, i;
+
+ error = 0;
+ new = malloc(sizeof(*new), M_IPACL, M_ZERO | M_WAITOK);
+ /* Should we support a jail wildcard? */
+ jid = strsep(&element, "@");
+ if (jid == NULL) {
+ error = EINVAL;
+ goto out;
+ }
+ new->jid = strtol(jid, &p, 10);
+ if (*p != '\0') {
+ error = EINVAL;
+ goto out;
+ }
+ allow = strsep(&element, "@");
+ if (allow == NULL) {
+ error = EINVAL;
+ goto out;
+ }
+ new->allow = strtol(allow, &p, 10);
+ if (*p != '\0') {
+ error = EINVAL;
+ goto out;
+ }
+ if_name = strsep(&element, "@");
+ if (sizeof(if_name) > IFNAMSIZ) {
+ error = EINVAL;
+ goto out;
+ }
+ /* Empty interface name is wildcard to all interfaces.*/
+ bzero(new->if_name, IFNAMSIZ);
+ bcopy(if_name, new->if_name, strlen(if_name));
+ fam = strsep(&element, "@");
+ if (fam == NULL) {
+ error = EINVAL;
+ goto out;
+ }
+ new->af = (strcmp(fam, "AF_INET") == 0) ? AF_INET :
+ (strcmp(fam, "AF_INET6") == 0) ? AF_INET6 : -1;
+ if (new->af == -1) {
+ error = EINVAL;
+ goto out;
+ }
+ ip_addr = strsep(&element, "@");
+ if (ip_addr == NULL) {
+ error = EINVAL;
+ goto out;
+ }
+ if (inet_pton(new->af, ip_addr, new->addr.addr32) != 1) {
+ error = EINVAL;
+ goto out;
+ }
+ mask = element;
+ if (mask == NULL) {
+ error = EINVAL;
+ goto out;
+ }
+ prefix = strtol(mask, &p, 10);
+ if (*p != '\0') {
+ error = EINVAL;
+ goto out;
+ }
+ /*Value -1 for prefix make policy applicable to individual IP only.*/
+ if (prefix == -1)
+ new->subnet_apply = false;
+ else {
+ new->subnet_apply = true;
+ if (new->af == AF_INET) {
+ if (prefix < 0 || prefix > 32) {
+ error = EINVAL;
+ goto out;
+ }
+ if (prefix == 0)
+ new->mask.addr32[0] = htonl(0);
+ else
+ new->mask.addr32[0] =
+ htonl(~((1 << (32 - prefix)) - 1));
+ new->addr.addr32[0] &= new->mask.addr32[0];
+ }
+ else {
+ if (prefix < 0 || prefix > 128) {
+ error = EINVAL;
+ goto out;
+ }
+ for (i = 0; prefix > 0; prefix -= 8, i++)
+ new->mask.addr8[i] =
+ prefix >= 8 ? 0xFF :
+ (u_int8_t)((0xFFU << (8 - prefix)) & 0xFFU);
+ for (i=0; i<16; i++)
+ new->addr.addr8[i] &= new->mask.addr8[i];
+ }
+ }
+out:
+ if (error != 0) {
+ free(new, M_IPACL);
+ *rule = NULL;
+ } else
+ *rule = new;
+ return (error);
+}
+
+/*
+ * Format of Rule- jid@allow@interface_name@addr_family@ip_addr@subnet_mask
+ * Example: sysctl security.mac.ipacl.rules=1@1@epair0b@AF_INET@192.0.2.2@24
+ */
+static int
+parse_rules(char *string, struct rulehead *head)
+{
+ struct ip_rule *new;
+ char *element;
+ int error;
+
+ error = 0;
+ while ((element = strsep(&string, ",")) != NULL) {
+ if (strlen(element) == 0)
+ continue;
+ error = parse_rule_element(element, &new);
+ if (error)
+ goto out;
+ TAILQ_INSERT_TAIL(head, new, r_entries);
+ }
+out:
+ if (error != 0)
+ destroy_rules(head);
+ return (error);
+}
+
+static int
+sysctl_rules(SYSCTL_HANDLER_ARGS)
+{
+ char *string, *copy_string, *new_string;
+ struct rulehead head, save_head;
+ int error;
+
+ new_string = NULL;
+ if (req->newptr != NULL) {
+ new_string = malloc(MAC_RULE_STRING_LEN, M_IPACL,
+ M_WAITOK | M_ZERO);
+ mtx_lock(&rule_mtx);
+ strcpy(new_string, rule_string);
+ mtx_unlock(&rule_mtx);
+ string = new_string;
+ } else
+ string = rule_string;
+
+ error = sysctl_handle_string(oidp, string, MAC_RULE_STRING_LEN, req);
+ if (error)
+ goto out;
+
+ if (req->newptr != NULL) {
+ copy_string = strdup(string, M_IPACL);
+ TAILQ_INIT(&head);
+ error = parse_rules(copy_string, &head);
+ free(copy_string, M_IPACL);
+ if (error)
+ goto out;
+
+ TAILQ_INIT(&save_head);
+ mtx_lock(&rule_mtx);
+ TAILQ_CONCAT(&save_head, &rule_head, r_entries);
+ TAILQ_CONCAT(&rule_head, &head, r_entries);
+ strcpy(rule_string, string);
+ mtx_unlock(&rule_mtx);
+ destroy_rules(&save_head);
+ }
+out:
+ if (new_string != NULL)
+ free(new_string, M_IPACL);
+ return (error);
+}
+SYSCTL_PROC(_security_mac_ipacl, OID_AUTO, rules,
+ CTLTYPE_STRING|CTLFLAG_RW, 0, 0, sysctl_rules, "A", "IP ACL Rules");
+
+static int
+rules_check(struct ucred *cred,
+ struct ipacl_addr *ip_addr, struct ifnet *ifp)
+{
+ struct ip_rule *rule;
+ int error, i;
+ bool same_subnet;
+ error = EPERM;
+
+ mtx_lock(&rule_mtx);
+
+ for (rule = TAILQ_FIRST(&rule_head);
+ rule != NULL;
+ rule = TAILQ_NEXT(rule, r_entries)) {
+
+ /*Skip if current rule applies to different jail.*/
+ if (cred->cr_prison->pr_id != rule->jid)
+ continue;
+
+ if (strcmp(rule->if_name, "\0") &&
+ strcmp(rule->if_name, ifp->if_xname))
+ continue;
+
+ switch (rule->af) {
+ case AF_INET:
+ if (rule->subnet_apply) {
+ if (rule->addr.v4.s_addr !=
+ (ip_addr->v4.s_addr &
+ rule->mask.v4.s_addr))
+ continue;
+ }
+ else
+ if (ip_addr->v4.s_addr !=
+ rule->addr.v4.s_addr)
+ continue;
+ break;
+ case AF_INET6:
+ if (rule->subnet_apply) {
+ same_subnet=true;
+ for ( i=0 ; i<16 ; i++ )
+ if (rule->addr.v6.s6_addr[i] !=
+ (ip_addr->v6.s6_addr[i] &
+ rule->mask.v6.s6_addr[i])) {
+ same_subnet=false;
+ break;
+ }
+ if (!same_subnet)
+ continue;
+ }
+ else
+ if (bcmp(&rule->addr, ip_addr,
+ sizeof(*ip_addr)))
+ continue;
+ break;
+ default:
+ error = EINVAL;
+ }
+
+ if (rule->allow)
+ error = 0;
+ else
+ error = EPERM;
+ }
+
+ mtx_unlock(&rule_mtx);
+
+ return (error);
+}
+
+/* Feature request: Can we make this a sysctl policy as well defaulting
+ * to jails only, but if changed also applying to the base system?
+ */
+static int
+ipacl_ip4_check_jail(struct ucred *cred,
+ const struct in_addr *ia, struct ifnet *ifp)
+{
+ struct ipacl_addr ip4_addr;
+
+ ip4_addr.v4 = *ia;
+
+ /*function only when requested by a jail*/
+ if (!jailed(cred))
+ return 0;
+
+ /*check with the policy only when it is enforced for ipv4*/
+ if (ipacl_ipv4)
+ return rules_check(cred, &ip4_addr, ifp);
+
+ return 0;
+}
+
+static int
+ipacl_ip6_check_jail(struct ucred *cred,
+ const struct in6_addr *ia6, struct ifnet *ifp)
+{
+ struct ipacl_addr ip6_addr;
+
+ ip6_addr.v6 = *ia6; /*make copy to not alter the original*/
+ in6_clearscope(&ip6_addr.v6);/* clear scope id*/
+
+ /*function only when requested by a jail*/
+ if (!jailed(cred))
+ return 0;
+
+ /*check with the policy when it is enforced for ipv6*/
+ if (ipacl_ipv6)
+ return rules_check(cred, &ip6_addr, ifp);
+
+ return 0;
+}
+
+static struct mac_policy_ops ipacl_ops =
+{
+ .mpo_init = ipacl_init,
+ .mpo_destroy = ipacl_destroy,
+//#ifdef INET
+ .mpo_ip4_check_jail = ipacl_ip4_check_jail,
+//#endif
+//#ifdef INET6
+ .mpo_ip6_check_jail = ipacl_ip6_check_jail,
+//#endif
+};
+
+MAC_POLICY_SET(&ipacl_ops, mac_ipacl, "TrustedBSD MAC/ipacl",
+ MPC_LOADTIME_FLAG_UNLOADOK, NULL);
Index: sys/security/mac_ipacl/notes.txt
===================================================================
--- /dev/null
+++ sys/security/mac_ipacl/notes.txt
@@ -0,0 +1,90 @@
+-----------------------------------
+Documentation Notes-
+IP Address access control policy
+
+1. mac_ipacl allows the root of the host to limit the VNET jail's privileges
+ of setting IPv4 and IPv6 addresses via sysctl(8) interface. So, the host
+ can define rules for jails and their interfaces about IP addresses.
+
+2. Its default behaviour is to deny all IP addresses if policy is enforced and allow/deny
+ IP(or subnets) according to rules specified with sysctl
+
+ Runtime Configuration-sysctl(8) MIB
+
+ security.mac.ipacl.ipv4: enforce the mac_ipacl for ipv4 addresses (default:1)
+
+ security.mac.ipacl.ipv6: enforce the mac_ipacl for ipv6 addresses (default:1)
+
+ security.mac.ipacl.rules:
+ jail_id@allow@interface@address_family@IP_addr@prefix_length[,jail_id@...]
+
+ jail_id: Describe the jail id of the jail for which the rule is written
+
+ allow: 1 for allow and 0 for deny. action to perform for the rule
+
+ interface: name of the interface the rule is enforced for. Interface is
+ left empty(ie, NULL) then it is a wildcard to enforce rule
+ for all interfaces.
+
+ address_family: Address family of the IP_addr. give input as AF_INET
+ or AF_INET6 string only
+
+ IP_addr: IP address(or subnet) to be allowed/deny. Action depend on the
+ prefix length
+
+ prefix_length: Prefix length of the subnet to be enforced by the policy.
+ -1 implies the policy is enforced for individual IP address.
+ For non-negative value, a range of IP address(present in subnet)
+ which calculated as subnet = IP_addr & mask
+3. Example-
+ a.)
+ sysctl security.mac.ipacl.ipv4=1
+ sysctl security.mac.ipacl.ipv6=0
+ sysctl security.mac.ipacl.rules=1@1@@AF_INET@169.254.123.123@-1
+ It allows only 169.254.123.123 IPv4 address for all interfaces(wildcard) of jail 1.
+ It allows all IPv6 address since policy is not enforced for IPv6.
+
+ b.)
+ sysctl security.mac.ipacl.ipv4=1
+ sysctl security.mac.ipacl.ipv6=1
+ sysctl security.mac.ipacl.rules=1@1@epair0b@AF_INET6@fe80::@32,1@0@epair0b@AF_INET6@fe80::abcd@-1
+ It deny all IPv4 address as policy is enforced but no rules are specified about it.
+ It allow all IPv6 address in the subnet- fe80::/32 except fe80::abcd for interface epair0b only
+ c.)
+ sysctl security.mac.ipacl.ipv4=1
+ sysctl security.mac.ipacl.ipv6=1
+ sysctl security.mac.ipacl.rules=2@1@@AF_INET6@fc00::@7,2@0@@AF_INET6@fc00::1111:2200@120,2@1@@AF_INET6@fc00::1111:2299@-1,1@1@@AF_INET@198.51.100.0@24
+ It allow IPv4 in the subnet 198.51.100.0/24 for jail 2 and all interfaces.
+ It allow IPv6 address in the subnet fc00::/7 but deny the subnet fc00::1111:2200/120, and allow
+ individual IP fc00::1111:2299 from the denied subnet for all interfaces in the jail 2
+
+4. Using the test scripts:
+ a.)
+ Test scripts are not completely automatic :( So, the user has to create
+ edit the scripts to enter the jid of the test jails and interface.
+ After editing the scripts run make && make install, which then install
+ the scripts in /usr/tests/sys/mac/ipacl.
+ you may also need to create that directory if it gives error.
+
+6. To discuss the limitation of the module and point to be kept in mind while
+ using it.
+ a.)
+ rules are checked in the same sequence they are given. If many rules are
+ there for a IP(or a set of IP), result depend on final rule.
+ b.)
+
+7. Future Works
+ a.)
+ rules are given with sysctl interface which gets very complex to give them all in
+ command line. It has to be simplified with a better way to input those rules.
+
+
+-------------------------------------
+Commands-
+1. kld
+ * kldstat
+ * kldload /usr/obj/usr/home/shivank/freebsd/amd64.amd64/sys/security/mac_ipacl/mac_ipacl.ko
+ * kldunload mac_ipacl
+2. make
+ * make obj depend all install #create obj in /boot/modules, can be loaded and unloaded by just name
+ * make -j 4 KERNCONF=VIMAGE kernel -DKERNFAST
Index: sys/security/mac_ipacl/tests/Makefile
===================================================================
--- /dev/null
+++ sys/security/mac_ipacl/tests/Makefile
@@ -0,0 +1,16 @@
+# $FreeBSD$
+
+PACKAGE= tests
+
+TESTSDIR= ${TESTSBASE}/sys/mac/ipacl
+
+${PACKAGE}FILES+= ipacl_script.sh
+
+TAP_TESTS_SH+= ip4_test
+TAP_TESTS_SH+= ip6_test
+.for t in ${TAP_TESTS_SH}
+TEST_METADATA.$t+= required_user="root"
+TEST_METADATA.$t+= timeout="450"
+.endfor
+
+.include <bsd.test.mk>
Index: sys/security/mac_ipacl/tests/ip4_test.sh
===================================================================
--- /dev/null
+++ sys/security/mac_ipacl/tests/ip4_test.sh
@@ -0,0 +1,78 @@
+#!/bin/sh
+# $FreeBSD$
+
+dir=`dirname $0`
+. ${dir}/ipacl_script.sh
+
+echo "1..32"
+jid1=1
+jid2=3
+#run this script for epair0a and epair0b as of now
+#use ifconfig epair create to generate epair
+#epair0a = host #epair0b = jail 1
+# make sure to create second jail(jid=2) with epair1b
+
+#this script also tests that host remain unaffected in all cases
+if1_host="epair0a"
+if1_jail1="epair0b"
+if2_jail1="lo0"
+if1_jail2="epair1b"
+if2_jail2="lo0"
+
+# Verify effect of changing security.mac.ipacl.ipv4
+sysctl security.mac.ipacl.ipv4=0 >/dev/null
+exec_test ok ipv4 ${if1_host} '192.168.43.26' 16 0
+exec_test ok ipv4 ${if1_jail1} '192.168.43.26' 16 1
+exec_test ok ipv4 ${if1_host} '127.1.32.31' 24 0
+exec_test ok ipv4 ${if1_jail1} '198.18.0.12' 15 1
+
+sysctl security.mac.ipacl.ipv4=1 >/dev/null
+sysctl security.mac.ipacl.rules= >/dev/null
+
+exec_test ok ipv4 ${if1_host} '192.168.43.26' 16 0
+exec_test fl ipv4 ${if1_jail1} '192.168.43.26' 16 1
+exec_test ok ipv4 ${if1_host} '127.1.32.31' 24 0
+exec_test fl ipv4 ${if1_jail1} '198.18.0.12' 15 1
+
+# rule: jid@allow@interface_name@addr_family@ip_addr@subnet_mask
+sysctl security.mac.ipacl.rules=${jid1}@1@${if1_jail1}@AF_INET@192.168.42.2@-1,${jid2}@1@${if1_jail2}@AF_INET@127.1.32.1@-1,${jid2}@1@@AF_INET@198.18.0.1@15,${jid2}@0@@AF_INET@198.18.0.12@-1 >/dev/null
+
+# Verify if security.mac.ipacl.rules allow jail to set certain IPv4 address
+exec_test ok ipv4 ${if1_jail1} '192.168.42.2' 16 ${jid1}
+exec_test fl ipv4 ${if1_jail1} '192.168.42.3' 16 ${jid1}
+exec_test ok ipv4 ${if1_jail2} '127.1.32.1' 24 ${jid2}
+exec_test fl ipv4 ${if2_jail2} '127.1.32.1' 24 ${jid2}
+
+# Verify if scurity.mac.ipacl.rules allow jail to set any address in subnet
+exec_test ok ipv4 ${if1_jail2} '198.18.0.192' 15 ${jid2}
+exec_test ok ipv4 ${if1_jail2} '198.18.132.121' 15 ${jid2}
+exec_test fl ipv4 ${if1_jail2} '197.1.123.123' 15 ${jid2}
+exec_test fl ipv4 ${if1_jail2} '198.18.0.12' 15 ${jid2} #last rule disllow the ip in that subnet
+
+# Verify if security.mac.ipacl.rules (interface wildcard) allow jail to set certain IPv4 address
+exec_test ok ipv4 ${if2_jail2} '198.18.0.192' 15 ${jid2}
+exec_test ok ipv4 ${if2_jail2} '198.18.132.121' 15 ${jid2}
+exec_test fl ipv4 ${if2_jail2} '197.1.123.123' 15 ${jid2}
+exec_test fl ipv4 ${if2_jail2} '198.18.0.12' 15 ${jid2} #last rule disllow the ip in that subnet
+
+# Add more checks on subnet
+sysctl security.mac.ipacl.rules=${jid2}@1@@AF_INET@10.0.0.0@16,${jid2}@1@@AF_INET@10.12.0.0@16
+
+exec_test fl ipv4 ${if2_jail2} '10.1.0.0' 16 ${jid2}
+exec_test ok ipv4 ${if2_jail2} '10.0.10.10' 16 ${jid2}
+exec_test fl ipv4 ${if2_jail2} '10.13.0.0' 24 ${jid2}
+exec_test fl ipv4 ${if2_jail2} '10.11.0.10' 24 ${jid2} #last rule disllow the ip in that subnet
+
+sysctl security.mac.ipacl.rules=${jid1}@1@@AF_INET@169.254.0.0@16,${jid1}@0@@AF_INET@169.254.123.0@24,${jid1}@1@@AF_INET@169.254.123.123@-1,${jid1}@1@@AF_INET@198.51.100.0@24,${jid1}@0@@AF_INET@198.51.100.100@-1 >/dev/null
+# Add more tests from Link-Local space and Documentation(TEST-NET-3)
+exec_test ok ipv4 ${if1_jail1} '169.254.121.121' 16 ${jid1}
+exec_test fl ipv4 ${if1_jail1} '169.254.123.121' 16 ${jid1}
+exec_test ok ipv4 ${if1_jail1} '169.254.123.123' 16 ${jid1}
+exec_test fl ipv4 ${if1_jail1} '169.253.121.121' 16 ${jid1}
+
+exec_test ok ipv4 ${if2_jail1} '198.51.100.001' 24 ${jid1}
+exec_test ok ipv4 ${if2_jail1} '198.51.100.254' 24 ${jid1}
+exec_test fl ipv4 ${if1_jail1} '198.51.100.100' 24 ${jid1}
+exec_test fl ipv4 ${if1_jail1} '198.151.100.100' 24 ${jid1}
+
+sysctl security.mac.ipacl.rules= >/dev/null
Index: sys/security/mac_ipacl/tests/ip6_test.sh
===================================================================
--- /dev/null
+++ sys/security/mac_ipacl/tests/ip6_test.sh
@@ -0,0 +1,88 @@
+#!/bin/sh
+# $FreeBSD$
+
+dir=`dirname $0`
+. ${dir}/ipacl_script.sh
+
+echo "1..36"
+jid1=1
+jid2=3
+
+if1_host="epair0a"
+if1_jail1="epair0b"
+if2_jail1="lo0"
+if1_jail2="epair1b"
+if2_jail2="lo0"
+
+#run this script for epair0a and epair0b as of now
+#use ifconfig epair create to generate epair
+#epair0a = host #epair0b = jail 1
+# make sure to create second jail(jid=2) with epair1b
+
+#this script also tests that host remain unaffected in all cases
+
+# Verify effect of changing security.mac.ipacl.ipv4
+sysctl security.mac.ipacl.ipv6=0 >/dev/null
+exec_test ok ipv6 ${if1_host} '2001:db8::1111' 32 0
+exec_test ok ipv6 ${if1_jail1} '2001:db8::1112' 64 1
+exec_test ok ipv6 ${if1_host} '2001:2::abcd' 24 0
+exec_test ok ipv6 ${if1_jail1} '001:470:1e01:5ea::11' 48 1
+
+sysctl security.mac.ipacl.ipv6=1 >/dev/null
+sysctl security.mac.ipacl.rules= >/dev/null
+
+exec_test ok ipv6 ${if1_host} '2001:db8::1111' 32 0
+exec_test fl ipv6 ${if1_jail1} '2001:db8::1112' 64 1
+exec_test ok ipv6 ${if1_host} '2001:2::abcd' 24 0
+exec_test fl ipv6 ${if1_jail1} '001:470:1e01:5ea::11' 48 1
+
+# rule: jid@allow@interface_name@addr_family@ip_addr@subnet_mask
+sysctl security.mac.ipacl.rules=${jid1}@1@epair0b@AF_INET6@2001:db8::1111@-1,${jid2}@1@epair1b@AF_INET6@2001:2::1234:1234@-1,${jid2}@1@@AF_INET6@fe80::@32,${jid2}@0@@AF_INET6@fe80::abcd@-1 >/dev/null
+
+# Verify if security.mac.ipacl.rules allow jail to set certain IPv4 address
+exec_test ok ipv6 ${if1_jail1} '2001:db8::1111' 16 ${jid1}
+exec_test fl ipv6 ${if1_jail1} '2001:db8::1112' 16 ${jid1}
+exec_test ok ipv6 ${if1_jail2} '2001:2::1234:1234' 48 ${jid2}
+exec_test fl ipv6 ${if1_jail1} '2001:2::1234:1234' 48 ${jid1}
+
+# Verify if scurity.mac.ipacl.rules allow jail to set any address in subnet
+exec_test ok ipv6 ${if1_jail2} 'FE80::1101:1221' 15 ${jid2}
+exec_test ok ipv6 ${if1_jail2} 'FE80::abab' 15 ${jid2}
+exec_test ok ipv6 ${if1_jail2} 'FE80::1' 64 ${jid2}
+exec_test fl ipv6 ${if1_jail2} 'FE80::abcd' 15 ${jid2} #last rule disllow the ip in that subnet
+
+# Verify if security.mac.ipacl.rules (interface wildcard) allow jail to set certain IPv4 address
+exec_test ok ipv6 ${if2_jail2} 'FE80::1101:1221' 15 ${jid2}
+exec_test ok ipv6 ${if2_jail2} 'FE80::abab' 32 ${jid2}
+exec_test fl ipv6 ${if2_jail2} 'FE81::1' 64 ${jid2}
+exec_test fl ipv6 ${if2_jail2} 'FE80::abcd' 32 ${jid2} #last rule disllow the ip in that subnet
+
+
+# add more tests for subnet
+sysctl security.mac.ipacl.rules=${jid2}@1@@AF_INET6@2001:2::@48,${jid2}@1@@AF_INET6@2001:3::@32 >/dev/null
+exec_test fl ipv6 ${if2_jail2} '2001:2:0001::1' 64 ${jid2}
+exec_test fl ipv6 ${if2_jail2} '2001:2:1000::1' 32 ${jid2}
+exec_test ok ipv6 ${if2_jail2} '2001:3:0001::1' 64 ${jid2}
+exec_test fl ipv6 ${if2_jail2} '2001:4::1' 64 ${jid2}
+
+
+#add more tests of ULA address space
+#allow subnet fc00::/7 except subnet fc00::1111:22xx but allow fc00::1111:2281
+sysctl security.mac.ipacl.rules=${jid1}@1@@AF_INET6@fc00::@7,${jid1}@0@@AF_INET6@fc00::1111:2200@120,${jid1}@1@@AF_INET6@fc00::1111:2299@-1,${jid1}@1@@AF_INET6@2001:db8::@32,${jid1}@0@@AF_INET6@2001:db8::abcd@-1 >/dev/null
+exec_test ok ipv6 ${if1_jail1} 'fc00::0000:1234' 48 ${jid1}
+exec_test ok ipv6 ${if1_jail1} 'fc00::1112:1234' 48 ${jid1}
+exec_test fl ipv6 ${if1_jail1} 'f800::2222:2200' 48 ${jid1}
+exec_test fl ipv6 ${if1_jail1} 'f800::2222:22ff' 48 ${jid1}
+
+exec_test ok ipv6 ${if1_jail1} 'fc00::1111:2111' 64 ${jid1}
+exec_test fl ipv6 ${if1_jail1} 'fc00::1111:2211' 64 ${jid1}
+exec_test fl ipv6 ${if1_jail1} 'fc00::1111:22aa' 48 ${jid1}
+exec_test ok ipv6 ${if1_jail1} 'fc00::1111:2299' 48 ${jid1}
+
+#add more tests of documentation range IPV6
+exec_test ok ipv6 ${if1_jail1} '2001:db8:abcd:bcde:cdef:def1:ef12:f123' 32 ${jid1}
+exec_test ok ipv6 ${if1_jail1} '2001:db8:1111:2222:3333:4444:5555:6666' 32 ${jid1}
+exec_test fl ipv6 ${if1_jail1} '2000:db9:1111:2222:3333:4444:5555:6666' 32 ${jid1}
+exec_test fl ipv6 ${if2_jail1} '2001:db8::abcd' 32 ${jid1}
+
+sysctl security.mac.ipacl.rules= >/dev/null
Index: sys/security/mac_ipacl/tests/ipacl_script.sh
===================================================================
--- /dev/null
+++ sys/security/mac_ipacl/tests/ipacl_script.sh
@@ -0,0 +1,69 @@
+#!/bin/sh
+# $FreeBSD$
+
+sysctl security.mac.ipacl >/dev/null 2>&1
+if [ $? -ne 0 ]; then
+ echo "1..0 # SKIP MAC_IPACL is unavailable."
+ exit 0
+fi
+
+if [ "$(id -u)" -ne 0 ]; then
+ echo "1..0 # SKIP testcases must be run as root"
+ exit 0
+fi
+
+ntest=1
+
+test_ip() {
+ local proto interface address prefix jid
+
+ proto=${1}
+ interface=${2}
+ address=${3}
+ prefix=${4}
+ jid=${5} #if jid = 0 then assume host
+
+ if [ "${proto}" = "ipv4" ]; then
+ if [ "${jid}" -eq 0 ]; then
+ echo | ifconfig ${interface} ${address}/${prefix} up
+ RetVal=$?
+ else
+ echo | jexec ${jid} ifconfig ${interface} ${address}/${prefix} up
+ RetVal=$?
+ fi
+ elif [ "${proto}" = "ipv6" ]; then
+ if [ "${jid}" -eq 0 ]; then
+ echo | ifconfig ${interface} inet6 ${address} prefixlen ${prefix}
+ RetVal=$?
+ else
+ echo | jexec ${jid} ifconfig ${interface} inet6 ${address} prefixlen ${prefix}
+ RetVal=$?
+ fi
+ fi
+ if [ ${RetVal} -eq 0 ]; then
+ echo ok
+ else
+ echo fl
+ fi
+
+}
+
+exec_test() {
+ local expect_with_rule proto interface address prefix jid
+ expect_with_rule=${1}
+ proto=${2}
+ interface=${3}
+ address=${4}
+ prefix=${5}
+ jid=${6}
+
+ out=$(test_ip "${proto}" "${interface}" "${address}" "${prefix}" "${jid}")
+ if [ "${out}" = "${expect_with_rule}" ]; then
+ echo "ok : PASS ${ntest}"
+ elif [ "${out}" = "ok" ] || [ "${out}" = "fl" ]; then
+ echo "not ok : FAIL ${ntest} # '${out}' != '${expect_with_rule}'"
+ else
+ echo "not ok : FAIL ${ntest} # unexpected output: '${out}'"
+ fi
+ : $(( ntest += 1 ))
+}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Thu, Nov 27, 4:08 PM (6 h, 57 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
26258741
Default Alt Text
D20967.id59909.diff (32 KB)
Attached To
Mode
D20967: new MAC policy module - mac_ipacl
Attached
Detach File
Event Timeline
Log In to Comment