To add a personal experience note to the above -- using selinux in conjunction with iptables makes both the policy and your iptables look extremely complicated and convoluted. It's one of those cases where the complexity trade-off must really be worth the trouble -- unless you are securing a military installation where correct packet labelling means life or death, I wouldn't recommend it.
SELinux does provide some basic port/protocol labelling that doesn't tie in with iptables. E.g. if you run semanage port -l
it will give you a list of all ports defined in the targeted policy. You can use this to restrict which ports an SELinux domain can communicate on. For example, you can write a policy stating that myapp_t
can only bind to myapp_port_t
and connect to http_port_t
. This is already pretty good -- if an attacker manages to exploit the app, they would not be able to bind to any other ports or connect to anything other than 80/tcp (e.g. this would foil an attempt to connect to IRC).
If you were really into it, you could then go further and say -- label all packets created by myapp_port_t
as myapp_packet_t
and configure the firewall to only pass myapp_packet_t
to -d 10.10.10.1 --dport 443
. Then, if an attacker managed to exploit that app, they would only be able to communicate with 10.10.10.1 on port 443, while other apps, such as a browser, would not otherwise be restricted.
That being said, while it's awesome in theory, in practice apps produce a lot more packet traffic than just that one outgoing tcp on port 443. An app would need to do nslookups (so you need to allow myapp_packet_t udp to port 53), and if your user info is coming from ldap, it would probably generate ldap traffic. As a result, your policies and your iptables quickly balloon into unmanageable monstrosities. I recommend sticking to basic port labelling. :)