Adding and loading SELinux modules using CFEngine (Was: SELinux Experience)

2012-09-22 Thread Aleksey Tsalolikhin
In this example, the desired end state is for SELinux to allow httpd
to connect and write to UNIX Stream Sockets (in order for PHP apps to
connect to database via a file socket rather than a TCP socket, as
frequent connections over TCP were exhausting available TCP ports).

CFEngine creates the SELinux policy text file with the appropriate
SELinux directives, compiles, packages and loads the policy.

Here is an example of CFEngine doing this repair:


[root@mil-mail00 verticalsysadmin_training_examples]# cf-agent -b
example -K -f 
./files__selinux__allow_httpd_to_connect_to_and_to_write_to_stream_sockets__for_pgbouncer.cf
-I
 >> Using command line specified bundlesequence
 -> Created directory /root/SELINUX/.
 -> Created file
/root/SELINUX/allowHttpdToConnectToUnixStreamSocketsAndToWriteToSocketFiles.te,
mode = 600
 -> Edited file
/root/SELINUX/allowHttpdToConnectToUnixStreamSocketsAndToWriteToSocketFiles.te
 -> Executing '/usr/bin/checkmodule  -M -m -o
/root/SELINUX/allowHttpdToConnectToUnixStreamSocketsAndToWriteToSocketFiles.mod
   
/root/SELINUX/allowHttpdToConnectToUnixStreamSocketsAndToWriteToSocketFiles.te
 && /usr/bin/semodule_package -o
/root/SELINUX/allowHttpdToConnectToUnixStreamSocketsAndToWriteToSocketFiles.pp
   -m
/root/SELINUX/allowHttpdToConnectToUnixStreamSocketsAndToWriteToSocketFiles.mod
 && /usr/sbin/semodule -i
/root/SELINUX/allowHttpdToConnectToUnixStreamSocketsAndToWriteToSocketFiles.pp'
...(timeout=-678,owner=-1,group=-1)
Q: "...heckmodule  -M ": /usr/bin/checkmodule:  loading policy
configuration from
/root/SELINUX/allowHttpdToConnectToUnixStreamSocketsAndToWriteToSocketFiles.te
Q: "...heckmodule  -M ": /usr/bin/checkmodule:  policy configuration loaded
Q: "...heckmodule  -M ": /usr/bin/checkmodule:  writing binary
representation (version 6) to
/root/SELINUX/allowHttpdToConnectToUnixStreamSocketsAndToWriteToSocketFiles.mod
I: Last 3 quoted lines were generated by promiser
"/usr/bin/checkmodule  -M -m -o
/root/SELINUX/allowHttpdToConnectToUnixStreamSocketsAndToWriteToSocketFiles.mod
   
/root/SELINUX/allowHttpdToConnectToUnixStreamSocketsAndToWriteToSocketFiles.te
 && /usr/bin/semodule_package -o
/root/SELINUX/allowHttpdToConnectToUnixStreamSocketsAndToWriteToSocketFiles.pp
   -m
/root/SELINUX/allowHttpdToConnectToUnixStreamSocketsAndToWriteToSocketFiles.mod
 && /usr/sbin/semodule -i
/root/SELINUX/allowHttpdToConnectToUnixStreamSocketsAndToWriteToSocketFiles.pp"
 -> Completed execution of /usr/bin/checkmodule  -M -m -o
/root/SELINUX/allowHttpdToConnectToUnixStreamSocketsAndToWriteToSocketFiles.mod
   
/root/SELINUX/allowHttpdToConnectToUnixStreamSocketsAndToWriteToSocketFiles.te
 && /usr/bin/semodule_package -o
/root/SELINUX/allowHttpdToConnectToUnixStreamSocketsAndToWriteToSocketFiles.pp
   -m
/root/SELINUX/allowHttpdToConnectToUnixStreamSocketsAndToWriteToSocketFiles.mod
 && /usr/sbin/semodule -i
/root/SELINUX/allowHttpdToConnectToUnixStreamSocketsAndToWriteToSocketFiles.pp
[root@mil-mail00 verticalsysadmin_training_examples]#

Here is the policy source code:

{{{

body common control {

inputs => { "/var/cfengine/inputs/cfengine_stdlib.cf" };

}


bundle agent 
files__selinux__allow_httpd_to_connect_to_and_to_write_to_stream_sockets__for_pgbouncer
{

classes:

  
"allowHttpdToConnectToUnixStreamSocketsAndToWriteToSocketFiles_module_is_loaded"

  expression => returnszero("/usr/sbin/semodule -l | /bin/grep
allowHttpdToConnectToUnixStreamSocketsAndToWriteToSocketFiles
>/dev/null", "useshell");

methods:
  
!allowHttpdToConnectToUnixStreamSocketsAndToWriteToSocketFiles_module_is_loaded::
  "any" usebundle => compile_and_package_and_load_selinux_module;

}


bundle agent compile_and_package_and_load_selinux_module {

files:

  "/root/SELINUX/."
   create => "true",
   comment => "/root/SELINUX is just a scratch space for
SELinux policy files as we compile, package and load SELinux policy
modules.";

files:

  
"/root/SELINUX/allowHttpdToConnectToUnixStreamSocketsAndToWriteToSocketFiles.te"
   create => "true",
   perms  => m("0600"),
   edit_line =>
Allow_Httpd_To_Connect_To_Unix_Stream_Sockets_And_To_Write_To_Socket_Files,
   comment => "httpd connects to Postgres database through
pgbouncer.  we want httpd to connect to pgbouncer using a socket file
instead of over TCP/IP, because we've had instances w
here PHP pages that connect to the database a lot in quick succession
use up all available network ports and subsequent connection attempts
fail.";


commands:

   "/usr/bin/checkmodule  -M -m -o
/root/SELINUX/allowHttpdToConnectToUnixStreamSocketsAndToWriteToSocketFiles.mod
\
   
/root/SELINUX/allowHttpdToConnectToUnixStreamSocketsAndToWriteToSocketFiles.te
 && \
/usr/bin/semodule_package -o
/root/SELINUX/allowHttpdToConnectToUnixStreamSocketsAndToWriteToSocketFiles.

Re: CFEngine Help: Managing Booleans

2012-09-22 Thread Aleksey Tsalolikhin
On Fri, Sep 21, 2012 at 8:23 AM,   wrote:
> Forum: CFEngine Help
> Subject: Managing Booleans
> Author: daveseff
> Link to topic: https://cfengine.com/forum/read.php?3,27478,27478#msg-27478
>
> I need to manage SElinux contexts on my systems. With that, I need to set 
> booleans either on or off with setsebool. It there an efficient way to manage 
> booleans in CFengine?

There isn't native support for SELinux booleans in CFEngine yet.

I set booleans with a commands type promise of "/usr/sbin/setsebool -P
name value".

This is efficient as far as the interface with the admin user is
concerned - in other words, it is easy to read and understand what
this policy is doing.

It is not efficient from the point of view of utilization of system
resources (as this command would run every time CFEngine runs, whether
its needed or not).  However the command is still convergent.  So if a
human admin or intruder were to toggle this boolean, the next run of
CFEngine would repair it.  But if it is already set, it'll stay set.

I have not experimented with running "getsebool" first to obtain and
parse the current value, and then only run "setsebool" if need, to see
if such an approach is lighter in weight partly because the Knowledge
Management win (having a concise policy) is big in my book.  But
that's the way to go to make this policy more efficient, within the
current constraints of having to use an external command to interface
with SELinux.

Best,
-at
___
Help-cfengine mailing list
Help-cfengine@cfengine.org
https://cfengine.org/mailman/listinfo/help-cfengine


False report of "no constrants" in constrained classes promises.

2012-09-22 Thread Aleksey Tsalolikhin
Situation:  I want to target a promise to a certain group of servers.
However I want to
abstract the elements of that group from the promises that target that
group, so that
when I add an element to that group, I only need to update *one*
promise, the one
enumerating that group.


(Let's assume my hosname is "web01".  The list is { "web01", "web02", "web03" }:


{{{


bundle common global_vars {

 vars:
"webservers"
   slist => { "web01", "web02", "web03" };

}


}}}




Attempt 1:  Loop over the list of server names, checking if any match
the current context.
FAIL.  3.3.5 complains "No constraints for class promise webfarm":

{{{
bundle common global_classes {

   classes:

   "webfarm"

   ifvarclass => canonify("$(global_vars.webservers)");

}

}}}

The body of a promise details and constrains its nature.  This promise
is constrained by the ifvarclass attribute.


Attempt 2: use a function to see if my hostname matches any element in
slist webservers.

{{{

}bundle common global_classes {

classes:

  "webfarm"
  expression => reglist("@(global_vars.webservers)", escape("$(sys.host)"));

}

}}}

The 2nd way is has a higher syntax to signal ratio, with an extra
function and an extra variable, which obscures my intention (compared
to the concise 1st way).

I've opened ticket 1220 to track the issue of CFEngine reporting "no
constraints" on a constrained promise.

Thank you.

Yours fondly,
-at
___
Help-cfengine mailing list
Help-cfengine@cfengine.org
https://cfengine.org/mailman/listinfo/help-cfengine