Description of problem: Iptables scripts need to add rules for secmark labeling from selinux policy. The latest selinux policy and userland tools will create a file containing iptables rules for secmark labeling. These need to be added to a separate iptables chain on iptables startup. The rules are stored at: /etc/selinux/[policy-name]/contexts/netfilter_contexts policy-name is the name of the currently active policy which can be found in /etc/selinux/config The rules are formatted for iptables-restore - below is an example: *mangle :PREROUTING ACCEPT [0:0] :INPUT ACCEPT [0:0] :FORWARD ACCEPT [0:0] :OUTPUT ACCEPT [0:0] :POSTROUTING ACCEPT [0:0] :selinux_input - [0:0] :selinux_output - [0:0] :selinux_new_input - [0:0] :selinux_new_output - [0:0] -A INPUT -j selinux_input -A OUTPUT -j selinux_output -A selinux_input -m state --state NEW -j selinux_new_input -A selinux_input -m state --state RELATED,ESTABLISHED -j CONNSECMARK -A selinux_output -m state --state NEW -j selinux_new_output -A selinux_output -m state --state RELATED,ESTABLISHED -j CONNSECMARK -A selinux_new_input -j SECMARK --selctx system_u:object_r:server_packet_t -A selinux_new_input -j CONNSECMARK --save -A selinux_new_input -j RETURN -A selinux_new_output -j SECMARK --selctx system_u:object_r:client_packet_t -A selinux_new_output -j CONNSECMARK --save -A selinux_new_output -j RETURN COMMIT
I have some questions: 1) Iptables is only able to save and load one file. This is /etc/sysconfig/iptables for us. 2) If we cat the files together, what should be done with "service iptables save"? Which rules should go where? What about user added rules? Where do we save them? Do we drop them? HOw do we separate the rules? 3) What do we do with user specific mangle rules. Those could conflict with the selinux rules? 4) How do we separate user defined rules from selinux-policy supplied ones? 5) Shouldn't system-config-securitylevel integrate the selinux rules info /etc/sysconfig/ipXtables? What do we do with user-specific firewall rules, then? 6) Will these rules be IPv4 or IPv6 specific? BTW: The file is located in /etc/selinux/[policy-name]/modules/active/netfilter_contexts
I have some questions: 1) Iptables is only able to save and load one file. This is /etc/sysconfig/iptables for us. 2) If we cat the files together, what should be done with "service iptables save"? Which rules should go where? What about user added rules? Where do we save them? Do we drop them? HOw do we separate the rules? Can the rules be catted together at runtime? The rules do not need to be saved since this file has them. The rough plan was that all of these rules would go in their own chain. 3) What do we do with user specific mangle rules. Those could conflict with the selinux rules? They could, but if the selinux rules are in their own chain won't that allow the user supplied mangle rules to just work? 4) How do we separate user defined rules from selinux-policy supplied ones? Separate chains. 5) Shouldn't system-config-securitylevel integrate the selinux rules info /etc/sysconfig/ipXtables? What do we do with user-specific firewall rules, then? Maybe, but these rules are _not_ generated from system-config-securitylevel. The policy tools (semodule/semanage) manage these rules which originate from selinux policy modules. 6) Will these rules be IPv4 or IPv6 specific? As far as I know. BTW: The file is located in /etc/selinux/[policy-name]/modules/active/netfilter_contexts That is not correct - that path is private for semodule. The correct path is /etc/selinux/[policy-name]/contexts/netfilter_contexts. Try semodule -B or semodule -b semodule -b /usr/share/selinux/targeted/base.pp and see if that file is generated. Otherwise, please check /var/log/audit/audit.log or /var/log/messages for denial messages from selinux.
1) How do we enable/disable the loading of netfilter_contexts? 2) If there are IPv4 and IPv6 specific rules, then we need two files: One for iptables and one for ip6tables. 3) Are there only mangle rules for secmark? Will this change sometimes? 4) According to your example from above, the default policy for the selinux mangle chains is ACCEPT. This could collide with a user configured firewall where default policy is DROP. If you change the default policy after the user configured firewall is applied, you could open up the firewall completely. 5) The rules should not be catted together. iptables has to load one file after the other. What should happen if the import of one of them fails? Wich one is the first, which the second one? (see 4) 6) If we drop all chains with the name "selinux_*", then we loose all user supplied chains and rules which match this name if the user is using "service iptables save". If we do not drop them, then the firewall is not loadable anymore without netfilter_contexts. 7) Should the selinux chains be used before or after user supplied chains? 8) I do have problems with the netfilter contexts on my machine. /etc/selinux/targeted/contexts/netfilter_contexts is not generated by default and when it is generated with semodule -B, it is empty. # cat /etc/sysconfig/selinux SELINUX=permissive SELINUXTYPE=targeted SETLOCALDEFS=0 # semodule -b semodule -b /usr/share/selinux/targeted/base.pp semodule: Could not read file 'semodule': # semodule -B # cat /etc/selinux/targeted/contexts/netfilter_contexts #
> 1) How do we enable/disable the loading of netfilter_contexts? Not certain what you mean here - disable on a single call to iptables start? Globally for a system? If selinux is enabled the user will probably want these rules but if not they won't - so checking for selinux being disabled should probably be added. > 2) If there are IPv4 and IPv6 specific rules, then we need two files: One for > iptables and one for ip6tables. Ok - I'll work with upstream to get this working. The current file is ipv4 only. > 3) Are there only mangle rules for secmark? Will this change sometimes? Only mangle and there are currently no plans to change this. > 4) According to your example from above, the default policy for the selinux > mangle chains is ACCEPT. This could collide with a user configured firewall > where default policy is DROP. If you change the default policy after the user > configured firewall is applied, you could open up the firewall completely. We are always assuming that the secmark rules are loaded first so that any user supplied rules will override these settings. > 5) The rules should not be catted together. iptables has to load one file > after the other. What should happen if the import of one of them fails? Wich > one is the first, which the second one? (see 4) The secmark rules should be loaded first to allow user supplied rules to override. If the loading of the secmark rules fails the rest of the rules should continue to be loaded. Generally, these rules not being present will _prevent_ access not allow it. > 6) If we drop all chains with the name "selinux_*", then we loose all user > supplied chains and rules which match this name if the user is using "service > iptables save". If we do not drop them, then the firewall is not loadable > anymore without netfilter_contexts. There is nothing that we can do about name collisions. I think that we need to treat chains with that name as reserved. We can potentially change that to a name that is less likely to be used by a user (any suggestions?) and I will request a mechanism for changing the name prefix to upstream. > 7) Should the selinux chains be used before or after user supplied chains? Again, before so that they can be overriden by the user. > 8) I do have problems with the netfilter contexts on my machine. > /etc/selinux/targeted/contexts/netfilter_contexts is not generated by default > and when it is generated with semodule -B, it is empty. > # cat /etc/sysconfig/selinux > SELINUX=permissive > SELINUXTYPE=targeted > SETLOCALDEFS=0 > # semodule -b semodule -b /usr/share/selinux/targeted/base.pp > semodule: Could not read file 'semodule': > # semodule -B > # cat /etc/selinux/targeted/contexts/netfilter_contexts > # Please file a separate bug for this against policycoreutils with the versions of libsemanage, selinux-policy, libselinux, and policycoreutils - the bug should be assigned to Dan Walsh (dwalsh). I am attaching a correct file to this bug so that this work can continue while your issue is fixed.
Created attachment 135055 [details] Example netfilter_contexts file
>> 7) Should the selinux chains be used before or after user supplied chains? > Again, before so that they can be overriden by the user. My original idea was to have the netfilter_contexts have a jump to a chain that has the user-specified rules, so they would be cleanly separated, e.g., -A selinux_new_input -j SECMARK --selctx system_u:object_r:server_packet_t -A selinux_new_input .... -A selinux_new_input .... -A selinux_new_input -j selinux_new_input_user -A selinux_new_input -j CONNSECMARK --save -A selinux_new_input -j RETURN Then we know for certain which four chains need to be handled by netfilter_contexts, we don't have to worry about trashing user rules by modfying these chains, and the user rules will be hit at the appropriate time. As for what the chains are named, I'm open to suggestions.
I'd say SECMARK is a good name. Are there already netfilter_contexts files for IPv4 and IPv6? I do not like the idea to pipe the output of iptables-save through sed or awk to drop the SECMARK rules. But the other solution is to drop the save option from the iptables startup script completely. I think it is not possible to allow user-defined secmark rules, because with selinux disabled or with secmark disabled, the firewall will not start anymore, which is a no go.
User defined secmark rules can be handled via the selinux infrastructure instead. That has the advantage that the rules could be checked for valid security contexts and they wouldn't be inserted if selinux is disabled (I assume that the iptables script will check if selinux is enabled). So sed'ing the secmark rules out on save should be fine.
I think sed'ing out secmark rules is the wrong thing to do. We shouldn't forbid people from adding secmark rules manually, it violates least surprised (I added this rule and saved but then it disappeared). Instead there should be so called "system" chains that don't get saved off and "user" chains that do. I'm not sure how best to inform people that they need to add selinux rules to specific chains though (or rather, not add them to specific chains). Another (much less likely) alternative is to make iptables-save semanage aware and have it save secmark rules that way but that is bad if we ever want to do access control on semanage stuff that isn't in a policy (since we won't know where the iptable rule came from)
actually, here is another suggestion: can iptables-save have a pre and post hook put in so that a script can be dropped in /etc/iptables-save.d or whatever that will remove semanage stored rules before iptables-save saves user rules off and put them back on after it restores user rules?
I'll drop save support in the iptables startup script, because using sed or similar to drop selinux rules is not an option. This could result in really big trouble. There is no iptables.save.d support. And btw. the order of such rules is important, therefore it is difficult to get this in sync if there are changes.
Here is a nice performance test of netfilter and nf-HiPAC. Please have a look at the performance loss of iptbales with more rules in a chain. Please also have a look at "Independent Tests". Do we have performance tests with and without the SECMARK ruleset? Currently there are 480 rules.
Here is the URL: http://www.hipac.org/performance_tests/results.html
Created attachment 136152 [details] Additional avc messages since SECMARK rules are applied.
I suggest investigating port ranges and the multiport match to reduce the number of rules, and only loading rules for services which are active.
THat just does not work. You would have to instrument every init script to add and unload secmark rules when they start and stop. Also what happens when someone executes ypbind. In this case their needs to be a secmark rule for every port on the machine to every domain. This does not work in userspace.
I don't see how it could not work. The same issue needs to be addressed for ensuring that policy modules are only loaded for active services. ypbind may be a special case, but in general, this is what needs to happen, to reduce kernel bloat caused by loading all policies. The netfilter rules are simply policy labeling rules.
We are not going to implement init script integration at this point. When we figure out what we need to do, another bugzilla will be opened to track this.