Rate this page del.icio.us  Digg slashdot StumbleUpon

Writing policy for confined SELinux users

by Dan Walsh

Last month, I wrote about confining the user with SELinux. I explained that–as of Fedora 9–SELinux supports the concept of the confined user and comes with 5 confined user types defined.

  • guest_t – Terminal login, nosetuid, nonetwork, noxwindows, noexec in homedir
  • xguest_t – X Windows Login and terminal login, nosetuid, nonetwork, noexec in homedir
  • user_t – X Windows Login and terminal login, nosetuid, noexec in homedir
  • staff_t – X Windows Login and terminal login, nosetuid except sudo
  • unconfined_t – Full login, able to run with almost all privs as with SELinux disabled.

These confined users are a great starting point, but what if you want to create a confined user with different privileges?

I want to create a limited privilege terminal login user with the ability to send mail and read/write files in the /maildir directory.

My son Timothy uses his confined xguest account, but is not happy because he wants to communicate with his friends using AOL.

Fedora 9 has the solution. The SELinux management environment (system-config-selinux) has been updated and includes the ability to build customized SELinux policy modules for the confinement of users.

Remember, this tool is just a wizard–it helps create a framework for building policy. You can then use tools like audit2allow or the package eclipse-slide for further editing of the policy. Thiswill give you a good head start.

In the toolbar panel select:

System->Administration->SELinux Management

This starts system-config-selinux.

Fig 1

Select Policy Module and then Select the New button.

Fig 2

This will start the policy template generator (polgengui).

Fig 3

Click Forward.

Fig 4

As you can see, this screen has been enhanced to allow the creation of policy for confined users as well as confined applications. Writing policy for confined applications was described in a previous article.

The second column, Login Users, allows you to build policy modules that either customize existing user roles or create brand new roles. Selecting Existing User Roles allows you to build policy to change one of the default user types defined above. (guest, xguest, user, staff). Select one of the other radio buttons to define a new user role, based off of the 4 default user roles.

  • Minimal Terminal User Role == guest_t
  • Minimal X Windows User Role == xguest_t
  • User Role == user_t
  • Admin Role == staff_t

The final column, Root Users, allows you to define a user type that other user types can transition to when they are running as root. For example you could define a root role, dbadm, to administer the mysql database. You could set up the staff role to transition to this role using sudo.

I want to create a limited privilege terminal login user with the ability to send mail and read/write files in the /maildir directory?

In order to answer this question, we want to create a new Minimal Terminal User Role called mailuser.

Select Minimal Terminal User Role, and press Forward.

Fig 5

Fig 6

This screen displays a list of confined domains to which this role might transition. For example, if you wanted the mailuser to transition to the ethereal domain you would select this now. Since we do not want any transitions we will just hit forward.

Fig 7

This screen allows you to select other roles to which the current role can transition. This is where you would define the transition to dbadm from staff role described above. We will just hit Forward.

Fig 8

This screen allows you to select ports that the user can listen to. If the confined user was going to run a network server you could select the ports here. We will just select Forward.

Fig 9

Finally, we get to a screen which defines the ports the confined user can connect to. We will select the smtp port #25 and then go forward again.

Fig 10

This screen allows you to define a boolean. If you wanted to allow our confined user to connect to the mail port, only if the “allow_mailuser_sendmail” boolean is set, we could create the boolean here. We are not going to do this so select forward.

Fig 11

This screen allows us to select the directory to write the policy framework into. The directory must already exist.

Fig 12

This final screen tells you which files you are about to create. Press Apply.

Fig 13

The tool will create the following policy:

#vi /root/mailuser/mailuser.te
     # Declarations

This one interface defines all the interaction of a guest user.

     # mailuser local policy
     allow mailuser_t self:tcp_socket create_stream_socket_perms;

These interfaces allow the mailuser_t to communicate with the smtp ports. Also, the policy generation tool added an interface to resolve host names. We now have enough policy to allow a mailuser_t to login to a machine and connect to a mail server, but not to read/write files to /maildir. This tool is just a framework-generating tool, not a policy editor. We will need to write policy for handing the /maildir directory ourselves. Since we want a directory that the mailuser can read/write to, we need to define a new type, mailuser_rw_t, then we need to tell the system that this is a type that affects files.

type mailuser_rw_t;

We also need to allow mailuser_t to manage files and directories of this type:

manage_dirs_pattern(mailuser_t, mailuser_rw_t, mailuser_rw_t)
manage_files_pattern(mailuser_t, mailuser_rw_t, mailuser_rw_t)

We are done with the mailuser.te file.

Now, we want to define the file context in the mailuser.fc file:

# vi /root/mailuser/mailuser.fc

/var/maildir(/.*)?                  gen_context(system_u:object_r:mailuser_rw_t,s0)

We use regular expressions to define the path.

Now we can run the shell script to compile the policy and install it to the test system.

#  sh mailuser.sh
Building and Loading Policy
+ make -f /usr/share/selinux/devel/Makefile
Compiling targeted mailuser module
/usr/bin/checkmodule:  loading policy configuration from tmp/mailuser.tmp
/usr/bin/checkmodule:  policy configuration loaded
/usr/bin/checkmodule:  writing binary representation (version 8) to tmp/mailuser.mod
Creating targeted mailuser.pp policy package
rm tmp/mailuser.mod.fc tmp/mailuser.mod
+ /usr/sbin/semodule -i mailuser.pp
+ /usr/sbin/semanage user -a -R mailuser_r mailuser_u

At this point we have a new SELinx user mailuser_u installed on the machine. We want to assign a linux user to this type:

# semanage login -a -s mailuser_u dwalsh

We also want to create the directories /var/maildir:

# mkdir /var/maildir
# restorecon /var/maildir
# chown dwalsh:dwalsh /maildir

Now dwalsh can log in and use the /var/maildir directories.

But what about my son and his friends on AOL?

My son Timothy uses his confined xguest account, but is not happy because he wants to communicate with his friends using AOL.

I want to confine my son’s account so that only Firefox can talk to internet ports–but I want to allow his account to communicate with AIM/AOL. I can customize the xguest account and add this access.

Back at system-config-selinux I select New to create a new policy module.

Fig 2

I click forward through the intro screen to get to the policy module selection screen.

Fig 14

I want to modify an existing user role, so I click on Existing User Roles and then click forward.

Fig 15

The next box shows me the list of all exising user roles. Select xguest. The tool will add “my” to the policy name and create policy files named myxguest.

Click forward through the next couple of screens, until you reach the network connect screen.

Fig 16

Add the AOL Ports as a comma separated list, then click forward until the end.

Fig 17

Now take a look at the myxguest.te file that was created:


      type xguest_t, xguest_devpts_t, xguest_tty_device_t;
      role xguest_r;

# xguest customized policy


allow xguest_t self:tcp_socket create_stream_socket_perms;

allow xguest_t self:udp_socket { create_socket_perms listen };

The tool added the AOL ports and the ability to resolve their hosts.

Compile to install the new policy like so:

sh myxguest.sh

Since I had previously set my son up to log in as xguest_u, no user management would need to be done. He can now use AOL Instant Messages in a secure environment.

If I had not set up his account I would need to execute:

# semodule login -a -s xguest_u twalsh


usermod -Z xguest_u twalsh

These examples show that it is fairly simple to extend SELinux confined users. If you need more advanced features, you can use system-config-selinux to build the framework and then use audit2allow or eclipse-slide to do further policy generation.

Next time, we will cover confinement of the root user.

10 responses to “Writing policy for confined SELinux users”

  1. “Writing policy for confined SELinux users” - Red Hat Mag | ThomasNicholson.com says:

    […] I found this in my security feeds yesterday.  I’m currently teaching a security policies and procedure class, from a management perspective so this is something currently on my mind.  For any of my students working with Linux here is an article about writing policies in SELinux to manage users.  The article is from Red Hat Magazine and is focused on Fedora and provides links to other articles about SELinux for those new to it. […]

  2. aziz says:

    dear editor
    I new for FC9 from oldest FC i looking for a solve for my problem in FC9 that is no privilege to setup any new software or update my software even to root the screen tell me you can not enter as a root but as user what can i do Help please

  3. Dan Walsh says:

    Aziz I do not know what you are asking?

  4. Ashok Harnal says:

    Good article.
    The author does work very hard.

  5. Sachin Gopal says:

    Dan, I am a regular follower of your blog.Wanted to say that today If I can say I know a bit on SE-linux Its just because of you. Thank you and keep up the good work.

    –Sachin Gopal

  6. جک says:

    thank you

  7. ericdes says:

    How do I get the SELinux context of a user with no login, example: postgres?

  8. Dan Walsh says:

    ericdes That does not make sense. A process has a context. So in reality the default context for a user is really the context of the initial shell that is run for the user. So since postgres never actually logs in there is no context associated with it. The postgresql daemon run as postgresql_t, You can see this by executing ps -eZ | grep postgres

  9. Kevin says:

    I’m new to SELinux and found your article (and almost all other SELinux articles) a bit discouraging, though I’m sure if I understood it, it would have been useful. I’d like to learn more about SELinux and how to use it. Do you have any suggestions on where to start? An uptodate book perhaps? Some good resources online maybe? Everything I find seems to either be for SELinux developers or just snippets of useful information (like this article). I need to understand the basic tools and concepts first. Please help.

  10. Dan Walsh says:

    danwalsh.livejournal.com Has lots of information similar to this. Start reading it from the beginning. We are in the process of writing a simple users guide for SELinux at http://fedoraproject.org/wiki/SELinux

    There is also a fedora-selinux mailing list, #selinux on freenode.

    “SELinux by Example” is the most up to date book available.