Saturday Mar 29, 2014

Oracle Solaris 11.1 Gets Common Criteria Certification

The Oracle Solaris 11.1 operating system achieved a Common Criteria certification on March 18, 2014 at EAL4+  under the Canadian Common Criteria Scheme (CCCS) conformant to the BSI Operating System Protection Profile v2.0 2010-06-01 with the following 4 extended packages.

  1. Advanced Management v2.0, 2010-05-28
  2. Extended identification & Authentication v2.0, 2010-05-28 
  3. Labeled Security v2.0, 2010-05-28
  4. Virtualization v2.0, 2010-05-28 

The evaluation is summarized in the list of certified products. Here is copy of the actual certificate.

This is a major accomplishment which has been over two years in the making. Oracle Solaris 11 was formally accepted into evaluation on January 31, 2012. Unlike previous Solaris evaluations, the Trusted Extensions functionality is included as a standard feature of the OS, as well as Role-Based Access Control and Solaris Zones. In addition the evaluation required FIPS evaluation of the cryptographic modules. The details are included in the Certification Report.

Wednesday Apr 10, 2013

Adding Users with OpenLDAP

In my previous blog I described how I had configured OpenLDAP with Oracle Solaris 11.1. After some more testing, I found a strange problem with useradd(1)

root# useradd -S ldap foo
ldap: operation failed.
ldap shadow database update failed for foo.
UX: useradd: ERROR: Cannot update system - login cannot be created.

Despite the error message, the account was actually created. After some debugging and with some help from my colleague Michen Chang, we found the root cause. Apparently OpenLDAP is stricter than ODSEE when interpreting INTEGER attributes, and rejects unspecified values. In particular, the attributes shadowInactive and shadowExpire in nis.schema must be specified. These correspond to the useradd option -f and -e, but I didn't want these options to be required.

An easy workaround is to set defaults for these attributes, as follows:

root# useradd -D -e 1/17/2038 -f 365 
group=staff,10  project=default,3  basedir=/export/home  
skel=/etc/skel  shell=/usr/bin/bash  inactive=365  
expire=1/19/2038  auths=  profiles=  roles=  limitpriv=  
defaultpriv=  lock_after_retries=

Now I can easily create accounts without getting that error message. The accounts will be valid until 2038 (when the 32 bit UNIX system time overflows) as long as the user logs in at least once a year.


Monday Apr 08, 2013

Getting Started with OpenLDAP

I decided to try out the OpenLDAP server that is bundled with Oracle Solaris 11.1 after reading Paul Johnson's blog entry Configuring a Basic LDAP Server + Client in Solaris 11. Paul's instructions were helpful, but he didn't explain how to configure OpenLDAP so that it could be used with the Solaris commands which accept the option:

-S files | ldap.

That option is interpreted by the following commands:

In addition, the passwd(1) command accepts -r files | ldap and the User Manager GUI has a Filter Users dialog which has radio buttons for files and ldap. All of these commands depend on LDAP schema extensions that are not configured in OpenLDAP by default. The various schema are documented in Working with Naming and Directory Services and Trusted Extensions Configuration and Administration:

I combined these into a single file called solaris.schema, and copied it into the /etc/openldap/schema directory. I also created and installed another file called automap.schema which contains just the attributes and object classes for the automount service. These are missing from the existing nis.schema file, which is apparently a subset of RFC 2307bis Network Information Service Schema.

Then I modified the configuration file /etc/openldap/slapd.conf to include the required schema, and changed the domain name to gfaden.com

a6,11
> include         /etc/openldap/schema/cosine.schema
> include         /etc/openldap/schema/inetorgperson.schema
> include         /etc/openldap/schema/nis.schema
> include         /etc/openldap/schema/solaris.schema
> include         /etc/openldap/schema/automap.schema
54,55c60,61
< suffix                "dc=my-domain,dc=com"
< rootdn                "cn=Manager,dc=my-domain,dc=com"
---
> suffix                "dc=gfaden,dc=com"
> rootdn                "cn=admin,dc=gfaden,dc=com"

Following Paul's advice, I did the following:

root# chown -R openldap:openldap /var/openldap/
root# svcadm enable ldap/server

Then I wrote two scripts and ran them to create the various containers in the directory. The following script creates empty containers corresponding to the top-level directory object and the organizational units for the object classes.

  1 #!/bin/ksh
  2 
  3 ME=gfaden
  4 LDAP_BASEDN="dc=${ME},dc=com"
  5 LDAP_ROOTDN="cn=admin,${LDAP_BASEDN}"
  6 
  7 TMP_LDIF=$(mktemp /tmp/toplevels.XXXX)
  8 
  9 ( cat << EOF
 10 dn: ${LDAP_BASEDN}
 11 objectClass: dcObject
 12 objectClass: organization
 13 o: ${ME}.com
 14 dc: ${ME}
 15 
 16 EOF
 17 )>  ${TMP_LDIF}
 18 
 19 for ou in users groups rpc protocols networks netgroup \
 20     aliases hosts services ethers projects \
 21     SolarisAuthAttr SolarisProfAttr ipTnet; do
 22 
 23     ( cat << EOF
 24 dn: ou=${ou},${LDAP_BASEDN}
 25 ou: ${ou}
 26 objectClass: top
 27 objectClass: organizationalUnit
 28 
 29 EOF
 30 )>>  ${TMP_LDIF}
 31 done
 32 
 33 ldapadd -cD ${LDAP_ROOTDN} -f ${TMP_LDIF}
 34 rm ${TMP_LDIF}
 

I'm not sure I got all the spelling right in lines 19-21, but it seems to work. There are some subtle differences between what OpenLDAP uses compared to ODSEE. I wrote a similar script to create the automap containers:


  1 #!/bin/ksh
  2 
  3 LDAP_BASEDN="dc=gfaden,dc=com"
  4 LDAP_ROOTDN="cn=admin,${LDAP_BASEDN}"
  5 
  6 TMP_LDIF=$(mktemp /tmp/automap.XXXX)
  7 
  8 for automap in auto_home auto_direct auto_master;do
  9 
 10     ( cat << EOF
 11 dn: automountMapName=${automap},${LDAP_BASEDN}
 12 automountMapName: ${automap}
 13 objectClass: top
 14 objectClass: automountMap
 15 
 16 EOF
 17 )>>  ${TMP_LDIF}
 18 done
 19 
 20 ldapadd -cD ${LDAP_ROOTDN} -f ${TMP_LDIF}
 21 rm ${TMP_LDIF}

The next step was to switch the nameservice configuration so that the host is a client of this ldap server. Since I needed to specify explicit (not anonymous) credentials, I could not use the Automatic Network Configuration Profile (NCP) that is enabled by default for Solaris GUI installations. Instead,  the DefaultFixed NCP must be enabled, and the IP networking must be configured.

root# netadm enable -p ncp DefaultFixed
root# ipadm create-ip net0
root# ipadm create-addr -T dhcp net0/v4

Then I used a modified version of Paul's ldapaddclient(1M) command to make my system an LDAP client of itself:

  1 #!/bin/ksh
  2 ldapclient manual \
  3 -a credentialLevel=proxy \
  4 -a authenticationMethod=simple \
  5 -a defaultSearchBase=dc=gfaden,dc=com \
  6 -a domainName=gfaden.com \
  7 -a defaultServerList=127.0.0.1 \
  8 -a proxyDN=cn=admin,dc=gfaden,dc=com \
  9 -a adminDN=cn=admin,dc=gfaden,dc=com \
 10 -a proxyPassword=secret \
 11 -a enableShadowUpdate=true \
 12 -a objectClassMap=shadow:shadowAccount=posixaccount \
 13 -a serviceSearchDescriptor=passwd:ou=users,dc=gfaden,dc=com \
 14 -a serviceSearchDescriptor=shadow:ou=users,dc=gfaden,dc=com \
 15 -a serviceSearchDescriptor=group:ou=groups,dc=gfaden,dc=c

Since I was doing this on my laptop, I just used localhost for the IP address (line 7). However, I needed to add the admin distinguished name (line 9), and enable shadow update (line 11). Together, these two settings allow the client to make updates without re-authenticating if it is running as root or with all privileges.

Again, following Paul's blog, I enabled DNS, and restarted the name service:

root# svccfg -s name-service/switch setprop config/host = astring: "files dns ldap"
root# svccfg  -s name-service/switch:default refresh
root# svcadm restart name-service/cache

Now I can specify the ldap option for any of the commands listed above. For example:

root# groupadd -S ldap -g 1001 world
root# ldapaddent -d group
world:*:1001:

Thursday Apr 04, 2013

New Sun Ray Software for Trusted Extensions

Oracle has announced the availability of Sun Ray Software 5.4, which fully supports Oracle Solaris 11.1 including the Trusted Extensions features. The Oracle Data Sheet for the Sun Ray Software has a summary of the supported platforms on page 3, and there's a well-documented section in the Administration Guide entitled Configuring Oracle Solaris 11 Trusted Extensions.  All the multilevel desktop features are supported including per-workspace authentication and device allocation for Pulse Audio.

Sunday Mar 31, 2013

Permissive and Restricted Policies

Recently I posted two entries about the new Extended Policy functionality in Oracle Solaris 11.1. One demonstrated how to create application sandboxes, and the other how to confine services, like MySQL. Both of these are examples of restrictive policies, whereas privileges have traditionally been used to implement permissive policies, hence the term privilege escalation. The basic functionality and terminology first appeared in Trusted Solaris in 1991, and was later adopted by AIX and HP-UX. Unfortunately, a draft of the POSIX 1.e Security Specification (withdrawn), used the term capabilities for this functionality, which was subsequently used by Linux developers. Oracle Solaris privileges do share some common terminology with Linux capabilities , including the permitted, effective, and inheritable privilege sets. But almost everything else is different.

For example, the term unprivileged doesn't apply in Oracle Solaris, since every process has at least some privileges. Instead, we use the term basic privileges to refer to the set that are traditionally granted to all UNIX processes. This set includes:

PRIV_FILE_LINK_ANY
PRIV_FILE_READ
PRIV_FILE_WRITE
PRIV_PROC_INFO
PRIV_PROC_SESSION
PRIV_NET_ACCESS
PRIV_PROC_FORK
PRIV_PROC_EXEC 

Removing some of these privileges, or enumerating the objects to which they apply is a powerful containment mechanism which I've previously described. But even normal users may choose to limit their basic privileges. For example, my .bash_profile contains the following line, which limits my view of processes on the system to just the ones I own by removing PRIV_PROC_INFO from my login shell. It makes programs like ps(1) and prstat(1) more friendly.

ppriv -s EI-proc_info $$

Another difference is that recent versions of Linux allow the setting of file capabilities in the extended attributes of executable files, as an alternative to using the setuid-to-root permission bit. That's what Trusted Solaris did, too, but now Oracle Solaris uses a special rights profile called Forced Privilege, to specify the process privileges for setuid-to-root programs. The Forced Privilege profile is unique in that it is always in effect regardless of who is executing these programs.

Both the AppArmor and SELinux security modules plug into the LSM framework, so they can restrict access to specific objects. But these modules are not invoked when such access requires a capability (privilege) which was not already granted to the process, so a permissive mechanism is also needed. Although file capabilities can be used to elevate process privileges, they must be used carefully because they apply to any user who executes that file. So most Linux user's rely on sudo(1M), which grants them additional access.

Although Solaris supports sudo, it isn't hooked into the kernel like rights profiles are. The sudo command needs to run as root with all privileges so that it can grant the attributes specified for each program in the /etc/sudoers file for the current user. But it cannot specify the attributes of any subsequent child processes. The best it can do is block their execution. For example, the Solaris version of sudo prevents this by removing the PRIV_PROC_EXEC privilege from the process.

Instead Solaris provides an integrated execution environment in which every program invoked by the user runs with the process attributes specified in the user's hierarchical set of rights profiles. Following the principle of least privilege, both restrictive and permissive policies are implemented using a single framework. This environment can be made completely transparent to users when their accounts are created, in which case their available programs are determined by their rights profile assignments. Alternatively, users may explicitly request profile-based execution by prepending the prefix pf to their favorite shell names, or via pfexec. Unlike the sudo command, these shells do not run with elevated privileges. Instead, they set a process flag, PRIV_PFEXEC, which is inherited by their child processes.  When programs are executed the kernel checks this flag; if set it queries a policy server, pfexecd, for the appropriate process attributes and applies them to the new process credential.

Unlike AppArmor and SELinux, the entire policy is not loaded into the kernel. Instead, the policy is cached in user space by the Name Service Cache Daemon, nscd. So the policy can be maintained in an LDAP directory, and updated at any time. Those aspects of the policy that apply to currently executing processes are maintained in their kernel credential structures. When programs are executed for which no explicit attributes are specified, the parent's process credential structure is shared with the child.

Here's a flowchart of how it all works:

Monday Mar 25, 2013

Oracle Solaris Extended Policy and MySQL

Jeremy Smyth has posted two entries on his blog describing how the mandatory access controls in AppArmor and SELinux apply to MySQL. That provides me an opportunity to demonstrate the Extended Policy functionality in Oracle Solaris. While Solaris provides an equivalent level of policy granularity, it doesn't need a knob to disable enforcement; nor does it require relabeling the filesystem to make the policy effective. Note in the steps below, that we never need to inform the kernel that the policy is updated because the policy is maintained in each process credential, not in a system-wide kernel database.

Let's begin by installing MySQL

gfaden@solaris: pfexec pkg install mysql-51

Since I originally installed this system, I have the Software Installation rights profile,  so I didn't need to become root for this step. But some of the following steps require more privileges than I have been granted, so I will use the root role for the remainder of the procedure.

gfaden@solaris:svcs -a|grep -i mysql
svc:/application/database/mysql:version_51 
gfaden@solaris:su -
Password: 
root@solaris#

Although the full FMRI name of the MySQL service is svc:/application/database/mysql:version_51, the last component is sufficient to uniquely specify the service. The service manifest specifies that the execution method is a shell script wrapper, /lib/svc/method/mysql_51. So this is the pathname that will be referenced in a new rights profile, called MySQL Service, created using the profiles(1) CLI.

root@solaris# profiles -p "MySQL Service"
MySQL Service> set desc="Locking down the MySQL Service"
MySQL Service> add cmd=/lib/svc/method/mysql_51
MySQL Service:mysql_51> set privs=basic
MySQL Service:mysql_51> add privs={net_privaddr}:3306/tcp
MySQL Service:mysql_51> add privs={file_write}:/var/mysql/5.1/data/*
MySQL Service:mysql_51> add privs={file_write}:/tmp/mysql.sock
MySQL Service:mysql_51> add privs={file_write}:/var/tmp/ib*
MySQL Service:mysql_51> end
MySQL Service> set uid=mysql
MySQL Service> set gid=mysql
MySQL Service> exit
root@solaris#

The file_write privilege is a basic privilege granted by default to all processes. By explicitly enumerating the writable pathnames, write access is restricted to just those pathnames. This constraint applies to the specified executable and its child processes.

The net_privaddr privilege is required to bind to a privilege port. In the case of MySQL, binding to the default port number, 3306, doesn't normally require this privilege, since it is greater than 1023. So the ipadm(1M) command is used to add it to the set of privileged ports.

root@solaris# ipadm set-prop -p extra_priv_ports+=3306 tcp
root@solaris# ipadm show-prop -p extra_priv_ports tcp
PROTO PROPERTY              PERM CURRENT      PERSISTENT   DEFAULT      POSSIBLE
tcp   extra_priv_ports      rw   2049,4045,   --           2049,4045    1-65535
                                 3306 

Next we assign the profile to the MySQL service using the svccfg(1M) CLI.

root@solaris# svccfg -s mysql:version_51
svc:/application/database/mysql:version_51> setprop method_context/profile="MySQL Service"
svc:/application/database/mysql:version_51> setprop method_context/use_profile=true
svc:/application/database/mysql:version_51> refresh
svc:/application/database/mysql:version_51> exit

Finally, we enable the service, using svcadm(1M).

root@solaris# svcadm enable mysql:version_51

To verify that the policy has been properly applied, we use the ppriv(1M) and pgrep(1) commands.

root@solaris# ppriv $(pgrep mysql)
103697: /usr/mysql/5.1/bin/mysqld --basedir=/usr/mysql/5.1 --datadir=/var/mysq
flags = PRIV_XPOLICY
        Extended policies:
                {net_privaddr}:3306/tcp
                {file_write}:/var/mysql/5.1/data/*
                {file_write}:/tmp/mysql.sock
                {file_write}:/var/tmp/ib*
        E: basic,!file_write
        I: basic,!file_write
        P: basic,!file_write
        L: all
103609: /bin/sh /usr/mysql/5.1/bin/mysqld_safe --user=mysql --datadir=/var/mys
flags = PRIV_XPOLICY
        Extended policies:
                {net_privaddr}:3306/tcp
                {file_write}:/var/mysql/5.1/data/*
                {file_write}:/tmp/mysql.sock
                {file_write}:/var/tmp/ib*
        E: basic,!file_write
        I: basic,!file_write
        P: basic,!file_write
        L: all

Sunday Mar 24, 2013

Application Containment via Sandboxing

Normally, the ability to specify process privileges is restricted to the root role to prevent privilege escalation. By default, root is all powerful, so it can delegate any of its privileges. For example, it can specify application-specific process privileges in Rights Profiles, and then assign them to users. But Oracle Solaris allows non-root users to delegate their process privileges, too.

Although it is possible to assign sufficient rights to users so they can manage their own Rights Profiles, that isn't necessary. Instead a normal user, with no special rights can create application sandboxes with shell script wrappers. That's because subsets of the basic privileges that users get by default, can be be removed or restricted by the users themselves.

Removing or restricting basic privileges from an application can be done using ppriv(1). However, determining which privileges to remove depends on what kind of behavior you are trying to restrict. For example, you may want to prevent an application from transmitting your files over the Internet, or simply from reading or writing files in directories where you have private information. This can't be prevented in traditional OS's because your applications are implicitly allowed such access (but some smartphones allow users to restrict access by their apps).

The following shell script provides an example of how application sandboxes can be created by normal users in Oracle Solaris. Note in the following line:

 50 ppriv -s I-$DENY -r $SANDBOX -De $program

that the ppriv(1) command is passed two privilege sets as shell variables, $DENY and $SANDBOX. The first set, $DENY,  prevents the process from reading or writing any file, executing any subprocess, observing other user's processes, and (conditionally) accessing the network. This is too much of a heavy hammer, so in the second set, $SANDBOX, we refine the policy by enumerating the directories which are available for reading, writing, and executing.

This shell script also demonstrates how the policy can be adjusted to permit specific applications more or less access. For example, in lines 38-42, firefox is granted write access to several dot files in the user's home directory, where session information is maintained. And firefox is not subject to line 46 where network access is removed. However, firefox is still restricted from reading arbitrary files in the user's home directory, and can only save files in its current directory.

As an extra level of paranoia,  the default program, at line 30, is a restricted bash shell which cannot change its current directory or execute the user's dot files. So any commands that are started from this shell are similarly locked into the sandbox.

Also note, in line 50, that the debug option, -D, is specified, so you can customize the policy based on whether you want to allow your applications additional access. Access failures are listed in realtime, and include the named object and the corresponding privilege that would be required for success.

  1 #!/bin/bash
  2 
  3 # Using bash because ksh misinterprets extended policy syntax
  4 
  5 PATH=/usr/bin:/usr/sbin:/usr/gnu/bin
  6 
  7 DENY=file_read,file_write,proc_exec,proc_info
  8 
  9 SANDBOX="\
 10 {file_read}:/dev/*,\
 11 {file_read}:/etc/*,\
 12 {file_read}:/lib/*,\
 13 {file_read,file_write}:/usr/*,\
 14 {file_read}:/proc,\
 15 {file_read,file_write}:/proc/*,\
 16 {file_read}:/system/volatile/*,\
 17 {file_read,file_write}:/tmp,\
 18 {file_read,file_write}:/tmp/*,\
 19 {file_read,file_write}:/var/*,\
 20 {file_write}:$HOME,\
 21 {file_read}:$HOME/.*,\
 22 {file_read,file_write}:$PWD,\
 23 {file_read,file_write}:$PWD/*,\
 24 {proc_exec}:/usr/*\
 25 "
 26 
 27 # Default program is restricted bash shell
 28 
 29 if [[ ! -n $1 ]]; then
 30     program="/usr/bin/bash --login --noprofile --restricted"
 31 else
 32     program="$@"
 33 fi
 34 
 35 
 36 # Firefox needs more file and network access
 37 if [[ "$program" =~ firefox ]]; then
 38     SANDBOX+=",\
 39 {file_read,file_write}:$HOME/.gnome*,\
 40 {file_read,file_write}:$HOME/.mozill*,\
 41 {file_read,file_write}:$HOME/.dbu*,\
 42 {file_read,file_write}:$HOME/.puls*\
 43 "
 44 
 45 else
 46     DENY+=",net_access"
 47 fi
 48 
 49 echo Starting $program in sandbox
 50 ppriv -s I-$DENY -r $SANDBOX -De $program

Thursday Feb 14, 2013

A Demonstration of File Relabeling

Multilevel ZFS Filesystems

A new zfs option, multilevel, was introduced in Oracle Solaris 11.1.  See the section entitled How to Create and Share a Multilevel Dataset in the Trusted Extensions Administration and Configuration Guide.

I've written a labeldemo shell script that can be used to try out this new feature.  Although it implemented using ksh, it uses two GNOME applications to provide GUIs for file selection and relabeling. The file selection uses zenity(1) and the relabeling uses the tgnome-selectlabel utility. The demo can be run in either the global zone or in a labeled zone using the Trusted Desktop. 

Here are some of the preliminary steps:

  • Create a multilevel file system in the global zone and mount it on /multi

zfs create -o multilevel=on -o mountpoint=/multi rpool/multi

  • Create top-level directories corresponding to your zone labels
cd /multi
mkdir -m 777 red
setlabel "zone red" red 
mkdir -m 777 blue
setlabel "zone blue" blue

 ...

    • Make this filesystem available to your labeled zones via a loopback read-write mount.

zoneccfg -z red "add fs;set dir=/multi;set special=/multi;set type=lofs;end"

  • Add the relabeling privileges to each zone:

zonecfg -z red set \  limitpriv=default,win_mac_read,win_mac_write,win_selection,file_downgrade_sl,\  file_upgrade_sl,sys_trans_label

  • Add the following profile to the user doing the demo:

usermod -P +"Object Label Management" myname

  •  Set the default directory pathname that the demo should open when you start it by editing line 21 in the shell script:

 21 default="/multi/white"

  • Now run the labeldemo by invoking the shell script as the user. Here's the first dialog you'll see:

Use this dialog to select a file to be relabeled. Then the second dialog will appear:

Note that the available labels are restricted since each file and directory must dominate its parent directory. The OS ensures that the labels are monotonically non-decreasing as the pathnames are traversed.  So you can upgrade a file in place, up to the label of the zone in which you are running.  

Here is where the warning about the upper bound check is generated:

 49         if [ "$flabel" == "$plabel" ]; then
 50             upgrading=0
 51             x=$(zenity --warning \
 52                 --title="$title" \
 53                 --text="$lbl \n\nCannot upgrade this pathname\n\
 54 higher than the zone label."
 55          fi

But you can only downgrade a file to the label of its directory. If you want to apply a lower label, you must first move the object to a directory which is dominated by that new label. However, this a quick rename if the destination directory is in the same multilevel filesystem.

In line 73 the selected file is moved into the selected lower-level directory.

 56         if [ "$flabel" == "$minlabel" ]; then
 57             x=$(zenity --question \
 58                 --title="$title" \
 59                 --text="$lbl \n\n\
 60 Cannot downgrade in place because the pathname\n\
 61 is constrained by its parent label.\n\n\
 62 Do you want to select a directory to which the file will be moved?")
 63             if [ $? == 0 ]; then
 64                 dirname=$(zenity  --file-selection \
 65                     --title="$title" \
 66                     --directory \
 67                     --filename=$default )
 68                 if [[ -z $dirname ]]; then
 69                     if [ upgrading == 0 ]; then
 70                         break
 71                     fi
 72                 else
 73                     err=$(mv $pathname $dirname 2>&1)
 74                     if [ $? != 0 ]; then
 75                         x=$(zenity --warning \
 76                             --title="$title" \
 77                             --text="$lbl \n\n\
 78 The file label must dominate the directory label.")
 79                         break
 80                     fi
 81                     filename=$(basename $pathname)
 82                     pathname=$dirname/$filename
 83                     lbl=$(getlabel $pathname 2>&1)
 84                     if [ $? != 0 ]; then
 85                         break
 86                     else
 87                         flabel="$(echo $lbl|cut -d" " -f2-99)"
 88                     fi
 89                 fi
 90             fi 
 91         fi

Friday Jan 11, 2013

What's new in User Rights Management

Per-user Security Attributes 

Way back in Solaris 8 we introduced an extensible database, user_attr(4), where we could maintain the security attributes of each user. Originally the database included just three properties: roles, auths, and profiles. These were exposed as the options -R, -A, and -P on the useradd(1M) man page. Since then we have been adding new properties in each Solaris release, while preserving backward compatibility in both the file /etc/user_attr and the corresponding LDAP schema. To avoid dealing with an alphabet full of new options, we standardized on the -K option, which can be used to set the values of any property.

Some of the more recently added properties are:

audit_flags

Specifies per-user audit preselection flags as colon-separated always-audit-flags and never-audit-flags. As in, audit_flags=always-audit-flags:never-audit-flags. See audit_flags(5).

pam_policy

Specifies the PAM policy to apply to a user. pam_policy must be either an absolute pathname to a pam.conf(4) -formatted file or the name of a pam.conf-formatted file located in/etc/security/pam_policy.

roleauth

Specifies whether the assigned role requires a role password or the password of the user who is assuming the role. Valid values are role and user. If roleauth is not specified, roleauth=role is implied.

and two previously existing properties now take more fine-grained values:

auths

Authorization names can be specified using an object, such as solaris.admin.edit/etc/motd, which grants permission to edit the file /etc/motd.

defaultpriv

 An Extended Policy can be specified that qualifies the objects for which the privileges are granted. See privileges(5).

Practical Examples

I've developed three hands-on labs that demonstrate how to take advantage of some of these new features.

  • The first lab demonstrates how to apply Extended Policy applies to individual privileges.
  • The second lab demonstrates how fine-grained user authorizations can be applied to managing services.
  • The third lab demonstrates how authentication policies can be customized for specific users.

 Give them a try and use the comments field to let me know what you think.


Friday Dec 28, 2012

The Year in Review

As 2012 comes to a close, I thought it would be a good time to look back at some of the changes that have been made to the Trusted Extensions features in Oracle Solaris. 

A Brief History

Oracle Solaris was one of the first systems to provide multilevel security, including the first multilevel desktops and thin clients. Security labels first became a bundled feature in Oracle Solaris 10 update 3. This label-based security policy is referred to as Trusted Extensions. Previously that technology was only available via a separate version of the Solaris 8 operating system, called Trusted Solaris. But the Trusted Extensions technology is not simply a port of Trusted Solaris. Instead, it is based on a new architecture, in which labeled zones provide a transparent implementation of multilevel security. The virtualization provided by zones simplifies the deployment of multiple instances of applications at each label, without having to customize their configurations. However, the initial release lacked some of the flexibility and scalability inherent in Trusted Solaris 8.


Oracle Solaris 11.0

Zones and Networking

In Oracle Solaris 11.0, a new virtualized network stack provided greater isolation for the management of labeled networks. For example, each zone could be configured with its own DHCP server, IP routers, and name servers. A new labeled zone brand was introduced to distinguish the label-specific characteristics from the default solaris brand. A new administrative command, tncfg(1M), was provided to simplify the management of labeled zones and networks, including the option to maintain the network labeling policy in an LDAP directory. The txzonemgr GUI was enhanced to provide point and click interfaces for all common administrative functions.


ZFS

Another major enhancement in Oracle Solaris 11.0 was labeled support for ZFS filesystems. To improve the robustness of the mandatory policy, each ZFS filesystem is now automatically and persistently labeled when it is initially mounted into a labeled zone. Once labeled, the system prevents subsequent attempts to mount the filesystem read-write by a zone with a different label. Read-only mounts require that the zone's label dominates the filesystem's label. The label attributes are preserved by the ZFS send and clone operations.


NFS

In addition, each labeled zone can now be configured as an NFS server. Previously, only the global zone could share filesystems, including those belonging to labeled zones. By default, a labeled zone NFS server can only serve clients whose label matches that of the zone. However, each zone can be configured by the global zone administrator to accept read-only requests from clients which dominate the zone's label. This is done by assigning the multilevel port attribute to the NFS service port for the zone.


Desktop

The multilevel desktop was also enhanced in Oracle Solaris 11.0. The CDE login manager was replaced by the GNOME session manager, including several GNOME dialogs related to labeling. The Device Manager was enhanced to work the Nautilus file manager and the Hardware Abstraction Layer, HAL. As a result, additional media such as DVDs, and filesystems such as UDFS can be mounted via the Trusted Path, and their contents are automatically displayed in labeled instances of Nautilus.


Oracle Solaris 11.1

The first update to Oracle Solaris 11 was delivered last autumn. It provides even greater flexibility in the configuration and application of labels.


Zones and Networking

Previously each labeled zone was required to have a unique label, but this restriction prevented isolating related service tiers, like databases and web services into separate zones. Now such services can be distributed among multiple zones which can share the same label, providing that such zones are configured with the exclusive IP stack option. The multilevel desktop only exposes a single zone for each label, which is referred to as the primary labeled zone. Thus, the end-user need not be aware of these secondary labeled zones.


The policy for associating labels with network clients has been extended, as well. Previously, labels were associated with unlabeled hosts based on the IP address of the client. Since labeled systems are often connected to multiple networks, the previous policy required that all the hosts on these various networks had unique IP addresses. The new extended policy provides the option to derive client labels based on the network interface on which their packets arrive. Therefore, the IP addresses only have to be unique for each network interface. The policy applies to both physical and virtual interfaces, and supports the use of VLAN tags to isolate network traffic on a single wire.


For communication between two labeled systems, labels can be transmitted using the IP option header. For IPv4 packets the labels are transmitted using the Commercial IP Security Option (CIPSO). For IPv6 packets, Trusted Extensions has been using a non-standard variant of CIPSO, which was disabled by default. Now, IPv6 labels are transmitted using a new standard protocol, Common Architecture Label IPv6 Security Option (CALIPSO), which is enabled by default.


ZFS

Previously all ZFS datasets were treated as single-level filesystems. A new ZFS option, multilevel, can now be specified when creating new filesystems. When this option is specified, each file and directory in the filesystem can be individually and persistently labeled. A mandatory labeling policy is enforced to ensure that users cannot observe portions of the filesystem for which they are not cleared. For example, the label of each directory must not dominate any of its children. Similarly, only empty directories can be relabeled, and their new labels must dominate their parent directory.


Since the labels are maintained as ZFS attributes, upgrading and downgrading of files and directories is instantaneous. However, the system prevents the relabeling of files that are currently in use. In addition, mandatory polices apply to both users and their processes associated with labeled zones. Only processes asserting the appropriate upgrade or downgrade privileges may relabel files or directories, and the specified labels must not conflict with the non-decreasing policy for pathname traversal.

Users must be cleared for both the existing and specified label, and their associated zone must have been configured with the required upgrade and/or downgrade privilege. This can be managed using usermod(1M), by assigning the Object Label Management rights profile to the user and setting the user's clearance.


Multilevel ZFS filesystems must be created and mounted within the global zone, by a user who has assumed the root role. However, such filesystems can be made available to labeled zones via loopback mounts, specified via zonecfg(1M). By default, such mounts are read-write. Additionally the required labeling privileges can also be assigned to zones via zonecfg(1M).


NFS

Multilevel filesystems can also be shared via NFS. Multilevel shares must be configured from within the global zone, and the multilevel attribute must be associated with the NFS port in the global zone. Clients connecting to this NFS service can only observe and open files that are dominated by their network label. NFS clients are not permitted to relabel files or directories.


Printing

The Common UNIX Printing System (CUPS), has been enhanced to display file labels on printed output. These labels appear as headers and footers on each body page. In addition, special banner and trailer pages are generated for each print job to facilitate proper dissemination of labeled material. The format of these pages is identical to what was generated by the LP print system in Oracle Solaris 10.


Multilevel printer servers can be configured in the global zone, and single-level printer servers can be configured in labeled zones. Cascade printing, in which a labeled zone proxies print requests from a remote client to the global zone print service, is also supported.


Desktop

A new release of the Sun Ray Software will support Oracle Solaris 11.1, and the multilevel desktop features of Trusted Extensions.

Evaluation

Oracle Solaris 11 is in official In Evaluation status under the Canadian Common Criteria Scheme at Evaluation Assurance Level (EAL) 4 Augmented by Flaw Remediation. The evaluation is being conducted against the Operating System Protection Profile (OS PP) and includes the following four extended packages. (1) Advanced Management (AM), (2) Extended Identification and Authentication (EIA), (3) Labeled Security (LS), and (4) Virtualization (VIRT).




Saturday Oct 27, 2012

Oracle Solaris 11.1 Security Lab

Recently I developed a set of lab exercises for an Oracle OpenWorld Hands On Lab, entitled HOL10201, Reduce Risk with Oracle Solaris Access Control to Restrain Users and Isolate ApplicationsThis explored the new Extended Policy for privilege assignments in Oracle Solaris 11.1. 

Today, Oracle Solaris 11.1 has been officially released via the Package Repository. Today's release and branch are numbered 0.5.11-0.175.1.0.0.24.2, which means it is based on build 24b of 11.1 which is, in turn, based on build 175a of 11.0.  There is a good summary of new features available here: Oracle Solaris 11.1 - What's New . Pages 5 thru 7 give an overview of some of the new security enhancements. There is much more information available in the newly published documentation for Oracle Solaris 11.1.

I plan to explore some of these enhancements in a series of blog entries. Meanwhile, I've published a copy of the lab materials, which you can try out with this new release.

Saturday Oct 17, 2009

Labeled Zone Manager 2.0

There is a new and improved version of txzonemgr, called Labeled Zone Manager 2.0  in the latest version of the OpenSolaris developer repository. There are about a dozen new features which should make it easier for both beginners and experienced users to configure their Trusted Extensions systems. I've updated the beginner's instructions to take advantage of some of the automation. For example, if you have not previously created any zones, you will be asked if you want to create the public zone automatically. If you click OK, the zone is configured, labeled, installed, and booted without any user intervention. The command layout is now more efficient to simplify the navigation of the menu hierarchy.

The old interface to select a zone's label has been replaced; we now use the same label builder dialog that is integrated into the Trusted Path menus. So any label_encodings file will work without any performance issues. Among the other new features are:

  • Adding or removing network access to/from specified hosts or networks for each zone
  • Adding or removing specified hosts or networks to/from the list of trusted hosts and networks
  • Configuring multilevel ports and label ranges for each zone
  • Support for the exclusive IP stacks and VNICs with labeled zones (Crossbow)
  • Preliminary code to support Encrypted ZFS datasets for each zone

Collectively the new features are a replacement for the functionality that was previously provided by the Computers and Networks tool in the Solaris Management Console. For a step-by-step walk through of the new features refer to the test plan.

Saturday Aug 29, 2009

Using the Dev Repository with Trusted Extensions

Now that OpenSolaris 2009.06 has been released, the next major release is planned for 2010.02. You can get early access to it by pointing the Package Manager at the Development repository. Since the 2009.06 release, based on build 111, there have already been some major changes. The latest OpenSolaris build number in the Dev repository is 121, and updates occur about every two weeks. This release includes some changes to the labeled zone brand. A new meta-package called trusted-nonglobal specifies the minimal set of packages needed to run the Trusted Desktop in a labeled zone. This is now installed automatically via the txzonemgr. While this is referred to as a whole-root zone, it should not be confused with the way that term is used in Solaris 10. Previously, a whole-root zone contained a copy of all the packages that have been installed in the global zone. But a whole-root labeled zone is a minimized install. The list of packages in the labeled zone brand is enumerated in this manifest. Other differences in the configuration of labeled brand zones have been factored out of the template file and made part of the brand specification. This makes it easier to make future changes transparent to the administrator.

The latest version of GNOME is 2.26.2. This fixes some previous problems like the Trusted Stripe occasionally crashing. But there are still a few required workarounds. These should be fixed in the next major GNOME version, 2.28, which is scheduled for OpenSolaris build 124.

I've added a link to the Trusted Extensions page on OpenSolaris which describes how to install and configure Trusted Extensions using the latest version from the development repository.

Friday Jan 30, 2009

SuperHappyDevHouse Event at Sun

Sun is hosting an Open House at its Executive Briefing Center on Saturday, January 31, for a local technical community called SuperHappyDevHouse. I have set up a demonstration system with 50 zones which is wide open for exploitation. The root password is posted, and remote access via vncviewer or telnet is unrestricted. This is a great opportunity to own your own zone, do whatever you want to it, and not get in trouble. All of the zones are cloned from a ZFS snapshot, so I can quickly restore them if they are destroyed. They are using the new Virtual NIC (vnic) support that I discussed in my previous blog entry. So each zone gets its IP addresss from the same  WiFi access point as our visitors. The ssid is ZONES.

This is all running on a single UltraSPARC T2 processor, with 8 cores and 64 hardware threads. It is running Solaris Nevada build 105. A corresponding x86/x64 version of OpenSolaris is available here.

Here is a very brief overview of the zone configuration, access instructions, and a list of activities to try. Have fun!

Monday Jan 26, 2009

Using IP Instances and Virtual NICs with Trusted Extensions

The OpenSolaris 2008.11 IPS packages are now organized in four respositories:

  • /release
  • /dev
  • /contrib
  • /pending

giving you the option to be a software pioneer. I used the /dev repository to update my Trusted Extensions laptop from the /release repository (running build 101) to build 105. In the Package Manager I selected Settings->Manage Repositories->Modify and changed the URL to http://pkg.opensolaris.org/dev. Then I selected Package->Update All, waited and rebooted. The new system came up running Trusted Extensions with only one hiccup: the Device Manager crashes when filling in its available device list; we're working on a fix.

My main reason for upgrading to this new build is that it includes new Virtual NIC (vnic) support  from the Crossbow project. This makes is easier to bring up both the wirelesss and wired NICs on my laptop, with the former  connected the public Internet, and the latter connected to Sun's Wide Area Network (SWAN). Naturally, I am using the trusted network features of Trusted Extensions to isolate these two networks. The wireless network is being used in my public zone and the wired network is used in the internal zone. Both networks are using DHCP, but each is independent. The public network is using NWAM, and is configured essentially the same way I have described in a previously entry.

The internal zone configuration is new. It takes advantage of the ability to create a vnic from the wired interface. Before doing so, I used the NWAM configuration menu in the GNOME panel to disable the wired interface. I first selected Always Use Wireless Network Interface (iwk0), and then selected the Edit Network Interface Priorities to ensure that Wireless (iwk0) was used. Since I wasn't sure that the NWAM GUI settings were persistent across reboots, I also edited the file /etc/nwam/llp, removing the entry for the wired interface.

Then I created a virtual instance of the wired interface.

# dladm create-vnic -l e1000g0 vpn0

for exclusive use within the internal zone. To change the zone's network configuration, I ran the following as root within the internal zone:

# sys-unconfig

which halted the zone. I used the zonecfg command to add the following to zone's existing configuration:

# zonecfg -z internal

zonecfg:internal> set ip-type=exclusive

zonecfg:internal> add net

zonecfg:internal:net> set physical=vpn0

zonecfg:internal:net > end

zonecfg:internal> exit

Since this zone will not be using the same DNS service as the global zone, it must have its own instance of the Name Service Cache Daemon, nscd. There is a global zone switch to run an instance of nscd in each zone. Although this can be set using the txzonemgr script, I wanted to continue sharing /etc/passwd and /etc/shadow, so I set the switch by hand as follows:

# touch /zone/internal/root/var/tsol/doors/nscd_per_label

This would normally be sufficient, except that I previously enabled another workaround which runs nscd with the privilege to communicate with lower-level DNS servers. So, it is also necessary to add the privilege net_mac_aware to the zone's default privilege set. This is done by adding the following line to /usr/lib/brand/labeled/config.xml:

<privilege set="default" name="net_mac_aware" />

The internal zone needs to be reconfigured as a DCHP client. This is done by copying the following into the file /zone/internal/root/etc/sysidcfg:

system_locale=C
terminal=vt100
network_interface=PRIMARY {
        dhcp
        protocol_ipv6=no
}
nfs4_domain=dynamic
security_policy=NONE
name_service=DNS
timezone=US/Pacific
service_profile=limited_net
timeserver=localhost

All the zones must now explicitly use DNS, so I copied /etc/nswitch.dns to /etc/nwswitch.conf in each zone.

Since the internal zone runs its own network, it needs an eventhook script to setup /etc/resolv.conf and (optionally) the nis service. The one included in Darren Moffat's blog worked nicely. I copied it to /etc/dhcp, making sure it was executable. The final step was to assign the internal network template to the set of SWAN IP adresses. As a simple approximation, I just added the following to /etc/security/tsol/tnrhdb:

129.0.0.0:internal

although the actual list of SWAN subnets is more restrictive (I'll fix this later). Then I crossed my fingers and rebooted the laptop. The two networks came up correctly. I brought up a Terminal in the internal zone, and verified that it was connected to SWAN. The only error I saw was that the nis client service in the internal zone was in the maintenace state. The log file complained that there was no binding directory for the nis service. I fixed that by typing:

# mkdir /var/yp/binding/it.sfbay.sun.com

# svcadm clear svc:/network/nis/client:default

Now I have two network infrastructures running on my laptop: an all-zones wireless interface for the public Internet, and a wired vnic interface for SWAN in the internal zone using nis. The only remaining problem is that the internal zone's network doesn't respond to ethernet hot-plug events. My workaround for this last minor problem is to restart the service in the internal zone by hand:

# svcadm restart svc:/network/physical:default

So now, I have a true mobile multilevel laptop which works anywhere on the Sun campus, that can be suspended and resumed, and automatically reconnects to both the Internet and SWAN networks.

About

This blog explores some of the security features of Oracle Solaris. In particular, topics such as Role-Based Access Control and Labeled Security are my special interests.

Search

Categories
Archives
« April 2014
SunMonTueWedThuFriSat
  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
   
       
Today
Bookmarks