Posts tonen met het label SELinux. Alle posts tonen
Posts tonen met het label SELinux. Alle posts tonen

donderdag 10 september 2009

Some SELinux experiences that i want to share with you:


Disclaimer: I am just thinking out loud here, and i am sure that in some cases i do not fully understand the complexity or the underlying ideas of, and behind the issues that i am about to describe.

1. (not fedora specific)
User space processes own files on tmpfs for pulseaudio. These user space processes want to read (and unlink) each others pulseaudio files on tmpfs. To facilitate this, it requires much policy and also by allowing a user space process to read another user space processes pulseaudio tmpfs files , you also give it access to the user space process non pulseaudio tmpfs files. which might not be desired.

maybe somehow we can implement a attribute for user space processes pulseaudio files on tmpfs. and/or create a generic interface for this interaction.

3. (fedora specific)
xserver policy has been modified and xserver_user_x_domain_template and xserver_x_domain_template have been added. These templates could be used instead of xserver_user_client and xserver_common_app.

By calling these templates other xserver related policy in the domain that call it can for a large part also be removed. The interfaces mentioned above include most of the required xserver policy for user and application processes to function.

There are some notable exceptions:

xserver_rw_xdm_home_files

Also it appears that the interfaces mentioned above were designed with mls policy in mind. To be able to enable xserver object manager in a way that could benefit targeted policy i think a solution could be found so that xserver policy can be easily extended to provide a basic multi purpose useable policy for targeted as well ( maybe create interfaces for the various scenarios ) so that interfaces (or maybe tunable policy) can be called to make xserver object manager work in a basic form and/or specific form in targeted policy.

So that the admin can easily extend xserver policy for his custom needs without having to write local policy himself or having to implement his own custom interfaces, at least as much as possible.

An example of stuff that currently has no policy implemented but in many cases is required is for example the functionality to change mouse button (for left handed people) and the use of acceleration (3d)

Also we should keep in mind that there is a allow_write_xshm boolean that probably should be used where ever required instead of allowing access to this by adding fixed policy.

My point is that i think xserver object manager could at least to some extend be usable in a targeted policy, and that it could be extendible. Currently in fedora there is no easy way to make openoffice work nice with XACE. I cannot extend its policy due to 'not within scope issues' (user domain prefixes). The java SELinux implementation suffers similar issues.

3. (not fedora specific)
This also brings me to staff and user domains. These domains do not have access to some devices (cannot rw to dri, cannot rw to wifi, webcam etc) maybe we should implement some booleans for this with a $1. e.g. userdom_$1_use_dri etc. or maybe create users domains that add this functionality. I think this is a requirement to makes confined domains acceptable for day-to-day GUI use. Also the allow_execmem boolean is a bit too coarse. Lets face it we are not close to a working none execmem/execstack environment yet. For example nautilus requires it, totem, etc. many of these apps run in the user domain. Setting allow_execmem would in my view be overkill to just allow a single user domain execmem permission. allow_$1_execmem, where $1 is a specific user domain would in my view be a reasonable temporary solution. In either case i do not think we should just ignore the issue.

The "easy" access to execmem and devices like dri are in my view important to help make confined user domains usable for the general public in a GUI environment.

zondag 12 juli 2009

FAQ: SELinux denies access but AVC denials can not be found.

It happens. There are a few reasons for this:

1. Silenced AVC denials (access vector cache).

In policy one can define to silently deny access vectors. This means access is denied and attempts are not logged. Such a rule (access vector) would look like this for example (fictional):

dontaudit user_t var_t:dir { read open };

When a user that operates in the user_t user domain tries to read a var_t directory object type, access is denied. The attempt that was denied would not be logged.

In general the use of "dontaudit" rules should be kept to a minimum. The issue of being denied access and not finding an audit trail for this reason should not happen often at all.

There are exceptions, like restricted user domains. These processes are restricted/limited for reason and those restrictions/limits might give violation attempts when a user operating in such a domain tries to do something that is not allowed. In this case the AVC denials are anticipated and silenced to avoid flooding of the logs with meaning less entries.

There is a way to expose these silenced AVC denials, but be aware that this may fill up your logs quicker than expected.

The semodule command used with the -DB options unloads "dontaudit" rules on-the-fly. All attempts to violate policy are now logged.

The semodule command used with the -B option builds the policy with the "dontaudit" rules included. Silenced AVC denials are back in policy.

2. User space object managers.

User space object managers are SELinux extensions on application layers. Applications that implement a SELinux Access Control Extension provides classes and permissions to be used for SELinux Policy. The application itself enforces policy that is defined using the classes and permissions it has provided.

There are only few applications that are also user space object managers. DBus implements this and this feature is enabled by default. If some access is denied and you've unloaded the "dontaudit" rules using the semodule command with -DB option, but you still cannot find any audit trail, then chances are the DBUS access control extension is responsible.

In some cases, which might be due to a bug, DBUS sends its user_avc denials to /var/log/messages instead of the expected /var/log/audit/audit.log

So it is recommended to also see /var/log/messages or dmesg if you suspect SELinux denied access but you cannot find any audit trail.

SELinux denials are called AVC denials and can also be listed using the ausearch command with -m option and avc parameter.

User space object manager denials are called USER_AVC denials and can also be listed using the ausearch command with the -m option and user_avc parameter. Note that this only works for denials logged to /var/log/audit/audit.log

Conclusion:

If you suspect SELinux denied some access but you can not find the audit trail then consider building the policy without the "dontaudit" rules using semodule -DB. If you still cannot find any audit trail than maybe a user space object manager denied access. Look for USER_AVC denials in audit.log or look in /var/log/messages, or dmesg. The log file for the application itself may also have them.

I think the goal is to have everything log to audit.log for simplicity but at the moment this is not the case.

Tip:

You can use the sesearch command to list "dontaudit" rules that are currently built-in policy. For example to list "dontaudit" rules where the httpd_t is the source domain:

sesearch --dontaudit -s httpd_t

Have a look at "man sesearch"

maandag 29 juni 2009

Multi Category Security

Multi Category Security or MCS is a discretionary implementation of the mandatory Multi Level Security or MLS Model. SELinux Policy MLS is a SELinux Policy model that is used in Department of Defense type environments. In a MLS environment processes are forced to operate on specified Security Levels. The s0 Security Level or SystemLow level is the lower end of the Security Level Range in a MLS environment. The s15 Security Level or SystemHigh level is the upper end of the Security Range in a MLS environment. Between the low and upper end there are fourteen levels to be used.

In MLS there is a rule that says: "no read up and no write down". This means that processes that are forced to operate on for example Security Level s14 can not read processes or files that operate on the s15 Security Level. Processes that are forced to operate on the s5 Security Level can not write to files or interact with processes on the s4 Security Level. The MLS model is used to enforce confidentiality.

MCS basically tries to use the MLS attributes: Security Levels and Security Compartments, in its own model in a way that may be useful in common environments. SELinux Policy Targeted can be build with the MCS functionality. Red Hat distributions have this MCS functionality enabled by default in its Targeted SELinux Policy model. Gentoo Hardened, as far as i know, does not have MCS functionality builtin by default.

MCS pretty much works like the DAC Extended attributes. Users are assigned categories and can apply these categories to content that they own to their discretion. You can easily recognise a MCS enabled system by looking at security contexts. A system that has SELinux Policy Targeted implemented without MCS enabled only has three fields in its Security Context tuples: user_u:role_r:type_t. Systems that have MCS implemented have one or more extra fields in their Security Context tuple: user_u:role_r:type_t:s0:c0. In MCS policy there is only one Security Level. This SystemLow level is s0. MCS does have 1024 categories that can be assigned to processes and files. Categories are the last field in the Security Context tuple. In a MCS environment s0:c0.c1023 is SystemHigh or the upper end of the MCS range. This means that if you are assigned the SystemHigh MCS range that you can access all categories. By default everything in a MCS environment has access to SystemLow or s0.

Example:

Create a new SELinux User that is based of off the user_u SELinux User. Call this SELinux User for example "mcsuser_u" and assign the full MCS range to this SELinux User:

sudo semanage user -a -L s0 -r s0-s0:c0.c1023 -R user_u -P user mcsuser_u
sudo cp /etc/selinux/targeted/contexts/users/user_u /etc/selinux/targeted/contexts/users/mcsuser_u

( to list the differences between SELinux User user_u and mcsuser_u simply: sudo semanage user -l | grep user_u )

Now create three Linux Users and map them to the mcsuser_u SELinux user. Give John access to the s0-s0:c122 MCS range. Give Jane access to the s0-s0:c123 MCS range, and give johnjane access to the s0-s0:c122,c123 MCS range.

sudo useradd john
sudo useradd jane
sudo useradd johnjane
sudo semanage login -a -s mcsuser_u -r s0-s0:c122 john
sudo semanage login -a -s mcsuser_u -r s0-s0:c123 jane
sudo semanage login -a -s mcsuser_u -r s0-s0:c122,c123 johnjane

Login as john, touch file with name test and list its attributes:

# touch test; ls -Z test;
mcsuser_u:object_r:user_home_t:s0 test

The file was created on the s0 SystemLow level which is accessible by everything. Now add the c122 category to the file with the chcat command, and list the SELinux attributes of file test:

# chcat -- +s0:c122 test
# ls -Z test
mcsuser_u:object_r:user_home_t:s0:c122

If you try to add for example category s0:c123 to the file you will be denied access to do so because your assigned MCS range does not include the s0:c123 category.

Try the same procedure for Jane but instead use the s0:c123 category.

Linux User johnjane has access to both s0:c122 and s0:c123 MCS categories. In a shared location where DAC permissions are sufficient johnjane would be able to access both files with s0:c122 as well as s0:c123 categories.

Johnjane can also assign both s0:c122 and s0:c123 to a single file, but then neither John nor Jane woould be able to access it.

If all these MCS category digits make you dizzy then you can install mcstrans. Mcstrans is a daemon that translates the MCS category numbers into strings of letters which are easier to work with. The mcstrans daemon has some problems though.

# sudo yum install mcstrans
# chkconfig mcstrans on
# service mcstrans start

Now one can add translations for the MCS category digits with the semanage command.

Translate s0:c122 to JohnsFriends, s0:c123 to JanesFriends, and s0:c122,c123 to JohnJanesFriends:

# sudo semanage translation -a -T JohnsFriends s0:c122
# sudo semanage translation -a -T JanesFriends s0:c123
# sudo semanage translation -a -T JohnsJanesFriend s0:c122,c123

( use sudo semanage translation -l to list current translation mappings )

Note: After this the mcstrans may have died. If required restart the mcstrans daemon.

# sudo service mcstrans restart

Users can use the chcat command to list which categories they have assigned:

# chcat -L john
john: JohnsFriends

User can also use the id command with the -Z option to view their security context. The context displays to categories.

# id -Z
mcsuser_u:user_r:user_t:SystemLow-JohnsFriends

Conclusion:

MCS is a neat extra functionality that can be enabled on systems that have SELinux Targeted Policy implemented.
The functionality of MCS is similar to that of Extended Attributes.


man: chcat, man semanage, man id

zondag 28 juni 2009

Mystaff SELinux User Domain

The staff module provided by Refpolicy is pretty cool but i needed a user domain with less privileges that would be able to transition to privileged admin domains.

One of my requirements was that this User Domain should only be accessible via OpenSSH and that it should be identical to the guest_t User Domain or have even less privileges. The guest_t User Domain was designed to not User Domain transition ever.

Another requirement for my mystaff User Domain was that this user should not be able to change passwords. I did this because the provided staff_t User Domain by Tresys can change passwords. If i sudo to root in the staff_t User Domain than in theory i would be able to change the root password. This is something i wanted to prevent for mystaff user.

Generally i wanted mystaff to have as little privileges as possible. It would be a very restricted login environment only accessible with OpenSSH that would be able to transition to specified admin User domains like for example webadm_t.

I started by reverse engineering the staff_t User Domain:

http://oss.tresys.com/projects/refpolicy/browser/trunk/policy/modules/roles/staff.te
http://oss.tresys.com/projects/refpolicy/browser/trunk/policy/modules/roles/staff.if

The staff.te file is mostly one call to a interface that is defined in the userdom modules interface file:

http://oss.tresys.com/projects/refpolicy/browser/trunk/policy/modules/system/userdomain.if ( line 927 to line 1020)

So far so good, but this interface has calls to to included several other interfaces that are defined in the same interface files:

userdom_restricted_user_template($1)
userdom_common_user_template($1)

These interfaces have calls to yet other interfaces defined in userdom.if file and so forth and so forth.

userdom_login_user_template($1)
userdom_basic_networking_template($1)

Which call:

userdom_base_user_template($1)
userdom_manage_home_role($1_r, $1_t)
userdom_manage_tmp_role($1_r, $1_t)
userdom_manage_tmpfs_role($1_r, $1_t)
userdom_exec_user_tmp_files($1_t)
userdom_exec_user_home_content_files($1_t)
userdom_change_password_template($1)

My goal was to expand all these userdomain interfaces so that i could remove parts of policy in there that i did not need.

Since i did not want mystaff to be able to change passwords i could for example remove the userdom_change_password_template altogether.

I also wanted mystaff to easily be customizable for different admin domain transitions and i started making different admin domains based of off webadm User domain. Basically i edited the name and declarations and replace the apache_admin interface calls by admin interface calls for other services. I also remove some policy specific to webadm.

For example:

http://oss.tresys.com/projects/refpolicy/browser/trunk/policy/modules/services/aide.if (line 46 to line 71)

The interface to call for administration of the aide domain.

Long story short. Below you will find the links to the mystaff user domain that is based of off the staff domain provided by upstream. In mystaff module i have expanded all userdom interface calls and i have removed policy that i did not require.

Basically the mystaff_u SELinux user is even more restricted then guest_u but unlike guest_u, mystaff_u can use sudo to user domain transition to admin domains. By default i have it call the webadm_role_change interface which allows mystaff_r access to the already by default installed webadm_r role. I also used the gen_user() macro to generate a mystaff_u SELinux User. However this SELinux user does not yet have the webadm_r role mapped. One could simply use semanage user -m <...> mystaff_u to add the webadm_r or edit the gen_user() macro to recflect mystaff_u SELinux Users access to the webadm_r role.

You will also notice plenty commented role_change template calls for other services. One can simple uncomment any of these calls to allow mystaff_r access to the role these provides. This requires that you install the corresponding admin User domains which can be found in the same modules directory.
It is then also required to map any of these roles to the mystaff_u SELinux User.

http:///82.197.205.60/~dgrift/stuff/modules/mystaff.te
http:///82.197.205.60/~dgrift/stuff/modules/mystaff.if
http:///82.197.205.60/~dgrift/stuff/modules/mystaff.fc

Other source policy modules:
http:///82.197.205.60/~dgrift/stuff/modules/

By the way: the mystaff module can be easily modified to reflect a myguest modified guest User Domain. Just comment:
optional_policy(`
sudo_role_template(mystaff, mystaff_r, mystaff_t)
')

# Available privileged roles
# Test
optional_policy(`
webadm_role_change(mystaff_r)
')
In that case one may also want to rename the mystaff to something more appropriate. One can simply modify this policy to add or remove privileges.

Oh, by the way, do not forget to add default contexts for mystaff_u. You can base you mystaff_u default context file of off the staff_u file in /etc/selinux/targeted/contexts/users/. All you have to do is replace staff by mystaff in this file. (see my previous article on creating custom user domains)

Policy module source

In this article i will try to explain a bit more about the policy module source files.

A policy module source has three files. The first file is a Type Enforcement file. These files have the .te extension. The second file is a interface file. These files have a .if extension. The third file is called a file context file. This file has a .fc extension.

Type enforcement source policy file.

This file has policy and declarations that a personal or local to the policy module. Policy that is used by the (personal) types that are declared in this module.

Interface source policy file.


This file has policy and declarations that are shared with other types.

File context source policy file.

This file has personal file contexts for the personal types that are (usually) declared in the Type Enforcement file.

Some background information:

Example of a AVC denial:

avc: denied { read write } for pid=1864 comm="tor" path="/dev/console" dev=tmpfs ino=496 scontext=system_u:system_r:tor_t:s0 tcontext=system_u:object_r:console_device_t:s0 tclass=chr_file

Example of the AVC denial when processed by audit2allow:

allow tor_t console_device_t:chr_file { read write };

Example of the AVC denial processed by audit2allow -R:

term_use_console(tor_t)

The AVC denial has a lot of information about details of a denied rule in the Access Vector Cache. The basic audit2allow command translates this AVC denial into human readable policy language. The
audit2allow -R command goes looking for any available shared policy that may be available for us to use.

In this example the
tor_t domain wants to read and write to /dev/console which is a character device file that has type console_device_t. Tor interacts with terminal.

To make policy manageable and to keep the footprint of policy as small as possible the concept of shared policy is used. There is no need for duplicate policy. There should be a single point where a certain access is defined. This point is defined in the interface file of the target.

In this example
term_use_console is shared policy that is hosted by the module that declared(owns) type console_device_t. Interfaces (shared policy) are usually prefixed by the name of the module that own the type of the target.

The
tor_t domain tries to read and write to console_device_t which is a type that is declared in the terminal.te source policy file. The terminal.if interface file hosts policy to interact with this type properly: term_use_console. term is the abbreviation for terminal which is the name of the module that hosts the console_device_t file.

The type
console_device_t is declared here -- it is a declaration the is personal to the terminal policy module (terminal.te):

http://oss.tresys.com/projects/refpolicy/browser/trunk/policy/modules/kernel/terminal.te (line 21)

The interface
term_use_console is defined here -- it is policy that is shared (hosted) by the terminal policy module (terminal.if):

http://oss.tresys.com/projects/refpolicy/browser/trunk/policy/modules/kernel/terminal.if
(line 219 to line 237)

The terminal module own the
console_device_t type and shares all policy other types need to be able to interact with this type. If something changes in the way that interaction is done with this type then the terminal.if is a central point to modify policy for this. Other types simple call this shared policy and changes automatically get synchronized.

Shared policy usually have a commented header which explains the purpose of the interface and the parameters it expects when it is called.

For term_use_console the description is:


Read from and write to the console

And the parameter it expects is:

Domain allowed access.

If the tor_t domain wants to read and write to the terminal a device file with type
console_device_t then it can simple call the shared policy that is hosted in the terminal.if file, which is the file that shares policy and declaration with regard to types and domains that are personal to the terminal policy module.

Look at interfaces like BASH functions. You can source a external file that has BASH functions and then call any functions that are provided by the sources functions file.

The purpose of the commented headers is that it is easy to reference and call the interfaces. The source policy can be converted to html if you run "
make html" in the source root.

An example of this is hosted here:

http://oss.tresys.com/docs/refpolicy/api/


The specific term_use_console interface is specified here:

http://oss.tresys.com/docs/refpolicy/api/kernel_terminal.html


Below the commented header for the term_use_console interface the actual shared policy can be found. This policy often has calls to shared policy for types that are external to the module. In this case the term_use_console as a interface call to
dev_list_all_dev_nodes($1) Which is shared policy that is hosted by the devices module (interfaces defined in device.if).

The
$1 is a variable of the parameter is expects. Look up the interface name here: http://oss.tresys.com/docs/refpolicy/api/kernel_devices.html and see what parameter is expects: Domain allowed to list device nodes.

If a domain type
tor_t wants to list device nodes then simple call dev_list_all_dev_nodes(tor_t)

$1, $2, $3 etc are variables that replace parameter 1, parameter 2, parameter 3 etc.

Another rule in the term_use_console interface in terminal.if is:

allow $1 console_device_t:chr_file rw_chr_file_perms;


If term_use_console(tor_t) is defined than the rule is translated:

allow tor_t console_device_t:chr_file rw_chr_file_perms;

Which basically allows the
tor_t domain type read and write access to character files with type console_device_t.

The last thing to mention about the term_use_console interface and interfaces in general is the
gen_require() blocks that can be seen.

Since type
console_device_t is declared in terminal.te and since term_use_console is called by tor_t domain in the tor.te source policy file, the tor_t files has to borrow the console_device_t type which is external to the tor.te file.

The
gen_require() and require{} block basically source types that are declared in other modules. After the types are sourced they can be used in personal policy.

another example:

If you encounter a AVC denial than consider that the target type (tcontext type) usually hosts policy to facilitate the access that the source type (scontext type) in the AVC denial needs. Run the AVC denial through audit2allow to hav it translated to raw policy language. Run the AVC denial through audit2allow -R to have it look for any shared policy that facilitates the access that is required.

Of course you can also do this yourself:

avc: denied { read } for pid=1842 comm="smartd" name="config" dev=dm-1 ino=39859 scontext=system_u:system_r:fsdaemon_t:s0 tcontext=system_u:object_r:selinux_config_t:s0 tclass=file

The smartd executable that runs in the
fsdaemon_t domain wants to read a file with name config and with type selinux_config_t.

allow fsdaemon_t selinux_config_t:file read;

The module that has declared
selinux_config_t should also provide shared policy that facilitates the access fsdaemon_t domain needs.

I would expect that type
selinux_config_t would be declared in selinux.te since types and interfaces are often prefixed by the name of the module that owns it. In this case it is not so straight forward. A little peruse of the policy shows that this type is declared in the selinuxutil.te file.

So shared policy related to this type should be in the selinuxutil.if file. On line 595 in the selinuxutil.if interface file here:

http://oss.tresys.com/projects/refpolicy/browser/trunk/policy/modules/system/selinuxutil.if


This interface called
seutil_read_config can be called by fsdaemon_t if we wish to give that domain this permissions.

seutil_read_config(fsdaemon_t)

However policy decisions are usually not that simple to make. A better idea may be to use this interface on line 575:

seutil_dontaudit_read_config(fsdaemon_t)


File context files define file contexts of types that are declared in the policy module. Have a look at some of the many examples Type Enforcement, Interface and File contexts files available in Tresys Reference policy.

zaterdag 27 juni 2009

SELinux screencasts

Here are some screen cast where i demonstrate some of the things that were discussed in the SELinux Lockdown series.

1. Create custom SELinux users.

Here i create a new SELinux User called new_u and map the staff_r, system_r and unconfined roles to this user. This SELinux User also has also has access to all available MCS categories.

Linux user joe is mapped to the new_u SELinux user. Default contexts for new_u SELinux were copied from those of staff_u since new_u is based of off staff_u with minor modifications (access to unconfined_r instead of sysadm_r)

Sudo is also set up to allow joe root access and to automatically Domain Transition to unconfined_t User Domain.

http://www.youtube.com/watch?v=NmkQqNq0DJE



2. Quick demonstration of PAM SEPermit.

http://www.youtube.com/watch?v=-0qge9vtPjg



3. Quick demonstration of unconfined_login boolean.

http://www.youtube.com/watch?v=Ky3jm5n4f8M



4. How to extend staff_t User Domain to allow listing of /var (part1)

http://www.youtube.com/watch?v=0gaxh0lZ4MU



4.1 How to extend staff_t User Domain to allow listing of /var (part2)

http://www.youtube.com/watch?v=Rnrca8khz1w



5. Create a new unprivileged (secondary) User Domain.

http://www.youtube.com/watch?v=bDFTiZOteiA



6. The newrole command is useful for unprivileged User Domain transitions.

http://www.youtube.com/watch?v=9N0WsncDrfY



7. Demonstration of how to create a Application Domain to achieve listing of /var for staff_t (part1)

http://www.youtube.com/watch?v=c06sjcC9CNs



7.1 Demonstration of how to create a Application Domain to achieve listing of /var for staff_t (part2)

http://www.youtube.com/watch?v=U2GDBor1BsQ



7.2 Demonstration of how to create a Application Domain to achieve listing of /var for staff_t (part3)

http://www.youtube.com/watch?v=riXisTFPEzo



Looks like the last episode turned out a bit too long for YouTube. Heres a trimmed down version:

http://www.youtube.com/watch?v=9UJUxqf3NkY



Excuse my bad english and funny dialect :)

SELinux Lockdown Part Ten: Conclusion

A lot was discussed in the previous nine articles. This is the last article in this series. In this article i will in short repeat the steps to maximize the security that SELinux provides. Details about any of these steps can be found in the previous articles.

1. SELinux User.

Map Linux Users by default to a confined SELinux User. Think least privilege. Use for example guest_u: sudo semanage login -m -s guest_u -r s0-s0 __default__

If you wish to override the default SELinux User for a new Linux User then you can do so with the useradd and -Z option.

Do not map Linux users to the unconfined_u SELinux user. An exception to this rule can be the root user. Root users should not be allowed to login except via TTY in emergencies.

2. PAM SEPermit.

Add entries for all your confined SELinux Users to /etc/security/sepermit.conf to block logins when SELinux is in permissive mode.

You can decide to create a unique SELinux User for yourself that is exempted from SEPermit.

3. Permissive mode Vs. Permissive Domains.

Always prefer the use of Permissive Domains over Permissive Mode.

4. Do not modify your default SELinux Users. If you need a custom SELinux User and or SELinux user Domain then create a new one. You can base them of off existing ones.

5. Use Role based Access control to confine root and user privileges.

6. Do not modify existing Roles/ User Domains.

If you need a custom role then base it of off an existing role and map the new role to a new SELinux user. You can however map existing roles to new SELinux users.

7. Use sudo. Not SU and newrole.

8. Remove the unconfined domain(s).

Be sure to sudo semodule -r unconfined to disable system services that have no policy defined. use sudo semodule -r unconfineduser to completely disable unconfined user environments (not recommended) If you do decide to remove unconfineduser, then make sure to configure your SELinux User mappings to reflect this. Use sysadm instead of unconfined

I prefer unconfined User Domain over sysadm User Domain for a secondary all purpose privileged user domain because:

a. unconfined_login boolean can be set to disable unconfined user logins.
b. ssh_sysadm_login, and xdm_sysadm_login booleans do not work.
c. sysadm is a drunken unconfined.
d. root logins are disabled.
e. i only use unconfined user domain as a secundary privileged user domain that can only be accessed via sudo
e.1. except for the root Linux User which can only login via TTY in emergencies.


9. Remove as much policy as possible by either disabling or enabling booleans.

set unconfined_login to off
set xserver_object_manager to on
set *_exec_content to off
consider the secure_mode_booleans

SELinux Lockdown Part Nine: Booleans

Booleans are blocks of policy that can be added or removed on the fly by toggling a boolean. The old NSA Example policy was based on a least privilege model. This means that as little as possible was allowed to successfully achieve a task. Almost each rule that gets added to SELinux policy adds new privileges. To maximize security that SELinux provide the mount of active rules should be kept to a minimum.

In Fedora 11 There is some policy enabled with booleans that your environment may not need. It is recommended that this policy is removed and that it is only added when it is needed.

Some booleans add policy when enabled, others add policy when disabled. A simple description of a booleans functionality can be displayed with the command: sudo semanage boolean -l. These descriptions are usually enough to understand its functionality but the descriptions are short. If you run a AVC denial through the audit2why command than audit2why will display which boolean to set in order to solve the issue if the problem can be solved by toggling a boolean.

Sometimes it is best to look to the contents of booleans to understand what they allow. Booleans are defined in Source Policy. You would have to have access to the Source Policy and you would have to know how to find the blocks of policy that are the content of the boolean.

There are three older tools that help you list, set and toggle SELinux booleans: getsebool, setsebool and togglesebool. In Fedora 11 the functionality that these tools provides has been built into the semanage command: semanage boolean.

The names of booleans should point to the Source Policy Module where the boolean is defined. Unfortunately it often is not that easy to find the location of the boolean definition in Source Policy. In a prefect scenario that name of the boolean has the name of the module where it is defined prepended.

Example: How to find the meaning and content of gpg_agent_env_file boolean:

# semanage boolean -l | grep gpg
gpg_agent_env_file -> off Allow usage of the gpg-agent --write-env-file option. This also allows gpg-agent to manage user files.

As the name of the boolean suggest, the boolean is defined somewhere in the gpg module:

http://oss.tresys.com/projects/refpolicy/browser/trunk/policy/modules/apps/gpg.te
On line 196 to line 203 the actually content of the boolean is defined.

This boolean allows programs that run in the gpg_agent_t SELinux Domain to write files in the user home space with the generic user_home_t type when the boolean is set to on.

I think there is actually a but in the block of policy as the gpg_agent_t may only type transition to user_home_t files and not to directories.

The boolean declaration can be found on line 9 to line 15. The declaration has a short description of the functionality of the boolean.

The reason why i showed you how to find a description and the actual content of a boolean is because i cannot discuss each and every boolean in this article. If it is decided to lock-down booleans one can look up whether it actually adds or removes policy when toggled on and what it actually does. Then the boolean can just be switched on and off to see if you need to policy it provides. If required that AVC denials can be fed to audit2why to see if there is a boolean available to allow the functionality.

There are a few booleans that i would like to highlight in this article:

The unconfined_login boolean:

unconfined_login -> off Allow a user to login as an unconfined domain

This boolean was discussed the Part Eight of this series. If set to on then users can login to the system in the unconfined_t User Domain.
Security can be improved much by setting this to off. The content of this boolean can be found in the unconfineduser.te file in Source Policy.

The ssh_sysadm_login and xdm_sysadm_login booleans:

ssh_sysadm_login -> off Allow ssh logins as sysadm_r:sysadm_t
xdm_sysadm_login -> off Allow xdm logins as sysadm

This boolean is similar to unconfined_login for the sysadm_t User Domain. This boolean currently does NOT work. Therefore it is not recommended to map any SELinux Users to the sysadm_r role. Users with access to this role can log into the system directly in this privileged domain.

The *_allow_exec_content_t booleans:

allow_sysadm_exec_content -> off allow_sysadm_exec_content
allow_xguest_exec_content -> off allow_xguest_exec_content
allow_user_exec_content -> off allow_user_exec_content
allow_staff_exec_content -> off allow_staff_exec_content
allow_guest_exec_content -> off allow_guest_exec_content

The description of this boolean is not very helpfull as you can see. When this boolean is set to on then users that operate in any of the mentioned User Domains can execute user content in their user space. This means files with type user_home_t, user_tmp_t or when nfs or samba home directories are enabled types nfs_t and cifs_t respectively. This boolean is Fedora specific and its contents can be found in the userdomain.if Source Policy file.

The secure_module boolean:

secure_mode -> off Enabling secure mode disallows programs, such as newrole, from transitioning to administrative user domains.

The secure_mode boolean can be enabled to disallow User Domain transitions to privileged User Domains. The content of this boolean can be found in the selinuxutil.te Source policy file: http://oss.tresys.com/projects/refpolicy/browser/trunk/policy/modules/system/selinuxutil.te

The policy for this boolean starts on line 289 and ends on line 295. This boolean currently only works for the newrole command. It does NOT work for the sudo command. Therefore it is encouraged to not depend on this boolean.


The secure_mode_insmod boolean:

secure_mode_insmod -> off Disable transitions to insmod.

When this boolean is set to on then confined users will not be able to transition to the insmod Domain. Restricted user domain will not be able to insert Linux Kernel modules. This boolean is defined in the modutils.te Source Policy file: http://oss.tresys.com/projects/refpolicy/browser/trunk/policy/modules/system/modutils.te

The policy starts on line 120 and end on line 122. The declaration for this boolean can be found on line 4 to line 6.

The secure_mode_policyload boolean:

secure_mode_policyload -> off boolean to determine whether the system permits loading policy, setting enforcing mode, and changing boolean values. Set this to true and you have to reboot to set it back

The description of this boolean is quite good. When enabled there is no policy to permit the loading of policy, setting the enforcing mode and changing of booleans. This policy can be found in the selinux.te Source Policy file: http://oss.tresys.com/projects/refpolicy/browser/trunk/policy/modules/kernel/selinux.te

The content of this boolean starts on line 44 and ends on line 52.

The xserver_object_manager boolean:

xserver_object_manager -> off Support X userspace object manager

This boolean is quite powerful. By enabling this boolean the X Server access control extensions become enable. XACE allows the operator to define how processes can interact with X Server. The default policy still has rough edges. XACE is implemented for the SELinux Multi Level Security Policy Model which enforces confidentiality. By default it is disabled with SELinux Policy Targeted. If you feel brave, enable it and experience the power of Xace.
After you set this boolean to true you are required to restart the X server.

The content of this boolean can be found in the xserver.te Source Policy file: http://oss.tresys.com/projects/refpolicy/browser/trunk/policy/modules/services/xserver.te

The content of this boolean starts on line 749 and ends on line 766.

It is not always easy to find where booleans are defined unfortunately. There is room for improvement with the naming of booleans.

Conclusion:

To achieve greater security minimize the amount of policy.
Sometimes policy is added by turning a boolean on and sometimes policy is added by turning a boolean off.
Content of booleans can be reviewed in Source Policy.

Refer: man getsebool, man setsebool, man togglesebool, man audit2why, man semanage

vrijdag 26 juni 2009

SELinux Lockdown Part Eight: Unconfined

The unconfined space is for processes that require almost unrestricted access. Almost because writable memory execution is not permitted. The following permissions are restricted for processes that operate in the unconfined space unless specified otherwise: Execmem Execstack Execheap Execmod.

Processes that in a default Fedora 11 installation operate in this Unconfined Domain are the Linux Kernel, RPM, init scripts, and unconfined users.
Unconfined processes usually run programs unconfined too unless other otherwise specified. It is expected that unconfined processes are unrestricted and that children inherit this unconfined environment. Exceptions to this rule as said should be specified by creating policy that transitions the Unconfined Domain to a restricted space when a unconfined process runs a program.

Security can be greatly improved by removing the unconfined space. This will cause all processes to be restricted by SELinux. In Fedora 11 the unconfined space was split into two parts. The first part is the unconfined space for programs, and the second part is the unconfined space for users. This second part was renamed to the unconfineduser domain.

The result of this split is that now either or both environments can be removed. If the unconfined domain which is the domain for unconfined programs is removed then the init scripts will be restricted. This means that system services that do not have SELinux policy defined will run in the restricted init script environment and will not run unrestricted. This is a great way to ensure that no unrestricted system services are implemented on the system. The kernel and RPM processes stay unconfined because these processes need many permissions in order to operate successfully.

The unconfineduser domain can be removed to ensure that all users operate in a restricted environment. If it is decided to remove the unconfineduser domain than you must reconfigure your SELinux mappings to reflect this change.

There should be no reason to not remove the unconfined domain if the operator feels comfortable with SELinux. The operator can implement SELinux policy for any system process that does not have policy defined already.

The unconfineduser domain is usually handy to keep, as the operator can mannually configure which Linux users are mapped to this User Domain. SELinux can be configured to not allow unconfined logins via OpenSSH or Grapical User Interface. This means that users that have access to the unconfineduser domain can only login using this environment on the TTY or access the unconfined user space via the sudo command or SU with newrole command.

Using the unconfined user domain as a secondary domain only improves security if unconfined logins are not enabled.

Example: Remove the unconfined domain, disallow unconfined user logins, map unconfined_r role to existing staff_u SELinux User, Remove the sysadm_r role for the staff_u SELinux User. Add Linux user John and map the Linux user to the staff_u SELinux user. Add an entry for John to /etc/sudoers.

sudo setsebool -P unconfined_login off
sudo semanage user -m -L s0 -r s0-s0:c0.c1023 -R "staff_r system_r unconfined_r" -P user staff_u
sudo semodule -r unconfined
sudo useradd -Z staff_u john
sudo visudo (john ALL=(ALL) TYPE=unconfined_t ROLE=unconfined_r ALL)

John logs into the system as the restricted Linux user staff_u. When John wants to acquire root privileges he simply runs the sudo command. John can open a root shell in the unconfined space by running the sudo command with the -s option.

This configuration should not change your ways of doing things too much since root logins are not encouraged and since the staff_t restricted user domain has all permissions that a unprivileged user requires. It is also possible to create a custom User Domain that is tailor made to your personal requirements and map its role to a custom SELinux Users together with the system_r and unconfined_r role. That way you can keep the staff_u SELinux User in its original state and can you modify your User Domain and SELinux user to your requirements.

Conclusion:

Consider removing the Unconfined Domain and or the Unconfineduser Domain to improve security.


Refer: man semanage, man semodule, man visudo, man setsebool, man sudo

donderdag 25 juni 2009

SELinux Lockdown Part Seven: SU, Newrole, Sudo and Run_init.

Before Fedora 9 was released users with access to roles would execute the newrole command to Domain Transition. This command can be installed as policycoreutils-newrole. The user would for example run: newrole -r , and get prompted to enter his user password. The newrole command would than verify whether the users has all access that is required to make the requested domain transition and allow or deny it.

If the user Transitioned to a privileged User Domain and wanted to perform a privileged task, he would then execute the SU command to meet that Discretionary Access Control requirements. The SU command prompts for the root password.

In a strict environment to become a privileged user, one would run two programs and enter two seperate passwords. A privileged user would require access to roots password to perform any privileged task this way.

For a user such as this to run a system service the is another command to execute. The Run_init command performs a Domain transition to the Init Script which in turn starts a system service in its proper Domain. This program also prompts for a password.

That is a lot of passwords and commands just to restart Apache for example.

In Fedora 9 the sudo command was modified to support Domain Transitions. The use of the sudo command is recommended over the SU and Newrole command.
Two main advantages of the Sudo command are that this command allows you to change Linux uid and SElinux Domain Transition in one turn and that you do not need the root password to do so as long as you are added to the /etc/sudoers configuration file.

The destination Domain can be specified as a parameter of the -t option, and the destination role can be specified as a parameter of the -r option. Sudo can also be configured to Transition to a specified role and domain by default in its /etc/sudoers file.

For example: Linux user joe logs into the system as SELinux user joe_u. SELinux User joe_u has access to the joe_r role as well as the webadm_r role and the system_r role. The joe_r role maps to the joe_t User Domain which has all the permissions required for a restricted login user. The joe_t User Domain has access to the system_r role as well as the webadm_r role in policy. An entry for joe in /etc/sudoers is as follows:

joe ALL=(ALL) TYPE=webadm_t ROLE=webadm_r ALL

This entry allows Sudo to transition user joe to webadm_r role and webadm_t role automatically when joe run the sudo command.

Joe logs in and finds himself in the joe_t User Domain. Then when Joe wants to start the Apache service he simple runs: sudo service httpd start.

Sudo changes Joes Linux UID to 0 and transitions Joes' Domain and Role automatically to the specified Role and Domain webadm_t and webadm_r.

Joe also has access to the system_r role that is required to transition to the Init script domain which starts httpd in its proper Domain. The Run_init command is no longer required.

If Joe has access to several roles then Joe can override the default role and domain specified in the Sudo configuration file by specifying the -t and -r options with the destination role and domain parameters.

Conclusion:

Prefer the Sudo command over the SU with Newrole commands.
Prefer access to the system_r role over the Run_init command.


Refer: man su, man sudo, man newrole, man run_init

woensdag 24 juni 2009

SELinux Lockdown Part Six: Customized SELinux Roles

In part four of this series i have demonstrated how to create and implement a customized SELinux User Domain. Creating Roles is done in very much the same way. As mentioned in my previous article about RBAC: Roles are mappings to User Domains. Some User Domains can be used by users to log into the system because those User Domains have permissions to access the user home directory for example. I refer those these User Domains as primary User Domains. Other User Domains are designed to be secondary. Users can Domain Transition using the sudo or su with newrole command to these secondary User Domains. Secondary User Domains can not be used by a user to log into the system.

In this Chapter i am going to demonstrate how such a secondary User Domain is create and implemented. The goal is to create a Privileged SELinux Role that provides the permissions required to manage a Bind DNS service. This role will be based of off the webadm_t User Domain that was discussed previously. I will also revisit some material from part four: Customized SELinux User Domains because the user primary User Domain must be modified to be able to access our new bindadm_r role.

As mentioned i will start with creating a new secondary User Domain called bindadm that is based of off the pre-defined webadm_t SELinux User Domain. The two SELinux Source Policy files i am going base my new User Domain of are:

http://oss.tresys.com/projects/refpolicy/browser/trunk/policy/modules/roles/webadm.te
http://oss.tresys.com/projects/refpolicy/browser/trunk/policy/modules/roles/webadm.if

SELinux Source Policy files that have a ".te" extension are called Type Enforcement files. Files with a ".if" extension are called Interface files. Type Enforcement files have Declarations and Policy that are personal or local to the Domain. Interface files have Declarations and Policy that are shared by the Domain with other Domains that may want to interact with our Domain.

mkdir ~/bindadm; cd ~/bindadm;
echo "policy_module(bindadm, 0.0.1)" > bindadm.te;
echo "role bindadm_r;" >> bindadm.te;
echo "userdom_base_user_template(bindadm)" >> bindadm.te;
echo "allow bindadm_t self:capability { dac_override dac_read_search kill sys_ptrace sys_nice };" >> bindadm.te;
echo "files_dontaudit_search_all_dirs(bindadm_t)" >> bindadm.te;
echo "files_manage_generic_locks(bindadm_t) >> bindadm.te;
echo "files_list_var(bindadm_t)" >> bindadm.te;
echo "selinux_get_enforce_mode(bindadm_t)" >> bindadm.te;
echo "seutil_domtrans_setfiles(bindadm_t)" >> bindadm.te;
echo "logging_send_syslog_msg(bindadm_t)" >> bindadm.te;
echo "userdom_dontaudit_search_user_home_dirs(bindadm_t)" >> bindadm.te;

This is the basic contents for a generic privileged secondary User Domain. I left out policy that is specific to managing the Apache service.
Now i will add policy that is specific to managing the Bind service. I am able to borrow this policy from the bind Source Policy. As i mentioned shared policy is located in Interface files. This means that if i want to include shared policy related to Bind i should be able to find this in the bind.te file if the policy is available:

http://oss.tresys.com/projects/refpolicy/browser/trunk/policy/modules/services/bind.if

Starting on line 252 in bind.if and ending on line 305 is policy shared by the Bind module to administrate the bind service. I just have to call this Interface in our bindadm Type Enforcement file to include this Policy:

echo "bind_admin(bindadm_t, bindadm_r)" >> bindadm.te;

This concludes my bindadm Type Enforcement file. Next my bindadm Source Policy should share policy that might be required by other Domains to be able to interact with our bindadm_t Domain. I will base this policy of off the webadm.if file.

echo "## Bind administrator role" > bindadm.if;

echo "########################################" >> bindadm.if;
echo "## " >> bindadm.if;
echo "## Change to the bind administrator role." >> bindadm.if;
echo "##
" >> bindadm.if;

echo '## ' >> bindadm.if;
echo "## " >> bindadm.if;
echo "## Role allowed access." >> bindadm.if;
echo "##
" >> bindadm.if;

echo "## " >> bindadm.if;
echo "## " >> bindadm.if;
echo "#" >> bindadm.if;
echo "interface(\`bindadm_role_change',\`" >> bindadm.if;
echo " gen_require(\`" >> bindadm.if;
echo " role bindadm_r;" >> bindadm.if;
echo " ')" >> bindadm.if;
echo " allow \$1 bindadm_r;" >> bindadm.if;
echo "')" >> bindadm.if;

The Bind Administrator Shared policy above will later be called by our user primary Customized SELinux User Domain. I am now finished with my bindadm_t User Domain.

My next step is to create a Customized SELinux User Domain for our Bind guy and allow that User Domain to transition to the bindadm_r role by calling the bindadm_role_change interface. This Customized SELinux User Domain will be based of off the staff_t User Domain:

http://oss.tresys.com/projects/refpolicy/browser/trunk/policy/modules/roles/staff.te

echo "policy_module(bindguy, 0.0.1)" > bindguy.te;
echo "role bindguy_r;" >> bindguy.te;
echo "userdom_unpriv_user_template(bindguy)" >> bindguy.te;
echo "sudo_role_template(bindguy, bindguy_r, bindguy_t)" >> bindguy.te;
echo "ssh_role_template(bindguy, bindguy_r, bindguy_t)" >> bindguy.te;
echo "kernel_read_ring_buffer(bindguy_t)" >> bindguy.te;
echo "kernel_getattr_core_if(bindguy_t)" >> bindguy.te;
echo "kernel_getattr_message_if(bindguy_t)" >> bindguy.te;
echo "kernel_read_software_raid_state(bindguy_t)" >> bindguy.te;
echo "auth_domtrans_pam_console(bindguy_t)" >> bindguy.te;
echo "libs_manage_shared_libs(bindguy_t)" >> bindguy.te;
echo "seutil_run_newrole(bindguy_t, bindguy_r)" >> bindguy.te;
echo "netutils_run_ping(bindguy_t, bindguy_r)" >> bindguy.te;
echo "domain_read_all_domains_state(bindguy_t)" >> bindguy.te;
echo "domain_getattr_all_domains(bindguy_t)" >> bindguy.te;
echo "domain_obj_id_change_exemption(bindguy_t)" >> bindguy.te;
echo "files_read_kernel_modules(bindguy_t)" >> bindguy.te;
echo "kernel_read_fs_sysctls(bindguy_t)" >> bindguy.te;
echo "modutils_read_module_config(bindguy_t)" >> bindguy.te;
echo "modutils_read_module_deps(bindguy_t)" >> bindguy.te;
echo "miscfiles_read_hwdata(bindguy_t)" >> bindguy.te;
echo "term_use_unallocated_ttys(bindguy_t)" >> bindguy.te;

Now i will call the bindadm_role_change interface that i have defined in the bindadm.if Interface file to allow the bindguy_t User Domain to transition to the bindadm_t SELinux restricted environment:

echo "bindadm_role_change(bindguy_r)" >> bindguy.te;

I can also automatically create a SELinux User Mapping called bindguy_u which is mapped to the bindguy_r, bindadm_r and system_r role. The system_r role is included so that bindadm_t can stop, start and restart the bind system service.

echo "gen_user(bindguy_u, user, bindguy_r system_r bindadm_r, s0, s0 - mls_systemhigh, mcs_allcats)" >> bindguy.te;

To let the login programs know that bindguy is a valid login user i will add default contexts for this user based of off staff_u default contexts:

cp /etc/selinux/targeted/contexts/users/staff_u /etc/selinux/targeted/contexts/users/bindguy_u
sed -i 's/staff/bindguy/g' /etc/selinux/targeted/contexts/users/bindguy_u

Both the bindguy and bindadm policy can now be build and installed:

make -f /usr/share/selinux/devel/Makefile
sudo semodule -i bindguy.pp bindadm.pp

Now i can add a new Linux user with the useradd command and -Z option and bindguy_u parameter:

sudo useradd -Z bindguy_u bindguy

For bindguy to be able to use sudo to automatically transition to Linux user root and SELinux Domain bindadm_t i will add to /etc/sudoers:

echo "bindguy ALL=(ALL) ROLE=bindadm_r TYPE=bindadm_t ALL" >> /etc/sudoers;

When bindguy logs into the system he will find himself in the bindguy_t User Domain which is based of off the staff_t User Domain. The bindguy_t User Domain can domain transition to the bindadm_t User Domain which is a Domain to be used with root access, that can manage the Bind service.

Bindguy would be able to restart the bind service for example by executing:

sudo service named restart

Bindguy will also be able to edit the various Bind content and configuration files. Bindguy will not be able to change the root password for example.

Note: If you found any errors in this exercise or if you have any question or comments, please contact me. Thanks!

refer: man bind, man semodule, man sudo, man useradd

dinsdag 23 juni 2009

SELinux Lockdown Part Five: SELinux RBAC

It was explained in part one of this series that SELinux users are mapped to SELinux User Domains and Multi Category Security Components. These mappings can be configured by running the semanage command with the user option, and the SELinux User mappings can also automatically be configured by calling the gen_user() interface in the Type Enforcement Source Module file for your User Domain.

SELinux RBAC is used to be able to assign several SELinux restricted environments to a single SELinux user.

SELinux User Roles are User Domains. When i refer to roles i often mean a SELinux Users' secondary User Domain. Often roles that were designed to be secondary User Domains differ from primary User Domains. This is because Linux Users do not actually use the roles that were designed to be secondary User Domains to log into the system.

Instead Linux users Domain Transition to their secondary role by using the sudo command or a combination of the su and newrole command.

Keep in mind that some roles were designed to be primary User Domains and other roles only support secondary User Domain functionality. Primary User Domains let a user log into the system and secondary User Domains can only be used with the sudo and su with newrole command.

Sysadm Role - An example of a role that is designed to be a primary User Domain:

The sysadm_u SELinux User is mapped to the sysadm_r role. This mapping can be listed by running: sudo semanage user -l | grep sysadm_u

Linux Users that are mapped to the sysadm_u SELinux User operate in the sysadm_r role by default. In this case sysadm_r is a primary User Domain.

The staff_u SELinux User is also mapped to the sysadm_r role. The primary User Domain for the staff_u SELinux user is staff_r role. The default contexts configured in /etc/selinux/targeted/contexts/users/staff_u define what User Domains users should be logged in with by default, and what User Domains users can log in with by for example specifying a User Domain to log in with.

By default a staff_u SELinux User logs into the system in the staff_t User Domain. The sysadm_r role which was designed to be a primary User Domain can optionally be used to log in by using for example: ssh joe/sysadm_r@localhost.localdomain.tld

The sysadm_r role can also be used to Domain Transition by running the sudo and su with newrole command the way secondary User Domains as accessed.

The sysadm_t User Domain is the default environment of operation for the sysadm_u SELinux User and is designed to be the secondary environment of operation for the staff_u SELinux User, but even the staff_u SELinux User can force the pam_selinux Pluggable Authentication Module to use sysadm_t as its primary User Domain.

Webadm Role - An example of a role that is designed to be a secondary domain:

Unlike the sysadm_r role, the webadm_t User Domain cannot be used to log in to the system directly. Instead it must be accessed from another User Domain with the sudo or su with newrole command. The webadm_t User Domain does not have the permissions required to run a full user environment.

To use the webadm_r role, it should be mapped to for example the staff_u SELinux user: sudo semanage user -m -L s0 -r s0-s0:c0-c1023 -R "staff_r system_r webadm_r" -P user staff_u

Please note that you are not encouraged to modify existing SELinux Users. It is preferred that the default SELinux Users are left in their original state. Instead add new customized SELinux Users:

sudo semanage user -a -L s0 -r s0-s0:c0-c1023 -R "staff_r system_r webadm_r" -P user webadm_u
cp /etc/selinux/targeted/contexts/users/staff_u /etc/selinux/targeted/contexts/users/webadm_u

The webadm_r role can only be used as a secondary User Domain for two reason in this example. The first reason is the the webadm_t User Domain does not have enough permissions to support a full login environment. The second reason this that the we have based our webadm_u default context file in /etc/selinux/targeted/contexts/users of off the staff_u default contexts file. In this file the webadm_t User Domain is not a valid context to use for system logins.

Using Roles to confine Root:

Role Based Access Control can be used to create different User Domains with different permissions and assign those roles to SELinux Users. Although RBAC can be used for both unprivileged and privileged users, it is common to use it to restrict the privileged root user.

The webadm_u SELinux user i create above for example can be used to restrict a Linux User with root access to only be able to manage the Apache environment. The staff_t User Domain is unprivileged. This means that if i run in the staff_t User Domain as root, then i will not be able to use the root powers. The webadm_t User Domain is a limited privileged User Domain. If i operate in the webadm_t User Domain as root then i can access root resources that are permitted by the webadm_t restricted environment.

For example, i, dgrift am mapped to the webadm_u SELinux User. I am also allowed all root permissions in the sudoers configuration file in /etc/sudoers. When i log into the system by default i will find myself in the staff_t User Domain. If i run the sudo command as staff_t then i will for example not be able to restart the Apache service.

If i use the sudo command to Domain Transition to webadm_t before restarting the service i will be able to succeed:

sudo -r webadm_r -t webadm_t service httpd restart

If i try to use the sudo command to change root password i will fail because neither staff_t nor webam_t User Domains have access to this privilege.

This is a powerful feature. It means that it is not possible to delegate limited specified root privileges without having to share roots password.

Next i will explain some of the pre-defined roles available:

The guest_r role:
This is a primary User Domain only. See part one in this series for a explanation of the guest_u SELinux user.

The xguest_r role:
This is a primary User Domain only. See part one in this series for a explanation of the xguest_u SELinux user.

The user_r role:
This is a primary User Domain only. See part one in this series for a explanation of the user_u SELinux user.

The staff_r role:
This is a primary User Domain only. See part one in this series for a explanation of the staff_u SELinux user.

The sysadm_r role:
This User Domain can be used as both primary as well as secondary User Domain. The sysadm_u SELinux Users uses sysadm_r as its default role and the staff_u SELinux user uses sysadm_r as its optional role. The sysadm_r role has permissions sufficient for user logins. See part one in this series for a explanation of the sysadm_u user.

The system_r role:
This role is used by the system as a primary role. Users can use the system_r role as a secondary role to restart system services in their proper context.

The unconfined_r role:
This User Domain can be used both as primary as well as secondary User Domain. See part one in this series for a explanation of the unconfined_u user.

The webadm_r role:
This User Domain can be used as secondary User Domain only. This role has does not have access to user home directories and many other privileges required by login users. This User Domain has the permission required to manage the Apache environment.

The logadm_r role:
This User Domain can be used as secondary User Domain only. This role has does not have access to user home directories and many other privileges required by login users. This User Domain has the permission required to manage the logging environment.

Refer: man newrole, man su, man sudo, man semanage