Hi all,
I've run into an architectural headache that someone else must already have visited, and perhaps solved. But, I find no mention of the problem in list archives or elsewhere.
I have several Python scripts that run under Cron. Some of these scripts access or modify sensitive data, and so I'd like to define one or more domains by means of which to limit their privileges. However, the exe name associated with such scripts is /usr/bin/python2.3, rather than the name of the script. Consistent with the principle of least privilege, I'd prefer to define distinct domains for each script, rather than an overly broad python_t domain, for instance.
Has anyone else been here already? What techniques are useful for constraining the privileges given to scripts?
One idea: Would it be a good thing to modify Run-parts to transition to a domain named for the Cron script it launches? Doing so would seem to solve my problem, but it might create others <g>.
Thanks,
On Sat, 2004-08-14 at 12:40 -0700, Bill McCarty wrote:
I've run into an architectural headache that someone else must already have visited, and perhaps solved. But, I find no mention of the problem in list archives or elsewhere.
Actually I think this is the same problem as the "crond/mailman" thread just above :)
I have several Python scripts that run under Cron. Some of these scripts access or modify sensitive data, and so I'd like to define one or more domains by means of which to limit their privileges.
Definitely possible.
However, the exe name associated with such scripts is /usr/bin/python2.3, rather than the name of the script.
You mean that you see exe=/usr/bin/python2.3 in the audit logs? That's just a side effect of the way the kernel interprets the #! header and executes the script, it doesn't mean all python scripts have to run in the same domain.
Consistent with the principle of least privilege, I'd prefer to define distinct domains for each script, rather than an overly broad python_t domain, for instance.
After creating your domain, just be sure that the context is set correctly on the executable file, and that you execute it directly.
For example:
[root@monk root]# id uid=0(root) gid=0(root) groups=0(root),1(bin),2(daemon),3(sys),4(adm),6(disk),10(wheel) context=root:sysadm_r:sysadm_t [root@monk root]# cat /usr/local/bin/foo.py #!/usr/bin/python2.3 import os os.system("id") [root@monk root]# ls -alZ /usr/local/bin/foo.py -rwxr-xr-x+ root root root:object_r:bin_t /usr/local/bin/foo.py [root@monk root]# /usr/local/bin/foo.py uid=0(root) gid=0(root) groups=0(root),1(bin),2(daemon),3(sys),4(adm),6(disk),10(wheel) context=root:sysadm_r:sysadm_t [root@monk root]# chcon -t unconfined_exec_t /usr/local/bin/foo.py [root@monk root]# ls -alZ /usr/local/bin/foo.py -rwxr-xr-x+ root root root:object_r:unconfined_exec_t /usr/local/bin/foo.py [root@monk root]# /usr/local/bin/foo.py uid=0(root) gid=0(root) groups=0(root),1(bin),2(daemon),3(sys),4(adm),6(disk),10(wheel) context=root:sysadm_r:unconfined_t
You can see from the above that when I originally executed the script, I remained in the security context root:sysadm_r:sysadm_t. That's because the script had the bin_t type, and there is no transition. However, when I changed the type of the script to unconfined_exec_t, this caused a transition to root:sysadm_r:unconfined_t (note the different type).
So what you would do is create your own domain foo_script_t, and just do: chcon -t foo_script_t /path/to/script
Does that make sense?
One idea: Would it be a good thing to modify Run-parts to transition to a domain named for the Cron script it launches? Doing so would seem to solve my problem, but it might create others <g>.
I don't think it's necessary to modify run-parts. Instead, inside the definition of your foo_script.te file, do something like:
ifdef(`crond.te', ` system_crond_entry(foo_script_exec_t, foo_script_t) ')
system_crond_entry is a macro that causes the transition to happen automatically.
On Sun, 15 Aug 2004 16:03, Colin Walters walters@redhat.com wrote:
One idea: Would it be a good thing to modify Run-parts to transition to a domain named for the Cron script it launches? Doing so would seem to solve my problem, but it might create others <g>.
I don't think it's necessary to modify run-parts. Instead, inside the definition of your foo_script.te file, do something like:
Absolutely. More than being unnecessary it's also exceedingly painful to go and modify lots of programs such as run-parts.
If we did modify run-parts to use a domain name based on the file name then run-parts would need code to map the file name to the domain name thus removing policy decisions from the policy database in the kernel and putting them in the application. Someone who used to work on a different trusted OS project told me that he thought that the SE Linux design of putting everything in the policy is absolutely the right thing to do, he had considerable experience with doing these things as C code compiled into binaries and found it not to be effective.
An on-going topic of discussion on the main SE Linux list for years has been about what other modifications should be made to applications. Most of the suggestions have been rejected (including some of mine).
Hi Russ, Colin, and all,
--On Sunday, August 15, 2004 2:03 AM -0400 Colin Walters walters@redhat.com wrote:
Actually I think this is the same problem as the "crond/mailman" thread just above :)
Yes, I believe that the new thread appeared after I'd searched for messages. But, perhaps my search was less effective than I'd hoped <g>.
However, the exe name associated with such scripts is /usr/bin/python2.3, rather than the name of the script.
You mean that you see exe=/usr/bin/python2.3 in the audit logs? That's just a side effect of the way the kernel interprets the #! header and executes the script, it doesn't mean all python scripts have to run in the same domain.
Ah! I hadn't considered that the behavior of a python script using a shebang (#!) and one invoking python with a script name as a an argument might differ. The distinction is obvious in retrospect. Part of my confusion arose because one of my files was incorrectly labeled. As someone wrote, it's not what you don't know that gets you, it's what you think you know that isn't really so <g>.
I don't think it's necessary to modify run-parts. Instead, inside the definition of your foo_script.te file, do something like:
ifdef(`crond.te', ` system_crond_entry(foo_script_exec_t, foo_script_t) ')
Thanks! I hadn't noticed that convenient macro. FYI, it looks like its definition already checks for crond.te:
# When system_crond_t domain executes a type $1 executable then transition to # domain $2, allow $2 to interact with crond_t as well. define(`system_crond_entry', ` ifdef(`crond.te', ` domain_auto_trans(system_crond_t, $1, $2) allow $2 crond_t:fifo_file { getattr read write ioctl }; # a rule for privfd may make this obsolete allow $2 crond_t:fd use; allow $2 crond_t:process sigchld;
Cheers,
On Sun, 2004-08-15 at 02:03, Colin Walters wrote:
You can see from the above that when I originally executed the script, I remained in the security context root:sysadm_r:sysadm_t. That's because the script had the bin_t type, and there is no transition. However, when I changed the type of the script to unconfined_exec_t, this caused a transition to root:sysadm_r:unconfined_t (note the different type).
So what you would do is create your own domain foo_script_t, and just do: chcon -t foo_script_t /path/to/script
Just as a reminder, domain transitions on scripts should only be done when shedding permissions.
Hi Stephen,
--On Monday, August 16, 2004 9:14 AM -0400 Stephen Smalley sds@epoch.ncsc.mil wrote:
Just as a reminder, domain transitions on scripts should only be done when shedding permissions.
I'm not sure that I understand. So, please pardon my flailing at the issue. I have a feeling that I'm missing important context <g>.
It does seem reasonable to avoid domain transitions whereby someone could gain permissions. But, Cron isn't all powerful and so I must allow one or more domain transitions that selectively add permissions. Otherwise, I'd have to extend Cron itself an unacceptably extensive range of permissions.
Cheers,
On Mon, 2004-08-16 at 14:33, Bill McCarty wrote:
It does seem reasonable to avoid domain transitions whereby someone could gain permissions. But, Cron isn't all powerful and so I must allow one or more domain transitions that selectively add permissions. Otherwise, I'd have to extend Cron itself an unacceptably extensive range of permissions.
True. A better statement would be "domain transitions on scripts should only be done when the caller is trusted not to abuse them."
I see--please pardon my pedanticism <g>.
Cheers,
--On Monday, August 16, 2004 2:54 PM -0400 Stephen Smalley sds@epoch.ncsc.mil wrote:
On Mon, 2004-08-16 at 14:33, Bill McCarty wrote:
It does seem reasonable to avoid domain transitions whereby someone could gain permissions. But, Cron isn't all powerful and so I must allow one or more domain transitions that selectively add permissions. Otherwise, I'd have to extend Cron itself an unacceptably extensive range of permissions.
True. A better statement would be "domain transitions on scripts should only be done when the caller is trusted not to abuse them."
-- Stephen Smalley sds@epoch.ncsc.mil National Security Agency
-- fedora-selinux-list mailing list fedora-selinux-list@redhat.com http://www.redhat.com/mailman/listinfo/fedora-selinux-list
Bill McCarty wrote:
Hi all,
I've run into an architectural headache that someone else must already have visited, and perhaps solved. But, I find no mention of the problem in list archives or elsewhere.
I have several Python scripts that run under Cron. Some of these scripts access or modify sensitive data, and so I'd like to define one or more domains by means of which to limit their privileges. However, the exe name associated with such scripts is /usr/bin/python2.3, rather than the name of the script. Consistent with the principle of least privilege, I'd prefer to define distinct domains for each script, rather than an overly broad python_t domain, for instance.
Has anyone else been here already? What techniques are useful for constraining the privileges given to scripts?
Instead of running python script
Change script to start with #! /usr/bin/python
And you can set context on the script
One idea: Would it be a good thing to modify Run-parts to transition to a domain named for the Cron script it launches? Doing so would seem to solve my problem, but it might create others <g>.
Thanks,
On Tuesday 23 November 2004 02:03, Daniel J Walsh dwalsh@redhat.com wrote:
Instead of running python script
Change script to start with #! /usr/bin/python
And you can set context on the script
This also saves space on the command-line. Replacing "python script" with "script" makes the command easier to read which is a good idea even when not using SE Linux.
selinux@lists.fedoraproject.org