CTS 2311 (Unix/Linux Security) Project #4
Install OTRS with SELinux enabled


Due: by the start of class on the date shown on the syllabus


OTRS (Open-source Ticket Request System) is a popular ticketing system for many platforms.  It comes in a FOSS version with no support and limited plug-ins available, and a commercial version with all those extras.  (The FOSS version does contain references to the “Pro” version, with many click here to upgrade buttons and menu items.)

While popular and with many features, the FOSS version is not simple to install (perhaps as a way to encourage paying for the Pro version).  What's worse, it is not designed to run under SELinux; most install guides simply tell you to turn off SELinux if running OTRS.  That is terrible advice!

In this project, you will install OTRS and run it with SELinux enabled.  To do so, you will need to make several changes to the SELinux policy by reading (and understanding) various audit log messages.


To begin with, bring your system (“Server A”) up to date with dnf.  You will also need to install, configure, and enable various services that OTRS depends on: Perl, Apache (with mod-perl), MySQL (MariaDB), and working email (including both MTA for sending emails and IMAP or POP for reading emails).  Prerequisite steps for these tasks is given first, followed by the OTRS install.

In this project, you will learn the general technique for working with SELinux and non-aware software: Install the software, set SELinux to permissive mode, and run the software through its paces (exercise the software).  Then turn all the audit error messages into a new policy module.  After installing that module, you should be able to run the software with SELinux in enforcing mode.

Part I — Set up Prerequisite Software

  1. Make sure SELinux is in enforcing mode for the initial steps.  All of the prerequisite software should work with SELinux in enforcing mode, as should the dnf install.  If there's any problems, you want to find them out now, before attempting the OTRS install.
  2. Install Perl.  (This step should be easy.)
  3. Install and set up the Apache web server, using similar steps from CTS-2322 Web Services, Part 1 project.  A default setup is fine.  However, make sure you've installed the mod_perl package.  Once installed, start the service and test it.  If working, consider enabling it to start at boot time automatically.
  4. Install the default MTA, sendmail.  (You can actually install any MTA you wish.)  Edit /etc/aliases by adding two lines at the end, so otrs email goes to root, and root email goes to your normal non-root account.  In my case, I added:
    otrs: root
    root: wpollock

    Next, run the command newaliases to activate your change.  Finally, start your email service and verify it works.  If so, you should consider enabling it to start at boot time automatically.

  5. Install and set up Dovecot for IMAP and/or POP3 service.  Unless you've changed your email setup (possibly for another project), the default configuration should work fine, with these changes:
    # cd /etc/dovecot/conf.d
    # diff 10-auth.conf-orig 10-auth.conf
    < #disable_plaintext_auth = yes
    > disable_plaintext_auth = no
    # diff 10-mail.conf-orig 10-mail.conf
    < #mail_location =
    > mail_location = mbox:~/mail:INBOX=/var/mail/%u
    < #mail_privileged_group =
    > mail_privileged_group = mail
    # chmod 600 /var/mail/*
    # gpasswd -a dovecot mail

    Start Dovecot and test it's POP and/or IMAP protocol.  (Testing with telnet is recommended.  See freesoft.org for sample POP3 commands.)  If successful, consider enabling Dovecot to start at boot.

    Set up Alpine for IMAP — Optional Step

    To make Alpine work with Dovecot, I had to change permissions of my inbox to 600 (from 660).  Alpine still complains that /var/spool/mail (/var/mail is a symlink to there) should have 1777 permissions, but I refuse to change that, and live with the Alpine warning message each time I run it.

    I also had to adjust the permissions in my home with:
    chmod a+X ~; chmod g+rwx ~/mail/
    and then:
    chgrp -R mail ~/mail/
    (I am not sure all these changes were required, but for localhost access only on a non-Internet host, the security should be fine.)

    Finally, you need to make Alpine listen for incoming email.  While you can do that by changing settings within Alpine, I find it is easier to edit ~/.pinerc directly:

    $ diff .pinerc-original .pinerc
    < feature-list=
    > feature-list=enable-incoming-folders,
    >     enable-incoming-folders-checking
    < incoming-folders=
    > incoming-folders=local {localhost/novalidate-cert}INBOX
  6. The last prerequisite step is to install and configure the MariaDB service, formally known as MySQL.  Before starting the service for the first time, you should make the configuration changes required to support OTRS:
    # cd /etc/my.cnf.d/
    # cp mariadb-server.cnf ~/mariadb-server.cnf-old
    # vi mariadb-server.cnf
    # diff ~/mariadb-server.cnf-old mariadb-server.cnf
    > # The following three settings are required to support OTRS:
    > max_allowed_packet = 20M
    > query_cache_size = 32M
    > innodb_log_file_size = 256M

    If you have previously started MariaDB, it is likely the old configuration was saved in /var/lib/mysql/, in the files ib_logfile00 and ib_logfile01.  After stopping MariaDB, delete those two files.

    Complete the MariaDB configuration by starting the service, then running the wizard (as root) “mysql_secure_installation”.  You should accept all the defaults, and be sure to record the root password someplace (remember, MariaDB like most databases keeps its own internal user list and passwords, so this is not the same as the root user's login password.)

    Optional step:
    Log into MariaDB as the root user and create a database and user for your regular Linux account (in my case, “wpollock”), giving that account admin privileges.  This can be done as follows:

    # mysql -p
    Enter password: 
    Welcome to the MariaDB monitor.  Commands end with ; or \g.
    Your MariaDB connection id is 11
    Server version: 10.1.24-MariaDB MariaDB Server
    Copyright (c) 2000, 2017, Oracle, MariaDB Corporation Ab and others.
    Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
    MariaDB [(none)]> create database wpollock;
    Query OK, 1 row affected (0.00 sec)
    MariaDB [(none)]> grant all privileges on *.* to wpollock@localhost
        ->          identified by 'XXXXXXXXX' with grant option;
    Query OK, 0 rows affected (0.02 sec)
    MariaDB [(none)]> flush privileges;
    Query OK, 0 rows affected (0.00 sec)
    MariaDB [(none)]> exit;

Part II — Install OTRS and Configure with SELinux

With web, mail, and database services set up and configured, and other prerequisite software installed (Perl), it is time to actually start the installation of OTRS.  While not found in major Yum repos, there is an RPM for OTRS you can use.  It is current but was built for Fedora 22; it should work fine on newer versions of Fedora up to version 25 at least (which is what I tested).

The problem is OTRS is not designed to work easily with SELinux.  Most install guides state you must turn off SELinux to run OTRS.  This is not true.  You can run OTRS with SELinux running and in enforcing mode.  However, you will need to make several changes to the SELinux policy for this to work.

This is not an uncommon issue, and there is a general technique for working with this.  First, install the troublesome software.  Once installed, enable SELinux in permissive mode, which will record all errors but won't actually prevent any access.  Now start and run your software.  Thoroughly use all its features.  When done, all policy violations have been recorded in the audit log.  You can turn the system's audit log messages into the required policy changes, semi-automatically.  Additionally, you will almost certainly need to change the SELinux security labels (context) on the newly installed files, then re-label the files correctly.  Once the changes are made and loaded, switch SELinux to enforcing mode.  If your policy changes were correct, the software should still run fine!

  1. Download the latest RPM for the latest Fedora available, for the FOSS version of OTRS:
    $ wget http://ftp.otrs.org/pub/otrs/RPMS/fedora/22/otrs-5.0.20-01.noarch.rpm
    $ md5sum otrs-5.0.20-01.noarch.rpm

    The sum for this version as reported on their website should be:

  2. Next, install the package and verify all required Perl modules are present:
    $ sudo mkdir /opt/otrs
    $ sudo dnf install -y otrs-5.0.20-01.noarch.rpm
    $ sudo /opt/otrs/bin/otrs.CheckModules.pl

    This should also install 11 Perl packages as well (unless you happen to have those installed already).  Next, make some changes required since OTRS will need to modify files and folders owned by the apache user.  To make this work, have otrs a member of group apache and later make the OTRS files group read/write:

    # gpasswd -a otrs apache
  3. The next step is to fix file permissions and SELinux labels.  OTRS keeps its web files under /opt/otrs/, in various subdirectories such as Kernel, var, and bin/cgi-bin.  Since apache must read, execute, and in some cases create and modify files in those directories, they must have the correct SELinux labels and permissions.  (Even without SELinux, the permissions must still be set correctly.)  Let's start with setting the file permissions.  Run these commands:
    # /opt/otrs/bin/otrs.SetPermissions.pl --dry-run --web-group=apache
    Setting permissions on /opt/otrs
    /i18n permissions 755 -> 2775
    /i18n ownership 0:0 -> 1001:48
    /i18n/otrs permissions 755 -> 2775
    /i18n/otrs ownership 0:0 -> 1001:48
    /var/webservices permissions 755 -> 2775
    /var/webservices ownership 0:0 -> 1001:48
    /var/processes permissions 755 -> 2775
    /var/processes ownership 0:0 -> 1001:48
    # /opt/otrs/bin/otrs.SetPermissions.pl --web-group=apache

    The first command shows the changes that will be made; the second actually makes the changes.

  4. Next we must make a change to the SELinux policy, by setting the correct file context for the OTRS web files.  Normally, files have their context (or labels) set based on what directory they are located within.  However, OTRS has its web files in its own /opt/otrs directory, and unless we change the labels, Apache will not be able to read those files, create new ones, nor execute the cgi-bin scripts.  To change the SELinux labels, run these commands:
    # semanage fcontext -a -t httpd_sys_content_t /opt/otrs/var/httpd/htdocs
    # semanage fcontext -a -t httpd_sys_script_exec_t /opt/otrs/bin/cgi-bin
    # semanage fcontext -a -t httpd_sys_rw_content_t "/opt/otrs/var(/.*)?"
    # restorecon -vR /opt/otrs
  5. The final preparation step is to set a couple of SELinux booleans, to allow OTRS (really, Apache) to connect to MariaDB and to send emails:
    # setsebool -P httpd_can_network_connect_db 1 # To connect to the DB.
    # setsebool -P httpd_can_network_connect 1 # Possibly needed(?) to send emails.
  6. Now we are ready to actually start OTRS.  To do so, restart httpd (so the new configuration will be used), set SELinux to permissive mode, then start the OTRS daemon:
    # systemctl restart httpd
    # setenforce 0 # make sure SELinux is in permissive mode
    # /opt/otrs/bin/Cron.sh start otrs
    # su -c "/opt/otrs/bin/otrs.Daemon.pl start" - otrs
    otrs.Daemon.pl - the OTRS daemon
    Copyright (C) 2001-2017 OTRS AG, http://otrs.com/
    Daemon started
    # su -c "/opt/otrs/bin/otrs.Daemon.pl status" - otrs
    otrs.Daemon.pl - the OTRS daemon
    Copyright (C) 2001-2017 OTRS AG, http://otrs.com/
    Daemon running

    (That last command reports the status of the daemon, but it must be run as the otrs user, hence the use of su.)

  7. The next step is to complete the install using a web browser.  Open a web browser to the URL http://localhost/otrs/installer.pl.  Complete the install by following the directions:
    1. Click Next to get to the license screen; accept that, then click Next.
    2. Use the default database settings for MySQL/MariaDB, then create a new database for “otrs”, and click Next.
    3. Enter your MySQL/MariaDB root user's password.  On that screen, change “” to “localhost”, since modern Linux tries to connect using IPv6.  Click on check settings to verify everything is correct.  Record the new MariaDB password for the otrs user created.  Wait a minute or so for “Database setup successful!” page to appear, then click Next.
    4. On the next page, you need to set some general settings: set AdminEmail to “root@localhost”, set Organization to “GCAW”, set CheckMXrecord to “no”, and select your local non-root user account to receive email.  (It's fine to leave the SystemID at the default value.)  Click next.
    5. Configure email: outbound email should use the default of sendmail and port 25.  Inbound email can use IMAP, localhost, and your non-root email account.  Click the “check email settings” button; in a moment you should see a success pop-up message.  Click Next.
    6. The final screen shows the OTRS admin user name and password; be sure to recode that information someplace safe.  Click on the URL shown (http://localhost/otrs/index.pl to start using OTRS.
  8. Now to put OTRS through its paces:
    1. Log into OTRS as the root@localhost user (the only user so far).
    2. Create an agent account using your non-root account name.  (Note the email address was required to be “name@localhost.localdomain”.  Be sure to configure the new agent account as part of the “admin” group (by checking the “RW” column to check the three checkboxes).
    3. Add a new customer account for someone; I used Hymie Piffl “hpiffl” with an ID of 1001.  (do this from the Customers→Customer Administration tab, then click on the “Add customer” button.)
    4. Next, log out (of the root user) and log back in as your agent account.
    5. Create new ticket for hpiffl and play with it.  Create several tickets if you wish.
    6. When done playing around with your new ticketing system, log out of it.
  9. The final step is to modify the SELinux policy to allow all the actions OTRS needs for its operation.  Run the following commands to turn any audit log error messages into the correct policy changes:
    # cd
    # cat /var/log/audit/audit.log | audit2allow -l -v -m otrs > otrs.te
    # vi otrs.te # edit out any non-otrs (or httpd) stuff
    # checkmodule -M -m -o otrs.mod otrs.te # Compile module
    # semodule_package -o otrs.pp -m otrs.mod  # I think modern SELinux has a simpler way.
    # semodule -v -i otrs.pp  # install new module
    # setenforce 1

    The resulting policy module created should look similar to this:

    # cat otrs.te
    module otrs 1.0;
    require {
    	type bin_t;
    	type httpd_t;
    	type httpd_sys_content_t;
    	type usr_t;
    	class dir { add_name remove_name write };
    	class file { append create rename unlink write };
    #============= httpd_t ==============
    # src="httpd_t" tgt="bin_t" class="dir", perms="{ add_name remove_name write }"
    # comm="/opt/otrs/bin/c" exe="" path=""
    #!!!! WARNING: 'bin_t' is a base type.
    allow httpd_t bin_t:dir { add_name remove_name write };
    # src="httpd_t" tgt="bin_t" class="file", perms="{ create unlink write }"
    # comm="/opt/otrs/bin/c" exe="" path=""
    allow httpd_t bin_t:file { create unlink write };
    # src="httpd_t" tgt="httpd_sys_content_t" class="dir", perms="{ add_name remove_name write }"
    # comm="/opt/otrs/bin/c" exe="" path=""
    #!!!! This avc can be allowed using the boolean 'httpd_unified'
    allow httpd_t httpd_sys_content_t:dir { add_name remove_name write };
    # src="httpd_t" tgt="httpd_sys_content_t" class="file", perms="{ create unlink write }"
    # comm="/opt/otrs/bin/c" exe="" path=""
    #!!!! This avc can be allowed using the boolean 'httpd_unified'
    allow httpd_t httpd_sys_content_t:file { create unlink write };
    # src="httpd_t" tgt="usr_t" class="file", perms="{ append create rename unlink write }"
    # comm="/opt/otrs/bin/c" exe="" path=""
    #!!!! WARNING: 'usr_t' is a base type.
    allow httpd_t usr_t:file { append create rename unlink write };
  10. If all went well, you should be able to use OTRS now even though SELinux was set back to enforcing mode.  If it is working, consider using it for the set of the term: open up tickets for any projects or other changes you plan to make.

To be turned in:

A copy of your journal pages showing all changes made for this project.  You can send as email to (preferred).  If email is a problem for some reason, you may turn in a hard-copy.  In this case the pages should be readable, dated, and stapled together.  Your name should appear on the first page.

Don't turn in your whole journal, you will need to add to it every day in class!  It is common in fact to keep the journal as a text file on the system (with a paper backup of course).

Please see your syllabus for more information about submitting projects.