1.问题出现
才安装了chrome,就获得了新版本的更新,使用proxychains工具通过yum升级之后,只要一打开就出现一堆插件崩溃提示,同时SELinux也发出警报,提示:
SELinux is preventing /opt/google/chrome/chrome from using the setcap access on a process.
2.原因分析
之所以出现这个问题是因为chrome在启动时会给予chrome_sandbox不受oom的kill指令结束的能力,而这种能力是被SELinux禁止的,所以SELinux才会发出警报
同时由于CentOS默认的SELinux Policy版本是十分低,以至于还没有收录与最新版本chrome相适应的策略
在Chrome新版中,最少查看的标签页会被后台暂停,直到其被再次切换到时才恢复。此外,它的内存清理措施也变得更加积极和富有侵略性。该技术有助于减少网页的影响,节省平均10%的存储资源。更给力的是,Flash-killing功能可以暂停所有非必要的Flash内容,从而降低15%的电量消耗
3.解决方法
解决方法有如下两种
***** Plugin chrome (98.5 confidence) suggests *****
If you want to use the plugin package
Then you must turn off SELinux controls on the Chrome plugins.
Do
# setsebool -P unconfined_chrome_sandbox_transition 0
***** Plugin catchall (2.46 confidence) suggests *****
If you believe that chrome should be allowed setcap access on processes labeled chrome_sandbox_t by default.
Then you should report this as a bug.
You can generate a local policy module to allow this access.
Do
allow this access for now by executing:
# grep chrome /var/log/audit/audit.log | audit2allow -M mypol
# semodule -i mypol.pp
4.对不同解决方法的深入讨论
第一种方法:使用setsebool命令
其原理是对指定服务关闭SELinux,看起来这种方式最为方便快捷,但是并不推荐,因为这样做,SELinux就不会监测该服务的所有动作,也就是说,不仅我们需要的动作被允许了,一些我们不需要但至关重要的动作也可以自由进行,无疑这样做风险是非常大的
第二种方法:使用audit2allow命令
这种方式通过创建自定的政策模块来扩展 SELinux 政策,允许一组特定的状态出理。
比如在 smtp 邮件服务器上增加 postgrey 服务。smtp 服务器须要通过一个 Unix 通讯端与 postgrey 沟通,但缺省的 SELinux 政策却禁止我们的 smtp 服务器如此做。结果该服务会被 SELinux 所封锁。这个问题不能通过更改或撤消文件的安全性脉络来解决,也没有可供切换二元值。所以必须使用audit2allow方法
这种方式要优于第一种方式,既保证我们需要的动作可以正常执行,同时也可以监测并阻止其他不被SELinux允许的动作的发生
这里用smtp做个例子,如果我们将 SELinux 切换至 Permissive 模式并让邮件服务器运行一段时间,我们便可以在允许访问的情况下记录 SELinux 的问题。查看日志时,我们会看见以下 SELinux AVC 信息:
type=AVC msg=audit(1218128130.653:334): avc: denied { connectto } for pid=9111 comm="smtpd" path="/var/spool/postfix/postgrey/socket"
scontext=system_u:system_r:postfix_smtpd_t:s0 tcontext=system_u:system_r:initrc_t:s0 tclass=unix_stream_socket
type=AVC msg=audit(1218128130.653:334): avc: denied { write } for pid=9111 comm="smtpd" name="socket" dev=sda6 ino=39977017
scontext=system_u:system_r:postfix_smtpd_t:s0 tcontext=system_u:object_r:postfix_spool_t:s0 tclass=sock_file
接下来我们可以用 audit2allow 来产生一组允许所需行动的政策规则。
方法是创建一个本地的 postgrey 强制类型政策档(postgreylocal.te):
# grep smtpd_t /var/log/audit/audit.log | audit2allow -m postgreylocal > postgreylocal.te
# cat postgreylocal.te
module postgreylocal 1.0;
require {
type postfix_smtpd_t;
type postfix_spool_t;
type initrc_t;
class sock_file write;
class unix_stream_socket connectto;
}
#============= postfix_smtpd_t ==============
allow postfix_smtpd_t initrc_t:unix_stream_socket connectto;
allow postfix_smtpd_t postfix_spool_t:sock_file write;
上面的操作是从 audit.log 筛选有关 smtp 服务器的问题,并将这些问题导向 audit2allow,让它产生一组规则,是它认为可用来允许被 SELinux 政策所封锁的行动。通过cat命令查阅这些规则时,我们可发现该 smtp 服务器想连接及写进一个 Unix 通讯端,而从日志里我们看见这个 Unix 通讯端正是 postgrey 服务所聆听的那个。既然这一些都合情合理,我们可以续继用 audit2allow 创建一个自定的政策模块,允许这些行动:
# grep smtpd_t /var/log/audit/audit.log | audit2allow -M postgreylocal
接着我们利用 semodule 这个指令将我们的 postgrey 政策模块装入现有的 SELinux 政策内:
semodule -i postgreylocal.pp
如此便会将我们的 postgrey 政策模块新增到/etc/selinux/targeted/modules/active/modules/postgreylocal.pp
我们还可以通过 semodule -l 来检查该政策模块已被正确地装入
5.其他处理方法
还有几种不同的处理方法,摘录如下:
This can be fixed in many ways:
* easy way: widen the privileges of a slightly less granular ACL (ie. grant access to /proc/PID/*) [ie. what was suggested here]
* hard way: rework the security of /proc in kernel so you can grant access to single files within /proc/PID (ie. /proc/PID/oom_adj) as opposed to just /proc/PID/* (like can be done currently) [this is an easy change, hard to get accepted upstream, and hard to get rolled out]
* hard way: rework the way Chrome does sandboxing to potentially work around this problem [this is a very complex change, but easy to get rolled out]
* stupid way (currently implemented) on selinux don't touch oom_adj and thus have other processes (like the X server) die on OOM instead of tabs of a browser (which is likely the memory hog anyway) - this is definitely sub-optimal.