A how-to guide for writing effective security policies
"Steve Glass, CISSP" (stglass@au.ibm.com) Security Specialist, IBM Australia 15 Apr 2004
This article explains how to secure UNIX applications using
Tivoli Access Manager for Operating Systems. It describes a
simple method for writing an access control policy and
outlines how such a process can be applied to an example
application.
Tivoli Access Manager for Operating Systems extends UNIX
to incorporate a centrally-managed, non-discretionary
access control mechanism that works in tandem with the
usual UNIX access controls. Tivoli Access Manager for
Operating Systems finds its place in a risk-based security
strategy as a technical measure to help prevent, detect
and contain breaches of security.
The nightmare scenario for a UNIX system is one in which a
hostile user successfully conducts an attack and obtains
superuser privileges. In such circumstances, conventional
UNIX access controls are rendered ineffective and the
attacker is free to do their worst. Tivoli Access Manager
for Operating Systems access controls, however, can
prevent even a rogue superuser from accessing sensitive
information, modifying program files or falsifying audit
trails.
This article explores how Tivoli Access Manager for
Operating Systems can be used for security hardening of
UNIX systems. It focuses on securing UNIX applications as
opposed to UNIX itself. While there are many resources for
security hardening of the UNIX operating system (some of
which are listed in the resources section), application
security is an oft-neglected area. Many applications are
deployed with ineffective security measures that undermine
the security of UNIX itself.
Tivoli Access Manager for Operating Systems enforces
policy-based access controls - it uses a security policy
to specify which objects to protect and identifies the
users and programs that are permitted access to those
objects. The key to securing a system using Tivoli Access
Manager for Operating Systems is an access control policy
that addresses the key risks faced by the system.
What risks must your policy address?
Before you consider writing a Tivoli Access Manager for
Operating Systems access control policy, define the
security threats that need to be addressed. There are
usually several measures that can be employed to minimize
particular risks. The task of securing an application
server, for example, requires consideration of physical
security, procedural issues and a host of measures apart
from the technical controls.
One technique for identifying the risks that must be
addressed is to create an attack tree (see
resources for more information). This technique requires
that you put yourself in the shoes of an attacker to
identify strategies for compromising your system. An
attack tree can help you decide which countermeasures are
most appropriate. A Tivoli Access Manager for Operating
Systems access control policy can be used to help to
prevent, detect and contain some of the technical security
threats you identify. Of course, there will be other
measures you can use in tandem. The amount of effort you
expend will normally reflect the seriousness of the threat.
For example, you maybe concerned about remote buffer
overflow attacks against vulnerable processes. In this
case, you may choose to implement access controls such as
the following:
-
Restricting incoming network access to trusted
hosts.
This is a preventative measure that works in
concert with the external firewall to reduce visibility of
the vulnerable program.
-
Denying access to sensitive data for user accounts that
could potentially be compromised.
This is a
containment mechanism that limits the damage in the event
of a compromise.
-
Implementing per-user auditing for denied resource
requests that are made by such users.
This is
primarily a detective measure. A sudden increase in
permission denials may indicate a process that has been
compromised. Tivoli Access Manager for Operating Systems
auditing allows an Intrusion Detection System (IDS) such
as Tivoli Risk Manager to rapidly respond to a system
intrusion.
Which user roles require access?
Once you have identified the threats to be addressed, the
next step is to define the user roles who have a
legitimate need to access the application and its
resources. Concentrating on the identification of roles
rather than individuals will ensure that the resulting
policy is easier to understand and modify. Some
individuals may need to be included, however, because they
play a special role (for example, the superuser or
identities such as "oracle"). As a guideline, your
application may have one or more of the following roles:
- Administrators,
- Operators,
- Auditors,
- Ordinary application users and
- System accounts
Administrators Many applications have the
concept of an administrator - a privileged class of user
that can reconfigure the application, start and stop
subsystems, inspect audit logs and so on.
Operators An operator role is a privileged
user somewhere between an ordinary user and an
administrator. They will often have the ability to start
and stop subsystems or inspect appropriate log files but
are not permitted to reconfigure the application. Only
large organizations and complex applications are likely to
require such a role.
Auditors The Auditor role may be appropriate
when there is a need to restrict access to audit trails
and define audit policies. This role is often a facet of
an application's administrator role (some applications do
not allow separation of administration and auditing
capabilities). You should define an auditor role when you
are seeking to separate administration from
monitoring. This is another role that applies mainly in
large or very security-conscious organizations.
Ordinary users Most applications have a class
of users with an ordinary level of access to the
application. These users will usually need to be able to
invoke an application client program or interact with
other utilities, and these are the users with whom this
guide is mostly concerned. Sometimes, of course, these
users gain access through a browser or network link and
never require UNIX level access. In such circumstances,
they can be ignored (as far as the Tivoli Access Manager
for Operating Systems policy is concerned) and left to the
normal application access control mechanisms.
System accounts It is a common practice for
applications to define user IDs for their own
purposes. For example, the Apache Webserver and Tivoli
WebSEAL application usually require superuser privileges
when they start (to open privileged TCP ports etc.) but
then switch to another identity to actually dispatch
requests. System accounts will typically not be used for
user logins and may have default, rarely changed or
widely-known passwords. Such accounts are a target for an
attack because intrusions are likely to remain undetected
for a significant period of time.
One special system account you will almost certainly need
to consider is the superuser. The superuser will probably
need to be included because the superuser will start and
stop the application at system start-up and shutdown.
Others There are also usually a whole group of
people with no application access. These are users other
than those identified above who have a legitimate reason
to use the system but not the application or its
resources.
Which application files should be protected?
Tivoli Access Manager for Operating Systems can apply
access controls to files, surrogate (setuid) behavior,
TCP ports and interactive logins. Of these, the most
important are files. One of the original design points of
the UNIX operating system is the concept that "everything
is a file." Although this is no longer entirely true, it
does emphasize the importance of files and hence
the importance of controlling file access.
Most applications have one or more directory hierarchies
for programs, configuration, audit and data
files. Preserving the confidentiality and integrity of
these file resources is usually one of the central goals
of any security policy. With that in mind, it is worth
discussing what not to protect.
Firstly, its worth noting that there is very little value
in simply re-implementing the existing UNIX permissions as
Tivoli Access Manager for Operating Systems access
controls. Instead, additional file access controls
should be implemented to assist in the prevention,
detection and containment of a potential security
intrusions. Tivoli Access Manager for Operating Systems
can protect some things UNIX cannot, and can enforce
restrictions based on the authenticated identity of the
user (as opposed to their effective identity). These are
the type of controls that should be defined.
Secondly, you should not need to individually identify
each of the files used by an application. An effective
policy uses a few well-chosen access controls applied to
directories close to the top of the hierarchy and lets
Tivoli Access Manager for Operating Systems apply these
access controls throughout the hierarchy.
Keep these considerations in mind when building a list of
candidate files to be protected. Start by listing the
top-level directories used by the application. The Tivoli
WebSEAL product, for example, uses
/opt/pdweb and
/var/pdweb for its top-level
directories.
Once you have identified the top-level directories, work
your way down the file hierarchy, adding any directories
or files which will be treated differently than their parent
directory. Examples might include:
- Program files,
- Configuration files,
- Audit or log files,
- Data files and
- Reference files (e.g. help files)
Again, list individual files only when absolutely
necessary and give preference to directories whenever
possible.
Define a role/resource matrix
Having identified the different roles and resources, you
must identify the permissions required for each particular
role and resource. This can be done by creating a
role/resource matrix, with rows representing the candidate
resources to be protected and columns representing the
potential roles. Using a matrix ensures that every
role/resource combination is considered and provides a
comprehensive specification for the resulting policy. Use
a spreadsheet so that you can edit, sort and manipulate
the data as you see fit.
For each row/column entry in the matrix, identify whether
the specified role may access the resource or not. For
files, start to add details such as whether access is
read/write or read-only. Apply the principle of
least-privilege, assigning each cell the minimum level of
access that the user needs to perform a task. The
permissions will be iteratively refined as the policy is
tested.
The following table is an example of a row/resource matrix
for the Tivoli WebSEAL product.
Role/Resource Matrix
|
File/Directory
|
Superuser
|
Webseal Administrators
|
Webseal Operators
|
Webseal runtime
|
any-other
| /opt/webseal Top-level directory | read+execute+kill | read+execute+kill | read+execute+kill | read+execute+kill | - | /opt/webseal/etc Configuration files | read | read+write+modify | read | read | - | /opt/webseal/www-default Web pages | read | read+write+modify | read | read | - | /var/webseal Top-level directory | read | read+rename+delete | read | read+write+modify | - | /var/webseal/log Log files | read | read+rename+delete | read | read+write+modify | - |
When creating a first draft matrix, the details of
permissions being granted need not be too
detailed. Descriptive permissions can be easier to
understand than permission strings. Before the policy can
be written, however, you must make detailed decisions as
to which permissions to grant. A simple mapping is the
best place to start: read/write access will get all Tivoli
Access Manager for Operating Systems read/write
permissions (NRudwop), read-only will get just the read
permissions (Dlr), and so on. On completion of this task
you should have a role/resource matrix with detailed
access permission for each cell.
Writing the first-draft policy
With the role/resource matrix complete, writing the policy
is straightforward. Each row of the matrix describes a
protected object and the access control list for that
object. Rewrite each row as an ACL and provide a
meaningful name for the ACL. For example, consider the
first row from the example row/resource matrix shown
above. This can be re-written as follows:
Listing 1. Example object/ACL policy item.
acl create "webseal-product-files"
acl modify "webseal-product-files" description "This ACL controls access to the top-level WebSEAL directory."
acl modify "webseal-product-files" set user "root" "T[OSSEAL]DlrxK"
acl modify "webseal-product-files" set group "administrators" "T[OSSEAL]DlrxK"
acl modify "webseal-product-files" set group "operators" "T[OSSEAL]DlrxK"
acl modify "webseal-product-files" set group "webseal-runtime" "T[OSSEAL]DlrxK"
acl modify "webseal-product-files" set any-other "[OSSEAL]"
acl modify "webseal-product-files" set unauthenticated "[OSSEAL]"
object create "/OSSEAL/branch/File/opt/pdweb" "WebSEAL product files." 4 ispolicyattachable yes
acl attach "/OSSEAL/branch/File/opt/pdweb" webseal-product-files
|
You will probably want to modify the policy after it has
been implemented (usually because your first-draft policy
is overly restrictive). The principle of least privilege
ensures that a user has access to only those resources
they need. Unfortunately, real applications often violate
this rule and a restrictive policy will introduce new
failure conditions. Simply put, certain applications never
expect to be refused access to a particular resource.
Invest some time debugging your access control policy to
ensure it doesn't break your application. To ensure that
you do no harm, enable Tivoli Access Manager for Operating
Systems auditing for deny decisions. If the application
fails unexpectedly, investigate the audit trail and see
which permission is being refused. Then evaluate how your
policy would be affected if you were to add that
permission for the appropriate role.
Test the policy
You may sometimes encounter problems because you don't
want to grant a specific permission that an application
needs in order to run. An example for the WebSEAL
application is the root user, which requires both read and
write access to the WebSEAL logfiles. It is usually not a
good idea to grant unrestricted write access, because a
superuser can then modify the logs. The solution is to
grant access to the user only when they use a trusted
program. Tivoli Access Manager for Operating Systems
access restrictions make this possible (in fact they are
commonly used to maintain the integrity of log files in
this way). An example policy for the WebSEAL log files is
shown in figure 2.
Listing 2. Example access restriction.
acl create "webseal-log-files"
acl modify "webseal-log-files" description "This ACL restricts access to the log files."
# grant root wide-ranging access - see below for restrictions
acl modify "webseal-log-files" set user "root" "T[OSSEAL]DNRUdloprw"
# let admins have read-only plus delete and rename permissions
acl modify "webseal-log-files" set group "webseal-admin" "T[OSSEAL]DlrRd"
acl modify "webseal-log-files" set group "webseal-operators" "T[OSSEAL]Dlr"
acl modify "webseal-log-files" set group "webseal-runtime" "T[OSSEAL]DNRUdloprw"
acl modify "webseal-log-files" set any-other "[OSSEAL]"
acl modify "webseal-log-files" set unauthenticated "[OSSEAL]"
# root has read-only access by default
acl modify "webseal-log-files" set attribute "Access-Restrictions" "user root:Drl:*"
# but has wide-ranging access when running webseald
acl modify "webseal-log-files" set attribute "Access-Restrictions" "user root:DNRUdloprw:/opt/pdweb/bin/webseald"
object create "/OSSEAL/branch/File/var/pdweb/log" "WebSEAL log files." 4 ispolicyattachable yes
acl attach "/OSSEAL/branch/File/var/pdweb/log" webseal-log-files
|
What other application resources should be protected?
Tivoli Access Manager for Operating Systems can apply
access controls not only to files but to surrogate
and setuid behavior, TCP ports and interactive logins.
setuid programs These programs change their
effective user ID and are of special concern from a
security perspective. UNIX has a somewhat complex model
for processes that change identity, the details of which
are often misunderstood (see the Resources section for a
good explanation of setuid behaviors). Tivoli
Access Manager for Operating Systems simplifies the model
because access controls are based on the authenticated
user identity and not the effective identity. This allows
users, for example, to be given privileged access but
still retain accountability for their actions via the
audit mechanism.
When setuid programs harbor security holes, an attacker
can exploit them to change identity and evade UNIX access
controls. Tivoli Access Manager for Operating Systems
provides a program named
pdosuidprog which can be used
to find all of the programs in a given directory hierarchy
which have the setuid bit set. You should use this to
identify potentially vulnerable programs.
Tivoli Access Manager for Operating Systems provides
various methods of handling setuid programs. For example,
there is the Impersonator-Programs mechanism which
will allow a setuid program to change both its UNIX and
Tivoli Access Manager for Operating Systems
identities. This can be useful because it allows setuid
programs to acquire rights that the invoking user might
not possess. Several Fast-Start Policy Modules make use of
this feature because it allows the privileges required by
the program to be partitioned into a distinct role. Access
controls should be applied to any Impersonator-Programs to
ensure that they can only be executed by users who must
have that level of access.
For simple applications, the list of candidate files is
pretty much ready at this stage but for larger
applications there is more to be done. The running
application may create temporary files. These files should
be identified and included in your candidate object
list. One of the best ways to do this is to use the lsof program to identify the
resources in use by the application as it runs.
TCP Ports TCP ports are often used to allow
non-local clients to connect to an application and are a
common weakness. Applications that contain buffer overflow
vulnerabilities in their port reading code allow remote
exploitation and are a major security headache. Tivoli
Access Manager for Operating Systems can limit inbound
connections to specific hosts, subnets or domains. Where
such protections are useful, you can add the application's
ports to your candidate resource list. It may also be the
case that you wish to ensure only certain users/programs
listen to a specific port and in this case you should also
add the port to the candidate resource list.
Most applications will describe the ports on which they
accept connections in their documentation. Where that
information isn't available, the ports used by an
application can be achieved using the
netstat and
lsof programs. Note that Tivoli Access Manager for Operating Systems
is not a substitute for an external firewall - it only
protects TCP ports and there are well-known security
deficiencies in the basic TCP protocol. It does, however,
allow for defense-in-depth; providing access controls
appropriate within the firewalled environment.
Login behavior There are a number of login
restrictions you may consider adding to the list:
time-of-day logins, no login permission (useful when
daemons use a specific identity) and so on. Check the
Tivoli Access Manager for Operating Systems documentation
for details and add any classes of login restriction to
the candidate resources list as appropriate. For each user
role you should ask the question "Are there any login
restrictions associated with this role?".
Developing an access control policy for any of the above
resources is actually a little simpler than it is for
files. You should construct a role/resource matrix as you
did for the filesystem resources but the permissions are
easier to manage. Most objects will have a single
permission that controls access to the resource: 'L' for
logins, 'C' to accept connections on TCP ports and so
on. Instead of using complicated permissions,
specialization of the resource types is achieved by
attaching the permission to an appropriate resource
object. For example, the WebSEAL runtime role is a machine
account - a security weak spot identified by the analysis.
To ensure it cannot be used for interactive logins, attach
permissions as shown in figure 3.
Listing 3. Example object/ACL policy item.
acl create "webseal-deny-logins"
acl modify "webseal-deny-logins" description "This ACL restricts interactive logins."
acl modify "webseal-deny-logins" set group "webseal-runtime" "[OSSEAL]"
acl modify "webseal-deny-logins" set any-other "T[OSSEAL]L"
acl modify "webseal-deny-logins" set unauthenticated "T[OSSEAL]L"
object create "/OSSEAL/branch/Login/Terminal" "Logins (both local and remote)." 0 ispolicyattachable yes
acl attach "/OSSEAL/branch/Login/Terminal" webseal-deny-logins
|
This article has outlined a simple process for developing
a Tivoli Access Manager for Operating Systems security
policy. Having identified the threats faced by the system,
appropriate countermeasures are selected for each of the
threats to be addressed. To ensure a comprehensive
security policy, roles and resources are identified and an
access control matrix is defined. This matrix can be
iteratively expanded and tested the matrix until it
addresses all the potential threats, while still allowing
enough flexibility for the application to work. Once these
have been mastered, the most important part of this policy
is is to ensure that it is iteratively improved. Security
should be seen as an evolving process, not just a product.
Resources
- Find Tivoli Access Manager for Operating Systems documentation at the IBM Tivoli Software Information Center.
- Download the Fast Start Policy for UNIX, a tool for generating a Tivoli Access Manager for Operating Systems policy for hardening the UNIX OS.
- The CERT security improvement modules define a variety of network security problems and outline best practice solutions.
- Download the lsof program - an invaluable tool for identifying the resources used by a running process.
- Read Bruce Schneier's paper on Attack Trees, a technique for identifying potential security threats.
- Setuid demystified explains the complexities of setuid programming.
About the author
Steve Glass is a software engineer at IBM Australia's Gold
Coast Lab. He works with Tivoli Access Manager for
Operating Systems and has developed several Fast-Start
Policy Modules for Tivoli Access Manager for Operating Systems. Steve has nearly twenty years
experience as a professional software developer and
specializes in operating system and network security.
|

|