Linux就该这么学_第10章 使用Apache服务器部署静态网站

本章讲解了如下内容:

  • 网站服务程序;
  • 配置服务文件参数;
  • SELinux安全子系统;
  • 个人用户主面功能
  • 虚拟主机功能
  • Apache的访问控制

本章先向读者科普什么是 Web 服务程序,以及 Web 服务程序的用处,然后通过对比当前
主流的 Web 服务程序来使读者更好地理解其各自的优势及特点,最后通过对 httpd 服务程序
中“全局配置参数”、“区域配置参数”及“注释信息”的理论讲解和实战部署,确保读者学会
Web 服务程序的配置方法,并真正掌握在 Linux 系统中配置服务的技巧。
刘遄老师还会在本章讲解 SELinux 服务的作用、三种工作模式以及策略管理方法,确
保读者掌握 SELinux 域和 SELinux 安全上下文的配置方法,并依次完成多个基于 httpd 服
务程序实用功能的部署实验,其中包括 httpd 服务程序的基本部署、个人用户主页功能和
口令加密认证方式的实现,以及分别基于 IP 地址、主机名(域名)、端口号部署虚拟主机
网站功能。

10.1 网站服务程序

1970 年,作为互联网前身的 ARPANET(阿帕网)已初具雏形,并开始向非军用部门开
放,许多大学和商业部门开始接入。虽然彼时阿帕网的规模(只有 4 台主机联网运行)还不
如现在的局域网成熟,但是它依然为网络技术的进步打下了扎实的基础。
想必我们大多数人都是通过访问网站而开始接触互联网的吧。我们平时访问的网站服务
就是 Web 网络服务,一般是指允许用户通过浏览器访问到互联网中各种资源的服务。如图 10-
1 所示,Web 网络服务是一种被动访问的服务程序,即只有接收到互联网中其他主机发出的
请求后才会响应,最终用于提供服务程序的 Web 服务器会通过 HTTP(超文本传输协议)或
HTTPS(安全超文本传输协议)把请求的内容传送给用户。
目前能够提供 Web 网络服务的程序有 IIS、Nginx 和 Apache 等。其中,IIS(Internet 
Information Services,互联网信息服务)是 Windows 系统中默认的 Web 服务程序,这是一款
图形化的网站管理工具,不仅可以提供 Web 网站服务,还可以提供 FTP、NMTP、SMTP 等服务。但是,IIS 只能在 Windows 系统中使用,而我们这本书的名字是《Linux 就该这么学》,
所以它也就不在我们的学习范围之内了。

2004 年 10 月 4 日,为俄罗斯知名门户站点而开发的 Web 服务程序 Nginx 横空出世。
Nginx 程序作为一款轻量级的网站服务软件,因其稳定性和丰富的功能而快速占领服务器市
场,但 Nginx 最被认可的还当是系统资源消耗低且并发能力强,因此得到了国内诸如新浪、
网易、腾讯等门户站的青睐。本书将在第 20 章讲解 Nginx 服务程序。
Apache 程序是目前拥有很高市场占有率的 Web 服务程序之一,其跨平台和安全性广
泛被认可且拥有快速、可靠、简单的 API 扩展。图 10-2 所示为 Apache 服务基金会的著名
Logo,它的名字取自美国印第安人的土著语,寓意着拥有高超的作战策略和无穷的耐性。
Apache 服务程序可以运行在 Linux 系统、UNIX 系统甚至是 Windows 系统中,支持基于
IP、域名及端口号的虚拟主机功能,支持多种认证方式,集成有代理服务器模块、安全
Socket 层(SSL),能够实时监视服务状态与定制日志消息,并有着各类丰富的模块支持。

总结来说,Nginx 服务程序作为后起之秀,已经通过自身的优势与努力赢得了大批站长
的信赖。本书配套的在线学习站点 http://www.linuxprobe.com 就是基于 Nginx 服务程序部署
的,不得不说 Nginx 也真的很棒!
但是,Apache 程序作为老牌的 Web 服务程序,一方面在 Web 服务器软件市场具有相当高的
占有率,另一方面 Apache 也是 RHEL 7 系统中默认的 Web 服务程序,而且还是 RHCSA 和 RHCE
认证考试的必考内容,因此无论从实际应用角度还是从应对红帽认证考试的角度,我们都有必要
好好学习 Apache 服务程序的部署,并深入挖掘其可用的丰富功能。

10.2 配置服务文件参数

需要提醒大家的是,前文介绍的 httpd 服务程序的安装和运行,仅仅是 httpd 服务程序的
一些皮毛,我们依然有很长的道路要走。在 Linux 系统中配置服务,其实就是修改服务的配
置文件,因此,还需要知道这些配置文件的所在位置以及用途,httpd 服务程序的主要配置文
件及存放位置如表 10-1 所示。

大家在首次打开 httpd 服务程序的主配置文件,可能会吓一跳—竟然有 353 行!这得至
少需要一周的时间才能看完吧?!但是,大家只要仔细观看就会发现刘遄老师在这里调皮了。
因为在这个配置文件中,所有以井号(#)开始的行都是注释行,其目的是对 httpd 服务程序
的功能或某一行参数进行介绍,我们不需要逐行研究这些内容。
在 httpd 服务程序的主配置文件中,存在三种类型的信息:注释行信息、全局配置、区域配置,如图 10-4 所示。

各位读者在学习第 4 章时已经接触过注释信息,因此这里主要讲解全局配置参数与区域
配置参数的区别。顾名思义,全局配置参数就是一种全局性的配置参数,可作用于对所有的
子站点,既保证了子站点的正常访问,也有效减少了频繁写入重复参数的工作量。区域配置
参数则是单独针对于每个独立的子站点进行设置的。就像在大学食堂里面打饭,食堂负责打
饭的阿姨先给每位同学来一碗标准大小的白饭(全局配置),然后再根据每位同学的具体要求
盛放他们想吃的菜(区域配置)。在 httpd 服务程序主配置文件中,最为常用的参数如表 10-2
所示。

 从表 10-2 中可知,DocumentRoot 参数用于定义网站数据的保存路径,其参数的默认值
是把网站数据存放到/var/www/html 目录中;而当前网站普遍的首页面名称是 index.html,因
此可以向/var/www/html 目录中写入一个文件,替换掉 httpd 服务程序的默认首页面,该操作

会立即生效。在执行上述操作之后,再在 Firefox 浏览器中刷新 httpd 服务程序,可以看到该程序的首
页面内容已经发生了改变,如图 10-5 所示。

[root@localhost ~]# echo "Welcome To LinuxProbe.com" > /var/www/html/index.html

图 10-5 httpd 服务程序的首页面内容已经被修改

大家在完成这个实验之后,是不是信心爆棚了呢?!在默认情况下,网站数据是保存在
/var/www/html 目录中,而如果想把保存网站数据的目录修改为/home/wwwroot 目录,该怎么
操作呢?且看下文。

第1步:建立网站数据的保存目录,并创建首页文件。

[root@localhost ~]# mkdir /home/wwwroot
[root@localhost ~]# echo "The New Web Directory" > /home/wwwroot/index.html
[root@localhost ~]# 

第2步:打开 httpd 服务程序的主配置文件,将约第 119 行用于定义网站数据保存路径的
参数 DocumentRoot 修改为/home/wwwroot,同时还需要将约第 124 行用于定义目录权限的参
数 Directory 后面的路径也修改为/home/wwwroot。配置文件修改完毕后即可保存并退出。

[root@linuxprobe ~]# vim /etc/httpd/conf/httpd.conf
………………省略部分输出信息………………
113
114 #
115 # DocumentRoot: The directory out of which you will serve your
116 # documents. By default, all requests are taken from this directory, but
117 # symbolic links and aliases may be used to point to other locations.
118 #
119 DocumentRoot "/home/wwwroot"
120
121 #
122 # Relax access to content within /var/www.
123 #
124 <Directory "/home/wwwroot">
125 AllowOverride None
126 # Allow open access:
127 Require all granted
128 </Directory>
………………省略部分输出信息………………
[root@linuxprobe ~]#

第3部::重新启动 httpd 服务程序并验证效果,浏览器刷新页面后的内容如图 10-6 所示。

奇怪!为什么看到了 httpd 服务程序的默认首页面?按理来说,只有在网站的首页面文件不存
在或者用户权限不足时,才显示 httpd 服务程序的默认首页面。我们在尝试访问
http://127.0.0.1/index.html 页面时,竟然发现页面中显示“Forbidden,You don't have permission 
to access /index.html on this server.”。而这一切正是 SELinux 在捣鬼。

[root@linuxprobe ~]# systemctl restart httpd

 图 10-6 httpd 服务程序的默认首页面

10.3  SELinux安全子系统

SELinux(Security-Enhanced Linux)是美国国家安全局在 Linux 开源社区的帮助下开发的
一个强制访问控制(MAC,Mandatory Access Control)的安全子系统。RHEL 7 系统使用 SELinux
技术的目的是为了让各个服务进程都受到约束,使其仅获取到本应获取的资源。
例如,您在自己的电脑上下载了一个美图软件,当您全神贯注地使用它给照片进行美颜
的时候,它却在后台默默监听着浏览器中输入的密码信息,而这显然不应该是它应做的事情
(哪怕是访问电脑中的图片资源,都情有可原)。SELinux 安全子系统就是为了杜绝此类情况而
设计的,它能够从多方面监控违法行为:对服务程序的功能进行限制(SELinux 域限制可以确
保服务程序做不了出格的事情);对文件资源的访问限制(SELinux 安全上下文确保文件资源
只能被其所属的服务程序进行访问)。
刘遄老师经常会把“SELinux 域”和“SELinux 安全上下文”称为是 Linux 系统中的双保
险,系统内的服务程序只能规规矩矩地拿到自己所应该获取的资源,这样即便黑客入侵了系
统,也无法利用系统内的服务程序进行越权操作。但是,非常可惜的是,SELinux 服务比较复
杂,配置难度也很大,加之很多运维人员对这项技术理解不深,从而导致很多服务器在部署
好 Linux 系统后直接将 SELinux 禁用了;这绝对不是明智的选择。
SELinux 服务有三种配置模式,具体如下。

➢ enforcing:强制启用安全策略模式,将拦截服务的不合法请求。
➢ permissive:遇到服务越权访问时,只发出警告而不强制拦截。
➢ disabled:对于越权的行为不警告也不拦截。

本书中的所有实验都是在强制启用安全策略模式下进行的,虽然在禁用 SELinux 服务后
确实能够减少报错几率,但这在生产环境中相当不推荐。建议大家检查一下自己的系统,查
看 SELinux 服务主配置文件中定义的默认状态。如果是 permissive 或 disabled,建议赶紧修改
为 enforcing。

[root@linuxprobe ~]# vim /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

SELinux 服务的主配置文件中,定义的是 SELinux 的默认运行状态,可以将其理解为系
统重启后的状态,因此它不会在更改后立即生效。可以使用 getenforce 命令获得当前 SELinux
服务的运行模式:

[root@linuxprobe ~]# getenforce
Enforcing

为了确认图 10-6 所示的结果确实是因为 SELinux 而导致的,可以用 setenforce [0|1]命令
修改 SELinux 当前的运行模式(0 为禁用,1 为启用)。注意,这种修改只是临时的,在系统
重启后就会失效:

[root@linuxprobe ~]# setenforce 0
[root@linuxprobe ~]# getenforce
Permissive

再次刷新网页,就会看到正常的网页内容了,如图 10-7 所示。可见,问题确实是出在了
SELinux 服务上面。

图 10-7 页面内容按照预期显示

现在,我们来回忆一下前面的操作中到底是哪里出问题了呢?
httpd 服务程序的功能是允许用户访问网站内容,因此 SELinux 肯定会默认放行用户对网站的请求操作。但是,我们将网站数据的默认保存目录修改为了/home/wwwroot,而这就产生
问题了。在 6.1 小节中讲到,/home 目录是用来存放普通用户的家目录数据的,而现在,httpd
提供的网站服务却要去获取普通用户家目录中的数据了,这显然违反了 SELinux 的监管原则。
现在,我们把 SELinux 服务恢复到强制启用安全策略模式,然后分别查看原始网站数据
的保存目录与当前网站数据的保存目录是否拥有不同的 SELinux 安全上下文值:

[root@linuxprobe ~]# setenforce 1
[root@linuxprobe ~]# ls -Zd /var/www/html
drwxr-xr-x. root root system_u:object_r:httpd_sys_content_t:s0 /var/www/html
[root@linuxprobe ~]# ls -Zd /home/wwwroot
drwxrwxrwx. root root unconfined_u:object_r:home_root_t:s0 /home/wwwroot

在文件上设置的 SELinux 安全上下文是由用户段、角色段以及类型段等多个信息项共同
组成的。其中,用户段 system_u 代表系统进程的身份,角色段 object_r 代表文件目录的角色,
类型段 httpd_sys_content_t 代表网站服务的系统文件。由于 SELinux 服务实在太过复杂,现在
大家只需要简单熟悉 SELinux 服务的作用就可以,刘遄老师未来会在本书的进阶篇中单独拿
出一个章节仔细讲解 SELinux 服务。
针对当前这种情况,我们只需要使用 semanage 命令,将当前网站目录/home/wwwroot 的
SELinux 安全上下文修改为跟原始网站目录的一样就可以了。

10.3.1 semanage命令

semanage 命令用于管理 SELinux 的策略,格式为“semanage [选项] [文件]”。
SELinux 服务极大地提升了 Linux 系统的安全性,将用户权限牢牢地锁在笼子里。
semanage 命令不仅能够像传统 chcon 命令那样—设置文件、目录的策略,还可以管理网络
端口、消息接口(这些新特性将在本章后文中涵盖)。使用 semanage 命令时,经常用到的几个
参数及其功能如下所示:
➢ -l 参数用于查询;
➢ -a 参数用于添加;
➢ -m 参数用于修改;
➢ -d 参数用于删除。
例如,可以向新的网站数据目录中新添加一条 SELinux 安全上下文,让这个目录以及里
面的所有文件能够被 httpd 服务程序所访问到:

[root@localhost ~]# semanage fcontext -a -t httpd_sys_content_t /home/wwwroot
[root@localhost ~]# semanage fcontext -a -t httpd_sys_content_t /home/wwwroot/*

注意,执行上述设置之后,还无法立即访问网站,还需要使用 restorecon 命令将设置好的
SELinux 安全上下文立即生效。在使用 restorecon 命令时,可以加上-Rv 参数对指定的目录进
行递归操作,以及显示 SELinux 安全上下文的修改过程。最后,再次刷新页面,就可以正常
看到网页内容了,结果如图 10-8 所示。

[root@localhost ~]# restorecon -Rv /home/wwwroot/
restorecon reset /home/wwwroot context unconfined_u:object_r:home_root_t:s0->unconfined_u:object_r:httpd_sys_content_t:s0
restorecon reset /home/wwwroot/index.html context unconfined_u:object_r:home_root_t:s0->unconfined_u:object_r:httpd_sys_content_t:s0

图 10-8 正常看到网页内容

真可谓是一波三折!原本认为只要把 httpd 服务程序配置妥当就可以大功告成,结果却反
复受到了 SELinux 安全上下文的限制。所以,建议大家在配置 httpd 服务程序时,一定要细
心、耐心。一旦成功配妥 httpd 服务程序之后,就会发现 SELinux 服务并没有那么难。

 10.4 个人用户主页功能

如果想在系统中为每位用户建立一个独立的网站,通常的方法是基于虚拟网站主机功能
来部署多个网站。但这个工作会让管理员苦不堪言(尤其是用户数量很庞大时),而且在用户
自行管理网站时,还会碰到各种权限限制,需要为此做很多额外的工作。其实,httpd 服务程
序提供的个人用户主页功能完全可以以胜任这个工作。该功能可以让系统内所有的用户在自
己的家目录中管理个人的网站,而且访问起来也非常容易。

第1步:在 httpd 服务程序中,默认没有开启个人用户主页功能。为此,我们需要编辑下
面的配置文件,然后在第 17 行的 UserDir disabled 参数前面加上井号(#),表示让 httpd 服务
程序开启个人用户主页功能;同时再把第 24 行的 UserDir public_html 参数前面的井号(#)去
掉(UserDir 参数表示网站数据在用户家目录中的保存目录名称,即 public_html 目录)。最后,
在修改完毕后记得保存。

第2步:在用户家目录中建立用于保存网站数据的目录及首页面文件。另外,还需要把
家目录的权限修改为 755,保证其他人也有权限读取里面的内容。

[root@localhost ~]# su - jingpan
上一次登录:一 10月 15 17:06:28 CST 2018pts/0 上
[jingpan@localhost ~]$ mkdir public_html
[jingpan@localhost ~]$ echo "This is linuxprob's website" > public_html/index.html
[jingpan@localhost ~]$ echo "This is jingpan's website" > public_html/index.html
[jingpan@localhost ~]$ chmod -Rf 755 /home/jingpan

第3步:重新启动 httpd 服务程序,在浏览器的地址栏中输入网址,其格式为“网址/~用
户名”(其中的波浪号是必需的,而且网址、波浪号、用户名之间没有空格),从理论上来讲就
可以看到用户的个人网站了。不出所料的是,系统显示报错页面,如图 10-9 所示。这一定还
是 SELinux 惹的祸。

图 10-9 禁止访问用户的个人网站

第4步:思考这次报错的原因是什么。httpd 服务程序在提供个人用户主页功能时,该用
户的网站数据目录本身就应该是存放到与这位用户对应的家目录中的,所以应该不需要修改
家目录的 SELinux 安全上下文。但是,前文还讲到了 Linux 域的概念。Linux 域确保服务程序
不能执行违规的操作,只能本本分分地为用户提供服务。httpd 服务中突然开启的这项个人用
户主页功能到底有没有被 SELinux 域默认允许呢?

接下来使用 getsebool 命令查询并过滤出所有与 HTTP 协议相关的安全策略。其中,off 为
禁止状态,on 为允许状态。

[root@localhost jingpan]# getsebool -a | grep http
httpd_anon_write --> off
httpd_builtin_scripting --> on
httpd_can_check_spam --> off
httpd_can_connect_ftp --> off
httpd_can_connect_ldap --> off
httpd_can_connect_mythtv --> off
httpd_can_connect_zabbix --> off
httpd_can_network_connect --> off
httpd_can_network_connect_cobbler --> off
httpd_can_network_connect_db --> off
httpd_can_network_memcache --> off
httpd_can_network_relay --> off
httpd_can_sendmail --> off
httpd_dbus_avahi --> off
httpd_dbus_sssd --> off
httpd_dontaudit_search_dirs --> off
httpd_enable_cgi --> on
httpd_enable_ftp_server --> off
httpd_enable_homedirs --> off
httpd_execmem --> off
httpd_graceful_shutdown --> on
httpd_manage_ipa --> off
httpd_mod_auth_ntlm_winbind --> off
httpd_mod_auth_pam --> off
httpd_read_user_content --> off
httpd_run_ipa --> off
httpd_run_preupgrade --> off
httpd_run_stickshift --> off
httpd_serve_cobbler_files --> off
httpd_setrlimit --> off
httpd_ssi_exec --> off
httpd_sys_script_anon_write --> off
httpd_tmp_exec --> off
httpd_tty_comm --> off
httpd_unified --> off
httpd_use_cifs --> off
httpd_use_fusefs --> off
httpd_use_gpg --> off
httpd_use_nfs --> off
httpd_use_openstack --> off
httpd_use_sasl --> off
httpd_verify_dns --> off
named_tcp_bind_http_port --> off
prosody_bind_http_port --> off

面对如此多的 SELinux 域安全策略规则,实在没有必要逐个理解它们,我们只要能通过
名字大致猜测出相关的策略用途就足够了。比如,想要开启 httpd 服务的个人用户主页功能,
那么用到的 SELinux 域安全策略应该是 httpd_enable_homedirs 吧?大致确定后就可以用
setsebool 命令来修改 SELinux 策略中各条规则的布尔值了。大家一定要记得在 setsebool 命令
后面加上-P 参数,让修改后的 SELinux 策略规则永久生效且立即生效。随后刷新网页,其效
果如图 10-10 所示。

[root@linuxprobe ~]# setsebool -P httpd_enable_homedirs=on

图 10-10 正常看到个人用户主页面中的内容

有时,网站的拥有者并不希望直接将网页内容显示出来,只想让通过身份验证的用户访
客看到里面的内容,这时就可以在网站中添加口令功能了。

第1步:先使用htpasswd命令生成密码数据库。-c 参数表示第一次生成;后面再分
别添加密码数据库的存放文件,以及验证要用到的用户名称(该用户不必是系统中已有的
本地账户)。

[root@linuxprobe ~]# htpasswd -c /etc/httpd/passwd linuxprobe
New password:
Re-type new password:
Adding password for user linuxprobe

第2步:编辑个人用户主页功能的配置文件。把第 31~35 行的参数信息修改成下列内
容,其中井号(#)开头的内容为刘遄老师添加的注释信息,可将其忽略。随后保存并退出配
置文件,重启 httpd 服务程序即可生效。

[root@linuxprobe ~]# vim /etc/httpd/conf.d/userdir.conf
27 #
28 # Control access to UserDir directories. The following is an example
29 # for a site where these directories are restricted to read-only.
30 #
31 <Directory "/home/*/public_html">
32 AllowOverride all
#刚刚生成出来的密码验证文件保存路径
33 authuserfile "/etc/httpd/passwd"
#当用户尝试访问个人用户网站时的提示信息
34 authname "My privately website"
35 authtype basic
#用户进行账户密码登录时需要验证的用户名称
36 require user linuxprobe
37 </Directory>
[root@linuxprobe ~]# systemctl restart httpd

此后,当用户再想访问某个用户的个人网站时,就必须要输入账户和密码才能正常访问
了。另外,验证时使用的账户和密码是用 htpasswd 命令生成的专门用于网站登录的口令密码,
而不是系统中的用户密码,请不要搞错了。登录界面如图 10-11 所示。

图 10-11 网站提示需要输入账户和密码才能访问

10.5 虚拟主机功能

如果每台运行 Linux 系统的服务器上只能运行一个网站,那么人气低、流量小的草
根站长就要被迫承担着高昂的服务器租赁费用了,这显然也会造成硬件资源的浪费。在
虚拟专用服务器(Virtual Private Server,VPS)与云计算技术诞生以前,IDC 服务供应商
为了能够更充分地利用服务器资源,同时也为了降低购买门槛,于是纷纷启用了虚拟主
机功能。
利用虚拟主机功能,可以把一台处于运行状态的物理服务器分割成多个“虚拟的服
务器”。但是,该技术无法实现目前云主机技术的硬件资源隔离,让这些虚拟的服务器共
同使用物理服务器的硬件资源,供应商只能限制硬盘的使用空间大小。出于各种考虑的
因素(主要是价格低廉),目前依然有很多企业或个人站长在使用虚拟主机的形式来部署
网站。
Apache 的虚拟主机功能是服务器基于用户请求的不同 IP 地址、主机域名或端口号,实
现提供多个网站同时为外部提供访问服务的技术,如图 10-12 所示,用户请求的资源不同,最终获取到的网页内容也各不相同。如果大家之前没有做过网站,可能不太理解其中的原理,
等一会儿搭建出实验环境并看到实验效果之后,您一定就会明白了。

 10.5.1 基于 IP 地址

如果一台服务器有多个 IP 地址,而且每个 IP 地址与服务器上部署的每个网站一一对应,
这样当用户请求访问不同的 IP 地址时,会访问到不同网站的页面资源。而且,每个网站都有
一个独立的 IP 地址,对搜索引擎优化也大有裨益。因此以这种方式提供虚拟网站主机功能不
仅最常见,也受到了网站站长的欢迎(尤其是草根站长)。
刘遄老师在第 4 章和第 9 章分别讲解了用于配置网络的两种方法,大家在实验中和工作
中可随意选择。就当前的实验来讲,需要配置的 IP 地址如图 10-13 所示。在配置完毕并重启
网卡服务之后,记得检查网络的连通性,确保三个 IP 地址均可正常访问,如图 10-14 所示(这
很重要,一定要测试好,然后再进行下一步!)。

图 10-13 使用 nmtui 命令配置网络参数

第1步:分别在/home/wwwroot 中创建用于保存不同网站数据的 3 个目录,并向其中分
别写入网站的首页文件。每个首页文件中应有明确区分不同网站内容的信息,方便我们稍后
能更直观地检查效果。

[root@localhost ~]# mkdir -p /home/wwwroot/3
[root@localhost ~]# mkdir -p /home/wwwroot/5
[root@localhost ~]# mkdir -p /home/wwwroot/6
[root@localhost ~]# echo "IP:192.168.1.3" > /home/wwwroot/3/index.html
[root@localhost ~]# echo "IP:192.168.1.5" > /home/wwwroot/5/index.html
[root@localhost ~]# echo "IP:192.168.1.6" > /home/wwwroot/6/index.html
[root@localhost ~]# 

第2步:在 httpd 服务的配置文件中大约 113 行处开始,分别追加写入三个基于 IP 地址的虚
拟主机网站参数,然后保存并退出。记得需要重启 httpd 服务,这些配置才生效。

#
<VirtualHost 192.168.1.3>
DocumentRoot /home/wwwroot/3
ServerName www.jingpan.site
<Directory /home/wwwroot/3 >
AllowOverride None
Require all granted
</Directory>
</VirtualHost>

<VirtualHost 192.168.1.5>
DocumentRoot /home/wwwroot/5
ServerName www.jingpan.site
<Directory /home/wwwroot/5 >
AllowOverride None
Require all granted
</Directory>
</VirtualHost>

<VirtualHost 192.168.1.6>
DocumentRoot /home/wwwroot/6
ServerName www.jingpan.site
<Directory /home/wwwroot/6 >
AllowOverride None
Require all granted
</Directory>
</VirtualHost>
#
# DocumentRoot: The directory out of which you will serve your
# documents. By default, all requests are taken from this directory, but
"/etc/httpd/conf/httpd.conf" 379L, 12312C written
[root@localhost ~]# httpd -t
AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using ::1. Set the 'ServerName' directive globally to suppress this message
Syntax OK
[root@localhost ~]# systemctl restart httpd

 图 10-15 基于不同的 IP 地址访问虚拟主机网站

10.5.2 基于主机域名

当服务器无法为每个网站都分配一个独立 IP 地址的时候,可以尝试让 Apache 自动识别
用户请求的域名,从而根据不同的域名请求来传输不同的内容。在这种情况下的配置更加简
单,只需要保证位于生产环境中的服务器上有一个可用的 IP 地址(这里以 192.168.10.10 为
例)就可以了。由于当前还没有介绍如何配置 DNS 解析服务,因此需要手工定义 IP 地址与
域名之间的对应关系。/etc/hosts 是 Linux 系统中用于强制把某个主机域名解析到指定 IP 地址
的配置文件。简单来说,只要这个文件配置正确,即使网卡参数中没有 DNS 信息也依然能够
将域名解析为某个 IP 地址。

第1 步:手工定义 IP 地址与域名之间对应关系的配置文件,保存并退出后会立即生效。
可以通过分别 ping 这些域名来验证域名是否已经成功解析为 IP 地址。

[root@localhost ~]# vi /etc/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.1.3 www.jingpan.site bbs.jingpan.site tech.jingpan.site

"/etc/hosts" 3L, 222C written
[root@localhost ~]# ping -c 4 www.jingpan.site
PING www.jingpan.site (192.168.1.3) 56(84) bytes of data.
64 bytes from www.jingpan.site (192.168.1.3): icmp_seq=1 ttl=64 time=0.037 ms
64 bytes from www.jingpan.site (192.168.1.3): icmp_seq=2 ttl=64 time=0.021 ms
64 bytes from www.jingpan.site (192.168.1.3): icmp_seq=3 ttl=64 time=0.017 ms
64 bytes from www.jingpan.site (192.168.1.3): icmp_seq=4 ttl=64 time=0.031 ms

--- www.jingpan.site ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3000ms
rtt min/avg/max/mdev = 0.017/0.026/0.037/0.009 ms

第2步:分别在/home/wwwroot 中创建用于保存不同网站数据的三个目录,并向其中分
别写入网站的首页文件。每个首页文件中应有明确区分不同网站内容的信息,方便我们稍后
能更直观地检查效果。

[root@localhost ~]# mkdir -p /home/wwwroot/www
[root@localhost ~]# mkdir -p /home/wwwroot/bbs
[root@localhost ~]# mkdir -p /home/wwwroot/tech
[root@localhost ~]# echo "WWW.jingpan.stie" > /home/wwwroot/www/index.html
[root@localhost ~]# echo "bbs.jingpan.stie" > /home/wwwroot/bbs/index.html
[root@localhost ~]# echo "tech.jingpan.stie" > /home/wwwroot/tech/index.html

第3步:在 httpd 服务的配置文件中大约 113 行处开始,分别追加写入三个基于主机名的
虚拟主机网站参数,然后保存并退出。记得需要重启 httpd 服务,这些配置才生效。

<VirtualHost 192.168.1.3>
DocumentRoot /home/wwwroot/www
ServerName www.jingpan.site
<Directory /home/wwwroot/www >
AllowOverride None
Require all granted
</Directory>
</VirtualHost>

<VirtualHost 192.168.1.3>
DocumentRoot /home/wwwroot/bbs
ServerName bbs.jingpan.site
<Directory /home/wwwroot/bbs >
AllowOverride None
Require all granted
</Directory>
</VirtualHost>

<VirtualHost 192.168.1.3>
DocumentRoot /home/wwwroot/tech
ServerName tech.jingpan.site
<Directory /home/wwwroot/tech >
AllowOverride None
Require all granted
</Directory>
</VirtualHost>

图 10-16 基于主机域名访问虚拟主机网站

10.5.3 基于端口号

基于端口号的虚拟主机功能可以让用户通过指定的端口号来访问服务器上的网站资源。
在使用 Apache 配置虚拟网站主机功能时,基于端口号的配置方式是最复杂的。因此我们不仅
要考虑 httpd 服务程序的配置因素,还需要考虑到 SELinux 服务对新开设端口的监控。一般来
说,使用 80、443、8080 等端口号来提供网站访问服务是比较合理的,如果使用其他端口号
则会受到 SELinux 服务的限制。
在接下来的实验中,我们不但要考虑到目录上应用的 SELinux 安全上下文的限制,还需
要考虑 SELinux 域对 httpd 服务程序的管控。

第1 步:分别在/home/wwwroot 中创建用于保存不同网站数据的两个目录,并向其中分
别写入网站的首页文件。每个首页文件中应有明确区分不同网站内容的信息,方便我们稍后
能更直观地检查效果。

[root@localhost ~]# mkdir -p /home/wwwroot/6111
[root@localhost ~]# mkdir -p /home/wwwroot/6222
[root@localhost ~]# echo "port:6111" > /home/wwwroot/6111/index.html
[root@localhost ~]# echo "port:6222" > /home/wwwroot/6222/index.html

第2步:在 httpd 服务配置文件的第 43 行和第 44 行分别添加用于监听 6111 和 6222
端口的参数。

[root@linuxprobe ~]# vim /etc/httpd/conf/httpd.conf
………………省略部分输出信息………………
33 #
34 # Listen: Allows you to bind Apache to specific IP addresses and/or
35 # ports, instead of the default. See also the <VirtualHost>
36 # directive.
37 #
38 # Change this to Listen on specific IP addresses as shown below to
39 # prevent Apache from glomming onto all bound IP addresses.
40 #
41 #Listen 12.34.56.78:80
42 Listen 80
43 Listen 6111
44 Listen 6222
………………省略部分输出信息………………

第3步:在 httpd 服务的配置文件中大约 113 行处开始,分别追加写入两个基于端口号的
虚拟主机网站参数,然后保存并退出。记得需要重启 httpd 服务,这些配置才生效。
[root@localhost ~]# systemctl restart httpd
Job for httpd.service failed because the control process exited with error code. See "systemctl status httpd.service" and "journalctl -xe" for details.
[root@localhost ~]# systemctl status httpd.service
● httpd.service - The Apache HTTP Server
   Loaded: loaded (/usr/lib/systemd/system/httpd.service; enabled; vendor preset: disabled)
   Active: failed (Result: exit-code) since 二 2018-10-16 13:36:54 CST; 2s ago
     Docs: man:httpd(8)
           man:apachectl(8)
  Process: 4201 ExecStop=/bin/kill -WINCH ${MAINPID} (code=exited, status=1/FAILURE)
  Process: 2090 ExecReload=/usr/sbin/httpd $OPTIONS -k graceful (code=exited, status=0/SUCCESS)
  Process: 4199 ExecStart=/usr/sbin/httpd $OPTIONS -DFOREGROUND (code=exited, status=1/FAILURE)
 Main PID: 4199 (code=exited, status=1/FAILURE)

10月 16 13:36:54 localhost httpd[4199]: (13)Permission denied: AH00072: make_sock: could not bind to address [::]:6111
10月 16 13:36:54 localhost httpd[4199]: (13)Permission denied: AH00072: make_sock: could not bind to address 0.0.0.0:6111

10月 16 13:36:54 localhost httpd[4199]: no listening sockets available, shutting down
10月 16 13:36:54 localhost httpd[4199]: AH00015: Unable to open logs
10月 16 13:36:54 localhost systemd[1]: httpd.service: main process exited, code=exited, status=1/FAILURE
10月 16 13:36:54 localhost kill[4201]: kill: cannot find process ""
10月 16 13:36:54 localhost systemd[1]: httpd.service: control process exited, code=exited status=1
10月 16 13:36:54 localhost systemd[1]: Failed to start The Apache HTTP Server.
10月 16 13:36:54 localhost systemd[1]: Unit httpd.service entered failed state.
10月 16 13:36:54 localhost systemd[1]: httpd.service failed.
Hint: Some lines were ellipsized, use -l to show in full.

[root@localhost ~]# semanage port -l | grep http
http_cache_port_t              tcp      8080, 8118, 8123, 10001-10010
http_cache_port_t              udp      3130
http_port_t                    tcp      80, 81, 443, 488, 8008, 8009, 8443, 9000
pegasus_http_port_t            tcp      5988
pegasus_https_port_t           tcp      5989

第4步:SELinux 允许的与 HTTP 协议相关的端口号中默认没有包含 6111 和 6222,因此需要将这两个端口号手动添加进去。该操作会立即生效,而且在系统重启过后依然有效。设置
好后再重启 httpd 服务程序,然后就可以看到网页内容了,结果如图 10-17 所示。

[root@linuxprobe ~]# semanage port -a -t http_port_t -p tcp 6111
[root@linuxprobe ~]# semanage port -a -t http_port_t -p tcp 6222
[root@linuxprobe ~]# semanage port -l| grep http
http_cache_port_t tcp 8080, 8118, 8123, 10001-10010
http_cache_port_t udp 3130
http_port_t tcp 6222, 6111, 80, 81, 443, 488, 8008, 8009, 8443, 9000
pegasus_http_port_t tcp 5988
pegasus_https_port_t tcp 5989
[root@linuxprobe ~]# systemctl restart httpd

图 10-17 基于端口号访问虚拟主机网站

10.6 Apache 的访问控制

Apache 可以基于源主机名、源 IP 地址或源主机上的浏览器特征等信息对网站上的资源
进行访问控制。它通过 Allow 指令允许某个主机访问服务器上的网站资源,通过 Deny 指令实
现禁止访问。在允许或禁止访问网站资源时,还会用到 Order 指令,这个指令用来定义 Allow
或 Deny 指令起作用的顺序,其匹配原则是按照顺序进行匹配,若匹配成功则执行后面的默认
指令。比如“Order Allow, Deny”表示先将源主机与允许规则进行匹配,若匹配成功则允许访
问请求,反之则拒绝访问请求。

第1 步:先在服务器上的网站数据目录中新建一个子目录,并在这个子目录中创建一个
包含 Successful 单词的首页文件。

[root@linuxprobe ~]# mkdir /var/www/html/server
[root@linuxprobe ~]# echo "Successful" > /var/www/html/server/index.html

第2步:打开 httpd 服务的配置文件,在第 129 行后面添加下述规则来限制源主机的访
问。这段规则的含义是允许使用 Firefox 浏览器的主机访问服务器上的首页文件,除此之外的
所有请求都将被拒绝。使用 Firefox 浏览器的访问效果如图 10-18 所示。

<Directory "/var/www/html/server">
SetEnvIf User-Agent "Firefox" ff=1
Order allow,deny
Allow from env=ff
</Directory>

图 10-18 火狐浏览器成功访问

除了匹配源主机的浏览器特征之外,还可以通过匹配源主机的 IP 地址进行访问控制。例
如,我们只允许 IP 地址为 192.168.1..64 的主机访问网站资源,那么就可以在 httpd 服务配置
文件的第 129 行后面添加下述规则。这样在重启 httpd 服务程序后再用本机(即服务器,其 IP
地址为 192.168.1.3)来访问网站的首页面时就会提示访问被拒绝了,如图 10-19 所示。

图 10-19 因 IP 地址符合要求访问成功。

猜你喜欢

转载自blog.csdn.net/tjjingpan/article/details/83060381