《Linux就该这么学》培训笔记_ch10_使用Apache服务部署静态网站
文章最后会post上书本的笔记照片。
文章主要内容:
网站服务程序
网站的粗略定义:让用户能够通过浏览器访问到的服务器上的文档资源。
网站服务就是Web网络服务,一般是指允许用户通过浏览器访问到互联网中各种资源的服务。
Web网络服务是一种被动访问的服务程序,即只有接收到互联网中其他主机发出的请求后才会响应,最终用于提供服务程序的Web服务器会通过HTTP(超文本传输协议)或HTTPS(安全超文本传输协议)把请求的内容传送给用户。
常见能提供Web网络服务的程序:IIS(只能在Windows系统中使用)、Apache、Nginx等。
部署Apache程序:
1 yum install httpd #安装Apache服务程序(Apache服务的软件包名为httpd) 2 systemctl start httpd #启用httpd服务 3 systemctl enable httpd #加入开机启动项
用浏览器访问:127.0.0.1(本机)可以看到httpd服务程序的默认页面,当看到这个页面时,说明服务程序正常启动,但有以下可能性导致没有显示本应显示的网站内容:
- 权限不足
- 网站内没有数据
配置服务文件参数
httpd服务程序的主要配置文件及存放位置:
服务目录 | /etc/httpd |
主配置文件 | /etc/httpd/conf/httpd.conf |
网站数据目录 | /var/www/html |
访问日志 | /var/log/httpd/access_log |
错误日志 | /var/log/httpd/error_log |
在httpd服务程序的主配置文件中,存在三种类型的信息:注释行信息、全局配置、区域配置。全局配置参数与区域配置参数的区别:
- 全局配置:一种全局性的配置参数,可作用于对所有的子站点,既保证了子站点的正常访问,也有效减少了频繁写入重复参数的工作量。
- 区域配置:单独针对于每个独立的子站点进行设置。
在httpd服务程序主配置文件中,最为常用的参数最常用的参数以及用途描述:
ServerRoot | 服务目录 |
ServerAdmin | 管理员邮箱 |
User | 运行服务的用户 |
Group | 运行服务的用户组 |
ServerName | 网站服务器的域名 |
DocumentRoot | 网站数据目录 |
Listen | 监听的IP地址与端口号 |
DirectoryIndex | 默认的索引页页面 |
ErrorLog | 错误日志文件 |
CustomLog | 访问日志文件 |
Timeout | 网页超时时间,默认为300秒 |
DocumentRoot参数用于定义网站数据的保存路径,其参数的默认值是把网站数据存放到/var/www/html目录中;而当前网站普遍的首页面名称是index.html,因此可以向/var/www/html目录中写入名为index的html文件,替换掉httpd服务程序的默认首页面,该操作会立即生效。
实例:修改保存网站数据的目录。
1 #1.建立新的网站数据保存目录,并创建首页文件。 2 mkdir /home/wwwroot 3 echo "hello" > /home/wwwroot/index.html 4 #2.修改httpd服务程序主配置文件,把网站数据保存路径修改为/home/wwwroot 5 vim /etc/httpd/conf/httpd.conf 6 ... 7 119 DocumentRoot "/home/wwwroot" #用于定义网站数据保存路径的参数DocumentRoot修改为/home/wwwroot 8 ... 9 124 <Directory "home/wwwroot"> #用于定义目录权限的参数Directory后面的路径也修改为/home/wwwroot 10 ... 11 128 </Directory> 12 ... 13 #3.重启httpd服务验证效果,此时会发现因为权限不足导致出现的是httpd默认首页(SElinux的安全上下文). 14 systemctl restart httpd 15 #4.暂时禁用SElinux,发现可以看到正常的网页内容了。 16 setenforce 0
SELinux安全子系统
RHEL 7系统使用SELinux技术的目的是为了让各个服务进程都受到约束,使其仅获取到本应获取的资源。
SELinux安全子系统能够从多方面监控违法行为:对服务程序的功能进行限制(SELinux域限制可以确保服务程序做不了出格的事情);对文件资源的访问限制(SELinux安全上下文确保文件资源只能被其所属的服务程序进行访问)。
“SELinux域”和“SELinux安全上下文”是Linux系统中的双保险,系统内的服务程序只能规规矩矩地拿到自己所应该获取的资源,这样即便黑客入侵了系统,也无法利用系统内的服务程序进行越权操作。
SELinux服务有三种配置模式:
- enforcing:强制启用安全策略模式,将拦截服务的不合法请求。
- permissive:遇到服务越权访问时,只发出警告而不强制拦截。
- disabled:对于越权的行为不警告也不拦截。
虽然在禁用SELinux服务后确实能够减少报错几率,但这在生产环境中相当不推荐。
SELinux服务主配置文件:/etc/selinux/config。其中的SELINUX参数定义的就是SELinux的默认配置模式。注意其为系统重启后的状态,不会再更改后立即生效。
1 vim /etc/selinux/config 2 ... 3 SELINUX=enforcing 4 ...
查看和设置SELinux服务运行命令:
getenforce:查看当前SELinxu服务的运行模式
setenforce [0|1]:修改SELinux当前的运行模式(0禁用,1启用)。此修改是临时的,在系统重启后就会失效。
分析上面实例被SELinux拦截的原因:
httpd服务程序的功能是允许用户访问网站内容,因此SELinux会默认放行用户对网站的请求操作。但是,/home目录是用来存放普通用户的家目录数据的,而将网站数据的默认保存目录修改为了/home/wwwroot,导致httpd提供的网站服务要去获取普通用户家目录中的数据,这显然违反SELinux的监管原则。
semanage命令:用于管理SELinux的策略,格式:semanage [选项] [文件]。
semanage命令不仅能够像传统chcon命令那样—设置文件、目录的策略,还可以管理网络端口、消息接口。常用参数:
- -l:用于查询;
- -a:用于添加;
- -m:用于修改;
- -d:用于删除;
- -t:指定要想修改的值。
semanage命令没有递归功能,因此要先修改目录的安全上下文,再修改目录里所有文件的安全上下文。另外semanage命令修改好的配置不会立即生效。
restorecon命令:将设置好的SELinux安全上下文立即生效。格式: restorecon [选项] [指定目录或文件]。
常用参数:
- -R:对指定目录进行递归操作
- -v:显示SELinux安全上下文的修改过程
实例:解决上面实例被SELinux拦截的问题。
1 #1.把SELinux服务恢复到强制启用安全策略模式 2 setenforce 1 3 #2.分别查看原始网站数据的保存目录与当前网站数据的保存目录的SELinux安全上下文值 4 ls -Zd /var/www/html #SElinux安全上下文为httpd_sys_content_t 5 ls -Zd /home/wwwroot #SELinux安全上下文为home_root_t 6 #3.把当前网站数据保存目录的安全上下文设置成和原始网站数据保存目录的安全上下文一样 7 semanage fcontext -a -t httpd_sys_content_t /home/wwwroot #修改目录的安全上下文 8 semanage fcontext -a -t httpd_sys_content_t /home/wwwroot/* #修改目录里的所有文件的安全上下文 9 #4.使设置好的SELinux安全上下文立即生效 10 restorecon -Rv /home/wwwroot/
个人用户主页功能
如果想在系统中为每位用户建立一个独立的网站,若采用基于虚拟网站主机功能来部署多个网站的方法,会累死管理员,而且在用户自行管理网站时,还会碰到各种权限限制,费时费力。
httpd服务程序提供的个人用户主页功能可以让系统内所有的用户在自己的家目录中管理个人的网站,而且访问起来也非常容易。
- getsebool命令:搭配-a参数输出所有安全策略(off禁止,on允许)
- setsebool命令:修改SELinux策略中各条规则的布尔值。搭配-P参数使得修改后的SELinux策略规则立即且永久生效。
实例:实现个人用户主页功能。
1 #1.修改配置文件/etc/httpd/conf.d/userdir.conf ,让httpd服务程序开启个人用户主页功能。 2 vim /etc/httpd/conf.d/userdir.conf 3 ... 4 17 UserDir public_html #UserDir参数表示网站数据在用户家目录中的保存目录名称,即public_html目录 5 ... 6 31 <Directory "/home/*/public_html"> #注意要和17行的目录名一致 7 ... 8 35 </Directory> 9 #2.在用户家目录中建立用于保存网站数据的目录及首页文件。把自己家目录的权限修改为755,以保证其他人也有权限读取里面的内容。退出该用户。 10 su - linuxprobe 11 mkdir public_html #注意要和配置文件中的目录名一致 12 echo "linuxprobe's website" > public_html/index.html 13 chmod -Rf 755 ~ #“~”代表就是当前用户的家目录,相当于/home/linuxprobe 14 exit 15 #3.重启httpd服务。在浏览器输入网址验证(格式:网址/~用户名),会报错。原因依然在于SELinux。 16 systemctl restart httpd 17 #4.查询并过滤出所有与http协议相关的安全策略。留意httpd_enable_homedirs是否为on状态,若不是,修改为on状态并立即且永久生效。 18 getsebool -a | grep http 19 setsebool -P httpd_enable_homedirs=on
自己探究出来的一个很重要的点:上面的个人用户网站数据目录public_html,可以是其他名字,只要确保配置文件中的两处地方,以及用户在家目录创建网站数据目录的名字保持一致就行了。不过,需要注意,用户在家目录创建的目录名字如果不是public_html,那么该目录的默认安全上下文就不会是httpd_user_content_t,也就会被SElinux所拦截(至于为什么只有名字是public_html,其安全上下文才会默认为httpd_user_content_t,这个就不清楚了)。所以这种情况的解决办法:
- 1.怎么方便怎么来,目录的名字还是public_html比较省事;
- 2.非要取一个自己喜欢的目录名称,在上面实例的基础之上,确保目录及里面的所有文件的安全上下文为httpd_user_content_t,若不是就修改。
实例:在上面实例的基础上,为网站中添加口令功能,让只有通过身份验证的用户访客才能看到网站内容。
htpasswd命令:建立和更新存储用户名、密码的文本文件, 用于对HTTP用户的basic认证。htpasswd 是开源 http 服务器apache httpd的一个命令工具。其中,用于验证的用户名称不必是系统已有的本地账户,该命令生成的账户密码和系统中的账户密码是独立的,没有联系。
-c参数:创建密码文件.如果密码文件已经存在,那么它会重新写入并删去原有内容。
1 #1.生成密码数据库 2 htpasswd -c /etc/httpd/passwd liwh #生成密码文件,添加一个名为liwh的用户 3 htpasswd /etc/httpd/passwd liangjm #往密码文件追加一个用户liangjm 4 #2.修改个人用户主页功能的配置文件 5 vim /etc/httpd/conf.d/userdir.conf 6 ... 7 31 <Directory "/home/*/public_html"> 8 32 AllowOverride all #允许伪静态技术 9 33 authuserfile "/etc/httpd/passwd" #指定生成的密码文件的存放路径 10 34 authname "Fuck you" #当用户尝试访问个人用户网站时的提示信息 11 35 authtype basic #采用基本验证方式 12 36 require user linagjm #指定用户进行账户密码认证时支持验证的用户(可以支持多个用户验证,比如:liangjm,liwh) 13 37 </Directory> 14 #3.重启httpd服务,刷新页面,会弹出窗口要求输入账户密码。其中liwh的帐号密码是没用的,只能用liangjm账号密码验证 15 systemctl restart httpd
虚拟网站主机功能
Apache的虚拟主机功能是服务器基于用户请求的不同IP地址、主机域名或端口号,实现提供多个网站同时为外部提供访问服务的技术。
在配置虚拟网站主机功能前,做些基本设置:
分别在/home/wwwroot中创建用于保存不同网站数据的3个目录,并向其中分别写入网站的首页文件。每个首页文件中要有明确区分不同网站内容的信息,以便能更直观地检查效果。由前面实例可知,目录/home/wwwroot及其下级目录和文件一定会受到SELinux安全上下文的制约,要修改相关内目录及其里面所有文件的SELinux安全上下文,并让设置立即生效。
1 mkdir -p /home/wwwroot/A 2 mkdir -p /home/wwwroot/B 3 mkdir -p /home/wwwroot/C 4 echo "This is A" > /home/wwwroot/A/index.html 5 echo "This is B" > /home/wwwroot/B/index.html 6 echo "This is C" > /home/wwwroot/C/index.html 7 semanage fcontext -a -t httpd_sys_content_t /home/wwwroot 8 semanage fcontext -a -t httpd_sys_content_t /home/wwwroot/A 9 semanage fcontext -a -t httpd_sys_content_t /home/wwwroot/B 10 semanage fcontext -a -t httpd_sys_content_t /home/wwwroot/C 11 semanage fcontext -a -t httpd_sys_content_t /home/wwwroot/A/* 12 semanage fcontext -a -t httpd_sys_content_t /home/wwwroot/B/* 13 semanage fcontext -a -t httpd_sys_content_t /home/wwwroot/C/* 14 restorecon -Rv /home/wwwroot
实例1:基于IP地址实现虚拟网站主机功能。
1 #1.为网卡配置3个ip地址(方法很多) 2 vim /etc/sysconfig/network-scripts/ifcfg-eno16777728 3 ... 4 IPADDR0=192.168.10.10 5 IPADDR1=192.168.10.20 6 IPADDR2=192.168.10.30 7 ... 8 #2.编辑httpd服务的主配置文件,追加写入3个基于IP地址的虚拟主机网站参数 9 vim /etc/httpd/conf/httpd.conf 10 ... 11 113 <VirtualHost 192.168.10.10> #虚拟主机参数开始 12 114 DocumentRoot /home/wwwroot/B #虚拟主机的家目录 13 115 ServerName www.b.com #虚拟主机的域名 14 116 <Directory /home/wwwroot/B > #子目录权限指定 15 117 AllowOverride None #关闭伪静态 16 118 Require all granted #允许所有环回请求 17 119 </Directory> 18 120 </VirtualHost> #虚拟主机参数结束 19 121 <VirtualHost 192.168.10.10> 20 122 DocumentRoot /home/wwwroot/A 21 123 ServerName www.a.com 22 124 <Directory /home/wwwroot/A > 23 125 AllowOverride None 24 126 Require all granted 25 127 </Directory> 26 128 </VirtualHost> 27 129 <VirtualHost 192.168.10.30> 28 130 DocumentRoot /home/wwwroot/C 29 131 ServerName www.c.com 30 132 <Directory /home/wwwroot/C > 31 133 AllowOverride None 32 134 Require all granted 33 135 </Directory> 34 136 </VirtualHost> 35 ... 36 #3.重启httpd服务,在浏览器分别输入相应的ip地址进行验证。 37 systemctl restart httpd
结果:
- 访问192.168.10.30,会出现“This is C”;
- 访问192.168.10.20,会出现默认页面(因为上面根本没有用到192.168.10.20);
- 访问192.168.10.10,会出现“This is B”。上面配置参数表明192.168.10.10这个ip地址是对应着两个虚拟主机网站参数,但是由于B页面的参数编辑在最上面,因此访问192.168.10.10时出现的是B页面。
实例2:在实例1的基础之上,基于主机域名实现虚拟网站主机功能。
1 #1.编辑IP地址与域名之间对应关系的配置文件,保存退出后会立即生效 2 vim /etc/hosts 3 ... 4 192.168.10.10 www.a.com www.b.com www.c.com 5 ...
基于主机域名的配置其实在实例1就已经配置好了,因为是基于主机域名,所以和ip地址无关。输入虚拟主机里定义的域名,就会出现相对应的页面。
分别在浏览输入相应的域名,结果:
- 访问www.a.com,出现“This is A”;
- 访问www.b.com,出现“This is B”;
- 访问www.c.com,出现“This is C”;
实例3:在实例1的基础上,基于端口号实现虚拟网站主机功能。
1 #1.修改httpd服务的主配置文件,添加几个用于监听端口的参数;修改虚拟主机网站参数为基于端口号的形式。 2 vim /etc/httpd/conf/httpd.conf 3 ... 4 43 Listen 6111 #监听端口6111参数 5 44 Listen 6222 6 45 Listen 6333 7 ... 8 113 <VirtualHost 192.168.10.10:6111> #基于端口的虚拟主机网站参数 9 ... 10 121 <VirtualHost 192.168.10.10:6222> 11 ... 12 129 <VirtualHost 192.168.10.10:6333> 13 ... 14 #2.查看SELinux是否允许Apache服务使用新添加的几个监听端口,若不允许则添加这些端口号 15 semanage port -l | grep http #使用semanage命令查询并过滤出所有与HTTP协议相关且SELinux服务允许的端口列表。 16 semanage port -a -t http_port_t -p tcp 6111 #在SELinux允许的与HTTP协议相关的端口号中添加相应的端口号 17 semanage port -a -t http_port_t -p tcp 6222 18 semanage port -a -t http_port_t -p tcp 6333 19 semanage port -l | grep http #添加端口号的操作会立即且永久生效,再一次查看与HTTP协议相关且SELinux服务允许的端口列表。 20 #3.重启httpd服务 21 systemctl restart httpd
测试结果:
- 访问192.168.10.10:6111,显示“This is B”。
- 访问192.168.10.10:6222,显示“This is A”。
- 访问192.168.10.10:6333,显示“This is C”。
Apache的访问控制
Apache可以基于源主机名、源IP地址或源主机上的浏览器特征等信息对网站上的资源进行访问控制。它通过Allow指令允许某个主机访问服务器上的网站资源,通过Deny指令实现禁止访问。在允许或禁止访问网站资源时,还会用到Order指令。
apache会按照order决定最后使用哪一条规则,比如“Order allow,deny”,虽然会优先匹配allow规则,但由于在order中allow不是最后规则,还需要看有没有deny规则。根据这个逻辑,有可能出现先允许所有人访问,但最后的deny规则禁止了A访问,最终的结果就是A无法访问。注意,order决定的“最后”规则非常重要。
实例:设置Apache访问控制,使得只有ip地址为192.168.10.1或使用火狐浏览器的客户端才能访问指定的网页。
1 #1.在默认网站数据目录新建一个子目录,并在该子目录创建一个首页文件。 2 mkdir /var/www/html/server 3 echo "NB" > /var/www/html/server/index.html 4 #2.修改httpd服务的主配置文件,编辑规则限制源主机的访问。 5 vim /etc/httpd/conf/httpd.conf 6 ... 7 129 <Directory "/var/www/html/server"> #针对该子目录的权限设置 8 130 SetEnvIf User-Agent "Firefox" ff=1 #设置环境变量,相当于ff="用户通过Firefox访问" 9 131 Order allow,deny #先匹配允许规则再匹配拒绝规则 10 132 Deny from 192.168.10.55 #拒绝ip地址为192.168.10.55的主机访问 11 133 Allow from env=ff #允许使用火狐浏览器的人访问 12 134 Allow from 192.168.10.1 #允许ip地址192.168.10.1的主机访问 13 135 </Directory> 14 ... 15 #3.重启httpd服务 16 systemctl restart httpd
测试结果:
- ip地址为192.168.10.1的主机使用非火狐浏览器也能访问;
- ip地址为192.168.10.55的主机即使使用火狐浏览器也不能访问;
- ip地址不是192.168.10.1的主机使用火狐浏览器可以访问。
书本笔记