Monday, July 7, 2014

couchdb is one of several widely used server applications written in erlang. I was surprised to find hundreds of Bugzilla tickets for erlang services and selinux-policy.

Problem #1: Erlang is treated by SELinux as part of the RabbitMQ Service
Erlang is a general purpose VM like Java. However selinux-policy treated core components of Erlang as part of the rabbitmq semodule.https://github.com/TresysTechnology/refpolicy-contrib/blob/master/rabbitmq.fc/usr/lib/erlang/erts.*/bin/beam.* -- gen_context(system_u:object_r:rabbitmq_beam_exec_t,s0)/usr/lib/erlang/erts.*/bin/epmd -- gen_context(system_u:object_r:rabbitmq_epmd_exec_t,s0)

Apparently someone attempted to make SELinux work only for rabbitmq, erroneously thinking that the generic erlang runtime binaries are part of rabbitmq.

The service is running as init_t. This is because /usr/lib/rabbitmq/bin/rabbitmq-server is not properly labeled with something like rabbitmq_exec_t so it never transitions into its own semodule when launched from systemd.

Similarly couchdb.service launched itself via ExecStart=/usr/bin/erl (symlink /usr/lib64/erlang/erts-5.10.4/bin) and it too was running as init_t. Lacking execve to anything labeled couchdb_exec_t, erl would fail to transition into couchdb_t. couchdb-1.6.0-9+ now runs from systemd with ExecStart=/usr/libexec/couchdb <parameters>. If the wrapper shell script /usr/libexec/couchdb is labeled as couchdb_exec_t then couchdb service actually runs as couchdb_t.

Note: couchdb-1.6.0-9+ does not use the upstream /bin/couchdb script from systemd because it is rather broken and upstream plans on removing it in the next release. The way we configure and exeucte couchdb from systemd is close to the future upstream standard way of handling the service. While we do not use it for the systemd service it remains in the $PATH because users may depend on its behavior for debugging.

Temporary Workaround for CouchDB + SELinux
couchdb-1.6.0-9 may be the first Erlang application in Fedora to properly be confined by its own semodule(?) We are waiting for selinux-policy to be fixed. Meanwhile this temporary workaround will allow CouchDB to operate with SELinux enforcing enabled. These instructions have been tested on Fedora 20 and RHEL 7.

Here are tested packages that I use on RHEL7 + EPEL7. EPEL7 will soon have these packages.

TODO'sErlang Service Packages
In general erlang packages with their own semodule must execute via a properly labeled wrapper script. /usr/bin/erl on its own is unable to guess and transition into the proper SELinux context. See couchdb-1.6.0-9+ /usr/libexec/couchdb for an example. As noted above, as rabbitmq never was running with the proper context someone who is familiar with rabbitmq will need to ensure the policy continues to operate as expected.

SELinux Policyhttps://bugzilla.redhat.com/show_bug.cgi?id=1116014
Generally, selinux-policy must no longer treat core Erlang binaries as part of rabbitmq. Everything in the /usr/lib*/erlang/erts-*/bin/ directory should be bin_t, perhaps somewhere in the core policies.

Every server application with its own semodule will need the aforementioned wrapper script(s) with context <something>_exec_t. For example these rabbitmq binaries need to be properly labeled.