Quantcast
Channel: Dan Walsh's Blog
Viewing all 181 articles
Browse latest View live

How should you disable IPV6?

$
0
0
Blogging twice in the same day, a new record...

Lots of people are out there disabling IPV6, and when you do invariably you get a flood of AVC messages about different confined domains asking the kernel to load the kernel module net-pf-10.   

type=AVC msg=audit(10/18/11 23:40:10.233:978087) : avc:  denied  { module_request } for  pid=32265 comm=pickup kmod="net-pf-10" scontext=system_u:system_r:postfix_pickup_t:s0 tcontext=system_u:system_r:kernel_t:s0 tclass=system

Now I am not recommending that you enable or disable IPV6, but if you do want to disable it and run with SELinux turned on, please read the following:

Eric Paris reports

"I believe the networking kernel community recommends (and it will shut up these AVCs) that IPv6 be disabled by:

echo 1 > /proc/sys/net/ipv6/conf/all/disable_ipv6

It still loads the module but unhooks almost all of the calls into the module. (apparently the IPv6 module has become so ingrained in the kernel that a number of other things, like certain firewall modules, require it. I didn't design it, I'm just telling it how it is) "


We recommend that you do not disable the ipv6 module but add

net.ipv6.conf.all.disable_ipv6 = 1

to /etc/sysctl.conf

And the AVC messages should go away.

The setroubleshoot plugin in Fedora reflects this info.


10 things you probably did not know about SELinux.. #8 How to remove a port from a port type?

$
0
0
How do you remove a network port from a network port type?

First a little explanation.  Linux contains 65536 network ports for both UDP and TCP.
SELinux uses types to group network ports together.  If you want to see a listing of the port types on the system you can execute:

semanage  port -l
SELinux Port Type              Proto    Port Number

afs_bos_port_t                 udp      7007
afs_client_port_t              udp      7001
afs_fs_port_t                  tcp      2040
afs_fs_port_t                  udp      7000, 7005
...


Then we write rules in SELinux like

allow httpd_t http_port_t : tcp_socket name_bind ;

This rules says the apache process can execute the bind command using any port that is currently labeled http_port_t.

# semanage  port -l | grep http_port_t
http_port_t                    tcp      80, 443, 488, 8008, 8009, 8443


Now a fairly common question that gets asked is, can I remove these ports.   IE I do not want to allow apache to bind to port 8008.

How would I do this?

The simplest thing to do is to redefine port 8008 as a different port type that httpd can not bind to. 

The default port type for all unassigned ports  > 1024 is unreserved_port_t or ephemeral_port_t (Fedora 16)

# semanage  port -l | grep ^unreserved_port_t
unreserved_port_t              tcp      1024-32767, 61001-65535
unreserved_port_t              udp      1024-32767, 61001-65535
# semanage  port -l | grep ^ephemeral_port_t
ephemeral_port_t               tcp      32768-61000
ephemeral_port_t               udp      32768-61000


Note SELinux will use a more specific port type if the port has been defined, for example when the kernel sees tcp port 8008, it will use http_port_t rather then unreserved_port_t. 

But the admin can override this by adding his own port definition.

# semanage port -m -t unreserved_port_t -p tcp 8008

To prove this worked, I tested using apache.

# sed -i 's/Listen 80/Listen 8008/g' /etc/httpd/conf/httpd.conf
# semanage  port -m -t unreserved_port_t -p tcp 8008
# service httpd restart
Restarting httpd (via systemctl):  Job failed. See system logs and 'systemctl status' for details.  [FAILED]
# semanage port -d -p tcp 8008
# service httpd restart
Restarting httpd (via systemctl):                          [  OK  ]


NOTE:

Be careful doing this, because you have just changed the definition of http_port_t for ALL domains, not just the httpd_t domain.   Meaning if you were running firefox with a sandbox_web_t sandbox on the same machine, the firefox would no longer be able to connect to port 8008, because sandbox_web_t is only allowed to connect to http_port_t and 8008 is no longer defined as 8008.

Open Source how do I love thee, let me count the ways.

$
0
0
Yesterday I got contacted by Red Hat Support about a problem we had in libselinux.  If you are setting up confined users you can use the semanage login command to setup a group of linux users to be assigned to a confined user type.

# semanage login -a -s staff_u -r s0-s0:c0.c1023 %wheel

This command would cause all linux users in the wheel group to login as the staff_u SELinux user.  Well we had a bug in getseuserbyname function in libseliunux.  When you login to a system the pam_selinux module uses this function to figure out which SELinux user should be used for your UID.  There was a bug where we were not allocating enough memory for reading the entire group file contents.  Basically if the number of users within a group was too large, the library would stop reading.  

A customer of ours found the problem and reported it.  

Now the reason I love Open Source...

The customer did not stop there.  They downloaded our source, found the problem, built a patch and attached it to the bug report.  So all I had to do was apply the patch and start the errata process.   This is the type of stuff that can't happen in a closed source system, and is why Open Source is better...

Open source is like The Elves and the Shoemaker, just don't tell my boss.  :^)

Customizing the Kiosk OS.

$
0
0
I receve a decent amount of interest about the kiosk spin, but I have never formalized it as a fedora spin.  The reason for this is almost everyone who looks at it, likes the idea but they need to customize it, in one way or another.  

My vision of the Kiosk Operating system was that it was readonly and periodically an admin would recut/rebuild a newer version and then redestribute it to his machines.  It is fairly easy to build your own image.  Just download the kiosk kickstart file (kiosk.ks), make some customization and rebuild your ISO file using the livecd-tools.  The last step would be to install it to your favorite medium, USB Sticks or DVD. 

I recently received an email that requested:

"I have downloaded kiosk just this afternoon and tried on my laptop: as I have been requested for such a spin in our city library for eight computers, how can I build a spin with language/keyboard set as Italian??? (the standard procedure to change settings/Logout/login seems not to be working..) "

Here is how I would go about building the Italian version of the Kiosk Operating System.

On the currently released version of Fedora.  As I write this blog, we are at Fedora 16.  Login as root and and follow this procedure.

You are going to build the Kiosk Operating System using the spin-kickstarts, so we need to install the sortware.

# yum install spin-kickstarts livecd-tools
# cd /usr/share/spin-kickstarts


Make sure you have the latest kiosk.ks file from my people page. http://people.fedoraproject.org/~dwalsh/SELinux/kiosk/kiosk.ks

# rm -f kiosk.ks*
# wget http://people.fedoraproject.org/~dwalsh/SELinux/kiosk/kiosk.ks


Change the default language within the kickstart file.   You can use your favorite editor to do this, and modify "lang" line.  I will just use a sed command.

# sed -i 's/en_US.UTF8/it_IT.UTF-8/g' kiosk.ks

Now you can build a new kiosk image.  Replacing the name of the livecd with your own content.

# livecd-creator -t MYLIBRARY -f MYLIBRARY -c kiosk.ks --cache=/var/cache/kiosk

Now go get a cup of coffee since this will take a long while, maybe a half hour. 
When it finishes, you will have an ISO image named MYLIBRARY.iso.  You need to install the iso ont a dvd or to a usb stick using livecd-iso-to-disk.

# livecd-iso-to-disk --totaltimeout 1  ./MYLIBRARY.iso /dev/sdb1

Remove your USB stick and attempt a boot a machine using it.

Of course if you want to add some less then free packages to your kiosk operating system, you would edit the kickstart file and add your alternative repositories.

For additional information on building livecd please use:

http://fedoraproject.org/wiki/How_to_create_and_use_Live_USB

And on using kickstart files.

http://fedoraproject.org/wiki/Anaconda/Kickstart

SELinux versus pam_google_authenticator...

$
0
0
I just became aware of a new PAM, pam_google_authenticator.

It is some kind of One TIme Password tool to allow you to add One Time Passwords to you Linux Login and I guess use your Android phone.

pam_google_authenticator causes login programs to  try and  write to ~/.google_authenticator by default.  SELinux does not like this.  SELinux prevents login programs from writing to random locations in the home directory.  It is usually not a good idea to rely on stuff in the home dir for authorization because the homedir may require authorization to be able to be mounted or decrypted. (kNFS for example).  

I got a bugzilla on sshd not being able to write to ~/.google_authenticator.  One option would be to set the label on the .google_authenticator as ssh_home_t.  I also did some "googling" and found the following entry:
http://code.google.com/p/google-authenticator/wiki/PamModuleInstructions

Comment by phil.may <snip>, Jul 7, 2011

If you are using Fedora and SELinux, you will need to use the right config. The default SELinux policy does not allow the SSH daemon to update the ~/.google_authenticator file.

In Fedora 14 (and possibly other versions) sshd runs under "sshd_t" and can only writelocations with certain SELinux labels. One such label is "var_auth_t" and the default policy sets this label on "/var/run/user/" Therefore, the following config works:

# If the user is NOT in group "otp_users", skip next module
auth [success=1 default=ignore] pam_succeed_if.so user notingroup otp_users
auth       required     pam_google_authenticator.so secret=/var/run/user/${USER}/.google_authenticator
auth       include      password-auth

BTW I have not tried this out on Fedora 16, and am curious if this will work, or does pam_google_authenticator expect the contents of .google_authenticator to survive a reboot.

SELinux versus pam_securid.so

$
0
0
Seems to be my month for fighting pam modules from third parties.   I have heard that RSA corporation is recommending SELinux be turned off to run their products.  I just love it when a supposed security company recommends that customers turn on a key security component of the Operating System.  Now did RSA ever contact me to work through the problems,? No. 

Come on RSA you can do better then this. 

I am trying to avoid underhanded security comment about using SELinux to protect key assets of the company...

I worked with Joe Lucchesi, to get this pam module to work with SELinux.  Joe was having problems with sshd working with the pam module.  He was getting execstack errors.  Turns out the pam_securid.so file was shipped with the execstack flag turned on.  Execstack is a dangerous protection to allow a domain, since it turns off protection against buffer overflow attacks.  Most app never need this access.

Executing

execstack -c /lib64/security/pam_securid.so

Cleared the flag.  And allowed sshd to get past this AVC.  Whatever is causing this flag to be set, the build procedure or installation needs to be fixed.

The next problems we hit was pam_securid seems to be running netstat under the covers.  I recall we had this problem with the Netscape Certificate libraries. They used to execute netstat in order to generate entropy when using certificates, so I figure this is what is going on here.  I also see the sshd executing ps?  Probably  for the same reason.  

RSA guys please use /dev/urandom and /dev/random. 

We turned off the use of netstat in our libraries years ago.  Using netstat and ps causes me to have to allow login programs to search /sys/net and because of bugs in our kernel add a dontaudit for sys_ptrace.   

Finally secureid uses /var/ace to store its authorization content.  This should probably be under /var/lib/ace, I have added a label for this directory

/var/ace(/.*)?                 gen_context(system_u:object_r:var_auth_t,s0)

This should allow the pam_securid module to use the content in this directory.

Now Joe can run his pam_securid.so on his machine in enforcing mode with a small custom module until we push updates to fix the problem.

Bottom line.  If you are a third party and you are having problems running your tools with SELinux, please, please contact me or Red Hat and lets work through the problems, and give our users a better experience.

Why isn't setroubleshoot working in Fedora 16?

$
0
0
Well if you did a fresh install it does work.  But if you did an upgrade install from an older Fedora you have a problem.

setroubleshootd is a dbus service launched by the audit daemon.    In Fedora 16 all daemons that were running under as System V init scripts and were converted to systemd, no longer are started by default.  Meaning the auditd daemon is probably no longer running on your machines.  You might notice AVC messages showing up in /var/log/messages, rather then /var/log/audit/audit.log.

It is simple to fix this problem by executing

# systemctl enable auditd.service
# systemctl start auditd.service


This will re-enable the auditd daemon and your setroubleshoot daemon should start working again.  If you get any AVC messages, they will start showing up in the /var/log/audit/audit.log.


10 things you probably did not know about SELinux #9 Backing up and Restoring Labels.

$
0
0
It has been a few years since I discusses backing up and restoring labels with SELinux.   

I was asked at the Lisa 11 conference by a backup utility developer, "How should he save and restore SELinux security contexts?"  He also asked whether or not his tool should always maintain these context?  Finally how should the tool react if the system would not allow the context to be restored? 

Interesting topic.  Lets first take a look at a few tools for backing up content with SELinux labels.

SELinux stores SELinux security labels (contexts) as extended attributes with the inode on the file system.  If an administrate wants to backup/restore files with the SELinux labels,  you need to use a utility that supports this.

When SELinux first shipped the only utility to do this was star (RHEL4) , GNU tar at that time did not support extended attributes.  Later extended attribute support was added to GNU tar.  ( tar --selinux -cvf /tmp/etc.tgz /etc ) Rsync also has support for maintaining extended attributes.  Even Dump/Restore can now support maintaining the extended attributes.

I often question is whether this is a good idea to maintain the labels.  In some cases your security goals require it.  For example backing up sensitivity labelled data (MLS) requires this.  If you have a file labelled TopSecret, you would definitely want to maintain this within the archive.

But most of us do not deal with sensitivity labelled data, and we would want to make sure the data on our system is labelled correctly based on the current security definition on our system.  Trying to maintain the SELinux labels and restore them can be a mistake in several cases. 

For example:

Target file system does not support extended attributes.

If you attempted to restore files to a file system that does not support extended attributes.  Does the administrator have a way to allow this?

Updating a machine for one version of the OS to another.

If you backed up your /home directory before updating from Fedora 15 to Fedora 16 and then restored the content of the archive, certain directories in you home directory will be mislabeled and potentially tools like googlechrome or colord will fail.  You would have been better off having the content restored the archive and then running restorecon -R - v /home.

Copying an archive from one machine to another machine with an older OS.

Attempting to maintain the labels would be wrong if you created an archive on a RHEL6 box and then attempting to restore the archive on a RHEL5 box.  If the RHEL5 kernel does not understand a label from a RHEL6 box, then the label will not be allowed to be placed on the disk.   In this case, again you would want to put the files down and then restore the labels. 

In this case it would be nice if the tools used to restore the content had the ability to label the content "correctly" based on the file_contexts definitions on the target system.  That way we would not have a race condition where the labels on the files are incorrect for a period of time.

In conclusion the backup/restore utility should:
  • allow the administrator to decide whether or not to save the SELinux labels and restore them.
  • Allow the administrator to specify the tool to restore the files using the default labels as specified on the target system (matchpathcon/setfscreatecon)
  • If the utility does not allow have the second option, in most cases the administrator should run restorecon on the restored files.

Fedora 17 New SELinux Feature part I - deny_ptrace

$
0
0
The deny_ptrace feature allows an administrator to toggle the ability of processes on the computer system from examining other processes on the system, including user processes.   It can even block processes running as root.

Most people do not realize that any program they run can examine the memory of any other process run by them.  Meaning the computer game you are running on your desktop can watch everything going on in Firefox or a programs like pwsafe or kinit or other program that attempts to hide passwords..

SELinux defines this access as ptrace and sys_ptrace.  These accesses allow one process to read the memory of another process.   ptrace allows developers and administrators to debug how a process is running using tools like strace, ptrace and gdb.    You can even use gdb (GNU Debugger) to manipulate another process running memory and environment. 

The problem is this is allowed by default. 

My wife does not debug programs, why is she allowed to debug them?  As a matter of fact most of the time, I am not debugging applications, so it would be more secure if we could disable it by default.

I created a feature for Fedora 17 called SELinuxDenyPtrace

Here is a youtube video demonstrating the SELinuxDenyPtrace feature.

Check it out.



More on deny_ptrace ...

$
0
0
This boolean brings into conflict two of my top goals with SELinux.

1. Make the system secure by default.

The problem with most security systems is NO ONE turns them on.  NO ONE increases the security of their system.
Now while these are exaggerations, I would bet you that 99 % of SELinux users never turn on confined users, or disable the unconfined module .  There are large numbers of people who run SELinux in permissive mode or even disabled.    If we shipped Fedora and RHEL with SELinux disabled, I would bet the number of people who would enable it would be infinitesimally small.    So when I add a feature, I always think about how it would help the vast majority of people.    Will this boolean make my Wife's computer more secure.

2. Keep the unconfined domain unconfined...

Read the blog for why uses expect things to just work, especially from their logged in accounts, especially if they are the admin.

Should deny_ptrace be on by default????

Well deny_ptrace actually confines the unconfined domain, so it conflicts with #2, but if I don't turn it on, for the most part people will not take advantage.  Most users would not see the benefit.  Right now I am going to turn it on by default (Of course I reserve the right to change my mind, or be beaten into submission.)  Any person who wants to disable it permanently can execute.

# setsebool -P deny_ptrace 0

Programmers and system admins if you get a "permission denied" or "Operation not supported" error with ptrace, strace or gdb, it is SELinux causing the problem, and if you need to debug a problem, you can turn the boolean on temporarily.

# setsebool deny_ptrace 0

And do your thing.

Since sysadmins and programmers understand Linux best, it would be easier for them to toggle the security feature.

Now some questions about this feature.

What happened to allow_ptrace boolean in RHEL versions and older Fedora's? 

I originally thought about extending allow_ptrace, but I thought I had better just create a new boolean and remove the old.

allow_ptrace only effected confined users. But since hardly anyone used confined users, I thought I needed a better way to describe the feature, and change its name.  I have removed allow_ptrace and now deny_ptrace will remove all ptrace, sys_ptrace that I know about from the system.

Does deny_ptrace guarantee no domains on my system can ptrace another domain? 

NO
If you load a custom policy with an "allow XYZ self:process ptrace", this boolean will not effect it.  So it only effects actually policy shipped by Fedora or Red Hat.
deny_ptrace does not effect permissive domains,  or permissive mode (obviously),  so if you want to make sure no processes can execute ptrace, you need to disable permissive domains.

After you turn on the deny_ptrace boolean, you can check if any domains are still able to ptrace by executing

# sesearch  -A -C -p ptrace,sys_ptrace | grep -v ^D

What about separation between root and users?

Well SELinux does not know anything about UID users, so root and non root mean nothing to SELinux.  The only way to get this distinction is by setting up confined users and then say run as staff_t as non root and then transition to unconfined_t, or sysadm_t or a confined admin type.  But since hardly anyone uses confined users, this is not an option, if I want to make most computers more secure.

Could you add a bunch of booleans that allows us to turn on and off ptrace per confined domain?

Well this is not really necessary, since most confined domains can not ptrace now, or only could ptrace because of some bugs in the kernel that generated ptrace avc's when running the ps command as root or if a process examined the /proc/PID files of another process.    We have fixed these kernel issues and are removing most domains ability to ptrace permanently, Ie turning deny_ptrace off DOES not allow every domain the ability to ptrace, only a few select domains that we believe might need it.  (Really just user domains.)

10 things you probably did not know about SELinux, #10 shipping policy versions

$
0
0
Can I install a policy module built on RHEL6 on a RHEL5 box?

First you need to understand policy is compiled statically.  Even if you use interfaces, all the rules are compiled into the policy.pp file.
If you use policy_module(mypol, 1.0), this will generate a gen_require(` ') block for all of the permissions, classes defined in policy. 
Meaning if you compile a policy on RHEL6 and install it on RHEL5 using policy_module(mypol,1.0) you are likely to fail with an error like:

# semodule -i mypol.pp
libsepol.permission_copy_callback: Module mypol depends on permission open in class file, not satisfied
libsemanage.semanage_link_sandbox: Link packages failed semodule:  Failed!


This is the compiler telling you that you tried to install a policy module that required the "open" permission and RHEL5 policy, and kernel for that matter, has no idea what the "open" permission is.

I guess the analogy would be compiling an executable on RHEL6 that uses a function call in a shared library that does not exists on a RHEL5 box, it won't work. 

Usually we recommend that you compile policy on the oldest machines policy that you plan on supporting, then it should be installable on all future versions of that policy.  We don't tend to remove accesses.

Can I install a policy module built on RHEL5 on a RHEL6 box?

Yes you can, but it probably will not work the way you expect!

In RHEL5 the access required to read a file was:

define(`read_file_perms',`{  getattr read ioctl lock }')

In RHEL6 the access required to read a file was:

define(`read_file_perms',`{ open getattr read ioctl lock }')

So if you compile in a line like:

allow httpd_t mysecret_t:file read_file_perms;

On RHEL5 this would allow the apache type to read files labeled mysecret_t, but if you compiled it on RHEL5 and installed it on RHEL6, apache would not be allowed to "open" the file so the access would fail.

Bottom Line:

If you want to ship policy for two MAJOR  DIFFERENT VERSIONS of RHEL then you would need to compile a version for RHEL5 and for RHEL6.

Policy should work for all Minor versions, as long as you compile on the oldest, supported version, although it might work if you compile on a newer version and install on an older version.

Meaning a compiled version of policy on RHEL6.1 should work on RHEL6.2, RHEL6.3 ...





Why I love Open Source... II

$
0
0
When SELinux does a full relabel, it prints a * for each 1000 files that it relabels.

Some users were complaining about a full relabel and not being able to estimate how much time was left. 

I explained to them that I did not know how many files were on the file system, so I could not estimate how much time was left.  They explained to me that there was ways to look at the file system and get then number of inodes, and then you could estimate how much time was left.  I told them patches accepted, and within a couple of days, I got a patch from John Reiser. 

As of policycoreutils-2.1.10-21.fc17

If you do a touch /.autorelabel; reboot or a fixfiles restore

You will see output like


# fixfiles  restore
10%

With the counter slowly rising.

Open source opens the possibility for all of us to contribute and make the whole better.

Thanks John.

Small change to semanage login record creation.

$
0
0
For those of you that use confined users, I have recently made a change to semanage that you may or may not notice.  This change will be back ported to RHEl6 also.

In the previous version of semanage, when you created a login user mapping, if you did not specify the level or range of the user, semanage would default the level to s0.

OLD
# semanage login -a -s staff_u dwalsh
# semanage login -l | grep dwalsh
dwalsh                    staff_u                   s0

In the new version of the tool, the semanage command will take the range of the SELinux user, staff_u, and assign it to the login record.

NEW
# semanage user -l | grep staff_u
staff_u         user       s0         s0-s0:c0.c1023                 staff_r sysadm_r system_r unconfined_r
# semanage login -a -s staff_u dwalsh
# semanage login -l | grep dwalsh
dwalsh                    staff_u                   s0-s0:c0.c1023          

I believe this is the correct behavior especially since if you specified a SELinux whose range did not include s0, the tool would blow up.

# semanage user -l | grep topsecret_u
topsecret_u         user       s15         s15-s15:c0.c1023                 staff_r sysadm_r system_r
# semanage login -a -s topsecret_u dwalsh
Would generate a error saying invalid range.

Of course if you specify the level/range it will override the SELinux user level.

Dan Walsh on Twitter @rhatdan

$
0
0
I guess I never blogged this.  But I have been tweeting for a while as rhatdan.  (Not so creative name).

And as always I will almost never tweet something that does not have to do with SELinux or Security....

Follow me if you like.

secommunicate is a handy little tool to analyze policy communication

$
0
0
I wrote about setrans back in October. 

setrans is a tool that you could use to analyze policy to see if how one process domain transitions to another process domain.

Today I got asked what type should a user assign to a file so that one process type "syslogd_t" could write and another process type "httpd_t" could read.   

I answered the question that httpd_log_t would be a good candidate.  Then he asked could figure this out? 

My suggestion was he could use these commands.

# sesearch -A -s syslogd_t -c file -p write

Which will search for all types that syslogd_t can write.

# sesearch -A -s httpd_t -c file -p read

Which will search for types httpd_t can read, then he could look at the intersection of these commands.  

Only that did not work...

# sesearch -A -s syslogd_t -c file -p write

Does not return my suggestion of httpd_log_t.  It did however return an attribute "logfile" which includes httpd_log_t.
Attributes are the way to group lots of types together.  And the sesearch command does not expand out the attributes.

I decided to go off an play with python and create secommunicate.  The goal of this command is to print out a list of types that a source process type can write and a target process type can read.

This little python script takes a source process type and a target process type and an optional class, defaulting to "file".  It uses the sesearch python bindings to search the selinux policy for:
  • What class types can the source type write?
  • What class types can the target type read? 
  • It expands all attributes into the associated types
  • Then it generates the intersection of these types, and prints them out. 

./secommunicate syslogd_t httpd_t
puppet_tmp_t
afs_cache_t
dirsrv_var_log_t
nagios_log_t
httpd_log_t
user_cron_spool_t
root_t


./secommunicate -c chr_file syslogd_t httpd_t
user_tty_device_t
devtty_t
initrc_devpts_t
null_device_t
zero_device_t


Seems like it could be a handy tool.  

Not sure how we should package or ship setrans and secommunicate, or what the correct syntax would be, but for those struggling to understand policy these seem to be handy tools.

./secommunicate -h
usage: secommunicate [-h] [-c TCLASS] [-s SOURCEACCESS] [-t TARGETACCESS]
                     source target

SELinux Communication Analysys Tool

positional arguments:
  source                Source type
  target                Source type

optional arguments:
  -h, --help            show this help message and exit
  -c TCLASS, --class TCLASS
                        Class to use for communications, Default 'file'
  -s SOURCEACCESS, --sourceaccess SOURCEACCESS
                        Comma separate list of permissions for the source type
                        to use, Default 'open,write'
  -t TARGETACCESS, --targetaccess TARGETACCESS
                        Comma separated list of permissions for the target
                        type to use, Default 'open,read'


Note:
If you wanted to know if a one domain can communicate with another domain via signals, you could just use

sesearch -A -s syslogd_t -t httpd_t -c process
Found 1 semantic av rules:
   allow syslogd_t domain : process getattr ;

SELinux problems on Fedora 17.

$
0
0
Anyone that has tried Fedora 17 over the last couple of days, might have noticed SELinux going nuts and blocking logins. 

systemd had a bug which was causing transitions to break.

The way the system is supposed to work is during boot systemd reads in the policy file on disk and then loads policy into the kernel.
This causes all processes at that are running to be labeled kernel_t. 

systemd then reads the label on its image file /sbin/systemd (init_exec_t) and the label that it is currently running as (kernel_t), then it asks the kernel what label would the /sbin/systemd process get if kernel_t executed it.  The answer would be init_t, and then systemd is supposed to set the current label to init_t.   From that point on all processes started by systemd would transition to their proper domains.

Well just before systemd/Fedora 17 Alpha was about to be released.  Systemd changed the location of its executable from /bin/systemd to /usr/lib/systemd/systemd.  But they never changed the checking code.  We fixed policy to look at the new location and labeled /usr/lib/systemd/systemd correctly, but when systemd checked for the label of /bin/systemd, there was no file and systemd just continued running as kernel_t.  Since there are few rules for transitions of kernel_t to any other label, most of the system was labeled as kernel_t.  Finally when a user logged in via gdm or login or sshd, they were running as kernel_t and the code transitioned them to abrt_t, one of the few domains kernel_t will transition to.

systemd-42-1.fc17 fixes this problem, so if you update to this systemd or later, you should be able to run your system in enforcing mode. 

Needless to say, we have been flooded with bug reports...

How can I allow a process to listing all processes on a system.

$
0
0
SELinux blocks lots of domains from listing all processes on the system. 

Lots of useful information can be optained from reading the process info on a machine, so we would like to block this by default.  But sometimes users/policy writers really need to allow their domains to be able to list the processes on a system.

Ole on the Fedora SELinux Users Mail list asked:

I have a problem with SELinux not allowing PHP to list other users' processes with the "ps" command.
If I disable SELinux with "setenforce 0" it works immediately.
Is it possible to allow PHP to do this without disabling SELinux completely?

Processes are listed by reading all of the contents of /proc.  SELinux linux labels everything in /proc based on the label of the process.

ps -eZ | grep sshd | head -1
system_u:system_r:sshd_t:s0-s0:c0.c1023 853 ?  00:00:00 sshd

ls -lZ /proc/853 | head -1
dr-xr-xr-x. root root system_u:system_r:sshd_t:s0-s0:c0.c1023 attr


If you want a confined process to run ps, it needs to list /proc/PID, it needs to read certain files in this directory, needs to read symbolic links in this directory and needs to getattr on the process.   When writing policy we have added a macro for this access.

define(`ps_process_pattern',`
    allow $1 $2:dir list_dir_perms;
    allow $1 $2:file read_file_perms;
    allow $1 $2:lnk_file read_lnk_file_perms;
    allow $1 $2:process getattr;
')


If we wanted to allow one process type (myuser_t) to read another process /proc data on sshd (sshd_t), we would need to write a line like:

ps_process_pattern(myuser_t, sshd_t)

What if I want to allow a type to list all processes types?

In SELinux policy language we use attributes are used to group multiple types together. 
SELinux calls processes "domains".  When we write policy we always give process types the domain attribute.

So if you wanted to allow a process myuser_t to  list all the processes on a system, you would write a rule like.

ps_process_pattern(myuser_t, domain)

Dominic Grift answered Ole question by suggesting he install a local policy module that looked like:
policy_module(mytest, 1.0.0)
gen_require(` 
  type httpd_t; 
  attribute domain; 
')
ps_process_pattern(httpd_t, domain)

This works great.  Note that the apache daemon runs all php scripts within its process space, to they run as httpd_t.

Another solution would be to use an interface that we have defined in policy to allow this, domain_read_all_domains_state.  

The /usr/share/selinux/devel/include/kernel/domain.if interface file defines several interfaces that can be used to interact with all domains.  An alternative policy module could have been written:

policy_module(mytest, 1.0.0)
gen_require(` 
  type httpd_t; 
')
domain_read_all_domains_state(httpd_t)

Fedora 17 New Security Feature part II - PrivateTmp

$
0
0
One of the reasons I am really excited about Fedora 17 is amount of new Security Features we have added, and not all of them involve SELinux ...

As  I blogged a few weeks ago, we have stopped the ability for one process to look at another processes memory even if they have same UID, with the deny_ptrace feature.

PrivateTmp

But today I want to talk about PrivateTmp.    One of my goals over the years has been to stop system services from using /tmp. 

I blogged about this back in 2007.    Any time I have found out a daemon was using /tmp, I tried to convince the packager to move the content to /run directory if it was temporary or /var/lib if it was permanent. 

Over the years there have been several vulnerabilities  (CVEs) about this.  For example:
CVE-2011-2722, which covered a case where hplib actually included code like.

fp = fopen ("/tmp/hpcupsfax.out", "w"); // <- VULN
system ("chmod 666 /tmp/hpcupsfax.out"); // <- "

Meaning if you setup a machine running cups daemon, a bad user or a application that a user ran could attack your system.

I have convinced a lot of packages to stop using /tmp, but I can't get them all and in some cases services like Apache,  need to use /tmp.   Apache runs lots of other packages that might store content in /tmp.

Well systemd has added lots of new security features (more on these later).  

PrivateTmp, which showed up in Fedora 16,  is an option in systemd unit configuration files. 

      > man system.unit
       ...
       A unit configuration file encodes information about a service, a socket, a device, a mount point, an automount point, a   
     swap file or partition, a start-up target, a file system path or a timer controlled and supervised by systemd(1).

     > man systemd.exec
     NAME
       systemd.exec - systemd execution environment configuration
     SYNOPSIS
       systemd.service, systemd.socket, systemd.mount, systemd.swap
     DESCRIPTION
       Unit configuration files for services, sockets, mount points and swap devices share a subset of configuration 
       options which define the execution environment of spawned processes.
      ...
       PrivateTmp=
           Takes a boolean argument. If true sets up a new file system namespace for the executed processes and mounts a 
           private /tmp directory inside it, that is not shared by processes outside of the namespace. This is useful to secure 
           access to temporary files of the process, but makes sharing between processes via /tmp impossible. 
           Defaults to false.
PrivateTmp causes systemd to do the following any time it starts a service with this option turned on:

   Allocate a private "tmp" directory
   Create a new file system namespace 
   Bind mount this private "tmp" directory within the namespace over /tmp
   Start the service.  

This means that processes running with this flag would see a different and unique /tmp from the one users and other daemons sees or can access.

Note:  We have found bugs using PrivateTmp in Fedora 16, so make sure you test this well before turning it on in Production.

For Fedora 17, I opened a feature page that requested all daemons that were using systemd unit files and /tmp to turn this feature on by default.

Apache and Cups now have PrivateTmp turned on by default in Fedora 17, along will several other daemons.

Giving three options as a Developer of System Service, I still believe that you should not use /tmp, you should use /run or /var/lib.  But if you have to use /tmp and do not communicate with other users then use PrivateTmp.  If you need to communicate with users be careful...

Fedora 17 New Security Feature part III - systemd starting daemons

$
0
0

Ok, this is not really a new feature in Fedora 17.  

systemd has been starting some daemons in Fedora 16, but more and more daemons and privileged processes are being started by systemd in 17.

Why is this a security feature?

Symbols: @ means Execute, -> indicates transition, === indicates a client/server communication

In the past daemons would be started in two ways.  At boot init (sysV) launches an initrc script and then this script would launch the daemon, or an admin could log in and launch the init script by hand causing the daemon to run.

 From an SELinux point of view this looked like:

init_t @ initrc_exec_t -> initrc_t @ httpd_exec_t -> httpd_t: 
This  apache processes would end up running with the full label of:
system_u:system_r:httpd_t:s0
If apache created content it would be labeled
system_u:object_r:httpd_sys_content_rw_t:s0

When an administrator started restarted the process say through service httpd restart
unconfined_t @initrc_exec_t -> initrc_t @httpd_exec_t -> httpd_t
The process would adopt the user portion of the SELinux label that started it
unconfined_u:system_r:httpd_t:s0
Content would be created by this apache would be:
unconfined_u:object_r:httpd_sys_content_rw_t:s0
SELinux ends up confusing the user since we have to ignore the user componant of the SELinux label. If you wanted to write policy to confine based on user type, you can't.

With systemd this improves greatly.

The transitions is very different.
init_t @ httpd_exec_t -> httpd_t
system_u:system_r:httpd_t:s0


But if you want to restart the Apache daemon as admin you now do.
unconfined_t === init_t @ httpd_exec_t -> httpd_t
system_u:system_r:httpd_t:s0


With systemd we don't have the labeling problem and we can tighten up the SELinux policy. 

Systemd starting daemons effects more then SELinux 

Over the years lots of vulnerabilities and administration failures had to be worked around because of admins restarting daemons.  Daemons need to be coded to cleanup any leaked information from the admin process influencing the way the Daemon ran.

  •     Need to clean $ENV
  •     Need to change working directory
        cd / in order to make sure they don't blow up because they lack access to the current working directory (service script does for them).
  •     Need do something with the terminal, close stdin, stdout, stderr after they start.
         In SELinux we are always in a quandary about this, since if we allow the daemon access to the terminal, a hacked daemon could present the admin with passwd:  and trick him into revealing the admin password.)
  •     Changing the controlling terminal
  •     Change the handling of signals
  •      ... 


If a daemon writer screws up on one of these he could make the system vulnerable or end up with unexpected bugs. 

Using systemd to start daemons, guarantees the daemon always gets started with  the same environment whether they are started at boot or restarted by an administrator.

Fedora 17 New Security Feature part IV - man pages for SELinux service domains

$
0
0
A couple of weeks ago, I began to look at the man pages for SELinux policy that we had written for SELinux several years ago.    I wanted to update them and maybe add a few new ones.    When I looked at the httpd_selinux man page, I noticed it was missing lots of descriptions of booleans and file types associated with the httpd domain.  When I started adding the boolean definitions, I quickly became board and realized this would not scale. 

I decided to write a tool genman.py, that would query the SELinux Policy and write a man page for every executable service domain.   
DOMAIN_selinux.8

I made a few assumptions that a service domain had an entrypoint ending in "_exec_t".  Which we have pretty much standardized on.  Then I truncated the first part of the name off and searched for types and booleans containing this name. 

httpd_exec_t -> httpd for example. 

I actually took is a step further and truncated a "d" off if the domain name ended in "d", since this is common. 

httpd -> http.

Booleans have a description in policy so this was fairly easy to add to the man pages.

# semanage boolean -l | grep http

Would give you all the booleans that mention http, for example.

Since we don't have a description for each file type associated with a domain, I had to hard code a big it/then table with common definitions,  for example.

def explain(f, k):
    if f.endswith("_var_run_t"):
        return "store the %s files under the /run directory." % prettyprint(f, "_var_run_t")

Then I added a special section for any domains that use public_content_t. 

Bottom line the tool was generated over 400 man pages that have been added to the selinux-policy-doc rpm.

For example abrt man page.

Are these man pages perfect? NO. 

But they are a lot better then nothing.  Now if you want to know the types/and or booleans associated with a service, all you need to execute is man SERVICE_selinux.

If anyone wishes to enhance this, by perhaps adding file context definitions, patches welcomed...
Viewing all 181 articles
Browse latest View live