fedora-selinux August 2010 archive
Main Archive Page > Month Archives  > fedora-selinux archives
fedora-selinux: Re: Sample Passenger/Rails policy for review

Re: Sample Passenger/Rails policy for review

From: Dominick Grift <domg472_at_nospam>
Date: Tue Aug 17 2010 - 15:58:11 GMT
To: selinux@lists.fedoraproject.org

On 08/17/2010 05:34 PM, Moray Henderson wrote:
> Dominick Grift wrote:
>> On 08/16/2010 03:58 PM, Moray Henderson (ICT) wrote:
>>> Hi all,
>>> I've been looking at getting a Ruby on Rails app working through
>>> Passenger under CentOS 5.5. I felt it should run in its own security
>>> context, so I came up with the following sample module. Please
> comment.
>> This is not how i would do it probably, although i am not sure if my
>> approach would be much better.
>> Instead of using the httpd_content_template() i would treat
> mod_passenger
>> as a normal domain.
>> Then allow httpd_t to transition to the new mod_passenger domain when
> it
>> runs the passenger executable file.
>> The advantage of this, i think, is that you do not have to allow rules
>> like this:
>> allow httpd_t self:capability { fowner fsetid };
>> Also with regard to the policy below:
>> allow httpd_t httpd_myapp_script_t:process { siginh rlimitinh
>> noatsecure };
>> This should not be needed and is by default silently denied.
> You're right, I removed the allow ...:process rule, and it still worked.
> How do I get httpd_t to transition to an ordinary domain? I've been
> experimenting with domain_entry_file and domain_transition_pattern, but
> keep getting denials for httpd_t writing to myapp_script_rw_t. It
> obviously has not transitioned by the time it tries to write its
> temporary files in /var/run/passenger.

These would be the process and executable file declarations in
passenger.te source policy file:

type passenger_t;
type passenger_exec_t;
domain_entry_file(passenger_t, passenger_exec_t)
role system_r types passenger_t;

This would be the shared policy that facilitates the domain transition
to passenger via passenger_exec_t for other domain like httpd_t in

## <summary>
## Execute a domain transition to
## run Passenger.
## </summary>
## <param name="domain">
## <summary>
## Domain allowed to transition.
## </summary>
## </param>
                type passenger_t, passenger_exec_t;

        domtrans_pattern($1, passenger_exec_t, passenger_t)

And then for httpd_t to transition to passenger_t you would call that
from from the apache local policy:


Then ofcourse you would have to declare types for passengers' object in
/tmp and also facilitate access to that the same way.

But i think all in all your solution is fine and easier.

I am just wondering if there is a way to get rid of this:

allow httpd_t self:capability { fowner fsetid };

Are you sure that you labelled all passenger executable files?

Can you show us the raw AVC denial that prompter the rule above.
It can show us if it was really apache running in the httpd_t domain
that needed the fowner and fsetid capability or maybe a passenger
executable that ran in the httpd_t domain.

If the latter, then you can avoid that by labelling it with the
passenger executable type.

> Are any of the macros in /usr/share/selinux/devel/include/support/
> documented anywhere? I couldn't find them in the Tresys Refpolicy API
> documentation or the selinuxproject.org wiki.
> Oh, I see, it's domain_auto_transition_pattern I need, not
> domain_transition_pattern. I'm trying to use this refpolicy stuff, but
> honestly, I find it easier and quicker to program the thing manually
> than to find the macro to do it for me!
> Now I'm getting a load of process signal denials and a "Cannot stat
> '/usr/lib/ruby/gems/1.9.1/gems/passenger-2.2.15/bin/passenger-spawn-serv
> er': Permission denied (13)" but at least it's in the correct domain
> now. I'll keep working on it.
>>> Summary
>>> -------
>>> The policy creates a new set of apache content types using
>>> apache_content_template. The Passenger
>>> ApplicationPoolServerExecutable is given type
>>> httpd_myapp_script_exec_t, so the app will execute in
>>> httpd_myapp_script_t. The remaining Passenger files, and the Rails
>>> app itself, are httpd_myapp_content_t. PassengerTempDir is set to
>>> /var/run/passenger, and given httpd_myapp_script_rw_t to allow the
>> sockets and stuff to be created.
>>> Source
>>> ------
>>> #### myapp.te ####
>>> policy_module(myapp,1.0)
>>> # Create a set of apache content types for myapp
>>> apache_content_template(myapp);
>>> # Give running app access to system things it will ask for
>>> kernel_read_kernel_sysctls(httpd_myapp_script_t);
>>> miscfiles_read_certs(httpd_myapp_script_t);
>>> term_use_all_user_ptys(httpd_myapp_script_t);
>>> # Allow apache to create and communicate with Passenger allow httpd_t
>>> self:capability { fowner fsetid }; allow httpd_t
>>> httpd_myapp_script_t:unix_stream_socket rw_socket_perms; allow
> httpd_t
>>> httpd_myapp_script_t:process { siginh rlimitinh noatsecure }; allow
>>> httpd_t httpd_myapp_script_rw_t:fifo_file manage_file_perms; allow
>>> httpd_t httpd_myapp_script_rw_t:sock_file { setattr unlink };
>>> # Access that Passenger will need
>>> allow httpd_myapp_script_t self:capability { chown dac_override
>>> dac_read_search fowner fsetid setgid setuid }; allow
>>> httpd_myapp_script_t httpd_t:unix_stream_socket { read write };
>>> #### myapp.fc ####
> /usr/lib/ruby/gems/1.9.1/gems/passenger-2.2.15/lib/phusion_passenger/A
>>> pp
>>> licationPoolServerExecutable --
>>> gen_context(system_u:object_r:httpd_myapp_script_exec_t, s0)
>>> /usr/lib/ruby/gems/1.9.1/gems/passenger-2.2.15(/.*)?
>>> gen_context(system_u:object_r:httpd_myapp_content_t, s0)
>>> /usr/local/lib/myapp(/.*)?
>>> gen_context(system_u:object_r:httpd_myapp_content_t, s0)
>>> /var/run/passenger(/.*)?
>>> gen_context(system_u:object_r:httpd_myapp_script_rw_t, s0)
> --
> selinux mailing list
> selinux@lists.fedoraproject.org
> https://admin.fedoraproject.org/mailman/listinfo/selinux

-- selinux mailing list selinux@lists.fedoraproject.org https://admin.fedoraproject.org/mailman/listinfo/selinux