Auditing Zones

Yes, I'm still paranoid. Having the X2100 out on the web is like being a fish in the ocean, and I'm at the bottom of the food chain. At some point I'll start creating some services, but I have this constant "look over my shoulder"  gut feeling. I've got the web server up and running, but it's disabled at the moment :)

Securing one's only child server is like Fight Club. The first rule of Fight Club is to not talk about Fight Club. However, I'm willing to take one for the team. I've got ipfilters running and zones are are running all necessary services with any unneeded services disabled. The global zone is doing pretty much nothing. Logging is enabled ... everywhere.

With the help of Sun Blueprints (here and here for example) and others (here and here), I thought I would utilize BART. However, I've only got one server. Unless someone wants to donate a second server and the monthly hosting fees, I don't have the luxury of auditing (BARTing) my system over ssh (Update: anyone want to take a guess as to why we don't call it File Audit and Reporting Tool?). So I took a related route by making the global zone the "master" system, sans SSH. BART is run from the global zone and audits the local zones from the global zone. While listening to the news last night, I threw together a script (below) to automate the auditing, with cron running the script via automated intervals. If you follow the blueprints, you can create a separate account with just enough privileges to run BART, but nothing more.

One feature I want to add is a second cron script to scan the "reports" directory, and email (via "zlogin mailzone mail ...") any potential issues. Before that, I have to write some code to clean up old reports & daily manifests.


#!/usr/bin/bash

#
# BART_DIR: top level directory for bart input and output files
#

BART_DIR=/var/bart

#
# RULES_DIR. While it is an option to have one rules file for all
# zones, this script copies a rules file template, which can later be
# customized for each zone
#

RULES_DIR=${BART_DIR}/rules

#
# CONTROL_MANIFEST_DIR contains The "Control" manifest. This contains the
# baseline manifest for each zone.
#

CONTROL_MANIFEST_DIR=${BART_DIR}/manifests


#
# DAILY_DIR containes manifests created daily, with a subdirectory for each
# zone.
#

DAILY_DIR=${BART_DIR}/daily

#
#  REPORT_DIR, whith a sub-directory for each zone, contains the daily
#  comparisons between the control manifest and the daily manifest.
#  These files will show file modifications
#

REPORT_DIR=${BART_DIR}/reports

#
# RULES_TEMPLATE. Default rules file that will be utilized by default for
# each zone.
#

RULES_TEMPLATE=${RULES_DIR}/rules.template

#
# The bart binary.
#

BART=/usr/bin/bart

#
# List of all zones on the host, running or not
#

zones=`/usr/sbin/zoneadm list -cp |  cut -d':' -f 2`

#
# Pre-create the various directories. This requires "/var/bart" (by default)
# to exist and have appropriate permissions.
#

if [ ! -d ${RULES_DIR} ];
then
   mkdir -p ${RULES_DIR}
fi

if [ ! -d ${DAILY_DIR} ];
then
   mkdir -p ${DAILY_DIR}
fi

if [ ! -d ${CONTROL_MANIFEST_DIR} ];
then
   mkdir -p ${CONTROL_MANIFEST_DIR}
fi

if [ ! -d ${REPORT_DIR} ];
then
   mkdir -p ${REPORT_DIR}
fi

#
# For each zone, run bart. The first time through, create the control
# manifest. Run this script before putting any newly created zone on
# the network. Creating a control manifest of compromised zone doesn't
# do much good :)
#

for zone in ${zones}
do
#
# Get the base directory of the zone. Wish there were a formal CLI
# way of doing this (zoneadm get property would be nice). If you have
# a better way of doing this, ping me.
#

   zonepath=`grep ${zone} /etc/zones/index | cut -d':' -f 3`

#
# Pre-create various "file" and "directory" variables before the heavy lifting.
#
   CONTROL_MANIFEST_FILE=${CONTROL_MANIFEST_DIR}/${zone}.control.manifest
   RULE_FILE=${RULES_DIR}/${zone}.rules
   DATE=`date '+%m_%d_%y'`
   DAILY_TEST_MANIFEST=${DAILY_DIR}/${zone}/${DATE}.manifest
   REPORT_FILE=${REPORT_DIR}/${zone}/${DATE}.report

#
# Determining the global zone base directory is different than local
# zones

   if [ "${zone}" = "global" ];
   then
       BASE_ZONE_DIR=/
   else 
       BASE_ZONE_DIR=${zonepath}/root
   fi


#
# If the control file doesn't exist, create it. If it does exist, create
# the daily manifest and generate a report.
#

   if [ ! -f ${CONTROL_MANIFEST_FILE} ];
   then
      if [ ! -f ${RULES_DIR}/rules.template ];
      then
         echo "Rules template does not exist, please create ${RULES_DIR}/rules.template"
         exit 1
      fi

      #
      # If a rules file doesn't exist, copy the template
      #

      if [ ! -f ${RULES_DIR}/${zone}.rules ];
      then
         cp ${RULES_DIR}/rules.template ${RULE_FILE}
      fi

      ${BART} create -R ${BASE_ZONE_DIR} -r ${RULE_FILE} > ${CONTROL_MANIFEST_FILE}
   else
      #
      # Create the zone's report and daily sub directory
      #
      if [ ! -d ${REPORT_DIR}/${zone} ];
      then
          mkdir -p ${REPORT_DIR}/${zone}
      fi

      if [ ! -d ${DAILY_DIR}/${zone} ];
      then
          mkdir -p ${DAILY_DIR}/${zone}
      fi

      #
      # Generate the daily manifest
      #

      ${BART} create -R ${BASE_ZONE_DIR} -r ${RULE_FILE} > ${DAILY_TEST_MANIFEST}

      #
      #
      # Generate the daily report by comparing the control manifest with the
      # daily manifest
      #

      ${BART} compare -r ${RULE_FILE} ${CONTROL_MANIFEST_FILE} \\
          ${DAILY_TEST_MANIFEST} >  ${REPORT_FILE}
   fi
done


Per the script, here is a sample "rules.template" file. Customize to your needs.
/usr/sbin
/usr/bin
/etc
CHECK all
IGNORE dirmtime
Comments:

Hi John, Bart is definitely a nifty utility, but the following note in the bart(1M) manual page makes me kinda nervous: Note - The root file system of any non-global zones must not be referenced with the -R option. Doing so might damage the global zone's file system, might compromise the security of the global zone, and might damage the non-global zone's file system. See zones(5). I have no idea how running bart in a non-global zone could cause damage the global zone, but I tend to follow the recommendations provided in the documentation. Since bart has this limitation, I decided to deploy Samhain (a file integrity checking package and beltran (a graphical front-end to samhain) instead: http://www.la-samhna.de/samhain/ If you happened to bump into one of the bart developers in the hall, could you ask him why bart has the limitation listed above? Thanks, - Ryan

Posted by Matty on August 16, 2006 at 04:19 AM PDT #

Matty, many thanks for the heads up. Actually, I did not catch that. However, I can't see what the issue is the way I use it (doesn't mean there isn't an issue :) ).

I run the above script as non-root user, and the only permissions that user has is file_dac_read and file_dac_search. No file_dac_write. Basically, the search in read-only mode to zone mount points. One general concern with running tools fromt the global zone is that the zone's mount point gets changed from 700 to something more accessible.

I'll ping around and see what the potential issues are. I'm scratching my head on the warning. However, warning's like that shouldn't be ignored. Again, thanks for the heads up.

Posted by John Clingan on August 16, 2006 at 05:37 AM PDT #

Matty, I found this. In particular, from the Solaris Security Toolkit:

"Because of security risks, you should never access a non-global zone file system from outside that zone. A path that is not dangerous in a non-global zone can be dangerous in the global zone. For example, a non-global zone administrator can link the /etc/shadow file to the ../../../shadow file. Inside the non-global zone, this is harmless, but modifications to the file from the global zone, using the path /opt/testzone/etc/shadow, would edit the global zone’s /etc/passwd file. Again, a non-global zone should never be hardened, undone, cleaned, or even audited unless you are logged into that zone."

I think the problem is not a specific technical one, it's a "best practices" problem. The more users directly address a local zone from the global zone, the greater the chance for either inadvertant destructive behavior or the inadvertant creation of security holes.

That being said, everything accomplished via the "above" script can be done via zlogin, although it will take some thinking about how to accomplish this as securely as possible as a non-root user.

Posted by John Clingan on August 16, 2006 at 05:58 AM PDT #

(a) You might want to run syslog as a logging server for the other zones in a dedicated, very limited zone that's only there for that purpose. Would make it a lot harder for attackers to hide their trails if they break zone-root. There's a very nice booklet on centralizing logging available from SAGE: http://www.sage.org/pubs/12_logging/ (b) The "perma" link to the post sent in the RSS feed is broken (it 404s).

Posted by Bernd Haug on August 17, 2006 at 02:34 AM PDT #

Bernd, excellent point. Thanks for the link!

Posted by John Clingan on August 17, 2006 at 06:22 AM PDT #

Post a Comment:
Comments are closed for this entry.
About

John Clingan

Search

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