11.5 httpd配置
LAMP环境搭建好之后,其实仅仅是安装上了软件,我们还有很多具体的配置工作要做。
默认虚拟主机
一台服务器上的httpd下,是能够跑多个网站、多个域名的。那么每一个网站就是一个虚拟主机。服务器上可以有多个虚拟主机,每个虚拟主机都会定义一个域名,也可以定义多个域名。
假设百度、谷歌都是在你的一台服务器上运行,那么百度是一个虚拟主机、谷歌是另外一个虚拟主机。httpd是支持多个虚拟主机的,,即可以在一个服务器上运行多个站点,标记多个域名。
但是,如果一个没有标记的域名也指向了服务器(域名可以做解析指向,域名解析服务器IP地址是由DNS服务器完成的),那总得有一个处理这个域名的虚拟主机吧,而这个虚拟主机就叫做默认虚拟主机。
总之,任何一个域名指向这台服务器,只要是没有对应的虚拟主机,就会由这个默认虚拟主机来处理。 我们要做的是去配置默认虚拟主机。
- 编辑配置文件
httpd.conf
(httpd的主配置文件):
# vim /usr/local/apache2.4/conf/httpd.conf
# Virtual hosts
#Include conf/extra/httpd-vhosts.conf #搜索httpd-vhosts,找到这行,删除行首 # 符号。这个是虚拟主机的配置文件
- 保存主配置文件,然后编辑虚拟主机配置文件:
# vim /usr/local/apache2.4/conf/extra/httpd-vhosts.conf
<VirtualHost *:80>
ServerAdmin webmaster@dummy-host.example.com
DocumentRoot "/usr/local/apache2.4/docs/dummy-host.example.com"
ServerName dummy-host.example.com
ServerAlias www.dummy-host.example.com
ErrorLog "logs/dummy-host.example.com-error_log"
CustomLog "logs/dummy-host.example.com-access_log" common
</VirtualHost>
<VirtualHost *:80>
ServerAdmin webmaster@dummy-host2.example.com
DocumentRoot "/usr/local/apache2.4/docs/dummy-host2.example.com"
ServerName dummy-host2.example.com
ErrorLog "logs/dummy-host2.example.com-error_log"
CustomLog "logs/dummy-host2.example.com-access_log" common
</VirtualHost>
该文件最后的两段就是虚拟主机的配置,一段对应一个虚拟主机,第一段就是默认虚拟主机的配置。
ServerAdmin 指定管理员邮箱;
DocumentRoot 为该虚拟主机站点的根目录,网站的程序就在这个目录下面;
ServerName 网站的域名,只能写一个;
ServerAlias 网站的第二域名,后面可以写多个,用空格分隔;
ErrorLog 站点的错误日志;
CustomLog 站点的访问日志。
这里我们定义两个站点:111.com 和 123.com ,用做测试。
- 修改虚拟主机的配置文件,作如下修改:
# vim /usr/local/apache2.4/conf/extra/httpd-vhosts.conf
<VirtualHost *:80>
ServerAdmin lzx@abc.com
DocumentRoot "/data/wwwroot/abc.com"
ServerName abc.com
ServerAlias www.abc.com
ErrorLog "logs/abc.com-error_log"
CustomLog "logs/abc.com-access_log" common
</VirtualHost>
<VirtualHost *:80>
ServerAdmin lzx@123.com
DocumentRoot "/data/wwwroot/123.com"
ServerName 123.com
ServerAlias www.123.com
ErrorLog "logs/123.com-error_log"
CustomLog "logs/123.com-access_log" common
</VirtualHost>
- 然后做一下其他配置:
# mkdir -p /data/wwwroot/abc.com /data/wwwroot/123.com
# vim /data/wwwroot/abc.com/index.php
<?php
echo "abc.com";
?> #这里最后一行可以省略
# vim /data/wwwroot/123.com/index.php
<?php
echo "123.com";
?>
# /usr/local/apache2.4/bin/apachectl -t #测试语法
Syntax OK
# /usr/local/apache2.4/bin/apachectl graceful #重新加载配置文件,避免重启;使用 ctrl+r 可以快速地匹配命令历史中的命令
# curl -x127.0.0.1:80 www.abc.com #127.0.0.1是环回地址,指本机
abc.com
# curl -x127.0.0.1:80 www.123.com
123.com
# curl -x127.0.0.1:80 www.111.com
abc.com
可以看出默认虚拟主机是 abc.com,不管是什么域名指向该服务器,只要配置文件中没有标记,就会访问到这个默认虚拟主机。
另外,如果我们想让真实Windows机器访问这两个网址,可以在Windows上修改hosts文件,该文件的路径是:C:\Windows\System32\drivers\etc\hosts
,在hosts文件最下面增加一行:
192.168.100.140 www.123.com #左边的IP地址为你的linux机器IP
用户认证
如何让没有被标记的域名不被访问呢?那就是在用户访问网站的时候,需要输入用户名密码才能顺利访问。
- 首先,修改 123.com 这个虚拟主机的配置,如下:
# vim /usr/local/apache2.4/conf/extra/httpd-vhosts.conf
<VirtualHost *:80>
ServerAdmin lzx@123.com
DocumentRoot "/data/wwwroot/123.com"
ServerName 123.com
<Directory /data/wwwroot/123.com> #指定认证的目录
AllowOverride AuthConfig #这个相当于打开认证的开关
AuthName "123.com user auth" #自定义认证的名字,作用不大
AuthType Basic #认证的类型,一般为Basic
AuthUserFile /data/.htpasswd #指定用户与密码文件所在位置
require valid-user #指定需要认证的用户为全部可用用户,即.htpasswd文件里设定的用户
</Directory>
</VirtualHost>
- 上面配置完后,还需要创建密码文件:
# /usr/local/apache2.4/bin/htpasswd -c -m /data/.htpasswd lzx #htpasswd命令用于创建用户,-c选项是创建、-m选项是使用md5加密算法,lzx是认证用户名
New password:
Re-type new password:
Adding password for user lzx
- 配置完成后,还需要到宿主机上面修改一下hosts文件,在最下面增加一行:
192.168.100.140 www.123.com
- 重新加载配置,进行访问测试:
# /usr/local/apache2.4/bin/apachectl -t
Syntax OK
# /usr/local/apache2.4/bin/apachectl graceful
# curl -x127.0.0.1:80 123.com -I
HTTP/1.1 401 Unauthorized
Date: Sat, 30 Jun 2018 08:26:28 GMT
Server: Apache/2.4.33 (Unix) PHP/5.6.36
WWW-Authenticate: Basic realm="123.com user auth"
Content-Type: text/html; charset=iso-8859-1
直接访问报401错误,401状态码就是需要认证。
# curl -x127.0.0.1:80 -ulzx:1234567 123.com -I
HTTP/1.1 401 Unauthorized
Date: Sat, 30 Jun 2018 08:25:22 GMT
Server: Apache/2.4.33 (Unix) PHP/5.6.36
WWW-Authenticate: Basic realm="123.com user auth"
Content-Type: text/html; charset=iso-8859-1
指定用户与密码,故意将密码输入错,也报401错误。
# curl -x127.0.0.1:80 -ulzx:123456 123.com -I
HTTP/1.1 200 OK
Date: Sat, 30 Jun 2018 08:24:33 GMT
Server: Apache/2.4.33 (Unix) PHP/5.6.36
X-Powered-By: PHP/5.6.36
Content-Type: text/html; charset=UTF-8
指定用户与密码,密码正确,认证通过,就是报200码。
用浏览器访问是这样:
- 如果是针对某个目录或者文件进行认证,以123.com为例,可以这样去配置虚拟主机的配置文件:
- 对于目录(比如
/data/wwwroot/www.123.com/admin/
):
将<Directory /data/wwwroot/www.123.com> 改为 <Directory /data/wwwroot/www.123.com/admin/>
- 对于文件(比如
www.123.com/admin.php
):
<VirtualHost *:80>
ServerAdmin lzx@123.com
DocumentRoot "/data/wwwroot/123.com"
ServerName 123.com
<FilesMatch admin.php> #这里将Directory 改为 FilesMatch ,后面也改为要认证的文件
AllowOverride AuthConfig
AuthName "123.com user auth"
AuthType Basic
AuthUserFile /data/.htpasswd
require valid-user
</FilesMatch> #这里将Directory 改为 FilesMatch
</VirtualHost>
配置域名跳转
一个网站可能有多个域名,在这种情况下,我们需要用到域名跳转,这样有两个作用:
-
一个站点有多个域名对SEO有影响(百度搜索关键词排名);
-
如果之前的域名不再使用了,可以很方便地把老域名做个跳转即可。
- 启用域名跳转 :是通过Apache的Rewrite模块来实现的(httpd.conf中启用该模块,httpd-vhosts.conf中定义跳转设置)
# /usr/local/apache2.4/bin/apachectl -M|grep -i rewrite #没有任何输出,需要编辑配置文件
# vim /usr/local/apache2.4/conf/httpd.conf
LoadModule alias_module modules/mod_alias.so
#LoadModule rewrite_module modules/mod_rewrite.so #搜索rewrite,找到这行,删除行首 # 符号
LoadModule php5_module modules/libphp5.so
#LoadModule php7_module modules/libphp7.so
# /usr/local/apache2.4/bin/apachectl -t
Syntax OK
# /usr/local/apache2.4/bin/apachectl graceful
# /usr/local/apache2.4/bin/apachectl -M|grep -i rewrite
rewrite_module (shared) #有这行输出,就说明正常加载了rewrite模块
- 做域名跳转需要去配置虚拟主机的配置文件:
# vim /usr/local/apache2.4/conf/extra/httpd-vhosts.conf
<VirtualHost *:80>
ServerAdmin lzx@123.com
DocumentRoot "/data/wwwroot/123.com"
ServerName 123.com
ServerAlias www.111.com
ErrorLog "logs/123.com-error_log"
CustomLog "logs/123.com-access_log" common
# <FilesMatch admin.php>
# AllowOverride AuthConfig
# AuthName "123.com user auth"
# AuthType Basic
# AuthUserFile /data/.htpasswd
# require valid-user
# </FilesMatch>
<IfModule mod_rewrite.c> #编译Apache的时候,指定了mods=most,会自动加入该模块
RewriteEngine on //打开rewrite功能
RewriteCond %{HTTP_HOST} !^123.com$ #定义rewrite条件,当主机名(域名)不是www.123.com 时满足条件(!表示取反)
RewriteRule ^/(.*)$ http://123.com/$1 [R=301,L] #定义rewrite规则,当满足上面的条件时,跳到 http://123.com去
</IfModule>
</VirtualHost>
RewriteRule 后面由空格划分成三个部分:
第一部分为当前的URL(网址);
第二部分为要跳转的目标地址;
第三部分为一些选项,要用方括号括起来,301为状态码,表示“永久重定向”(还有一种是302,表示“临时重定向”),L表示“last”,表示跳转一次就结束。
- 重新加载配置文件:
# /usr/local/apache2.4/bin/apachectl -t
Syntax OK
# /usr/local/apache2.4/bin/apachectl graceful
- 验证跳转测试:
# curl -x127.0.0.1:80 123.com -I
HTTP/1.1 301 Moved Permanently
Date: Sat, 30 Jun 2018 09:08:50 GMT
Server: Apache/2.4.33 (Unix) PHP/5.6.36
X-Powered-By: PHP/5.6.36
Content-Type: text/html; charset=UTF-8
配置访问日志
访问日志作用很大,不仅可以记录网站的访问情况,还可以在网站有异常发生时帮助我们定位问题。
- 要配置httpd访问日志,首先要在主配置文件中定义访问日志的格式,打开主配置文件:
# vim /usr/local/apache2.4/conf/httpd.conf
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
LogFormat "%h %l %u %t \"%r\" %>s %b" common
可以看到两个格式的日志,建议使用第一个,因为记录的信息会更全。
%h 访问网站的IP;
%l 远程登录名,基本上是“-”;
%u 用户名;
%t 时间;
%r 请求的动作(如curl -I时就是HEADE);
%s 请求的状态码,写成%>s 为最后的状态码;
%b 传输数据大小;
%{Referer}i Referer信息(请求本次地址的上一次地址就是Referer);
%{User-Agent}i 浏览器标识。
- 继续编辑虚拟主机配置文件:
# vim /usr/local/apache2.4/conf/extra/httpd-vhosts.conf
<VirtualHost *:80>
ServerAdmin lzx@123.com
DocumentRoot "/data/wwwroot/123.com"
ServerName 123.com
ServerAlias www.123.com
# ErrorLog "logs/123.com-error_log"
# CustomLog "logs/123.com-access_log" common
# <FilesMatch admin.php>
# AllowOverride AuthConfig
# AuthName "123.com user auth"
# AuthType Basic
# AuthUserFile /data/.htpasswd
# require valid-user
# </FilesMatch>
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{HTTP_HOST} !^123.com$
RewriteRule ^/(.*)$ http://123.com/$1 [R=301,L]
</IfModule>
CustomLog "logs/123.com-access_log" combined #增加这样一行
</VirtualHost>
- 保存配置文件后,重新加载配置:
# /usr/local/apache2.4/bin/apachectl -t
Syntax OK
# /usr/local/apache2.4/bin/apachectl graceful
# curl -x127.0.0.1:80 123.com -I
# tail /usr/local/apache2.4/logs/123.com-access_log
127.0.0.1 - - [30/Jun/2018:22:38:52 +0800] "HEAD HTTP://123.com/ HTTP/1.1" 301 - "-" "curl/7.29.0"
已经生成了日志,并有相关的记录。
访问日志不记录静态文件
apache的访问日志会记录网站每个文件被获取的信息,这样日志信息量会很大,我们排查日志的时候不容易筛选有用的记录。我们可以把静态文件的日志设置为不记录,提高我们排查日志信息的效率。
- 在
conf/extra/httpd-vhosts.conf
配置文件下进行编辑:
# vim /usr/local/apache2.4/conf/extra/httpd-vhosts.conf
<VirtualHost *:80>
ServerAdmin lzx@123.com
DocumentRoot "/data/wwwroot/123.com"
ServerName 123.com
ServerAlias www.123.com
SetEnvIf Request_URI ".*\.gif$" img #定义元素为img
SetEnvIf Request_URI ".*\.jpg$" img
SetEnvIf Request_URI ".*\.png$" img
SetEnvIf Request_URI ".*\.bmp$" img
SetEnvIf Request_URI ".*\.swf$" img
SetEnvIf Request_URI ".*\.js$" img
SetEnvIf Request_URI ".*\.css$" img
ErrorLog "logs/123.com-error_log"
CustomLog "logs/123.com-access_log" common env=!img # !表示取反,指定非img的文件才记录日志。
</VirtualHost>
- 重新加载配置文件:
# /usr/local/apache2.4/bin/apachectl -t
Syntax OK
# /usr/local/apache2.4/bin/apachectl graceful
这样再访问访问网站下的图片文件,查看日志就不会再记录图片的访问日志了。
访问日志切割
随着网站访问量的增大,我们网站的访问日志文件也会变得很大,为了保持磁盘空间,方便访问日志的管理(备份、删除历史日志等。),我们可以进行日志切割,每天的访问日志独立切割出来。
- 在
conf/extra/httpd-vhosts.conf
配置文件下进行编辑:
# vim /usr/local/apache2.4/conf/extra/httpd-vhosts.conf
<VirtualHost *:80>
ServerAdmin lzx@123.com
DocumentRoot "/data/wwwroot/123.com"
ServerName 123.com
ServerAlias www.123.com
SetEnvIf Request_URI ".*\.gif$" img
SetEnvIf Request_URI ".*\.jpg$" img
SetEnvIf Request_URI ".*\.png$" img
SetEnvIf Request_URI ".*\.bmp$" img
SetEnvIf Request_URI ".*\.swf$" img
SetEnvIf Request_URI ".*\.js$" img
SetEnvIf Request_URI ".*\.css$" img
ErrorLog "logs/123.com-error_log"
CustomLog "|/usr/local/apache2.4/bin/rotatelogs -l logs/111.com-access_%y%m%d.log 86400" common env=!img #%y%m%d以年月日命名,86400秒即1天切割一次,rotatelogs是apache自带的切割日志工具。
</VirtualHost>
配置静态元素过期时间
浏览器访问网站,获取的图片、css等静态元素会保存在本地电脑缓存文件夹里,我们可以在服务器端设置这些静态元素的过期时间,可以降低服务器的资源消耗,还可以提升用户访问网站的速度
,而这个就涉及到了一个静态文件缓存时长的问题,也叫作“缓存过期时间”。
- 编辑虚拟主机配置文件(在上面配置的条件下增加下面内容):
# vim /usr/local/apache2.4/conf/extra/httpd-vhosts.conf
<IfModule mod_expires.c>
ExpiresActive on #打开该功能的开关
ExpiresByType image/gif "access plus 1 days" #gif类型文件的失效时间是1天
ExpiresByType image/jpeg "access plus 24 hours"
ExpiresByType image/png "access plus 24 hours"
ExpiresByType text/css "now plus 2 hour"
ExpiresByType application/x-javascript "now plus 2 hours"
ExpiresByType application/javascript "now plus 2 hours"
ExpiresByType application/x-shockwave-flash "now plus 2 hours"
ExpiresDefault "now plus 0 min"
</IfModule>
上面用到了mod_expires
模块。
- 重新加载配置文件:
# /usr/local/apache2.4/bin/apachectl -M|grep -i expires #没有任何输出,需要编辑配置文件
# vim /usr/local/apache2.4/conf/httpd.conf
LoadModule env_module modules/mod_env.so
#LoadModule expires_module modules/mod_expires.so #搜索expires,找到这行,删除行首 # 符号
LoadModule headers_module modules/mod_headers.so
# /usr/local/apache2.4/bin/apachectl -t
Syntax OK
# /usr/local/apache2.4/bin/apachectl graceful
# /usr/local/apache2.4/bin/apachectl -M|grep -i rewrite
rewrite_module (shared) #有这行输出,就说明正常加载了rewrite模块
更多资料参考: