2024年6月2日发(作者:)

SELinux从出现至今,已经走过将近13年历史,然而在Linux相关QQ技术群或

者Linux相关论坛,经常有人遇到问题问题都归咎与SELinux,如httpd各项配置

都正常,但客户就是无法访问;又比如vsftpd配置均正常,但客户端访问提示无

法转换家目录。于是乎很多人都对SELinux有了极大的偏见,认为SELinux带来

的似乎只有麻烦,于是很多人选择在安装系统第一件事就是将SELinux设置为禁

用。不过随着日益增长的0-day安全漏洞,SELinux在很多时候给了我们关键的保

障。

什么是SELinux?

SELinux全称SecurityEnhancedLinux(安全强化Linux),是美国国家安全局2000年

以GNUGPL发布,是MAC(MandatoryAccessControl,强制访问控制系统)的一个实

现,目的在于明确的指明某个进程可以访问哪些资源(文件、网络端口等)。强制访

问控制系统的用途在于增强系统抵御0-Day攻击(利用尚未公开的漏洞实现的攻击

行为)的能力。所以它不是网络防火墙或ACL的替代品,在用途上也不重复。在目

前的大多数发行版中,已经默认在内核集成了SELinux。

举例来说,系统上的Apache被发现存在一个漏洞,使得某远程用户可以访问系统

上的敏感文件(比如/etc/passwd来获得系统已存在用户),而修复该安全漏洞的

Apache更新补丁尚未释出。此时SELinux可以起到弥补该漏洞的缓和方案。因为

/etc/passwd不具有Apache的访问标签,所以Apache对于/etc/passwd的访问会

被SELinux阻止。相比其他强制性访问控制系统,SELinux有如下优势:

控制策略是可查询而非程序不可见的。

可以热更改策略而无需重启或者停止服务。

可以从进程初始化、继承和程序执行三个方面通过策略进行控制。

控制范围覆盖文件系统、目录、文件、文件启动描述符、端口、消息接口和网

络接口。

那么SELinux对于系统性能有什么样的影响呢?根据Phoronix在2009年使用

Fedora11所做的横向比较来看,开启SELinux仅在少数情况下导致系统性能约5%

的降低。

SELinux是不是会十分影响一般桌面应用及程序开发呢?原因是,因为SELinux的

策略主要针对服务器环境。但随着SELinux13年来的广泛应用,目前SELinux策

略在一般桌面及程序开发环境下依然可以同时满足安全性及便利性的要求。以刚刚

发布的Fedora15为例,笔者在搭建完整的娱乐(包含多款第三方原生Linux游戏

及Wine游戏)及开发环境(AndroidSDK+Eclipse)过程中,只有Wine程序的首次运

行时受到SELinux默认策略的阻拦,在图形化的“SELinux故障排除程序”帮助下,

点击一下按钮就解决了。

了解和配置SELinux

1.获取当前SELinux运行状态

getenforce

可能返回结果有三种:Enforcing、Permissive和Disabled。Disabled代表SELinux

被禁用,Permissive代表仅记录安全警告但不阻止可疑行为,Enforcing代表记录

警告且阻止可疑行为。

目前常见发行版中,RHEL、CentOS、Fedora等默认设置为Enforcing,其余的如

openSUSE等为Permissive。

2.改变SELinux运行状态

setenforce[Enforcing|Permissive|1|0]

该命令可以立刻改变SELinux运行状态,在Enforcing和Permissive之间切换,

结果保持至关机。一个典型的用途是看看到底是不是SELinux导致某个服务或者

程序无法运行。若是在setenforce0之后服务或者程序依然无法运行,那么就可以

肯定不是SELinux导致的。

若是想要永久变更系统SELinux运行环境,可以通过更改配置文件

/etc/selinux/config实现。注意当从Disabled切换到Permissive或者Enforcing模

式后需要重启计算机并为整个文件系统重新创建安全标签

(touch/.autorelabel&&reboot)。

[root@web2~]#vim/etc/selinux/config

#ThisfilecontrolsthestateofSELinuxonthesystem.

#SELINUX=cantakeoneofthesethreevalues:

#enforcing-SELinuxsecuritypolicyisenforced.

#permissive-SELinuxprintswarningsinsteadofenforcing.

#disabled-NoSELinuxpolicyisloaded.

SELINUX=enforcing

#SELINUXTYPE=cantakeoneofthesetwovalues:

#targeted-Targetedprocessesareprotected,

#mls-MultiLevelSecurityprotection.

SELINUXTYPE=targeted

x运行策略

配置文件/etc/selinux/config还包含了SELinux运行策略的信息,通过改变变量

SELINUXTYPE的值实现,该值有两种可能:targeted代表仅针对预制的几种网络

服务和访问请求使用SELinux保护,strict代表所有网络服务和访问请求都要经过

SELinux。

RHEL、CentOS、Fedora等默认设置为targeted,包含了对几乎所有常见网络服务

的SELinux策略配置,已经默认安装并且可以无需修改直接使用。若是想自己编

辑SELinux策略,也提供了命令行下的策略编辑器seedit以及Eclipse下的编辑插

件eclipse-slide。

ils工具的SELinux模式

常见的属于coreutils的工具如ps、ls等等,可以通过增加Z选项的方式获知

SELinux方面的信息。

4.1使用ps获取:

[barlow@web1~]$ps-auxZ|grephttpd|head-5

Warning:badsyntax,perhapsabogus'-'?See/usr/share/doc/procps-

3.2.8/FAQunconfined_u:system_r:httpd_t:s0apache13930.00.22796482272?SJun270:01/usr/sbin/httpdu

nconfined_u:system_r:httpd_t:s0apache13950.01.527296415528?SJun270:02/usr/sbin/httpdunconfined

_u:system_r:httpd_t:s0apache13990.01.727296417828?SJun270:02/usr/sbin/httpdunconfined_u:system

_r:httpd_t:s0apache14050.01.227296412732?SJun270:02/usr/sbin/httpdunconfined_u:system_r:httpd_t:

s0apache14090.01.427296814784?SJun270:03/usr/sbin/httpd

4.2使用ls获取

[barlow@web1~]$ls-

Z/var/www/barlowunconfined_u:object_r:httpd_sys_script_exec_t:s0cgi-

barlowunconfined_u:object_r:httpd_sys_content_t:bar

lowunconfined_u:object_r:httpd_sys_content_t:barlowunconfined_u:object_r:

httpd_sys_content_t:barlowsystem_u:object_r:httpd_sys_content_t:s0lost+fo

und

以此类推,Z选项可以应用在几乎全部coreutils工具里。

5、常用修改有关httpd服务的SELinux策略方法:

如上,ls-Z方法查询到的文件SELinux上下文跟默认要求的不匹配,则服务无法正

常使用,如SELinux要求httpd服务的网页目录或文件的上下文要为

httpd_sys_content_t,否则客户端无法访问。

5.1使用chcon修改httpd目录或文件安全上下文:

如nagios服务器的网页目录上下文默认为unconfined_u:object_r:usr_t:s0,则客户

端无法访问:

[root@nagios~]#ll-Z/usr/local/nagios/share/

-apachesystem_u:object_r:usr_t:

apacheunconfined_u:object_r:usr_t:s0contexthelp

apacheunconfined_u:object_r:usr_t:s0docs

apacheunconfined_u:object_r:usr_t:s0images

apacheunconfined_u:object_r:usr_t:s0includes

-apachesystem_u:object_r:usr_t:

-apachesystem_u:object_r:usr_t:

……以下略……

使用chcon修改/usr/local/nagios/share/目录及其下所有文件安全上下文为

unconfined_u:object_r:httpd_sys_content_t

[root@nagios~]#chcon-Runconfined_u:object_r:httpd_sys_content_t:s0/usr/local/nagios/share/

查询结果:

[root@nagios~]#ls-Z/usr/local/nagios/share/

-apacheunconfined_u:object_r:httpd_sys_content_t:

apacheunconfined_u:object_r:httpd_sys_content_t:s0contexthelp

apacheunconfined_u:object_r:httpd_sys_content_t:s0docs

apacheunconfined_u:object_r:httpd_sys_content_t:s0images

apacheunconfined_u:object_r:httpd_sys_content_t:s0includes

-apacheunconfined_u:object_r:httpd_sys_content_t:

-apacheunconfined_u:object_r:httpd_sys_content_t:

apacheunconfined_u:object_r:httpd_sys_content_t:s0locale

-apacheunconfined_u:object_r:httpd_sys_content_t:

不用重启httpd服务,客户端就已经可以访问。

5.2使用semanage工具,让httpd支持非标准端口:

semanage工具非常强大,基本能实现所有SELinux配置,但很多时候我们并不知

道SELinux错在哪里,在图形界面下有图形化的分析工具,在终端界面下也有一

个功能非常强大的分析工具sealert,但默认情况下,这两个工具都没有被安装,

需要先安装semanage和sealert工具:

[root@web2~]#yum-yinstallpolicycoreutils-pythonsetroubleshoot

注:semanage的使用也可以参见我的另外一篇博文:Selinux管理工具semanage。

默认情况下Apache只侦听80、443等几个端口,若是直接指定其侦听808端口

的话,会在servicehttpdrestart的时候报错:

[root@web2~]#servicehttpdstart

正在启动httpd:(13)Permissiondenied:make_sock:couldnotbindtoaddress0.0.0.0:808

nolisteningsocketsavailable,shuttingdown

Unabletoopenlogs[失败]

查看/var/log/messages文件,可以看到如下这样的错误:

[root@web2~]#tail/var/log/messages

Jun2910:30:51web2setroubleshoot:SELinuxispreventing/usr/sbin/httpdfromname_bindaccessonthetcp_s

lert-l2ad073a4-7c64-4175-93ff-9d78f75133af

根据提示,运行sealert-l2ad073a4-7c64-4175-93ff-9d78f75133af,生成SELinux

报告如下:

[root@web2~]#sealert-l2ad073a4-7c64-4175-93ff-9d78f75133af

#semanageport-a-tPORT_TYPE-ptcp808

其中PORT_TYPE是以下之一:

ntop_port_t,http_cache_port_t,http_port_t,puppet_port_t,jboss_messaging_port_t,jboss_management_

port_t。

根据提示,运行semanageport-a-tPORT_TYPE-ptcp808,此处需将PORT_TYPE替

换为http_port_t

[root@web2~]#semanageport-a-thttp_port_t-ptcp808

查询结果:

[root@web2~]#semanageport-l|grephttp

http_cache_port_ttcp3128,8080,8118,8123,10001-10010

http_cache_port_tudp3130

http_port_ttcp808,80,443,488,8008,8009,8443##可以看到808端口已经加入

pegasus_http_port_ttcp5988

pegasus_https_port_ttcp5989

重启服务:

[root@web2~]#servicehttpdstart

正在启动httpd:[确定]

5.3修改selinux布尔值,允许创建私人网站

若是希望用户可以通过在~/www/放置文件的方式创建自己的个人网站的话,那

么需要在Apache策略中允许该操作执行。使用:

[root@web2~]#setseboolhttpd_enable_homedirs1

默认情况下setsebool的设置只保留到下一次重启之前,若是想永久生效的话,需

要添加-P参数,比如:

[root@web2~]#setsebool-Phttpd_enable_homedirs1

setsebool是用来切换由布尔值控制的SELinux策略的,当前布尔值策略的状态可

以通过getsebool来获知。查看与httpd相关的布尔值:

[root@web2~]#getsebool-a|grephttp

allow_httpd_anon_write-->off

allow_httpd_mod_auth_ntlm_winbind-->off

allow_httpd_mod_auth_pam-->off

allow_httpd_sys_script_anon_write-->off

httpd_builtin_scripting-->on

httpd_can_check_spam-->off

httpd_can_network_connect-->off

httpd_can_network_connect_cobbler-->off

httpd_can_network_connect_db-->on

httpd_can_network_memcache-->off

httpd_can_network_relay-->off

httpd_can_sendmail-->off

httpd_dbus_avahi-->on

httpd_enable_cgi-->on

httpd_enable_ftp_server-->off

httpd_enable_homedirs-->on

httpd_execmem-->off

httpd_manage_ipa-->off

httpd_read_user_content-->off

httpd_run_stickshift-->off

httpd_setrlimit-->off

httpd_ssi_exec-->off

httpd_tmp_exec-->off

httpd_tty_comm-->on

httpd_unified-->on

httpd_use_cifs-->off

httpd_use_gpg-->off

httpd_use_nfs-->on

httpd_use_openstack-->off

httpd_verify_dns-->off

named_bind_http_port-->off

以上列举了httpd服务常见selinux配置,其他服务(如vsftpd)也可以采用相同

的办法处理。