/home/janfrode
Various notes about projects Jan-Frode Myklebust is or has been involved in…
»Home
»Java OTP
»selinux
»Zenoss
»Exercise

I'm working on a project were we will be using argus for auditing of network activity. Unfortunately the RPMs provided by QoSient, LLC didn't include any SElinux policy for it, and it wasn't very well packaged. So, I started by repackaging it as an rpm, which did require a few tweaks to the build, but nothing major.

# rpm -q --qf %{description} argus
Argus (Audit Record Generation and Utilization System) is an IP network
transaction auditing tool.  The data generated by argus can be used
for a wide range of tasks such as network operations, security
and performance management.

IMHO argus is a perfect fit for a SElinux policy. It's pretty much self contained, only listening on the network and writing packet dumps to a file.

Analyzing and building initial module for Argus

I start by setting SElinux in permissive mode:

# setenforce 0
# sestatus
SELinux status:                 enabled
SELinuxfs mount:                /selinux
Current mode:                   permissive
Mode from config file:          enforcing
Policy version:                 21
Policy from config file:        targeted

Now generate base policy:

# /usr/share/selinux/devel/policygentool argus /usr/sbin/argus


This tool generate three files for policy development, A Type Enforcement (te)
file, a File Context (fc), and a Interface File(if).  Most of the policy rules
will be written in the te file.  Use the File Context file to associate file
paths with security context.  Use the interface rules to allow other protected
domains to interact with the newly defined domains.

After generating these files use the /usr/share/selinux/devel/Makefile to
compile your policy package.  Then use the semodule tool to load it.

# /usr/share/selinux/devel/policygentool myapp /usr/bin/myapp
# make -f /usr/share/selinux/devel/Makefile
# semodule -l myapp.pp
# restorecon -R -v /usr/bin/myapp "all files defined in myapp.fc"

Now you can turn on permissive mode, start your application and avc messages
will be generated.  You can use audit2allow to help translate the avc messages
into policy.

# setenforce 0
# service myapp start
# audit2allow -R -i /var/log/audit/audit.log

Return to continue:

If the module uses pidfiles, what is the pidfile called?

If the module uses logfiles, where are they stored?
/var/log/argus/
If the module has var/lib files, where are they stored?

Does the module have a init script? [yN]
y
Does the module use the network? [yN]
y

Build and load the module.

# make -f /usr/share/selinux/devel/Makefile
Compiling targeted argus module
/usr/bin/checkmodule:  loading policy configuration from tmp/argus.tmp
/usr/bin/checkmodule:  policy configuration loaded
/usr/bin/checkmodule:  writing binary representation (version 6) to tmp/argus.mod
Creating targeted argus.pp policy package
rm tmp/argus.mod.fc tmp/argus.mod
# semodule -i argus.pp

Restore contexts on known files..

# restorecon /usr/sbin/argus
# restorecon -R /var/log/argus

Flush the audit-log, run the daemon, stop daemon, look at what would have failed:

# mv /var/log/audit/audit.log /var/log/audit/audit.log.1
# /etc/init.d/auditd restart
Stopping auditd:                                           [  OK  ]
Starting auditd:                                           [  OK  ]
# /etc/init.d/argus start
Starting argus:                                            [  OK  ]
# /etc/init.d/argus stop
Shutting down argus:                                       [  OK  ]
# cat /var/log/audit/audit.log  | audit2allow -m argus
module argus 1.0;

require {
        class capability { net_raw setuid };
        class chr_file { read write };
        class netlink_route_socket { bind create getattr nlmsg_read read write };
        class packet_socket { bind create getopt ioctl read setopt };
        class process signull;
        class sock_file write;
        class unix_dgram_socket { connect create sendto write };
        type argus_t;
        type devlog_t;
        type devpts_t;
        type syslogd_t;
        role system_r;
};

allow argus_t self:capability { net_raw setuid };
allow argus_t self:netlink_route_socket { bind create getattr nlmsg_read read write };
allow argus_t self:packet_socket { bind create getopt ioctl read setopt };
allow argus_t self:process signull;
allow argus_t self:unix_dgram_socket { connect create write };
allow argus_t devlog_t:sock_file write;
allow argus_t devpts_t:chr_file { read write };
allow argus_t syslogd_t:unix_dgram_socket sendto;

Add these to the end of argus.te and rebuild, reload:

# vi argus.te
# make -f /usr/share/selinux/devel/Makefile
Compiling targeted argus module
/usr/bin/checkmodule:  loading policy configuration from tmp/argus.tmp
/usr/bin/checkmodule:  policy configuration loaded
/usr/bin/checkmodule:  writing binary representation (version 6) to tmp/argus.mod
Creating targeted argus.pp policy package
rm tmp/argus.mod.fc tmp/argus.mod
# semodule -i argus.pp
# mv /var/log/audit/audit.log /var/log/audit/audit.log.1
mv: overwrite `/var/log/audit/audit.log.1'? yes
# /etc/init.d/auditd restart
Stopping auditd:                                           [  OK  ]
Starting auditd:                                           [  OK  ]
# /etc/init.d/argus start
Starting argus:                                            [  OK  ]
# ps -eZ|grep argus
root:system_r:argus_t           22199 ?        00:00:00 argus
root:system_r:argus_t           22201 ?        00:00:00 argus
# cat /var/log/audit/audit.log|audit2allow -m argus
/usr/bin/audit2allow: No AVC messages found.
# /etc/init.d/argus stop
Shutting down argus:                                       [  OK  ]
# cat /var/log/audit/audit.log|audit2allow -m argus
/usr/bin/audit2allow: No AVC messages found.

So now argus is running in domain argus_t, and not getting any denials. I think this is an acceptable confinement or argus, but I wouldn't expect it to be good enough to be included in the reference policy. It's almost an automated policy-generation, and gives a bit too broad accesses. It's allowed to read all etc_t files, write to var_log_t, etc.

Let's try again before packaging it into the RPM and distributing it further.. —> argus from scratch