eucalyptus-selinux: security as a first-class citizen!

Eucalyptus 4.3 development sprint is almost over. SELinux support for Eucalyptus is one of the most exciting features [EUCA-1620] for this release.

Like me, if you haven’t looked into SELinux in a while or it is a new thing to you, here are few tips and tricks that may come handy if things don’t work as expected with SELinux while you are playing with Eucalyptus nightly builds or source code during dev cycles or any other new software while SELinux is set to enforcing on the system.

[It is recommended that you try Eucalyptus 4.3 with SELinux on RHEL 7.x or CentOS 7.x.]

Recently while trying Eucalyptus when SELinux is enabled, I was having issues with starting eucanetd.service, which gave me a chance to look further into Eucalyptus SELinux. It appears that the very latest eucanetd requires to open an UDP port and since SELinux doesn’t yet know about it, it is giving an AVC (Access Vector Cache) error.

In case of situation like this or when a newly installed application fails to run/execute on an SELinux enable box, the first thing to check would be /var/log/audit/audit.log.

In the log I found the following error:

type=AVC msg=audit(1462905888.565:1432): avc: denied { name_bind } for pid=10725 comm="eucanetd" src=63822 
scontext=system_u:system_r:eucalyptus_eucanetd_t:s0 tcontext=system_u:object_r:unreserved_port_t:s0 tclass=udp_socket

type=SYSCALL msg=audit(1462905888.565:1432): arch=c000003e syscall=49 success=no exit=-13 a0=3 a1=7ffef025a010 a2=10 
a3=7ffef0259d90 items=0 ppid=1 pid=10725 auid=4294967295 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=(none) 
ses=4294967295 comm="eucanetd" exe="/usr/sbin/eucanetd" subj=system_u:system_r:eucalyptus_eucanetd_t:s0 key=(null)

To debug further and start eucanetd.service, I have installed the following tool,
yum install policycoreutils-python

This tools comes with a fantastic command called ‘audit2allow‘, which is useful for both debugging and fixing SELinux policy related issues.

The following command shows the list of SELinux failures with reasons.

audit2allow --why --all

Example:

type=AVC msg=audit(1462905222.124:825): avc:  denied  { name_bind } for  pid=2304 comm="eucanetd" src=63822 scontext=system_u:system_r:eucalyptus_eucanetd_t:s0 tcontext=system_u:object_r:unreserved_port_t:s0 tclass=udp_socket
	Was caused by:
		Missing type enforcement (TE) allow rule.

		You can use audit2allow to generate a loadable module to allow this access.

type=AVC msg=audit(1462905888.565:1432): avc:  denied  { name_bind } for  pid=10725 comm="eucanetd" src=63822 scontext=system_u:system_r:eucalyptus_eucanetd_t:s0 tcontext=system_u:object_r:unreserved_port_t:s0 tclass=udp_socket
	Was caused by:
		Missing type enforcement (TE) allow rule.

		You can use audit2allow to generate a loadable module to allow this access.

Update:
Though the above information is okay, but if you are submitting an issue for a project or asking for SELinux related queries, ausearch is probably a better tool as it combines the SYSCALL and AVC records. Thanks Garrett Holmstrom for the suggestion.

Example:

ausearch -c eucanetd --start recent

Output:

----
time->Tue May 10 17:05:36 2016
type=SYSCALL msg=audit(1462925136.650:5237): arch=c000003e syscall=49 success=no exit=-13 a0=3 a1=7ffe13b6d920 a2=10 
a3=7ffe13b6d6a0 items=0 ppid=1 pid=6069 auid=4294967295 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=(none) 
ses=4294967295 comm="eucanetd" exe="/usr/sbin/eucanetd" subj=system_u:system_r:eucalyptus_eucanetd_t:s0 key=(null)

type=AVC msg=audit(1462925136.650:5237): avc:  denied  { name_bind } for  pid=6069 comm="eucanetd" src=63822 
scontext=system_u:system_r:eucalyptus_eucanetd_t:s0 tcontext=system_u:object_r:unreserved_port_t:s0 tclass=udp_socket

We can see that eucalyptus_eucanetd type (eucalyptus_eucanetd_t) is missing rules for access. In my case I had quite a few, but the above example gives an idea of how it might look.

Newbie tips:
Run the following command to check security context of a file on a SELinux enabled system,

# ls -ltrhZ /usr/sbin/eucanetd

-rwxr-xr-x. root root system_u:object_r:eucalyptus_eucanetd_exec_t:s0 /usr/sbin/eucanetd

selinux-penguin-new_medium

Now that we’ve identified the problem, solving it is easy. We can use audit2allow to generate modules to install necessary policies. Though, this can be a tedious job sometimes.

To generate missing policies, we can run the following command,

audit2allow -M my_eucanetd_policy < /var/log/audit/audit.log

which will generate an output like below:

******************** IMPORTANT ***********************
To make this policy package active, execute:

semodule -i my_eucanetd_policy.pp

Now load the module as it says in the output.

At this point we try to run the service again, if it’s a new service, it may fails due to not enough permission, e.g a typical service may require following access for a file { getattr read open } in multiple system calls, but generate policy with audit2allow may only detect the last error.

So, if the service fails to start, we check the audit.log, if it’s another AVC denial error, run the command again to generate module, continue this process until there is no AVC denial in the audit.log.

By this time there could be a couple of policy modules generated and we may want have one single policy file to make future usage easier. After merging the policy files, we need to compile and create policy module package and then install module package like above.

For example after merging policies, mine looked like following:
[WARNING]
this post is for debugging and learning purposes only, under no circumstance you should need to apply custom policies for Eucalyptus. Please open an issue if you run across an AVC denial.


module eucanetd_policy 1.0;

require {
        type user_tmp_t;
        type unreserved_port_t;
        type eucalyptus_cloud_t;
        type eucalyptus_eucanetd_t;
        type eucalyptus_var_lib_t;
        type node_t;
        type eucalyptus_var_run_t;
        class capability { dac_read_search dac_override };
        class file { create getattr write open };
        class udp_socket { name_bind node_bind };
        class dir { read write search add_name };
}

#============= eucalyptus_cloud_t ==============
allow eucalyptus_cloud_t self:capability { dac_read_search dac_override };
allow eucalyptus_cloud_t user_tmp_t:dir read;

#============= eucalyptus_eucanetd_t ==============
allow eucalyptus_eucanetd_t eucalyptus_var_lib_t:dir search;
allow eucalyptus_eucanetd_t eucalyptus_var_run_t:dir { write add_name };
allow eucalyptus_eucanetd_t eucalyptus_var_run_t:file { create getattr write open };

allow eucalyptus_eucanetd_t node_t:udp_socket node_bind;
allow eucalyptus_eucanetd_t unreserved_port_t:udp_socket name_bind;

Update:
If planning to merge to another selinux module, the following command could be provide outputs precisely, thanks Tony Beckham for the suggestion.

ausearch --start recent --success no | audit2allow

After merging all the policies generated by audit2allow, it needs to be compiled and then packaged to be installed as a module.

# compile policy
checkmodule -M -m eucanetd_policy.te -o eucanetd_policy.mod

# create module package
semodule_package -m eucanetd_policy.mod -o eucanetd_policy.pp

# install module
semodule -i eucanetd_policy.pp

By following the above steps, typically we should be able to avoid problems like AVC denials.

The source for eucalyptus-selinux: https://github.com/eucalyptus/eucalyptus-selinux
Report for Eucalyptus related issues: https://eucalyptus.atlassian.net

Advertisements

Install Dropbox from source in Debian Squeeze

Currently I faced a problem setting up Dropbox package In Debian Squeeze. So it I installed it from source.
To install it from source you’ll need the following package (or equivalent)
libnautilus-extension-dev

install it from terminal:
 sudo apt-get install libnautilus-extension-dev 

then change your directory where the nautilus-dropbox-0.6.7.tar.bz2 resides and type the following in terminal:
 tar xvjf nautilus-dropbox-0.6.7.tar.bz2
 cd nautilus-dropbox-0.6.7
 ./configure
it may show error like this
configure: error: couldn’t find docutils

then install the missing component/s and then again do start from where it crashed last time.
 ./configure
 make
 make install

and we are done!
Keeping the source file is recommended. Because may be now you want to delete/remove/uninstall it 😉 To do that, change directory to the dropbox folder and type:
 sudo make uninstall

and it’s gone! 😀

Install phpmyadmin in ubuntu

In the previous article you’ve seen how to setup a LAMP server. Now if you want to install phpmyadmin open your terminal and type
sudo apt-get install phpmyadmin
follow the screen.

Now, open browser go to http://localhost/phpmyadmin/

you are done with your phpmyadmin installation. now, login with the password you provided earlier.

Install LAMP on ubuntu

Installing LAMP(Linux, Apache, MySQL, PHP) is not that tough now-a-days.

The easiest way
First open the synaptic manager with sudo synapti
then Edit ==> Mark Packages by Task
select LAMP server from the list and click OK.

Another easy way
go to terminal and type
sudo tasksel

press space bar to select and then tab to <ok>
Follow the screen.

One line command setup
go to terminal and type
sudo apt-get install lamp-server^
N. B the character ‘^’ is not a typo
Follow the screen, it’ll ask to change password for the root user of MySQL database.

Now. test Apache. Open a browser and type http://localhost/

if you see this, you are done with you apache installation.

test PHP installation. open terminal and type
sudo vim /var/www/test.php
save the file.
again, sudo /etc/init.d/apache2restart
now, open browser and try http://localhost/test.php

you see this, means your PHP installation is completed.

Test MySQL setup
go to terminal and type
mysql -u root -p

you see this, ahhhh….you are done with the famous LAMP installation 😀

For phpmyadmin setup try this

alias in unix

alias is probably the best option in order to save key strokes.

to make an alias
suppose I want to open htdocs folder which is in /Application/MAMP/htdocs/ , but for that i have to type few lines in terminal. But by making an alias it can be done with only one small word. To do so, just type this line in the terminal.
alias ht='open /Applications/MAMP/htdocs/'

to see the alias
just type
alias

to remove all aliases
unalias -a

to remove a specific one
unalias [name of the alias]

chmod – change file/folder permission in ubuntu

sample command:

 sudo chmod 754 /opt/lampp/htdoc

chmod command sets the permission of a file or folder. chmod command uses three digit code as an argument and the file or folder location.

In the example,

  • 7 – Owner(current user)
  • 5 – Group(set by owner)
  • 4 – anyone else

The fundamental concept:

Execute is 1, Write is 2 and Read is 4.

Sum of these basic ones makes combination of permissions:

  • 0 – no permission, this person cannot read, write or execute
  • 1 – execute only
  • 2 – write only
  • 3 – execute and write only (1 + 2)
  • 4 – read only
  • 5 – execute and read only (1 + 4)
  • 6 – write and read only (2 + 4)
  • 7 – execute, write and read (1 + 2 + 4)

source: online