日期:2014-05-16  浏览次数:20748 次

使oracle运行在selinux中的实践-附源代码

已经差不多1年半没有发文了,眼看着2012即将成为过去,看着荒草丛生的博客,心中想着还是发点什么东西,也许会帮到别人。同时,也聊以自慰自己还在技术圈混呢。


2011年初,在一次安装体验FC14的过程中注意到了其已经很完善的SELinux模块。记得在几年前第一次看到Linux发行版中的SELinux简直认为就是个鸡肋,什么都不能运行。但在FC14中大量的模块使我映像深刻,所有系统的默认服务:比如,httpd,ftpd,mysql等等都有了相应的安全策略模块,而且都可以在开启SELinux的情况下使用这些服务,注意,带来的好处是系统运行在SELinux 的enforcing的安全策略上下文中-即MAC(Mandatory Access Control),那就是说这里的web服务器将比任何一个不运行SELinux的web服务器安全的多,黑客的入侵基本上不可能。技术人员的天生的学习欲望驱使我开始学些并挖掘如何能最大化SELinux的优点,并为我所用。当时,正好碰到一个问题,我安装的Oracle服务器无法启动,当时忘记了系统默认是SELinux开启的。最后经过一番苦斗才无意中发现了/var/log/audit.log中尽然有大量被Denied请求,而且进程都是oracle的进程,才意识到是SELinux阻止了oracle进程运行。所以,作为一个学习SELinux练习和实践,开始练习如何自己创建SELinux模块,以使某一个服务能够运行于其安全上下文的实践。

过程不是很长,大概1个多星期的所有业余时间,最终完成了创建oracle SELinux模块。也对整个SELinux的架构有了深刻的了解。设计细节就不讲太多了,直接上结果和代码。也许有人需要(据我了解oracle他们给客户的解决方案仍然停留在:停止SELinux,运行Oracle 层面 :-))

这是ps的截屏:

可以看到oracle的进程运行在一个自定义的安全上下文unconfined_u:system_r:oradb_t:SystemLow 中。 oradb_t是进程运行的域(Domain)-我大致按照SELinux命名习惯起的名字。后面在相关代码将看到更多命名。


这是相关文件一览。

于2011-02-16上传最后一次修改,到2012年年底才发文,我太懒了:-(

模块源文件介绍:

oradb.fc  - SELinux模块的文件上下文(file context)定义,或安全上下文定义。我们将需要用restorecon或setfiles工具 重新label文件系统,使所有这里定义的文件具有我们所设计的安全上下文。

oradb.if  - SELinux接口定义。我还没有想到代码重用的必要,所以并没有设计可重用的接口,所以这个文件是空的,只有一行注释。我也不贴内容了。

oradb.te  - 这就是SELinux安全策略源文件。所有的访问,运行,以及域转换的策略都定义于此。

oradb.pp -  这不是源文件,只是上面的3个源文件编译后生成的目标代码。使用semodule工具进行安装。


源文件oradb.fc

# dbora executable will have:
# label: system_u:object_r:oradb_exec_t
# MLS sensitivity: s0
# MCS categories: <none>

#
# ORACLE_HOME
#
/usr/share/oracle/product/11.2.0/dbhome_1(/.*)?         gen_context(system_u:object_r:oradb_dbhome_content_t,s0)
/usr/share/oracle/product/11.2.0/dbhome_1/.*\.log  --      gen_context(system_u:object_r:oradb_log_t,s0)
/usr/share/oracle/product/11.2.0/dbhome_1(/.*)?/bin/.*      gen_context(system_u:object_r:oradb_exec_t,s0)
/usr/share/oracle/product/11.2.0/dbhome_1/lib(/.*)?		gen_context(system_u:object_r:lib_t,s0)
#
# /usr/share/oracle/diag
#
/usr/share/oracle/diag(/.*)?            gen_context(system_u:object_r:oradb_diag_content_t,s0)

#
# /usr/share/oracle/admin
#
/usr/share/oracle/admin(/.*)?            gen_context(system_u:object_r:oradb_admin_content_t,s0)

#
# /usr/share/oracle/flash_recovery_area
#
/usr/share/oracle/flash_recovery_area(/.*)?            gen_context(system_u:object_r:oradb_flash_recovery_area_t,s0)

#
# /usr/share/oracle/cfgtoollogs
#
/usr/share/oracle/cfgtoollogs(/.*)?            gen_context(system_u:object_r:oradb_cfgtoollogs_t,s0)
/usr/share/oracle/cfgtoollogs(/.*)?\.log  --      gen_context(system_u:object_r:oradb_log_t,s0)

#
# /usr/share/oraInventory
#
/usr/share/oraInventory(/.*)?           gen_context(system_u:object_r:oraInventory_home_t,s0)


#
# /etc
#
/etc/rc\.d/init\.d/dbora	--	gen_context(system_u:object_r:oradb_initrc_exec_t,s0)
/etc/oratab			--	gen_context(system_u:object_r:oradb_etc_t,s0)

#
# /var
#
/var/lock/subsys/dbora	--	gen_context(system_u:object_r:oradb_var_lock_t,s0)
/var/spool/cron/oracle  --  gen_context(system_u:object_r:user_cron_spool_t,s0)

#
# /repo
#
/repo/oradata(/.*)?	gen_context(system_u:object_r:oradb_db_t,s0)



注意:我把oracle安装到/usr/share/oracle目录中的,数据文件(表空间)放在/repo/oradata,生产环境这样做不好。如果你要用这代码,自己修改吧。

源文件oradb.te

policy_module(oradb,1.0.0)

########################################
#
# Declarations
#

type oradb_t;
type oradb_exec_t;
type oradb_dbhome_content_t;
type oradb_diag_content_t;
type oradb_admin_content_t;
type oradb_flash_recovery_area_t;
type oraInventory_home_t;
type oradb_cfgtoollogs_t;

allow oradb_t oradb_dbhome_content_t:dir {