[Translated]RHCSA Series--Part 13--Mandatory Access Control Essentials with SELinux in RHEL 7.md

This commit is contained in:
Chang Liu 2015-09-21 19:32:41 +08:00
parent e02c215cf1
commit 103420797f
2 changed files with 177 additions and 178 deletions

View File

@ -1,178 +0,0 @@
FSSlc translating
RHCSA Series: Mandatory Access Control Essentials with SELinux in RHEL 7 Part 13
================================================================================
During this series we have explored in detail at least two access control methods: standard ugo/rwx permissions ([Manage Users and Groups Part 3][1]) and access control lists ([Configure ACLs on File Systems Part 7][2]).
![RHCSA Exam: SELinux Essentials and Control FileSystem Access](http://www.tecmint.com/wp-content/uploads/2015/06/SELinux-Control-File-System-Access.png)
RHCSA Exam: SELinux Essentials and Control FileSystem Access
Although necessary as first level permissions and access control mechanisms, they have some limitations that are addressed by Security Enhanced Linux (aka SELinux for short).
One of such limitations is that a user can expose a file or directory to a security breach through a poorly elaborated chmod command and thus cause an unexpected propagation of access rights. As a result, any process started by that user can do as it pleases with the files owned by the user, where finally a malicious or otherwise compromised software can achieve root-level access to the entire system.
With those limitations in mind, the United States National Security Agency (NSA) first devised SELinux, a flexible mandatory access control method, to restrict the ability of processes to access or perform other operations on system objects (such as files, directories, network ports, etc) to the least permission model, which can be modified later as needed. In few words, each element of the system is given only the access required to function.
In RHEL 7, SELinux is incorporated into the kernel itself and is enabled in Enforcing mode by default. In this article we will explain briefly the basic concepts associated with SELinux and its operation.
### SELinux Modes ###
SELinux can operate in three different ways:
- Enforcing: SELinux denies access based on SELinux policy rules, a set of guidelines that control the security engine.
- Permissive: SELinux does not deny access, but denials are logged for actions that would have been denied if running in enforcing mode.
- Disabled (self-explanatory).
The `getenforce` command displays the current mode of SELinux, whereas `setenforce` (followed by a 1 or a 0) is used to change the mode to Enforcing or Permissive, respectively, during the current session only.
In order to achieve persistence across logouts and reboots, you will need to edit the `/etc/selinux/config` file and set the SELINUX variable to either enforcing, permissive, or disabled:
# getenforce
# setenforce 0
# getenforce
# setenforce 1
# getenforce
# cat /etc/selinux/config
![Set SELinux Mode](http://www.tecmint.com/wp-content/uploads/2015/05/Set-SELinux-Mode.png)
Set SELinux Mode
Typically you will use setenforce to toggle between SELinux modes (enforcing to permissive and back) as a first troubleshooting step. If SELinux is currently set to enforcing while youre experiencing a certain problem, and the same goes away when you set it to permissive, you can be confident youre looking at a SELinux permissions issue.
### SELinux Contexts ###
A SELinux context consists of an access control environment where decisions are made based on SELinux user, role, and type (and optionally a level):
- A SELinux user complements a regular Linux user account by mapping it to a SELinux user account, which in turn is used in the SELinux context for processes in that session, in order to explicitly define their allowed roles and levels.
- The concept of role acts as an intermediary between domains and SELinux users in that it defines which process domains and file types can be accessed. This will shield your system against vulnerability to privilege escalation attacks.
- A type defines an SELinux file type or an SELinux process domain. Under normal circumstances, processes are prevented from accessing files that other processes use, and and from accessing other processes, thus access is only allowed if a specific SELinux policy rule exists that allows it.
Lets see how all of that works through the following examples.
**EXAMPLE 1: Changing the default port for the sshd daemon**
In [Securing SSH Part 8][3] we explained that changing the default port where sshd listens on is one of the first security measures to secure your server against external attacks. Lets edit the `/etc/ssh/sshd_config` file and set the port to 9999:
Port 9999
Save the changes, and restart sshd:
# systemctl restart sshd
# systemctl status sshd
![Change SSH Port](http://www.tecmint.com/wp-content/uploads/2015/05/Change-SSH-Port.png)
Restart SSH Service
As you can see, sshd has failed to start. But what happened?
A quick inspection of `/var/log/audit/audit.log` indicates that sshd has been denied permissions to start on port 9999 (SELinux log messages include the word “AVC” so that they might be easily identified from other messages) because that is a reserved port for the JBoss Management service:
# cat /var/log/audit/audit.log | grep AVC | tail -1
![Inspect SSH Logs](http://www.tecmint.com/wp-content/uploads/2015/05/Inspect-SSH-Logs.png)
Inspect SSH Logs
At this point you could disable SELinux (but dont!) as explained earlier and try to start sshd again, and it should work. However, the semanage utility can tell us what we need to change in order for us to be able to start sshd in whatever port we choose without issues.
Run,
# semanage port -l | grep ssh
to get a list of the ports where SELinux allows sshd to listen on.
![Semanage Tool](http://www.tecmint.com/wp-content/uploads/2015/05/SELinux-Permission.png)
Semanage Tool
So lets change the port in /etc/ssh/sshd_config to Port 9998, add the port to the ssh_port_t context, and then restart the service:
# semanage port -a -t ssh_port_t -p tcp 9998
# systemctl restart sshd
# systemctl is-active sshd
![Semanage Add Port](http://www.tecmint.com/wp-content/uploads/2015/05/Semenage-Add-Port.png)
Semanage Add Port
As you can see, the service was started successfully this time. This example illustrates the fact that SELinux controls the TCP port number to its own port type internal definitions.
**EXAMPLE 2: Allowing httpd to send access sendmail**
This is an example of SELinux managing a process accessing another process. If you were to implement mod_security and mod_evasive along with Apache in your RHEL 7 server, you need to allow httpd to access sendmail in order to send a mail notification in the wake of a (D)DoS attack. In the following command, omit the -P flag if you do not want the change to be persistent across reboots.
# semanage boolean -1 | grep httpd_can_sendmail
# setsebool -P httpd_can_sendmail 1
# semanage boolean -1 | grep httpd_can_sendmail
![Allow Apache to Send Mails](http://www.tecmint.com/wp-content/uploads/2015/05/Allow-Apache-to-Send-Mails.png)
Allow Apache to Send Mails
As you can tell from the above example, SELinux boolean settings (or just booleans) are true / false rules embedded into SELinux policies. You can list all the booleans with `semanage boolean -l`, and alternatively pipe it to grep in order to filter the output.
**EXAMPLE 3: Serving a static site from a directory other than the default one**
Suppose you are serving a static website using a different directory than the default one (`/var/www/html`), say /websites (this could be the case if youre storing your web files in a shared network drive, for example, and need to mount it at /websites).
a). Create an index.html file inside /websites with the following contents:
<html>
<h2>SELinux test</h2>
</html>
If you do,
# ls -lZ /websites/index.html
you will see that the index.html file has been labeled with the default_t SELinux type, which Apache cant access:
![Check SELinux File Permission](http://www.tecmint.com/wp-content/uploads/2015/05/Check-File-Permssion.png)
Check SELinux File Permission
b). Change the DocumentRoot directive in `/etc/httpd/conf/httpd.conf` to /websites and dont forget to update the corresponding Directory block. Then, restart Apache.
c). Browse to `http://<web server IP address>`, and you should get a 503 Forbidden HTTP response.
d). Next, change the label of /websites, recursively, to the httpd_sys_content_t type in order to grant Apache read-only access to that directory and its contents:
# semanage fcontext -a -t httpd_sys_content_t "/websites(/.*)?"
e). Finally, apply the SELinux policy created in d):
# restorecon -R -v /websites
Now restart Apache and browse to `http://<web server IP address>` again and you will see the html file displayed correctly:
![Verify Apache Page](http://www.tecmint.com/wp-content/uploads/2015/05/08part13.png)
Verify Apache Page
### Summary ###
In this article we have gone through the basics of SELinux. Note that due to the vastness of the subject, a full detailed explanation is not possible in a single article, but we believe that the principles outlined in this guide will help you to move on to more advanced topics should you wish to do so.
If I may, let me recommend two essential resources to start with: the [NSA SELinux page][4] and the [RHEL 7 SELinux Users and Administrators][5] guide.
Dont hesitate to let us know if you have any questions or comments.
--------------------------------------------------------------------------------
via: http://www.tecmint.com/selinux-essentials-and-control-filesystem-access/
作者:[Gabriel Cánepa][a]
译者:[译者ID](https://github.com/译者ID)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创翻译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:http://www.tecmint.com/author/gacanepa/
[1]:http://www.tecmint.com/rhcsa-exam-manage-users-and-groups
[2]:http://www.tecmint.com/rhcsa-exam-configure-acls-and-mount-nfs-samba-shares/
[3]:http://www.tecmint.com/rhcsa-series-secure-ssh-set-hostname-enable-network-services-in-rhel-7/
[4]:https://www.nsa.gov/research/selinux/index.shtml
[5]:https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/7/html/SELinux_Users_and_Administrators_Guide/part_I-SELinux.html

View File

@ -0,0 +1,177 @@
RHCSA 系列: 在 RHEL 7 中使用 SELinux 进行强制访问控制 Part 13
================================================================================
在本系列的前面几篇文章中,我们已经详细地探索了至少两种访问控制方法:标准的 ugo/rwx 权限([管理用户和组 Part 3][1]) 和访问控制列表([在文件系统中配置 ACL Part 7][2])。
![RHCSA 认证SELinux 精要和控制文件系统的访问](http://www.tecmint.com/wp-content/uploads/2015/06/SELinux-Control-File-System-Access.png)
RHCSA 认证SELinux 精要和控制文件系统的访问
尽管作为第一级别的权限和访问控制机制是必要的,但它们同样有一些局限,而这些局限则可以由安全增强 Linux(Security Enhanced Linux,简称为 SELinux) 来处理。
这些局限的一种情形是:某个用户可能通过一个未加详细阐述的 chmod 命令将一个文件或目录暴露在安全漏洞面前(注:这句我的翻译有点问题),从而引起访问权限的意外传播。结果,由该用户开启的任意进程可以对属于该用户的文件进行任意的操作,最终一个恶意的或受损的软件对整个系统可能会实现 root 级别的访问权限。
考虑到这些局限性,美国国家安全局(NSA) 率先设计出了 SELinux一种强制的访问控制方法它根据最小权限模型去限制进程在系统对象(如文件,目录,网络接口等)上的访问或执行其他的操作的能力,而这些限制可以在后面根据需要进行修改。简单来说,系统的每一个元素只给某个功能所需要的那些权限。
在 RHEL 7 中SELinux 被并入了内核中,且默认情况下以强制模式开启。在这篇文章中,我们将简要地介绍有关 SELinux 及其相关操作的基本概念。
### SELinux 的模式 ###
SELinux 可以以三种不同的模式运行:
- 强制模式SELinux 根据 SELinux 策略规则拒绝访问,这些规则是用以控制安全引擎的一系列准则;
- 宽容模式SELinux 不拒绝访问,但对于那些运行在强制模式下会被拒绝访问的行为,它会进行记录;
- 关闭 (不言自明,即 SELinux 没有实际运行).
使用 `getenforce` 命令可以展示 SELinux 当前所处的模式,而 `setenforce` 命令(后面跟上一个 1 或 0) 则被用来将当前模式切换到强制模式或宽容模式,但只对当前的会话有效。
为了使得在登出和重启后上面的设置还能保持作用,你需要编辑 `/etc/selinux/config` 文件并将 SELINUX 变量的值设为 enforcingpermissivedisabled 中之一:
# getenforce
# setenforce 0
# getenforce
# setenforce 1
# getenforce
# cat /etc/selinux/config
![设置 SELinux 模式](http://www.tecmint.com/wp-content/uploads/2015/05/Set-SELinux-Mode.png)
设置 SELinux 模式
通常情况下,你将使用 `setenforce` 来在 SELinux 模式间进行切换(从强制模式到宽容模式,或反之),以此来作为你排错的第一步。假如 SELinux 当前被设置为强制模式,而你遇到了某些问题,但当你把 SELinux 切换为宽容模式后问题不再出现了,则你可以确信你遇到了一个 SELinux 权限方面的问题。
### SELinux 上下文 ###
一个 SELinux 上下文由一个权限控制环境所组成,在这个环境中,决定的做出将基于 SELinux 的用户,角色和类型(和可选的级别)
- 一个 SELinux 用户是通过将一个常规的 Linux 用户账户映射到一个 SELinux 用户账户来实现的,反过来,在一个会话中,这个 SELinux 用户账户在 SELinux 上下文中被进程所使用,为的是能够显示地定义它们所允许的角色和级别。
- 角色的概念是作为域和处于该域中的 SELinux 用户之间的媒介,它定义了 SELinux 可以访问到哪个进程域和哪些文件类型。这将保护您的系统免受提权漏洞的攻击。
- 类型则定义了一个 SELinux 文件类型或一个 SELinux 进程域。在正常情况下,进程将会被禁止访问其他进程正使用的文件,并禁止对其他进程进行访问。这样只有当一个特定的 SELinux 策略规则允许它访问时,才能够进行访问。
下面就让我们看看这些概念是如何在下面的例子中起作用的。
**例 1改变 sshd 守护进程的默认端口**
在[加固 SSH Part 8][3] 中,我们解释了更改 sshd 所监听的默认端口是加固你的服务器免收外部攻击的首个安全措施。下面,就让我们编辑 `/etc/ssh/sshd_config` 文件并将端口设置为 9999
Port 9999
保存更改并重启 sshd
# systemctl restart sshd
# systemctl status sshd
![更改 SSH 的端口](http://www.tecmint.com/wp-content/uploads/2015/05/Change-SSH-Port.png)
重启 SSH 服务
正如你看到的那样, sshd 启动失败,但为什么会这样呢?
快速检查 `/var/log/audit/audit.log` 文件会发现 sshd 已经被拒绝在端口 9999 上开启(SELinux 日志信息包含单词 "AVC",所以这类信息可以被轻易地与其他信息相区分),因为这个端口是 JBoss 管理服务的保留端口:
# cat /var/log/audit/audit.log | grep AVC | tail -1
![查看 SSH 日志](http://www.tecmint.com/wp-content/uploads/2015/05/Inspect-SSH-Logs.png)
查看 SSH 日志
在这种情况下,你可以像先前解释的那样禁用 SELinux(但请不要这样做!),并尝试重启 sshd且这种方法能够起效。但是 `semanage` 应用可以告诉我们在哪些端口上可以开启 sshd 而不会出现任何问题。
运行:
# semanage port -l | grep ssh
便可以得到一个 SELinux 允许 sshd 在哪些端口上监听的列表:
![Semanage 工具](http://www.tecmint.com/wp-content/uploads/2015/05/SELinux-Permission.png)
Semanage 工具
所以让我们在 `/etc/ssh/sshd_config` 中将端口更改为 9998 端口,增加这个端口到 ssh_port_t 的上下文,然后重启 sshd 服务:
# semanage port -a -t ssh_port_t -p tcp 9998
# systemctl restart sshd
# systemctl is-active sshd
![Semanage 添加端口](http://www.tecmint.com/wp-content/uploads/2015/05/Semenage-Add-Port.png)
Semanage 添加端口
如你所见,这次 sshd 服务被成功地开启了。这个例子告诉我们这个事实SELinux 控制 TCP 端口数为它自己端口类型中间定义。
**例 2允许 httpd 访问 sendmail**
这是一个 SELinux 管理一个进程来访问另一个进程的例子。假如在你的 RHEL 7 服务器上,你要实现 Apache 的 mod_security 和 mod_evasive(注:这里少添加了一个链接,链接的地址是 http://www.tecmint.com/protect-apache-using-mod_security-and-mod_evasive-on-rhel-centos-fedora/),你需要允许 httpd 访问 sendmail以便在遭受到 (D)DoS 攻击时能够用邮件来提醒你。在下面的命令中,如果你不想使得更改在重启后任然生效,请去掉 `-P` 选项。
# semanage boolean -1 | grep httpd_can_sendmail
# setsebool -P httpd_can_sendmail 1
# semanage boolean -1 | grep httpd_can_sendmail
![允许 Apache 发送邮件](http://www.tecmint.com/wp-content/uploads/2015/05/Allow-Apache-to-Send-Mails.png)
允许 Apache 发送邮件
从上面的例子中,你可以知道 SELinux 布尔设定(或者只是布尔值)分别对应于 true 或 false,被嵌入到了 SELinux 策略中。你可以使用 `semanage boolean -l` 来列出所有的布尔值,也可以管道至 grep 命令以便筛选输出的结果。
**例 3在一个特定目录而非默认目录下服务一个静态站点**
假设你正使用一个不同于默认目录(`/var/www/html`)的目录来服务一个静态站点,例如 `/websites` 目录(这种情形会出现在当你把你的网络文件存储在一个共享网络设备上,并需要将它挂载在 /websites 目录时)。
a). 在 /websites 下创建一个 index.html 文件并包含如下的内容:
<html>
<h2>SELinux test</h2>
</html>
假如你执行
# ls -lZ /websites/index.html
你将会看到这个 index.html 已经被标记上了 default_t SELinux 类型,而 Apache 不能访问这类文件:
![检查 SELinux 文件的权限](http://www.tecmint.com/wp-content/uploads/2015/05/Check-File-Permssion.png)
检查 SELinux 文件的权限
b). 将 `/etc/httpd/conf/httpd.conf` 中的 DocumentRoot 改为 /websites并不要忘了
更新相应的 Directory 代码块。然后重启 Apache。
c). 浏览到 `http://<web server IP address>`,则你应该会得到一个 503 Forbidden 的 HTTP 响应。
d). 接下来,递归地改变 /websites 的标志,将它的标志变为 httpd_sys_content_t 类型,以便赋予 Apache 对这些目录和其内容的只读访问权限:
# semanage fcontext -a -t httpd_sys_content_t "/websites(/.*)?"
e). 最后,应用在 d) 中创建的 SELinux 策略:
# restorecon -R -v /websites
现在重启 Apache 并再次浏览到 `http://<web server IP address>`,则你可以看到被正确展现出来的 html 文件:
![确认 Apache 页面](http://www.tecmint.com/wp-content/uploads/2015/05/08part13.png)
确认 Apache 页面
### 总结 ###
在本文中,我们详细地介绍了 SELinux 的基础知识。请注意,由于这个主题的广泛性,在单篇文章中做出一个完全详尽的解释是不可能的,但我们相信,在这个指南中列出的基本原则将会对你进一步了解更高级的话题有所帮助,假如你想了解的话。
假如可以,请让我推荐两个必要的资源来入门 SELinux[NSA SELinux 页面][4] 和 [针对用户和系统管理员的 RHEL 7 SELinux 指南][5]。
假如你有任何的问题或评论,请不要犹豫,让我们知晓吧。
--------------------------------------------------------------------------------
via: http://www.tecmint.com/selinux-essentials-and-control-filesystem-access/
作者:[Gabriel Cánepa][a]
译者:[FSSlc](https://github.com/FSSlc)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创翻译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:http://www.tecmint.com/author/gacanepa/
[1]:http://www.tecmint.com/rhcsa-exam-manage-users-and-groups
[2]:http://www.tecmint.com/rhcsa-exam-configure-acls-and-mount-nfs-samba-shares/
[3]:http://www.tecmint.com/rhcsa-series-secure-ssh-set-hostname-enable-network-services-in-rhel-7/
[4]:https://www.nsa.gov/research/selinux/index.shtml
[5]:https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/7/html/SELinux_Users_and_Administrators_Guide/part_I-SELinux.html