Follow Techotopia on Twitter

On-line Guides
All Guides
eBook Store
iOS / Android
Linux for Beginners
Office Productivity
Linux Installation
Linux Security
Linux Utilities
Linux Virtualization
Linux Kernel
System/Network Admin
Programming
Scripting Languages
Development Tools
Web Development
GUI Toolkits/Desktop
Databases
Mail Systems
openSolaris
Eclipse Documentation
Techotopia.com
Virtuatopia.com
Answertopia.com

How To Guides
Virtualization
General System Admin
Linux Security
Linux Filesystems
Web Servers
Graphics & Desktop
PC Hardware
Windows
Problem Solutions
Privacy Policy

  




 

 

NOTE: CentOS Enterprise Linux is built from the Red Hat Enterprise Linux source code. Other than logo and name changes CentOS Enterprise Linux is compatible with the equivalent Red Hat version. This document applies equally to both Red Hat and CentOS Enterprise Linux.

8.3. Writing New Policy for a Daemon

These section provides an overall methodology to follow for writing a new policy from scratch. Although this is more complex than adding a few rules to local.te, the concepts are the same. You bring the application under TE rules and work through the AVC denials, adding rules each time until all permissions are resolved.

New Policy Writing Procedure

  1. Work with a proper daemon under Red Hat Enterprise Linux. This means it has an initscript in /etc/init.d/ and can be managed using chkconfig. For example, this procedure assumes you are going to use the service command to control starting and stopping the daemon.

    For this procedure, you are writing policy for the fictional foo package and it's associated foo daemon. Use a real daemon name in this place when developing your own policy.

  2. Create a file at $SELINUX_SRC/domains/program/foo.te.

  3. Put the daemon domain macro call in the file:

    daemon_domain(foo)
    
  4. Create the file contexts file, $SELINUX_SRC/file_contexts/program/foo.fc.

  5. Put the first list of file contexts in file.fc. You may need to add to this later, depending on the needs of the foo daemon.

    /usr/bin/foo      --     system_u:object_r:foo_exec_t
    /var/run/foo.pid  --     system_u:object_r:foo_var_run_t
    /etc/foo.conf     --     system_u:object_r:foo_conf_t
    
  6. Load the new policy with make load.

  7. Label the foo files:

    restorecon /usr/bin/foo /var/run/foo.pid /etc/foo.conf
    
  8. Start the daemon, service foo start.

  9. Examine your audit log for denial messages:

    grep "avc:  denied" /var/log/messages > /tmp/avc_denials
    cat /tmp/avc_denials
    

    Familiarize yourself with the errors the daemon is generating. You are writing policy with the help of audit2allow, but you need to understand the nature of the denials. You can also use seaudit for viewing the log messages, as explained in Section 6.2 Using seaudit for Audit Log Analysis.

  10. Use audit2allow to start the first round of policy rules.

    audit2allow -l -i /var/log/messages -o \
      /etc/selinux/targeted/src/policy/domains/program/foo.te
    

    When looking at the generated rules, if you see a rule that gives the foo_t domain read access to a file or directory, change the permission to read { read gettatr }. The domain is likely to need that permission if it already wants to read a file.

  11. Look to see if the foo_t domain tries to create a network socket, that is, udp_socket or tcp_socket as the object class in the AVC denial:

    avc:  denied  { create } for  pid=7279 exe=/usr/bin/foo \
      scontext=root:system_r:foo_t tcontext=root:system_r:foo_t\
      tclass=udp_socket
    

    If this is the case, then add the can_network() macro to foo.te:

    can_network(foo_t)
    
  12. Continue to iterate through the basic steps to generate all the rules you need. Each set of rules added to the policy may reveal additional permission needs from the foo_t domain.

    1. Start the daemon.

    2. Read the AVC messages.

    3. Write policy from the AVC messages, using audit2allow and your own knowledge, looking for chances to use macros.

    4. Load new policy.

    5. Go back to beginning, starting the daemon ...

  13. If the domain tries to access port_t, which relates to tclass=tcp_socket or tclass=udp_socket in the AVC log message, you need to determine what port number foo needs to use. To diagnose, put these rules in foo.te:

    allow foo_t port_t:tcp_socket name_bind;
    auditallow foo_t port_t:tcp_socket name_bind;
    

    The auditallow rule helps you determine the nature of the port connection attempt.

  14. Iterate through the remaining AVC denials. When they are resolved with new policy, you can configure the unique port requirements for the foo_t domain.

  15. With the daemon started, determine which port foo is using. Look at the AVC allowed message and see what port the daemon is connected to:

    lsof | grep foo.*TCP
    foo  2283  root  3u  IPv6   3192    TCP *:4242 (LISTEN)
    

    The foo daemon is listening on port 4242.

  16. Remove the generic port_t rule, replacing it with a specific rule for a new port type based on the foo_t domain.

    type foo_port_t, port_type;
    allow foo_t foo_port_t:tcp_socket name_bind;
    

    Add this line to $SELINUX_SRC/file_contexts. This reserves the port 4242 for the domain foo_t:

    ifdef(`foo.te', `portcon tcp 4242 system_u:object_r:foo_port_t')
    

 
 
  Published under the terms of the GNU General Public License Design by Interspire