Creating Systrace Policies


In a true paranoid's ideal world, sysadmins would read the source code for every application on their system and be able to build system call access policies by hand relying only on their intimate understanding of every feature of the application. Most system administrators don't have that sort of time and would have better things to do with that sort of time if they had it. You have a couple of choices for building system call policies in the real world: using an available policy or using a tool to build your policy for you.

Public Systrace Policies

The Hairy Eyeball project, at http://blafasel.org/~floh/he/, contains systrace policies for hundreds of programs. Even if you only want to use systrace for one or two programs, I recommend that you download the entire Hairy Eyeball distribution, for use as examples if nothing else. Using a predefined policy can save you a lot of annoyance, but you still need to be able to edit these to fit your particular circumstances. Also, you'll have to generate policies from scratch for programs that are not in the repository.

Policy Generation with systrace(1)

Systrace(1) includes a policy-generation tool that will generate a policy that lists every system call the application wants to run. You can then use that policy as a starting point to narrow down the access you will give the application. We'll use this method to generate a policy for inetd(8). Use the "-A" flag to systrace and the full path to the program you want to run.

 # systrace -A /usr/sbin/inetd 

If you had any flags to add to inetd, you would add them at the end of the command line.

Now exercise the program you're developing a policy for. This system has ident, daytime, and time services running out of inetd(8), so run programs that require those services. Fire up an IRC client to trigger ident requests, and telnet to port 13 and 37 to get time services.

Once you have put inetd through its paces, shut it down. Inetd has no control program, so you need to kill it by process ID. Checking the process list for inetd will show two processes:

 # ps -ax | grep inetd 24421 ??  Ixs     0:00.00 /usr/sbin/inetd 12929 ??  Is      0:00.01 systrace -A /usr/sbin/inetd # 

Do not kill the systrace process, pid 12929 in this example! That process has all the records of the system calls that inetd(8) has made. Just kill the inetd process, and the systrace process will exit normally.

Now check your home directory for a ".systrace" directory, which will contain systrace(1)'s first stab at an inetd(8) policy. Remember, policies are placed in files named after the full path to the program, replacing slashes with underscores.

 # ls .systrace usr_libexec_identd  usr_sbin_inetd # 

Systrace created two policies, not one! In addition to the expected policy for /usr/sbin/inetd, there's one for /usr/libexec/identd. If you're familiar with inetd(8), you've probably already guessed why this happened. Those new to inetd should go off to the /etc/inetd.conf discussion in Chapter 14, where they would learn that the time services are implemented internally within inetd, while ident requires a separate program that inetd calls to service requests. As inetd(8) spawned identd(8), systrace(1) captured the identd system calls as well.

By reading the policy, you can improve your understanding of what the program actually does. Look up each system call the program uses, and see if you can restrict access further. An experienced systems administrator can probably find ways to tighten access, but junior sysadmins can just use the autogenerated policy. If you just run the autogenerated policy, you're already improving your system's security. For example, the autogenerated policy contains rules that only allow it to listen on particular TCP/IP ports and only read certain files on the system.

Using Systrace Policies

Applying a policy to a program is much like creating the systrace policy itself; just run the program as an argument to systrace, using the "-a" option.

 # systrace -a /usr/sbin/inetd 

If the program tries to perform any system calls that are not listed in the policy, the system call will fail. This may cause the program to behave unpredictably. Systrace will log failed entries in /var/log/messages. For example, after running inetd under this particular systrace policy I found messages like this throughout /var/log/messages:

 Dec  2 01:31:11 openbsdtest systrace: deny user: _identd, prog: 1 /usr/libexec/ identd, pid: 27046(1)[12989], policy: /usr/libexec/identd, filters: 24, syscall: native-fsread(5), filename: 2 /etc/spwd.db Dec  2 01:31:11 openbsdtest identd[27046]: /etc/pwd.db: Operation not permitted Dec  2 01:31:11 openbsdtest identd[27046]: getpwuid() could not map uid (25) to name 

We can trace this back and see what exactly happened. In the first log entry, 1 identd tried to read 2 /etc/spwd.db. This is the secure hash of the password file. Identd(8) should certainly be able to look up system users -- that's the service it provides, after all! I'm not certain why identd(8) wants the secure version of this hash, however. This needs to be researched. On the other hand, if nothing seems to be breaking, you might just want to live with it.

Editing a policy is very simple: Just add the desired statement to the end of the rule list, and it will be picked up.




Absolute Openbsd(c) Unix for the Practical Paranoid
Absolute OpenBSD: Unix for the Practical Paranoid
ISBN: 1886411999
EAN: 2147483647
Year: 2005
Pages: 298

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net