Hi, all:
Most of the selinux+iptables guides out there talk about using iptables to label incoming packets, which would then be either allowed or denied by the domain of the application.
I want to do it the other way around. Let's say I have a shared web hosting site where every client's application is running inside its own SELinux domain (e.g. httpd_myapp_script_t). I would like to be able to only allow httpd_myapp_script_t to connect to 192.168.1.1 port 443, but not any other IP address. This is actually quite common -- an application may need to make a REST call to some site, but it really has no business talking to any other hosts on the net.
I can use standard approach to allow httpd_myapp_script_t to connect to httpd_port_t, but this will allow it to talk to any host at all. How would I write a policy that would label packets going out of httpd_myapp_script_t (e.g. httpd_myapp_packet_t) and then use OUTPUT rules to only allow such packets to go out to 192.168.1.1:443?
Has anyone done anything like that?
Best,
On October 23, 2013 10:28 , Konstantin Ryabitsev icon@fedoraproject.org wrote:
I want to do it the other way around. Let's say I have a shared web hosting site where every client's application is running inside its own SELinux domain (e.g. httpd_myapp_script_t). I would like to be able to only allow httpd_myapp_script_t to connect to 192.168.1.1 port 443, but not any other IP address. This is actually quite common -- an application may need to make a REST call to some site, but it really has no business talking to any other hosts on the net.
I am doing this. My solution is bad because it uses a kernel module that uses private SELinux data structures (and hence is both fragile and unsupported), and because it goes against the SELinux goal of having all security policy in a single place (some security policy winds up in the iptables rules). I am very interested in any better solution that SELinux experts can suggest.
My solution is to load the following iptables module:
https://github.com/markmont/xt_selinux
...and then use iptables rules like this:
# Restrict what things running under php-fpm can access. We're using a # local policy named phpfcgi here because Red Hat's policies include an # alias of httpd_t for phpfpm_t, and if we use that then these rules would # prevent httpd from communicating with clients. -N PHPFPM -A OUTPUT -m selinux --task-ctx system_u:system_r:phpfcgi_t:s0 -j PHPFPM -A PHPFPM -o lo -j ACCEPT -A PHPFPM -4 -m set --match-set webapp-allow dst -j ACCEPT -A PHPFPM -6 --destination ::1 -j ACCEPT -A PHPFPM -j LOG --log-prefix "iptables rejected output: " --log-level 5 --log-uid -A PHPFPM -j REJECT
Although I'm using a hash:net ipset in the example above, you could use a hash:ip,port ipset instead to restrict traffic to certain destination ports. Alternatively, just write the permitted addresses and ports direclty into iptables rules.
I hope this helps.
-- Mark Montague mark@catseye.org
On October 23, 2013 11:00 , Mark Montague mark@catseye.org wrote:
On October 23, 2013 10:28 , Konstantin Ryabitsev icon@fedoraproject.org wrote:
I would like to be able to only allow httpd_myapp_script_t to connect to 192.168.1.1 port 443, but not any other IP address. This is actually quite common -- an application may need to make a REST call to some site, but it really has no business talking to any other hosts on the net.
# Restrict what things running under php-fpm can access. We're using a # local policy named phpfcgi here because Red Hat's policies include an # alias of httpd_t for phpfpm_t, and if we use that then these rules would # prevent httpd from communicating with clients. -N PHPFPM -A OUTPUT -m selinux --task-ctx system_u:system_r:phpfcgi_t:s0 -j PHPFPM
I should add that the local SELinux policy that I'm using for PHP-FPM is a modified version of prometheanfire's work, which he has previous posted to this list:
https://github.com/prometheanfire/selinux-modules.git
I've renamed the types and added a couple extra allow rules for things that my installation of PHP-FPM needs to be able to do, but none of the modifications are related to restricting network traffic; the magic for that is all in the kernel module and iptables rules.
-- Mark Montague mark@catseye.org
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1
On 10/23/2013 11:16 AM, Mark Montague wrote:
On October 23, 2013 11:00 , Mark Montague mark@catseye.org wrote:
On October 23, 2013 10:28 , Konstantin Ryabitsev icon@fedoraproject.org wrote:
I would like to be able to only allow httpd_myapp_script_t to connect to 192.168.1.1 port 443, but not any other IP address. This is actually quite common -- an application may need to make a REST call to some site, but it really has no business talking to any other hosts on the net.
# Restrict what things running under php-fpm can access. We're using a # local policy named phpfcgi here because Red Hat's policies include an # alias of httpd_t for phpfpm_t, and if we use that then these rules would # prevent httpd from communicating with clients. -N PHPFPM -A OUTPUT -m selinux --task-ctx system_u:system_r:phpfcgi_t:s0 -j PHPFPM
I should add that the local SELinux policy that I'm using for PHP-FPM is a modified version of prometheanfire's work, which he has previous posted to this list:
https://github.com/prometheanfire/selinux-modules.git
I've renamed the types and added a couple extra allow rules for things that my installation of PHP-FPM needs to be able to do, but none of the modifications are related to restricting network traffic; the magic for that is all in the kernel module and iptables rules.
-- Mark Montague mark@catseye.org -- selinux mailing list selinux@lists.fedoraproject.org https://admin.fedoraproject.org/mailman/listinfo/selinux
It is better that these types of questions go to the upstream SELinux list selinux@tycho.nsa.gov
selinux@lists.fedoraproject.org