I am trying to restrict an application I have installed to have access to a specific network interface only (tun0).
Are all network interfaces labelled 'automatically' by SELinux with 'netif_xx_t' or do I have to label them manually from the policy file? If I have to do that manually is it done with the network_interface(...) macro?
Also, if I relabel the interface would I have to amend all other policies for applications which need access to that interface (applications which use the 'generic' naming - netif_t) or is this not necessary?
I've seen there is a macro in corenetwork.if.in called 'corenet_all_recvfrom_labelled' - is that macro allowing me to receive packets from labelled interface?
Thanks in advance!
Mr Dash Four wrote:
I am trying to restrict an application I have installed to have access to a specific network interface only (tun0).
Are all network interfaces labelled 'automatically' by SELinux with 'netif_xx_t' or do I have to label them manually from the policy file? If I have to do that manually is it done with the network_interface(...) macro?
Also, if I relabel the interface would I have to amend all other policies for applications which need access to that interface (applications which use the 'generic' naming - netif_t) or is this not necessary?
I've seen there is a macro in corenetwork.if.in called 'corenet_all_recvfrom_labelled' - is that macro allowing me to receive packets from labelled interface?
Thanks in advance!
selinux mailing list selinux@lists.fedoraproject.org https://admin.fedoraproject.org/mailman/listinfo/selinux
I just wanted to note that I have had much more difficulty knowing if I have control over my network devices since the 2.6.30 kernel. Network control (Internet) is the only reason I use SELinux. If there is new and improved documentation for the usage of the network controls, I would greatly appreciate knowing about it.
-Ken-
On 08/29/2010 12:54 AM, Mantaray wrote:
Mr Dash Four wrote:
I am trying to restrict an application I have installed to have access to a specific network interface only (tun0).
Are all network interfaces labelled 'automatically' by SELinux with 'netif_xx_t' or do I have to label them manually from the policy file? If I have to do that manually is it done with the network_interface(...) macro?
Also, if I relabel the interface would I have to amend all other policies for applications which need access to that interface (applications which use the 'generic' naming - netif_t) or is this not necessary?
I've seen there is a macro in corenetwork.if.in called 'corenet_all_recvfrom_labelled' - is that macro allowing me to receive packets from labelled interface?
Thanks in advance!
selinux mailing list selinux@lists.fedoraproject.org https://admin.fedoraproject.org/mailman/listinfo/selinux
I just wanted to note that I have had much more difficulty knowing if I have control over my network devices since the 2.6.30 kernel. Network control (Internet) is the only reason I use SELinux. If there is new and improved documentation for the usage of the network controls, I would greatly appreciate knowing about it.
-Ken-
Did you have a look at this blog?: http://paulmoore.livejournal.com/
And this:
http://securityblog.org/brindle/2007/05/28/secure-networking-with-selinux/
And this:
http://james-morris.livejournal.com/11010.html
-- selinux mailing list selinux@lists.fedoraproject.org https://admin.fedoraproject.org/mailman/listinfo/selinux
I just wanted to note that I have had much more difficulty knowing if I have control over my network devices since the 2.6.30 kernel. Network control (Internet) is the only reason I use SELinux.
I agree completely! One thing I find really frustrating is working/defining ports and assigning different types to these ports.
For example: In the targeted policy there is a line in corenetwork.te.in which defines tor ports as 9001, 9090, 9091, 9050 and 9051. All this is classified as tor_port_t type. Most applications utilising tor (like Privoxy for example) only need to have access to the 9050 (and, may be, 9051) tor port and not the rest, but as things stand this is impossible to achieve as the above group of ports are lumbered together having the same type.
This, of course, presents a security loophole for applications to exploit. The above example is not unique to tor - I experienced very similar scenario when dealing with pop/smtp/imap ports - they are all packed together as one type - very inflexible.
So, in order to avoid this I had 2 choices: redefine the targeted policy and alter the corenetwork.te.in file appropriately, or, find another way of defining these ports and fine tune my custom policy to suit. Since I hit the wall with the latter (I posted a thread on here and got zero responses!) I was left with no choice, but to redefine the targeted policy and, in the above example, split the tor port classification in 4 groups (as they should be!):
tor_or - port 9001 (used internally by tor) tor_dir - ports 9090, 9091 (tor directory/bridge connections are done here) tor_proxy - port 9050 (most applications utilising tor use this port) tor_ctl - port 9051 (tor control port, used for controlling tor by other applications - like Vitalia for example)
If there is new and improved documentation for the usage of the network controls, I would greatly appreciate knowing about it.
I second that! Searching for sources of good information to resolve the above issues proved very frustrating indeed!
On 08/29/2010 12:26 AM, Mr Dash Four wrote:
I am trying to restrict an application I have installed to have access to a specific network interface only (tun0).
Are all network interfaces labelled 'automatically' by SELinux with 'netif_xx_t' or do I have to label them manually from the policy file? If I have to do that manually is it done with the network_interface(...) macro?
Also, if I relabel the interface would I have to amend all other policies for applications which need access to that interface (applications which use the 'generic' naming - netif_t) or is this not necessary?
I've seen there is a macro in corenetwork.if.in called 'corenet_all_recvfrom_labelled' - is that macro allowing me to receive packets from labelled interface?
I think you indeed have to declare new network interface types if you want to differentiate between the various network interfaces in targeted policy using network_interface()
The, i think you would have to manually label the interfaces using semanage i think. or maybe the network_interfaces() interface takes care of labelling. Not sure
By default most domains are allowed to use any network interface. The have access to the netif_type network interface attribute that is assigned to all network interface types (probably via network_interface()
That , i think, probably means that you would have to replace the rules allowing the domain to use all network interfaces by rules that govern more specific access to the various network interface types.
You can probably test this by auditing grants.
auditallow domain netif_type:netif *; or something along those lines.
try it i would say.
Thanks in advance!
selinux mailing list selinux@lists.fedoraproject.org https://admin.fedoraproject.org/mailman/listinfo/selinux
I think you indeed have to declare new network interface types if you want to differentiate between the various network interfaces in targeted policy using network_interface()
The, i think you would have to manually label the interfaces using semanage i think. or maybe the network_interfaces() interface takes care of labelling. Not sure
There is a good example at the very end of corenetwork.te.in, which 'redefines' the 'lo' network interface using the network_interfaces() macro. If I have to use a specific labelling I think I could follow that example (I wasn't sure if 'automatic' relabelling wasn't already done in some other obscure place in the targeted policy, hence my initial query).
By default most domains are allowed to use any network interface. The have access to the netif_type network interface attribute that is assigned to all network interface types (probably via network_interface()
As I understand it (again, by looking at the corenetwork files) specific netif labelling, when defined, is used as an alias of netif_t, which grants access to all applications using the 'generic' type. If that is so and I am correct with that assumption all I need to do is define an alias for a specific net device (as shown in the corenetwork files) - say netif_tun0_t - and use this type in my custom policy to grant access to this device only. All other applications in the policy utilising the generic type (netif_t) should not be affected as the netif_xx_t is an alias of netif_t.
At least that is my understanding of it.
That , i think, probably means that you would have to replace the rules allowing the domain to use all network interfaces by rules that govern more specific access to the various network interface types.
Not if, as is in my case, I am building a new policy, from scratch, for an application which needs access to a specific interface only (tun0) - if all of my assumptions in this post are true, of course.
You can probably test this by auditing grants.
auditallow domain netif_type:netif *; or something along those lines.
try it i would say.
That is pretty useful! I'll give it a go!
I think you indeed have to declare new network interface types if you want to differentiate between the various network interfaces in targeted policy using network_interface()
This is what is defined in corenetwor.te.m4:
# # network_interface(if_name,linux_interface,mls_sensitivity) # define(`network_interface',` gen_require(``type unlabeled_t;'') type $1_netif_t alias netif_$1_t, netif_type; declare_netifs($1_netif_t,shift($*)) ')
So, by that I am assuming that if I include 'network_interface(tun0,tun0,s0)' (in corenetwork.te.in instead of 's0' there is 's0 - mls_systemhigh' - does that matter?) in my policy file this is all I need to do, right?
Also, as part of the policy I wish to enable/restrict the program to connect on mysqld port, but ONLY on the local (lo) interface and then listen/bind on a predefined port but on the tun0 interface. How do I do that? There are 2 relevant macros in corenetwork.te.m4 for this:
corenet_tcp_bind_voip_sandbox_port(voip_sandbox_t) corenet_tcp_connect_mysqld_port(voip_sandbox_t)
which are taken from:
######################################## ## <summary> ## Bind TCP sockets to the $1 port. ## </summary> ## <param name="domain"> ## <summary> ## Domain allowed access. ## </summary> ## </param> ## <infoflow type="none"/> # interface(`corenet_tcp_bind_$1_port',` gen_require(` $3 $1_$2; ')
allow dollarsone $1_$2:tcp_socket name_bind; $4 ')
and
######################################## ## <summary> ## Make a TCP connection to the $1 port. ## </summary> ## <param name="domain"> ## <summary> ## Domain allowed access. ## </summary> ## </param> # interface(`corenet_tcp_connect_$1_port',` gen_require(` $3 $1_$2; ')
allow dollarsone $1_$2:tcp_socket name_connect; ')
For me it is clear that $1 is the port type (voip_sandbox and mysqld in my case) and 'dollarsone' expands to the parameter in brackets (voip_sandbox_t in my case), but what are $2, $3 and $4 (in the 1st macro above) and what values to these have? The <param> tag does not describe any of these and I cannot find any reference anywhere! Would SLIDE have picked up those?
If I manage to 'decipher' these I may restrict the above statements to the proper net device type if there is no suitable other macro found, but as it stands I am a bit stuck!
On 08/29/2010 06:02 PM, Mr Dash Four wrote:
I think you indeed have to declare new network interface types if you want to differentiate between the various network interfaces in targeted policy using network_interface()
This is what is defined in corenetwor.te.m4:
# # network_interface(if_name,linux_interface,mls_sensitivity) # define(`network_interface',` gen_require(``type unlabeled_t;'') type $1_netif_t alias netif_$1_t, netif_type; declare_netifs($1_netif_t,shift($*)) ')
So, by that I am assuming that if I include 'network_interface(tun0,tun0,s0)' (in corenetwork.te.in instead of 's0' there is 's0 - mls_systemhigh' - does that matter?) in my policy file this is all I need to do, right?
i would probably use s0 - mls_systemhigh if possible for compatibility with mls policy
Also, as part of the policy I wish to enable/restrict the program to connect on mysqld port, but ONLY on the local (lo) interface and then listen/bind on a predefined port but on the tun0 interface. How do I do that? There are 2 relevant macros in corenetwork.te.m4 for this:
corenet_tcp_bind_voip_sandbox_port(voip_sandbox_t) corenet_tcp_connect_mysqld_port(voip_sandbox_t)
those are unrelated to netif related policy. Basically when you declare a netif type there are probably interface create that provide access to your network interface type. That is what governs whether your app can or cannot use it. If your app cannot use a network interface, then it cannot use it to connect to mysqld.
which are taken from:
######################################## ## <summary> ## Bind TCP sockets to the $1 port. ## </summary> ## <param name="domain"> ## <summary> ## Domain allowed access. ## </summary> ## </param> ## <infoflow type="none"/> # interface(`corenet_tcp_bind_$1_port',` gen_require(` $3 $1_$2; ')
allow dollarsone $1_$2:tcp_socket name_bind; $4 ')
and
######################################## ## <summary> ## Make a TCP connection to the $1 port. ## </summary> ## <param name="domain"> ## <summary> ## Domain allowed access. ## </summary> ## </param> # interface(`corenet_tcp_connect_$1_port',` gen_require(` $3 $1_$2; ')
allow dollarsone $1_$2:tcp_socket name_connect; ')
For me it is clear that $1 is the port type (voip_sandbox and mysqld in my case) and 'dollarsone' expands to the parameter in brackets (voip_sandbox_t in my case), but what are $2, $3 and $4 (in the 1st macro above) and what values to these have? The <param> tag does not describe any of these and I cannot find any reference anywhere! Would SLIDE have picked up those?
The $1_$2 is probably some hack to make it work. its just the single parameter $3 (domain)
If I manage to 'decipher' these I may restrict the above statements to the proper net device type if there is no suitable other macro found, but as it stands I am a bit stuck!
Like i said above the rule has nothing to do with network interfaces. It governs access for specified domain to connect to tcp ports.
Also you've taken the above interface block from the template file. This file is used to automatically generate interfaces for declared port types.
i would probably use s0 - mls_systemhigh if possible for compatibility with mls policy
Noted.
Also, as part of the policy I wish to enable/restrict the program to connect on mysqld port, but ONLY on the local (lo) interface and then listen/bind on a predefined port but on the tun0 interface. How do I do that? There are 2 relevant macros in corenetwork.te.m4 for this:
corenet_tcp_bind_voip_sandbox_port(voip_sandbox_t) corenet_tcp_connect_mysqld_port(voip_sandbox_t)
those are unrelated to netif related policy. Basically when you declare a netif type there are probably interface create that provide access to your network interface type. That is what governs whether your app can or cannot use it. If your app cannot use a network interface, then it cannot use it to connect to mysqld.
You've lost me here.
In my policy I would need to do the following: 1) allow access to lo:mysqld, BUT restrict access to tun0:mysqld; and 2) allow bind on tun0:voip_sandbox, BUT restrict access to lo:voip_sandbox if such attempts are made.
In other words, both lo and tun0 as interfaces should be allowed (and properly labelled) - I presume with network_interface(..) - as mentioned in my previous post (every other access to another interface, if exist, should be restricted), though different ports should be enabled for different network interfaces.
The point I made above is that corenet_tcp_bind_$1_port and corenet_tcp_connect_$1 do not allow me to specify on which interface I need this to be allowed!
If I am able to decipher this macro I will certainly be able to create a group of statements for the 2 different interfaces, but as it stands I seem to be able to define voip_sandbox port binding on ANY interface as well as connecting to mysqld port also on ANY interface, which is not what I want.
The $1_$2 is probably some hack to make it work. its just the single parameter $3 (domain)
Is there any way I could 'expand' these statements and see what this really is made of?
If I manage to 'decipher' these I may restrict the above statements to the proper net device type if there is no suitable other macro found, but as it stands I am a bit stuck!
Like i said above the rule has nothing to do with network interfaces. It governs access for specified domain to connect to tcp ports.
Which is not what I need really as I would like to specify/govern access for specific domain to connect/bind to tcp ports on specific interface!
Also you've taken the above interface block from the template file. This file is used to automatically generate interfaces for declared port types.
What do you mean? I thought this is a part of the policy as statements from this file are used by a lot of policy modules, or are you saying this transforms to something else?
On 08/29/2010 08:10 PM, Mr Dash Four wrote:
i would probably use s0 - mls_systemhigh if possible for compatibility with mls policy
Noted.
Also, as part of the policy I wish to enable/restrict the program to connect on mysqld port, but ONLY on the local (lo) interface and then listen/bind on a predefined port but on the tun0 interface. How do I do that? There are 2 relevant macros in corenetwork.te.m4 for this:
corenet_tcp_bind_voip_sandbox_port(voip_sandbox_t) corenet_tcp_connect_mysqld_port(voip_sandbox_t)
those are unrelated to netif related policy. Basically when you declare a netif type there are probably interface create that provide access to your network interface type. That is what governs whether your app can or cannot use it. If your app cannot use a network interface, then it cannot use it to connect to mysqld.
You've lost me here.
In my policy I would need to do the following: 1) allow access to
example:
corenet_tcp_sendrecv_lo_if(myapp_t) corenet_tcp_connect_mysqld_port(myapp_t)
It means myapp_t can only tcp sendrecv on netif_lo_t. And it can connect to mysqld tcp ports.
so:
It can only connect to mysqld tcp ports using the lo interface because thats the only interface it can tcp sendrecv.
lo:mysqld, BUT restrict access to tun0:mysqld; and 2) allow bind on tun0:voip_sandbox, BUT restrict access to lo:voip_sandbox if such attempts are made.
In other words, both lo and tun0 as interfaces should be allowed (and properly labelled) - I presume with network_interface(..) - as mentioned in my previous post (every other access to another interface, if exist, should be restricted), though different ports should be enabled for different network interfaces.
The point I made above is that corenet_tcp_bind_$1_port and corenet_tcp_connect_$1 do not allow me to specify on which interface I need this to be allowed!
If I am able to decipher this macro I will certainly be able to create a group of statements for the 2 different interfaces, but as it stands I seem to be able to define voip_sandbox port binding on ANY interface as well as connecting to mysqld port also on ANY interface, which is not what I want.
The $1_$2 is probably some hack to make it work. its just the single parameter $3 (domain)
Is there any way I could 'expand' these statements and see what this really is made of?
If I manage to 'decipher' these I may restrict the above statements to the proper net device type if there is no suitable other macro found, but as it stands I am a bit stuck!
Like i said above the rule has nothing to do with network interfaces. It governs access for specified domain to connect to tcp ports.
Which is not what I need really as I would like to specify/govern access for specific domain to connect/bind to tcp ports on specific interface!
Also you've taken the above interface block from the template file. This file is used to automatically generate interfaces for declared port types.
What do you mean? I thought this is a part of the policy as statements from this file are used by a lot of policy modules, or are you saying this transforms to something else?
I mean the corenetwork module works a bit different than the common modules. In that it uses a template to generate interfaces for declared port types automatically. Thats where it uses the file you were looking at for. Its not an normal interface file and it should not be used manually. Theres a script in refpolicy that does it for you.
All you need to do is declare network object types and build the policy, then the script will generate the interfaces for you, unlike it does with most other modules.
example:
corenet_tcp_sendrecv_lo_if(myapp_t) corenet_tcp_connect_mysqld_port(myapp_t)
It means myapp_t can only tcp sendrecv on netif_lo_t. And it can connect to mysqld tcp ports.
so:
It can only connect to mysqld tcp ports using the lo interface because thats the only interface it can tcp sendrecv.
Yeah, but as part of the same policy I also need to bind to and send/receive tcp packets on the tun0 interface (as I posted before - I need 2 active interfaces)! Where does that go if I have to use the bind statement?
Not to mention, that if I need to, say, connect and send/receive packets on the https port on tun0 as part of the same policy - and therefore need to add another 'corenet_tcp_connect_https_port' statement - where would this go and which interface would be 'enabled' this on?
Your example above is fine if I only need one interface to connect to and send/receive packets. That is not the case here!
What do you mean? I thought this is a part of the policy as statements from this file are used by a lot of policy modules, or are you saying this transforms to something else?
I mean the corenetwork module works a bit different than the common modules. In that it uses a template to generate interfaces for declared port types automatically. Thats where it uses the file you were looking at for. Its not an normal interface file and it should not be used manually. Theres a script in refpolicy that does it for you.
All you need to do is declare network object types and build the policy, then the script will generate the interfaces for you, unlike it does with most other modules.
Is there a way I could see the 'expanded' version of this as this would be the key for me to use these statements in my policy file - just in case I run out of alternatives?
On 08/29/2010 08:38 PM, Mr Dash Four wrote:
example:
corenet_tcp_sendrecv_lo_if(myapp_t) corenet_tcp_connect_mysqld_port(myapp_t)
It means myapp_t can only tcp sendrecv on netif_lo_t. And it can connect to mysqld tcp ports.
so:
It can only connect to mysqld tcp ports using the lo interface because thats the only interface it can tcp sendrecv.
Yeah, but as part of the same policy I also need to bind to and send/receive tcp packets on the tun0 interface (as I posted before - I need 2 active interfaces)! Where does that go if I have to use the bind statement?
So you would additionally add:
corenet_tcp_sendrecv_tun0_if(myapp_t) corenet_tcp_bind_mysqld_port(myapp_t)
That would allow myapp_t to also tcp sendrecv tun0 network interface. and it would allow myapp_t to bind tcp sockets to mysqld ports.
But i think i see where this is going:
Because now myapp_t can also connect to mysqld ports via the tun0 network interface. Something you probably wanted to prevent.
Additionally now myapp_t can also listen on the lo network interface. Also something you probably wanted to prevent.
I am not sure how to best deal with this problem.
Not to mention, that if I need to, say, connect and send/receive packets on the https port on tun0 as part of the same policy - and therefore need to add another 'corenet_tcp_connect_https_port' statement - where would this go and which interface would be 'enabled' this on?
Your example above is fine if I only need one interface to connect to and send/receive packets. That is not the case here!
Good question that i cannot answer.
What do you mean? I thought this is a part of the policy as statements from this file are used by a lot of policy modules, or are you saying this transforms to something else?
I mean the corenetwork module works a bit different than the common modules. In that it uses a template to generate interfaces for declared port types automatically. Thats where it uses the file you were looking at for. Its not an normal interface file and it should not be used manually. Theres a script in refpolicy that does it for you.
All you need to do is declare network object types and build the policy, then the script will generate the interfaces for you, unlike it does with most other modules.
Is there a way I could see the 'expanded' version of this as this would be the key for me to use these statements in my policy file - just in case I run out of alternatives?
get refpolicy and build it. if will generate a corenetwork.if file.
Yeah, but as part of the same policy I also need to bind to and send/receive tcp packets on the tun0 interface (as I posted before - I need 2 active interfaces)! Where does that go if I have to use the bind statement?
So you would additionally add:
corenet_tcp_sendrecv_tun0_if(myapp_t) corenet_tcp_bind_mysqld_port(myapp_t)
That would allow myapp_t to also tcp sendrecv tun0 network interface. and it would allow myapp_t to bind tcp sockets to mysqld ports.
But i think i see where this is going:
Because now myapp_t can also connect to mysqld ports via the tun0 network interface. Something you probably wanted to prevent.
Additionally now myapp_t can also listen on the lo network interface. Also something you probably wanted to prevent.
Exactly!!!
The whole point of this entire thread is to see how to split both interfaces and define various permissions, which are interface dependant.
If I cannot do that with the above macros, then there must be another way, hence why I would need to see what has been generated after corenetwork.te.m4 has done its job! I cannot, for one second, believe that it is not possible - what is the point of labelling the network interfaces if you cannot specify which permissions go to which interface?!
Actually....wait a second!
Looking back at the macros all this translates to something like:
allow myapp_t lo_netif_t:netif { tcp_send tcp_recv }; allow myapp_t mysqld_port_t:tcp_socket { name_connect };
Correct?
If so, then I have myapp_t bound to lo_netif_t (lo interface, sending and receiving tcp packets) AND mysqld_port_t (on the same interface and allow connections to be made on it), right?
What if I define another type and name it, say, 'myapp_tun0_t' at the beginning of my policy file and then issue this:
allow myapp_tun0_t tun0_netif_t:netif { tcp_send tcp_recv }; allow myapp_tun0_t voip_sandbox_port_t:tcp_socket { name_bind };
This will bind my newly defined type (myapp_tun0_t) to the tun0 interface AND then bind to my (also defined) voip_sandbox port (i.e. listen for connections, but ONLY on the tun0 interface). Would that separate both permissions for both ports as they relate to different types? If so ... mission accomplished?
I am not sure how to best deal with this problem.
I offered something above, though I am not sure if the two types defined (myapp_t and myapp_tun0_t) would sit together in one policy file and how would this be permitted in one executable file/type - that is the unknown for me. All this, if the above is doable, of course!
On 08/29/2010 10:17 PM, Mr Dash Four wrote:
Yeah, but as part of the same policy I also need to bind to and send/receive tcp packets on the tun0 interface (as I posted before - I need 2 active interfaces)! Where does that go if I have to use the bind statement?
So you would additionally add:
corenet_tcp_sendrecv_tun0_if(myapp_t) corenet_tcp_bind_mysqld_port(myapp_t)
That would allow myapp_t to also tcp sendrecv tun0 network interface. and it would allow myapp_t to bind tcp sockets to mysqld ports.
But i think i see where this is going:
Because now myapp_t can also connect to mysqld ports via the tun0 network interface. Something you probably wanted to prevent.
Additionally now myapp_t can also listen on the lo network interface. Also something you probably wanted to prevent.
Exactly!!!
The whole point of this entire thread is to see how to split both interfaces and define various permissions, which are interface dependant.
If I cannot do that with the above macros, then there must be another way, hence why I would need to see what has been generated after corenetwork.te.m4 has done its job! I cannot, for one second, believe that it is not possible - what is the point of labelling the network interfaces if you cannot specify which permissions go to which interface?!
Actually....wait a second!
Looking back at the macros all this translates to something like:
allow myapp_t lo_netif_t:netif { tcp_send tcp_recv }; allow myapp_t mysqld_port_t:tcp_socket { name_connect };
Correct?
If so, then I have myapp_t bound to lo_netif_t (lo interface, sending and receiving tcp packets) AND mysqld_port_t (on the same interface and allow connections to be made on it), right?
What if I define another type and name it, say, 'myapp_tun0_t' at the beginning of my policy file and then issue this:
allow myapp_tun0_t tun0_netif_t:netif { tcp_send tcp_recv }; allow myapp_tun0_t voip_sandbox_port_t:tcp_socket { name_bind };
And what if another instance of the same app may use lo_netif_t and not tun0_netif_t. How are you going to define which domain the app should run in?
This will bind my newly defined type (myapp_tun0_t) to the tun0 interface AND then bind to my (also defined) voip_sandbox port (i.e. listen for connections, but ONLY on the tun0 interface). Would that separate both permissions for both ports as they relate to different types? If so ... mission accomplished?
I am not sure how to best deal with this problem.
I offered something above, though I am not sure if the two types defined (myapp_t and myapp_tun0_t) would sit together in one policy file and how would this be permitted in one executable file/type - that is the unknown for me. All this, if the above is doable, of course!
And what if another instance of the same app may use lo_netif_t and not tun0_netif_t. How are you going to define which domain the app should run in?
The application should utilise both domains as it needs access to both interfaces. Is that not possible to define more than one domain for a particular application?
Just a guess on my part, but is it not possible to create two init_daemon_domain statements at the start of the policy file and associate them both with the executable file? That is provided there isn't any other elegant solution in which to utilise both interfaces with separate set of permissions - I am still looking to see if that is not the case.
I think I found a solution, inspired by reading two very good articles by James Morris (article here - http://james-morris.livejournal.com/11010.html) and Paul Moore (article here - http://paulmoore.livejournal.com/4281.html). Both are members of this list, so if they read this thread I welcome their comments.
Both articles refer to an elegant solution for my problems by using SECMARK (which is supported by both the new kernels and SELinux) - using iptables to mark the packets I am interested in with a specific security context (using the --selctx iptables option), and then using my SELinux policy to control/manipulate access to this context by using the (new) 'packet' class permissions.
With this approach I will have more fine-grained control over what goes where and that will also allow me to use more than one net interface to enforce control within the same policy - exactly what I wanted.
As the articles were about 4 years old I am not sure whether there is something better out there, but this will do for the time being.
I've had a little snag, however! As an experiment, I tried to mark packets using iptables, but my attempt failed - miserably so! I executed this:
iptables -t mangle -A INPUT -p tcp --dst 127.0.0.1 --dport 3306 -j SECMARK --selctx system_u:object_r:mysqld_t:s0
Error message received: "iptables: Invalid argument. Run `dmesg' for more information.". dmesg reveals: "SECMARK: unable to obtain relabeling permission" (note the wrong speLLing!), which then led me to my avc:
type=AVC msg=audit(1283619145.372:45): avc: denied { relabelto } for pid=1846 comm="iptables" scontext=unconfined_u:unconfined_r:iptables_t:s0-s0:c0.c1023 tcontext=system_u:object_r:mysqld_t:s0 tclass=packet type=SYSCALL msg=audit(1283619145.372:45): arch=40000003 syscall=102 success=no exit=-22 a0=e a1=bfb86510 a2=cf392c a3=cf15e4 items=0 ppid=1512 pid=1846 auid=0 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts0 ses=1 comm="iptables" exe="/sbin/iptables-multi" subj=unconfined_u:unconfined_r:iptables_t:s0-s0:c0.c1023 key=(null)
I quickly examined iptables.te and there is a macro 'relabelto_all_packets(iptables_t)', which, in essence, translates to 'allow iptables_t packet_type:packet relabelto;'
On the face of it, I can't see why I should get the above avc as the domain in both cases is 'iptables_t'?! Any suggestions?
One additional inconvenience is that I am using Shorewall, which, from what I can gather, does not support SECMARK and CONSECMARK and I have to execute iptables directly to do what I want - not very nice and that would be a matter for the Shorewall support forum.
Further to my previous post a few days ago, I found what was causing the AVCs when I was executing iptables to create my SELinux packet context, though it was not iptables to blame - it was my own fault, which boiled down to lack of knowledge really.
Using my previous example, if I wish to mark connections to lo:3306 with security context system_u:object_r:mysqld_t:s0 using the statement
iptables -t mangle -A INPUT -p tcp --dst 127.0.0.1 --dport 3306 -j SECMARK --selctx system_u:object_r:mysqld_t:s0
That won't work! The reason why it does not work turned out to be very simple - mysqld_t was already an existing type (defined with mysqld.te) and this type did not have the "packet_type" attribute attached to it. The appropriate way to use this, generally, is to create another policy file (or extend mysqld.te) and define another type specifically defined for use with packets, something like:
type mysqld_packet_t, packet_type;
With that defined when I implement the policy and execute iptables with:
iptables -t mangle -A INPUT -p tcp --dst 127.0.0.1 --dport 3306 -j SECMARK --selctx system_u:object_r:mysqld_packet_t:s0
all is well and the control is enforced as expected, though there is a 'side' effect in that when I loaded the module I started getting AVCs for all other applications, which have their traffic unlabelled (basically any other application needing some sort of internet access). To mitigate that, temporarily, I had to include the following statement in the same policy file:
# Allow all unlabelled packets to all domains. # allow domain unlabeled_t:packet { send recv };
This is, of course, NOT secure and it will be removed as soon as I define the appropriate policy captures for every application, which needs/uses net traffic.
There is one small issue remaining, however, which I hope the more knowledgeable on here will help me out with!
There are 3 different attributes defined in the policy: packet_type (which I take it is a general-purpose, encompassing packet traffic in both directions), client_packet_type and server_packet_type. What I would like to know is when the client_packet_type and server_packet_type are used?
Do I define/use the server_packet_type in 'server' connections (i.e. when the application/process I am writing the policy for listens on a particular port and accepts client connections only, hence that sort of traffic should be defined with server_packet_type attribute - i.e. recv only permission)? If that is the case and I am writing a policy for the connecting application (which connects to the same port) do I have to use the same type, but the client_packet_type attribute attached to it and then 'send' only permission?
Without using server_packet_type and client_packet_type (utilising packet_type only) when writing policy for both server- and client- processes connecting/using the same port the general type attribute (packet_type) is doing the job, provided I attach the appropriate permissions ('send' for the client part and 'recv' for the server part) to the type I defined, though I am not sure if using server_packet_type and client_packet_type is the better way of doing it, so help would be much appreciated by the more knowledgeable on here!
selinux@lists.fedoraproject.org