A Taste of Computer Security
Security in Solaris 10
The complexity of the "Security Problem", and of its attempted solutions may be appreciated by looking at what all could be listed under a loosely defined security umbrella. While Linux is a commonly chosen system for implementing research ideas — security-related and otherwise — Solaris 10 has a very impressive out-of-the-box security repertoire amongst general purpose operating systems. Using Solaris 10 as an example, we see in this section that the collection of security-related mechanisms in a modern operating system could amount to a dizzying array of technologies. Knowing what these are in a given system is the first step — an easy one. The next step is to understand them, but the hardest part is using these effectively.
Note that some mechanisms and features listed here also exist in Microsoft's recent systems (consider Microsoft Security Services in Windows Server 2003).
Login Administration
Solaris provides various tools for monitoring and controlling a user's ability to access the system. There is support for multiple password encryption algorithms, which may be implemented as 3rd party modules.
Resource Management
In Solaris, a task is a group of processes representing a component of some workload. A task is a manageable entity. Moreover, each workload (possibly consisting of several tasks) is tagged with a project identifier: a network-wide name for related work. Each logging in user must be assigned at least a default project.
Solaris provides flexible resource management through a number of control mechanisms:
- Partitioning (for binding a workload to a subset of the system's available resources)
- Constraining (for setting bounds on the consumption of specific resources for a workload)
- Scheduling
Examples of available resource controls include CPU shares, total amount of locked memory allowed, limits on the sizes of the heap, the stack, and overall address space (summed over segment sizes), and limits on the number of various entities such as IPC objects, lightweight processes, file descriptors, etc.
# prctl $$
...
# cat /etc/project
...
test-project:100::root::task.max-lwps=(privileged,2,deny)
# newtask -p test-project /bin/zsh
# id -p
uid=0(root) gid=1(other) projid=100(test-project)
# prctl -n task.max-lwps -i project test-project
3536: prctl -n task.max-lwps -i project test-project
task.max-lwps
2 privileged deny
2147483647 system deny [max]
# sleep 100 &
[1] 3563
# sleep 100 &
zsh: fork failed: resource temporarily unavailable
The resource capping daemon, rcapd, regulates physical memory consumption by processes running in projects that have resource caps defined. Per-project physical memory caps are supported.
Zones
Zones provide a virtual mapping from the application to the platform resources. They could be simply understood as "application containers": a software partitioning scheme so that operating system services may be virtualized to yield similar, but isolated execution environments for applications.
The software limit on the maximum number of Zones per-machine is 8192, although in real life it would depend upon available resources, and on "normal" systems, the allowable number would be far lesser.
Note that one zone, called the global zone, is always present, and represents the conventional (default) Solaris execution environment. The global zone is the only zone that is bootable from physical hardware. Additional zones are configured, installed, and removed only from within the global zone. However, each zone can be administered independently. Therefore, zones allow delegation of administration without compromising overall system security.
Non-global zones can be used in association with resource management for better control and more efficient resource utilization. Once a process is placed in a non-global zone, the process (or any of its descendents) will be confined to that zone. A non-global zone's privileges are always a subset of the global zone's.
An example of using zones follows.
Initially, you only have one zone: the global zone. The zonecfg command is used to create and configure a new zone.
# zoneadm list
global
# zonecfg -z test-zone
test-zone: No such zone configured
Use 'create' to begin configuring a new zone.
zonecfg:test-zone> create
zonecfg:test-zone> set zonepath=/zones/test-zone
zonecfg:test-zone> set autoboot=false
zonecfg:test-zone> add fs
zonecfg:test-zone:fs> set dir=/shared/tmp
zonecfg:test-zone:fs> set special=/tmp
zonecfg:test-zone:fs> set type=lofs
zonecfg:test-zone:fs> end
zonecfg:test-zone> add net
zonecfg:test-zone:net> set address=10.0.0.10
zonecfg:test-zone:net> set physical=iprb0
zonecfg:test-zone:net> end
zonecfg:test-zone> add device
zonecfg:test-zone:device> set match=/dev/fd0*
zonecfg:test-zone:device> end
zonecfg:test-zone> verify
zonecfg:test-zone> commit
zonecfg:test-zone> exit
The zone must be installed before it can be booted and used.
# zoneadm -z test-zone install
Preparing to install zone <test-zone>.
Creating list of files to copy from the global zone.
Copying <2178> files to the zone.
Initializing zone product registry.
Determining zone package initialization order.
Preparing to initializing <681> packages on the zone.
Initialized <681> packages on zone.
Zone <test-zone> is initialized.
...
Booting a zone is similar in many respects to booting a regular Solaris system. You can log in to a booted zone using the zlogin command.
# zoneadm -z test-zone boot
# zoneadm list -v
ID NAME STATUS PATH
0 global running /
1 test-zone running /zones/test-zone
# zonename
global
# zlogin -C test-zone
[Connected to 'test-zone' console]
/*
* The first time you do this, you must
* set language, time zone, root password, etc.
* Zone will reboot.
*/
test-zone console login: root
Password: ********
Jul 5 18:49:55 test-zone login: ROOT LOGIN /dev/console
Sun Microsystems Inc. SunOS 5.10 s10_58 May 2004
Now you can explore the isolation and virtualization aspects of zones. Note that a zone is not identical to a conventional Solaris environment. For example, a zone cannot be an NFS server; you cannot use the mknod system call inside a zone, and so on.
# zonename
test-zone
# ls /shared/tmp
... (files from global /tmp)
# ls /proc
10640 10691 ...
10643 10730 ...
10666 10740 ...
# ifconfig -a
iprb0:1: flags=...
inet 10.0.0.10 netmask ff000000
lo0:1: flags=...
inet 127.0.0.1 netmask ff000000
Role-Based Access Control (RBAC)
RBAC is an alternative to the traditional all-or-nothing super-user model. RBAC is based on the principle that no user should have more privileges than are necessary for performing an operation (the principle of least privilege). Following are key aspects of RBAC:
- Using RBAC, you can configure any number of roles (special identities for executing privileged programs, such as setuid ones). Examples of common roles are Primary Administrator, System Administrator, and Operator.
- These roles are assigned to users.
- A role's capabilities become available to a user upon assuming the role.
- Roles derive their capabilities from rights profiles, which contain authorizations (permissions for performing a normally disallowed set of operations) and privileged commands (that is, commands that need to be executed with administrator capabilities).
- Privileges are distinct rights that can be granted to a role, a user, a command, or even the system. Privileges are logically grouped into categories such as FILE, IPC, NET, PROC, and SYS.
Note that without the appropriate privilege, a process will not be able to perform a privileged operation (the kernel will ensure it). However, without an authorization, a user may not be able to run a privileged application (or perform certain operations within such an application).
# ppriv -l
cpc_cpu
dtrace_kernel
dtrace_proc
...
sys_suser_compat
sys_time
Now, let us try to read a file that we do not have privileges to read. The -D option of ppriv will turn on privilege debugging.
$ ppriv -e -D cat /etc/shadow
cat[1399]: missing privilege "file_dac_read" \
(euid = 100, syscall = 225) needed at ufs_iaccess+0xd2
cat: cannot open /etc/shadow
We could create a new role, say called "filerole", and assign ourselves to that role.
# roleadd -s /bin/pfksh -d /home/filerole \
-K defaultpriv=basic,file_dac_read filerole
# passwd filerole
# New Password: ********
# Re-enter new Password: ********
passwd: password successfully changed for filerole
# mkdir /home/filerole
# chown filerole:other /home/filerole
# usermod amit -R filerole
# su - amit
$ su - filerole
Password: ********
$ cat /etc/shadow
You can list the privileges that your current shell has as follows:
$ ppriv -v $$
...
Device Management
Solaris provides two mechanisms for controlling device access:
Device Policy - access to a particular device needs a certain set of privileges. For example, in order to access a network device directly (for sending raw packets, say), you would need the net_rawaccess privilege. The getdevpolicy command can be used to inspect the system's device policy:
# getdevpolicy
DEFAULT
read_priv_set=none
write_priv_set=none
ip:*
read_priv_set=net_rawaccess
write_priv_set=net_rawaccess
icmp:*
read_priv_set=net_icmpaccess
write_priv_set=net_icmpaccess
...
spdsock:*
read_priv_set=sys_net_config
write_priv_set=sys_net_config
Device Allocation - use of a device requires authorization, and only one user may allocate a device at a time. The list_devices command can be used to list allocable devices:
# list_devices -l
device: fd0 type: fd files: /dev/diskette ...
device: sr0 type: sr files: /dev/sr0 ...
It is also possible to prevent a device from being used entirely.
Auditing
Solaris supports auditing, that is, collection of data about system usage, at the kernel level. Solaris auditing can be configured to generate audit records for a wide variety of events.
Basic Audit Reporting Tool (BART)
Unrelated to the kernel-based auditing mentioned earlier, BART is a tool that can be used to determine what file-level changes have occurred on a system relative to a known baseline. Thus, BART is a file-tracking tool, and it operates at the filesystem level. It allows you to define which files to monitor, and you can use it to create a control manifest — a baseline, or a trusted data set — from a fully installed and configured system. For each file being monitored, the manifest includes information about the file's attributes, its MD5 checksum, etc.
# bart create -R /etc > /tmp/etc.ctrl.manifest
# touch /etc/DUMMY
# chmod 444 /etc/zshenv
# bart create -R /etc > /tmp/etc.test.manifest
# cd /tmp
# bart compare etc.ctrl.manifest etc.test.manifest
/DUMMY:
delete
/zshenv:
mode control: 100444 test:100644
acl control:user::r--,group::r--,mask:r--,other:r-- \
test:user::rw-,group::r--,mask:r--,other:r--
Automated Security Enhancement Tool (ASET)
ASET is a security package that provides automated administration tools for controlling and monitoring system security. It runs various tasks that perform specific checks and adjustments based on the level at which ASET is run — one of low, medium, or high (access permissions of many files restricted). ASET tasks include:
- System file permissions tuning
- System file checks
- User and group checks
- System configuration files check (in /etc)
- Environment variables check
- EEPROM check
- Firewall setup
In a typical usage scenario, ASET would be run periodically via a crontab entry.
Solaris Security Toolkit (JASS)
This toolkit, also known as the JumpStart Architecture and Security Scripts (JASS), helps in simplifying and automating the process of securing a Solaris system. This process includes minimizing (removal of unnecessary packages) and hardening (performing modifications aimed at improving system security). JASS includes a profiling tool, a reporting tool, and undo capability.
Access Control Lists (ACLs)
In additional to conventional Unix file permissions, Solaris supports access control lists for files and directories. Using ACLs, you can define default and specific permissions for the file or directory owner, group, others, and for specific users or groups.
The getfacl and setfacl commands can be used to view and set file ACLs, respectively.
Solaris Cryptographic Services
Solaris includes a central framework of cryptographic services for kernel-level and user-level consumers, such as Internet Key Exchange (IKE), Kerberos, IPsec, and end-users encrypting/decrypting data.
The framework includes user-level, kernel-level, and hardware plugins.
# cryptoadm list
user-level providers:
/usr/lib/security/$ISA/pkcs11_kernel.so
/usr/lib/security/$ISA/pkcs11_softtoken.so
kernel software providers:
des
aes
arcfour
blowfish
sha1
md5
rsa
kernel hardware providers:
Solaris Authentication Services
Solaris includes support for various authentication services and secure communication mechanisms:
- Secure RPC and Secure NFS
- Pluggable Authentication Module (PAM)
- Simple Authentication and Security Layer (SASL), a layer that provides authentication and optional security services to network protocols
- Sun Enterprise Authentication Module (SEAM), a client/server architecture that provides secure transactions over networks. It is a single-sign-on system providing once-per-session user authentication, as well as data integrity and privacy. Note that SEAM is essentially Kerberos V5.
- Support for Smart Cards
- Solaris Secure Shell
While PAM is widely used on many systems today, it was introduced on Solaris. PAM provides a uniform abstraction (through a library interface) for a number of authentication mechanisms. Thus, if an authentication mechanism changes, or a new one is introduced, services that use these mechanisms would not need to be modified.
Securing the PROM
On SPARC hardware, you can gain access to the OpenBoot PROM, even while the operating system is running (using the Stop-A keyboard sequence). This has obvious (and some non-obvious) security implications, such as:
- You could boot the system into single-user mode
- You could boot the system off another device, including the network
- You can read and write physical memory from within the PROM. You could use this to gain super-user privileges. Say, you are logged in as a normal user. If you know the address of the
procstructure of your running shell, you could compute the address of theuidfield within the credential structure, and overwrite it with a zero. Note that on recent versions of Solaris, it may not be possible for a normal user to determine the address of a process structure.
Thus, the administrator must protect access to the PROM with a password, or must disable breaking into PROM entirely.
Preventing Stack Executability
You can set the noexec_user_stack system variable to 1 in /etc/system to mark the stack of every process in the system as non-executable. Attempts to execute "code" from the stack will result in a SIGSEGV (segmentation fault). Moreover, such attempts can be logged by setting noexec_user_stack_log to 1.
Note that this feature is available on SPARC and AMD64, but not IA-32, as the latter does not implement a per-page execute bit in hardware.
Automated Patching
Solaris includes support for downloading, verifying the signatures of, and installing patches automatically, possibly based on a specified criteria (for example, installations of those patches that would not require a system reboot).
<<<
Sandboxing
|
main
|
Miscellaneous
>>>
|