danwalsh


Dan Walsh's Blog

Got SELinux?


Previous Entry Share Next Entry
How do I tell what would be allowed by a boolean?
danwalsh

I received and Email today that asked the following question:

I still fail to understand the difference between  httpd_can_network_connect_db and httpd_can_network_connect. Some people say the former allows connections to known database ports. My question are:

What are these ports? Where are the corresponding policy defined? I found many  .pp files deeply under /etc/selinux, and I feel sorry that they are binary which are almost impossible to interpret, so where can I find the the source files for the compiled policy, and what is the language to define policies?


You could use the semanage command for how the booleans are described.

> semanage boolean -l | grep httpd_can_network_connect
httpd_can_network_connect_db   (off  ,  off)  Allow HTTPD scripts and modules to connect to databases over the network.
httpd_can_network_connect      (off  ,  off)  Allow HTTPD scripts and modules to connect to the network using TCP.


The best answer to this is to look at the sesearch and seinfo tools and on newer (Fedora/RHEL7) systems sepolicy command.  Also look at the man pages that have been generated.

man httpd_selinux

sesearch and seinfo are available in the setools-cmdline package.  sepolicy is in policycoreutils-python package.

httpd_can_network_connect_db

sesearch -A -s httpd_t -b httpd_can_network_connect_db -p name_connect
   allow httpd_t postgresql_port_t : tcp_socket { recv_msg send_msg name_connect } ;
   allow httpd_t mssql_port_t : tcp_socket name_connect ;
   allow httpd_t oracle_port_t : tcp_socket name_connect ;
   allow httpd_t mysqld_port_t : tcp_socket { recv_msg send_msg name_connect } ;
   allow httpd_t gds_db_port_t : tcp_socket name_connect ;


The command above reads in the policy and prints out what happens when you enable the httpd_can_network_connect_db boolean.  We further restrict the search to see how it affects the httpd_t, apache, process type with the name_connect access.     sesearch tells us that turning on httpd_can_network_connect_db would allow the httpd_t domain to connect to tcp ports labeled postgresql_port_t, mssql_port_t, oracle_port_t, mysqld_port_t, gds_db_port_t.  You can use seinfo to turn these port types into port definitions. semanage port -l would also work.

> seinfo  --port | grep -e postgresql_port_t -e mysqld_port_t -e oracle_port_t -e gds_db_port_t | grep tcp
    portcon tcp 3050 system_u:object_r:gds_db_port_t:s0
    portcon tcp 1186 system_u:object_r:mysqld_port_t:s0
    portcon tcp 3306 system_u:object_r:mysqld_port_t:s0
    portcon tcp 63132-63164 system_u:object_r:mysqld_port_t:s0
    portcon tcp 1521 system_u:object_r:oracle_port_t:s0
    portcon tcp 2483 system_u:object_r:oracle_port_t:s0
    portcon tcp 2484 system_u:object_r:oracle_port_t:s0
    portcon tcp 5432 system_u:object_r:postgresql_port_t:s0


> sepolicy network -t postgresql_port_t
postgresql_port_t: tcp: 5432


httpd_can_network_connect

> sesearch -A -s httpd_t -b httpd_can_network_connect -p name_connect
Found 1 semantic av rules:
   allow httpd_t port_type : tcp_socket name_connect ;


The above command shows that httpd_can_network_connect allows httpd_t to connect to all tcp socket types that have the port_type attribute.

> seinfo -aport_type -x | wc -l
245


Using seinfo above would show you that port_type is the attribute of all port types, meaning that turning on the httpd_can_network_connect boolean, allows the httpd_t domain to connect to ALL tcp network ports.

Bottom Line httpd_can_network_connect_db allows httpd_t to connect to an additional 10 ports while httpd_can_network_connect adds thousands.


Is any plan making boolean per-domain? Just current implementation is similary strange. We have a globaly defined variable for specified application, so can't make a different rules for different instances of one app... this not a stopper and WA exist, but ... that's strange :)

Not sure what you mean. You can define a boolean any way you want in policy.

Many thanks, Dan, for thorough explanation. I followed your instructions and verified in my CentOS 6.4 release, although the output in my box differs from yours a little, I have amlost clear understanding, except a few minor points:

1) say in this rule,

allow httpd_t postgresql_port_t : tcp_socket { recv_msg send_msg name_connect } ;

httpd_selinux(8) says httpd_t type is entered via the httpd_exec_t file type whose label rules can be found in /etc/selinux/targeted/modules/active/file_contexts. And by either seinfo or semanage the postgresql_port_t port type can be verified as tcp/5432.

I read tcp_sockt as resource class and those in curly brackets are permissions, but there is still a minor gap between them and my old understanding of Linux system APIs. How can I resolve the gap?

2) I read the 'allow source_type target_type: resoure_class { permissions }' as kind of policy language syntax. And I recall you mentioned in an old post that it is m4, and Brindle's blog mentioned there will be a new policy language. So where can I find the source of the existing policies, and when will the new language take over?

3) there's a minor mind leap I saw this command

seinfo -aport_type -x | wc -l

where port_type is an attribute. What's an attribute? I guess it is kind of aggregation of types?

PS: I read almost 80 recent posts last night, I wish I have read your blog many years ago.

1. SELinux rules are between types (or attributes). You have a source type httpd_t representing a process type of in SELinux lingo a "domain". And you have a target type, in this case postgresql_port_t. Then as you properly stated you have the class of the target object and the list of permissions you are granting. In SELinux there is no concept of UID or ownership of an object like there is in DAC (Descretionary Access Control == Linux System APIs)

2 Sources for the policy released productes are included in the SRC RPM. Newer policies are stored in git either Fedora git.fedorahosted.org/git/selinux-policy.git which is based off the refpolicy in http://oss.tresys.com/git/refpolicy.git

3. Attributes as ways of grouping types together so yes thinking of this as a aggregate type of a group. For example all process types have a attribute of "domain". All file types have an attribute of "file_type", and all port types have a attribute of "port_type". These attributes can then be used for writing policy like

allow rpm_t file_type:file manage_file_perms;

equivalent of _db for webports available?

rodehoed

2013-05-29 10:50 am (UTC)

Hi Dan,

Great reading! Is there also an boolean on RHEL 6 to have something like this httpd_can_network_connect_web. So the webserver is only allowed to connect to other webports (eg. 80,443,8080,8443). This is handy when using payment provider scripts and stuff like REST. Currently I use httpd_can_network_connect only for this reason.

Greetz,
Rodehoed

Re: equivalent of _db for webports available?

danwalsh

2013-05-29 01:15 pm (UTC)

sesearch -A -b httpd_can_network_relay -s httpd_t -p name_connect
Found 7 semantic av rules:
allow httpd_t squid_port_t : tcp_socket name_connect ;
allow httpd_t memcache_port_t : tcp_socket name_connect ;
allow httpd_t gopher_port_t : tcp_socket name_connect ;
allow httpd_t ephemeral_port_type : tcp_socket name_connect ;
allow httpd_t ftp_port_t : tcp_socket name_connect ;
allow httpd_t http_cache_port_t : tcp_socket name_connect ;
allow httpd_t http_port_t : tcp_socket name_connect ;

Is the closest. If you run your avc's for a blocked connection in RHEL7 and Latest Fedora's it will tell you if a boolean would allow the access. Also setroubleshoot should tell you the name of the booleans in RHEL6.

Re: equivalent of _db for webports available?

rodehoed

2013-05-30 12:18 pm (UTC)

Dan,

I enabled the httpd_can_network_connect_relay boolean but then a remote connection fails with:

type=AVC msg=audit(1369915326.405:289991): avc: denied { name_connect } for pid=3030 comm="php-cgi" dest=80 scontext=system_u:system_r:httpd_sys_script_t:s0 tcontext=system_u:object_r:http_port_t:s0 tclass=tcp_socket
type=SYSCALL msg=audit(1369915326.405:289991): arch=c000003e syscall=42 success=no exit=-13 a0=6 a1=7fffbe6978a0 a2=10 a3=0 items=0 ppid=25932 pid=3030 auid=0 uid=10106 gid=505 euid=10106 suid=10106 fsuid=10106 egid=505 sgid=505 fsgid=505 tty=(none) ses=20175 comm="php-cgi" exe="/usr/bin/php-cgi" subj=system_u:system_r:httpd_sys_script_t:s0 key=(null)

Any clue?

Re: equivalent of _db for webports available?

danwalsh

2013-05-30 12:37 pm (UTC)

Well it looks like we treat cgi scripts that run under httpd_t differently for this boolean.

sesearch -CA -s httpd_sys_script_t -t http_port_t -p name_connect
Found 3 semantic av rules:
DT allow httpd_script_type reserved_port_type : tcp_socket name_connect ; [ httpd_enable_cgi nis_enabled && ]
DT allow nsswitch_domain reserved_port_type : tcp_socket name_connect ; [ nis_enabled ]
DT allow httpd_sys_script_t port_type : tcp_socket { recv_msg send_msg name_connect } ; [ httpd_enable_cgi httpd_can_network_connect && ]

Which means the best boolean that will get you what you want is httpd_can_network_connect.

nis_enabled should only be used in an NIS environment, since it is really loose.

Another tighter option would be to build a custom policy module using audit2allow.

# grep httpd_sys_script_t /var/log/audit/audit.log | audit2allow -M myhttpd
# semodule -i myhttpd.pp

This would modify policy to allow cgi scripts to connect to only the httpd ports.

The other advanced option would be to use sepolgen or sepolicy generate --cgi to create policy for you cgi script.

Re: equivalent of _db for webports available?

rodehoed

2013-05-30 01:12 pm (UTC)

Works now :-) Will sesearch be backported to EL 6.4 too? Seems a handy tool!

Re: equivalent of _db for webports available?

danwalsh

2013-05-30 01:26 pm (UTC)

It is in there, setools-cmdline package, might not be in primary RHEL packages.

You are viewing danwalsh