前面系列文章讲解了Linux下通过文件传输、文件共享、邮件系统来分享和获取资源,本文讲解网络资源获取和共享的另外一种形式,通过Apache服务程序来提供Web服务。
本文先讲解目前主流的Web服务程序以及各自的特点和优势,然后以Apache服务为例讲解Linux下Web网站的部署,并在部署过程中穿插讲解SELinux的使用。最后在以示例讲解Apache的虚拟主机功能及访问控制。
一、Web服务程序分类
我们平时在互联网上访问的网站服务就是Web服务,比如我们常用的百度网站,他就是一个Web网站。Web网络服务,一般是指允许用户通过浏览器访问到其中各种资源的服务。
Web网络服务是一种被动访问的服务程序,当接入到互联网中的用户主机发出请求后,Web服务才会响应并通过HTTP或HTTPS把请求的内容回传给用户。示意图如下:
目前提供Web服务的程序有:IIS、Apache、Ngnix等。
1.1 IIS
IIS(Internet Information Services):互联网信息服务,是Windows系统中默认的Web服务程序。它是一款带图形化界面的网站管理工具,不仅提供Web网站服务,还可以提供FTP、SMTP等服务,功能丰富。但是由于它是用在Windows系统中,因此不介绍它。
1.2 Apache
Apache程序是目前市场上占有率很高的Web服务程序之一,其特点是跨平台、安全性高、API扩展简单可靠。
Apache服务程序可以运行在Linux、UNIX、 Windows系统中,支持基于IP、域名及端口号的虚拟主机功能,支持多种认证方式,集成有代理服务器模块、安全Socket层(SSL),能够实时监视服务状态与定制日志消息,有着各类丰富的模块支持。
由于它是RHEL5、6、7中默认的Web服务程序,并且作为老牌的Web服务程序,市场占用率还是很高的,因此本文主要以Apache为例进行Web服务的演示。
1.3 Ngnix
2004年,为俄罗斯知名门户站点开发的Web服务程序Nginx横空出世。它作为一款轻量级的网站服务软件,因其稳定性和丰富的功能而快速占领服务器市场。
它因系统资源消耗低、并发能力强的特点,在国内受到诸如新浪、腾讯、网易等门户网站的青睐。Ngnix作为后起之秀,截至本文写作时为止市场占有率几乎与Apache齐平,以后有机会再单独对其进行演示和讲解。
二、Apache安装及操作案例
2.1 Apache安装及配置
2.1.1 Apache安装
Apache是RHEL7默认的web程序,以包含在默认的安装镜像中,因此可以直接挂载安装镜像直接安装,也可以用远程Yum仓库进行安装。
需要注意的是,在CentOS和RHEL上,Apache软件包和服务称为httpd而非apache。
- 安装Apache
先检查Apache是否安装,如果未安装,通过yum仓库安装即可
[root@apache ~]# rpm -q httpd
package httpd is not installed
[root@apache ~]# yum install httpd
Loaded plugins: fastestmirror, langpacks
...省略部分内容
Complete!
[root@apache ~]# rpm -q httpd
httpd-2.4.6-90.el7.centos.x86_64
[root@apache ~]#
安装完成后,httpd服务是没有启动的,还需要将其启动,并加入到开机启动中
[root@apache ~]# systemctl start httpd
[root@apache ~]# systemctl enable httpd
ln -s '/usr/lib/systemd/system/httpd.service' '/etc/systemd/system/multi-user.target.wants/httpd.service'
[root@apache ~]#
此时在虚拟机Centos内部,打开浏览器,即可看到apache部署成功
如果要让外部机器(如宿主机)访问此Web,则需要对防火墙进行设置,当然直接关闭防火墙也可以,不过这样存在风险。
根据前文讲解的防火墙知识,打开HTTP和HTTPS的80和443端口
[root@apache ~]# firewall-cmd --permanent --zone=public --add-service=http
success
[root@apache ~]# firewall-cmd --permanent --zone=public --add-service=https
success
[root@apache ~]# firewall-cmd --reload
success
[root@apache ~]#
这样宿主机上也可以直接访问该Web,如下图
- 查看httpd版本信息:
[root@apache ~]# httpd -v
Server version: Apache/2.4.6 (CentOS)
Server built: Aug 8 2019 11:41:18
[root@apache ~]#
- 查看httpd运行状态
[root@apache ~]# systemctl status httpd
httpd.service - The Apache HTTP Server
Loaded: loaded (/usr/lib/systemd/system/httpd.service; enabled)
Active: active (running) since Mon 2020-02-10 10:52:35 CST; 7min ago
Docs: man:httpd(8)
man:apachectl(8)
...省略部分内容
2.1.2 Apache配置
只有掌握httpd服务相关配置文件以及各自的用途,才能更好地对其进行配置了。
- 主要配置文件
httpd服务程序默认主要配置文件(这些默认配置是可以进行修改的)如下:
用途 | 文件 |
---|---|
服务目录 | /etc/httpd |
主配置文件 | /etc/httpd/conf/httpd.conf |
网站数据目录 | /var/www/html |
访问日志 | /var/log/httpd/access_log |
错误日志 | /var/log/httpd/error_log |
主配置文件为:/etc/httpd/conf/httpd.conf,在此文件中存存在三种类型的类型:注释行信息、全局配置、区域配置。
从主配置文件中截取部分进行说明如下:
全局配置参数
全局配置参数就是一种全局性的配置参数,可作用于对所有的子站点,既保证了子站点的正常访问,也有效减少了频繁写入重复参数的工作量。
区域配置参数
区域配置参数则是单独针对于每个独立的子站点进行设置的。
- 主要参数
httpd服务程序最常用的参数如下
参数 | 用途 |
---|---|
ServerRoot | 服务目录 |
ServerAdmin | 管理员邮箱 |
User | 运行服务的用户 |
Group | 运行服务的用户组 |
ServerName | 网站服务器的域名 |
DocumentRoot | 网站数据目录 |
Directory | 网站数据目录的权限 |
Listen | 监听的 IP 地址与端口号 |
DirectoryIndex | 默认的索引页页面 |
ErrorLog | 错误日志文件 |
CustomLog | 访问日志文件 |
Timeout | 网页超时时间,默认为 300 秒 |
- 案例演示:修改网站首页内容
分析:既然上表中提到DocumentRoot是用于定义网站数据的保存路径,那我们查看下其参数的默认值,然后把对应网页内容放入该目录,就可以实现网页替换。静态网页名称一般为index.html。
打开主配置文件
[root@apache ~]# vim /etc/httpd/conf/httpd.conf
查看到看默认网站数据目录为:/var/www/html。默认该目录为空,向目录中创建index.html文件,并通过浏览器进行查看。
如果忘记VI或VIM编辑器使用方法的,请返回复习前面的文章:“linux入门系列4--vi&vim编辑器”。
[root@apache ~]# ll /var/www/html/
total 0
[root@apache ~]# echo "hi,this is heimatengyun's blog">/var/www/html/index.html
[root@apache ~]# ll /var/www/html/
total 4
-rw-r--r--. 1 root root 31 Feb 10 11:59 index.html
[root@apache ~]#
在宿主机通过浏览器再次查看,即可查看刚才新加的网页文件内容
通过这样的操作,我们应该明白,如果你已经做好你的网页内容,只需要往/var/www/html/目录存放,即可实现网站的访问。
但实际工作中,有可能我们会更换网站目录,把网站内容存放到一个指定的目录中,而非默认的/var/www/html/。这该怎么做呢?这就会涉及到SELinux的问题,因此请继续下边的实验。
2.2 SELinux相关知识
2.2.1 问题引出
假设我们把系统根目录下的website目录作为网站目录,我们进行如下操作:
(1)创建自定义网站目录和网页文件
[root@apache /]# mkdir /website
[root@apache /]# cd /website/
[root@apache website]# echo "this is my custom directory">index.html
[root@apache website]# ll
total 4
-rw-r--r--. 1 root root 28 Feb 10 12:21 index.html
[root@apache website]#
(2)主配置文件中配置目录
[root@apache website]# vim /etc/httpd/conf/httpd.conf
主要修改DocumentRoot参数指定网站目录为/website,同时修改定义目录权限的区域参数Directory。
(3)访问验证
配置完成后,重启httpd服务
[root@apache website]# systemctl restart httpd
在宿主机中浏览器查看
见鬼,怎么显示的还是httpd默认的页面呢?
一般情况只有网站的首页页面文件不存在或用户权限不足时,才显示httpd默认的页面。比如后文的4.1,设置禁止的ip访问后,就直接跳转到此页面。
我们在加上文件名试下呢
可以看到提示权限不足,看到这里,你应该想到是SELinux在搞鬼。为了验证一下,让我们把SELinux关闭后在试试看
[root@apache website]# getenforce
Enforcing
[root@apache website]# setenforce 0
[root@apache website]# getenforce
Permissive
[root@apache website]#
再次在宿主机浏览器访问
发现可以访问了,那说明果然是SELinux在搞鬼。但生产环境不建议直接关闭SELinux,接下来我们就来看看SELinux相关的知识,掌握之后我们在来开启SELinux并进行设置,使其在SELinux开启的情况下依然可以访问我们Web网站。
2.2.2 SELinux相关知识
在前面的文件传输、文件共享、邮件系统的文章中或多或少都讲解了SELinux相关的知识,本文再次集中总结一下。
2.2.2.1 SELinux概述
SELinux(Security-Enhanced Linux)是美国国家安全局在Linux开源社区的帮助下开发的 一个强制访问控制(MAC,Mandatory Access Control)的安全子系统。
RHEL7系统使用SELinux技术的目的是为了让各个服务进程都受到约束,使其仅获取到本应获取的资源。它的重要性不言而喻,举个例子,比如你从网上下载了一个软件用于编辑文档,但是这个软件“不老实”,当你正在努力码字的同时,它却悄悄监视你在各个网站登录时输入的密码,然后悄悄上传到黑客指定的地址。SELinux就是为了防止这种情况的发生而开发的,从而更好的保护你的电脑。
SELinux具体从两个方面进行限制:SELinux域和上下文。
SELinux域对服务程序的功能进行限制,可以确保服务程序做不了出格的事情。
SELinux上下文对文件资源的访问限制,确保文件资源 只能被其所属的服务程序进行访问。
开启SELinux后,这样就等于开启了系统双保险,系统内的服务程序只能规规矩矩地拿到自己所应该获取的资源,这样即便黑客入侵了系 统,也无法利用系统内的服务程序进行越权操作。
SELinux配置有三种模式,如下:
参数值 | 作用 |
---|---|
enforcing | 强制启用安全策略模式,将拦截服务的不合法请求 |
permissive | 遇到服务越权访问时,只发出警告而不强制拦截 |
disabled | 对于越权的行为不警告也不拦截 |
正如2.2.1中,通过setenforce 0命令将SELinux关闭后,我们的Web就可以访问了,就是这个道理。
SELinux配置文件对应为:/etc/selinux/config 。
[root@apache website]# cat /etc/selinux/config
# This file controls the state of SELinux on the system.
# SELINUX= can take one of these three values:
# enforcing - SELinux security policy is enforced.
# permissive - SELinux prints warnings instead of enforcing.
# disabled - No SELinux policy is loaded.
SELINUX=enforcing
# SELINUXTYPE= can take one of these two values:
# targeted - Targeted processes are protected,
# minimum - Modification of targeted policy. Only selected processes are protected.
# mls - Multi Level Security protection.
SELINUXTYPE=targeted
[root@apache website]#
该文件中的值定义的是SELinux默认的运行状态,也就是系统重启后的状态,因此修改它不会立即生效。
2.2.2 SELinux相关命令
- getenforce命令
用于查看SELinux的运行模式
[root@apache website]# getenforce
Enforcing
[root@apache website]#
- setenforece命令
setenforce 0或1,用于禁用(0)或启用(1)SELinux,注意这个命令的修改只是临时的,系统重启后就会失效。
[root@apache website]# getenforce
Enforcing
[root@apache website]# setenforce 0
[root@apache website]# getenforce
Permissive
[root@apache website]
因此,如果原来系统的SELinux是关闭的,如果要开启它,需要在配置文件中将进行设置SELINUX=enforcing,并同时要通过setenforce 1进行设置。这样即使系统重启,依然生效。
- semanage命令
用于设置SELinux上下文的值,管理SELinux的策略。
语法格式:semanage [选项] [文件]”
参数
参数 | 作用 |
---|---|
-l | 查询 |
-a | 添加 |
-m | 修改 |
-d | 删除 |
具体使用细节可以通过帮助命令man semanage进行查看。
- getseboll命令
该命令用于查看SELinux域相关的安全策略。
语法格式:getsebool -a(其中-a参数表示查看所有域相关的安全策略)
[root@apache ~]# getsebool
usage: getsebool -a or getsebool boolean...
[root@apache ~]# getsebool -a
abrt_anon_write --> off
abrt_handle_event --> off
abrt_upload_watch_anon_write --> on
antivirus_can_scan_system --> off
...省略部分内容
其中,on表示允许状态,off表示禁止状态。
- setsebool命令
该命令用于修改SELinux域相关的策略规则。
语法格式:setsebool -P 规则项=on或off (其中-P参数表示立即让修改永久生效)
[root@apache ~]# getsebool -a | grep xdm_write_home
xdm_write_home --> off
[root@apache ~]# setsebool -P xdm_write_home=on
[root@apache ~]# getsebool -a | grep xdm_write_home
xdm_write_home --> on
[root@apache ~]# setsebool -P xdm_write_home=off
[root@apache ~]# getsebool -a | grep xdm_write_home
xdm_write_home --> off
[root@apache ~]# getsebool xdm_write_home
xdm_write_home --> off
以上实验,我们先查看grep xdm_write_home状态,然后将其改为on,查看修改是否生效,然后再将其改回原值。查看某一项的值可以通过正则匹配,也可以直接通过该具体项获取。
有了以上这些储备知识,我们再继续完成开启SELinux的情况下让我们自定义目录的网站也能访问。
2.3 Apache案例1:修改网站目录
通过上边的讲解,我们大概已经知道了前面的问题就是SELinux上下文引起,因此我们通过以下命令来查看下默认的/var/www/html和我们自定义的/website他们的SELinux上下文的值究竟有什么不同
[root@apache website]# ll -Z /var/www/html/
-rw-r--r--. root root unconfined_u:object_r:httpd_sys_content_t:s0 index.html
[root@apache website]# ll -Z /website/
-rw-r--r--. root root unconfined_u:object_r:default_t:s0 index.html
[root@apache website]#
我们通过ll命令的-Z参数进行查看,很明显就看到了不同。(-Z参数专门用于查看SELinux域相关设置)
可以看到在文件上设置的SELinux安全上下文是由用户段、角色段以及类型段等多个信息项共同组成的。以上示例中,用户段system_u代表系统进程的身份,角色段object_r代表文件目录的角色, 类型段httpd_sys_content_t代表网站服务的系统文件。
搞清楚区别后,我们直接用前边讲解的semanage命令添加SELinux安全上下文即可,使其目录及里边的所有文件能够被httpd服务程序访问到
[root@apache website]# ll -Z /var/www/html/
-rw-r--r--. root root unconfined_u:object_r:httpd_sys_content_t:s0 index.html
[root@apache website]# ll -Z /website/
-rw-r--r--. root root unconfined_u:object_r:default_t:s0 index.html
[root@apache website]# semanage fcontext -a -t httpd_sys_content_t /website
[root@apache website]# semanage fcontext -a -t httpd_sys_content_t /website/*
[root@apache website]# ll -Z /website/
-rw-r--r--. root root unconfined_u:object_r:default_t:s0 index.html
[root@apache website]# restorecon -Rv /website/
restorecon reset /website context unconfined_u:object_r:default_t:s0->unconfined_u:object_r:httpd_sys_content_t:s0
restorecon reset /website/index.html context unconfined_u:object_r:default_t:s0->unconfined_u:object_r:httpd_sys_content_t:s0
[root@apache website]# ll -Z /website/
-rw-r--r--. root root unconfined_u:object_r:httpd_sys_content_t:s0 index.html
[root@apache website]#
需要注意的是,设置上下文值后并非立即生效,还需要执行restorecon才会生效,过程如上,请自行体验。
经过这样设置后,就可以正常访问了。
本案例演示了SELinux上下文对资源的限制导致的web不能访问,以及设置上下文值。
2.4 Apache案例2:用户个人主页功能
上一个案例演示了SELinux上下文的设置,本案例再通过Apache的个人用户主页功能来演示SELinux域的设置。
假设有这样有一个需求:需要为Linux每一位系统用户建立一个独立的网站。我们该怎么做呢?
方法有很多,httpd服务程序提供的个人用户主页功能完全可以实现这个需求。它可以让系统内所有的用户在自己的家目录中管理个人的网站,而且访问起来也非常容易。
步骤如下:
2.4.1 开启个人主页功能
个人用户主页功能配置文件为:/etc/httpd/conf.d/userdir.conf 。主要修改2处:注释掉UserDir disabled使其开启个人主页功能,同时设置个人网站目录,取消UserDir public_html 前的注释即可。
[root@apache website]# vim /etc/httpd/conf.d/userdir.conf
2.4.2 创建网站目录及文件
在用户家目录中建立用于保存网站数据的目录及首页面文件。
[root@apache website]# useradd heima
[root@apache website]# echo "123456" | passwd --stdin heima
Changing password for user heima.
passwd: all authentication tokens updated successfully.
[root@apache website]# su - heima
[heima@apache ~]$ ls
[heima@apache ~]$ pwd
/home/heima
[heima@apache ~]$ mkdir public_html
[heima@apache ~]$ echo "this is heima's website">public_html/index.html
[heima@apache ~]$ ll public_html/
total 4
-rwxrwxr-x. 1 heima heima 24 Feb 10 16:11 index.html
[heima@apache ~]$ chmod -Rf 775 /home/heima/
另外,还需要把家目录的权限修改为755,保证其他人也有权限读取里面的内容。
2.4.3 设置SELinux安全域策略
文章最开始已经设置了防火墙,此时我们大致一想,应该是可以访问个人网页了吧。我们先切换到root用户,重启httpd服务,然后进行访问,结果很不幸,这次又提示权限不足。
[root@apache ~]# systemctl restart httpd
访问地址为ip/~用户名,其中的波浪号是必需的,而且网址、波浪号、用户名之间没有空格。
我们回想一下,这个现象和案例1遇到的症状有几分相似,当时是因为我们新建了一个目录/website,而没有设置SELinux上下文所导致。那这次是不是也是因为SELinux的上下文导致呢?
很显然不是,httpd服务程序在提供个人用户主页功能时,该用户的网站数据目录本身就应该是存放到与这位用户对应的家目录中的,所以应该不需要修改家目录的 SELinux 安全上下文,如果你实在不放心,也可以执行如下命令验证:
[heima@apache ~]$ ll -Z /home/heima/
drwxrwxr-x. heima heima unconfined_u:object_r:httpd_user_content_t:s0 public_html
[heima@apache ~]$
对吧,很明显不是SELinux上下文导致,因为httpd默认就给用户目录添加了上下文值。
那是什么原因呢,我们还是按照之前的方法来排查,先把SELinux关闭,然后在此访问。结果可以正常访问了,那说明就是SELinux的问题,再回想我们前面提到的SELinux通过上下文和域这两个方面进行限制和保护。既然上下文没问题,因此自然而然,我们应该知道这就是SELinux域导致的。
Linux 域确保服务程序不能执行违规的操作,只能本本分分地为用户提供服务。httpd 服务中突然开启的这项个人用 户主页功能到底有没有被SELinux域默认允许呢?
给个人主页相关的域规则项为:httpd_enable_homedirs,如果不知道记住即可。我们看下他的状态确实为off,因此将其改为on就可以了,切换到root用户进行操作
[root@apache ~]# getsebool httpd_enable_homedirs
httpd_enable_homedirs --> off
[root@apache ~]# setsebool httpd_enable_homedirs=on
[root@apache ~]#
此时,我们再次访问,即可正常访问了。
2.4.4 设置需要用户密码才能登陆
有时候我们不希望别人直接就可以访问个人网站,需要通过身份认证才能进行查看,这就需要在网站中添加口令功能来实现。
(1)生成密码数据库
[root@apache ~]# htpasswd -c /etc/httpd/passed heima
New password:
Re-type new password:
Adding password for user heima
[root@apache ~]#
注意,文件名任意取,在下一步中保持一致即可,-c参数表示第一次生成。设置密码为888888,以区别之前heima用户登录系统的密码123456,这样做的目的是为了区分说明不此处设置的密码不是用户登录系统的密码。
(2)修改配置文件
[root@apache ~]# vim /etc/httpd/conf.d/userdir.conf
<Directory "/home/*/public_html">
# AllowOverride FileInfo AuthConfig Limit Indexes
# Options MultiViews Indexes SymLinksIfOwnerMatch IncludesNoExec
# Require method GET POST OPTIONS
AllowOverride all
authuserfile "/etc/htppd/passed"
authname "heima website"
authtype basic
require user heima
Require method GET POST OPTIONS
</Directory>
将文末的内容注释并按如下进行修改即可
修改完成后,重启httpd
[root@apache ~]# systemctl restart httpd
再次访问,就要求输入密码了。
此时输入用户名heima,以及刚才创建的888888密码(注意不是heima登录系统的密码)即可登录网站。
这个案例演示了SELinux域对进程的控制,以及如何对其进行设置。
通过案例1和案例2,不仅完整演示了Apache常用操作,还特别演示了生产级别的SELinux域和上下文的设置。
下一篇文章继续演示Apache的虚拟主机功能和访问控制的实现方法。