【作者按】本人并未系统的学习使用过apache,对其使用也仅限于在搭建一些工具类网站时的使用,例如gerrit。因此在遇到了问题之后,往往手足无措,借助于之前照抄网上成功的案例进行对比配置,找出其中的差异,然后一一排除试错,最终可能解决问题,这是幸运的,但是却完全不知道为什么失败了,又为什么就改好了。也有可能改了半天也没有成功,这时候往往心烦意乱,归咎于时间的紧急,把所有安装配置全部删除,重新按照网上的成功案例一步一步进行配置,不敢有丝毫的差错,说实话这个过程毫无技术可言,也学不到任何东西。事后还往往不谦虚地跟人吹嘘说:我会搭建某某工具环境,某某公司的某某项目就是我的杰作。实际上真的如此吗?扪心自问,自己真的知道每个步骤是为什么吗?恐怕未尝如此。此文即作者本人在又一次经历了上述历程之后,下定决心研究一下apache。当然又是老套的借口限于时间原因,按照案例方式来罗列问题及解决过程,望各位读者海涵。
背景
结合使用gerrit + apache环境搭配的过程,并且已经大致按照上篇文章《gerrit安装配置及过程中遇到的问题》安装好gerrit及其配置gerrit.config,安装好了apache及其配置gerrit.conf, 但是在浏览器输入配置的网址时,失败的心路历程就此开始:
1. 错误的在2.4的apache上使用了2.2的配置方法
首先映入眼帘的是浏览器报出如下信息:
查了半天发现当前配置使用apache时2.4.x版本的,而成功案例中的apache使用的是2.2
满怀信心的找到了原因,将apache的虚拟主机(gerrit.conf,当时根本不知道这是虚拟主机),中关于<proxy的配置由
<Proxy *>
Order deny,allow
Allow from all
</Proxy>
改为
<Proxy *>
Require all granted
</Proxy>
2. 浏览器访问失败之后,如何对问题进行定位分析
修改完毕之后,再次满怀希望输入网址产看,发现问题依旧。这个时候除了照已有案例配置进行对比分析,还有什么办法呢?
对,就是查看log,对于专业程序开发人员来说,查看log是一项必备的技能
那么log在哪里呢?
默认情况下:
apache log: /var/log/apache2/
access.log 默认的80端口虚拟主机的访问log
error.log 服务器访问异常的log
other_vhosts_access.log 其他(自定义)虚拟主机的访问log
gerrit log: gerritpath/los/
error_log
httpd_log
sshd_log
通过这几个log可以分析出以下结论(后来得到的总结,当时远未如此清晰):
如果一次访问在apache的三种log中会产生log日志,那么证明输入的网址及端口能够被服务器监听到
如果在apache中的errot.log中产生了log日志,而在gerrit中的httpd没有产生日志,说明输入的网址能够被服务器监听到但是未被gerrit监听到。
导致这种情况原因有两种:
1)虚拟主机配置有问题
2)gerrit的配置有问题,是否httpd的listenUrl有问题
3. 勿入歧途。归咎于权限因素
当时只关注了gerrit的error_log,发现了如下的错误信息:
[authz_core:error] [pid 8235] [client 192.168.134.78:55925] AH01630: client denied by server configuration: /var/www/project
根据此日志判断是因为apache没有权限访问/var/www/project这个路径导致的。
由此得出了一下的结论:
1)需要修改apache的默认工程路径的权限
2)将gerrit放入到apache能够访问的到的工程路径下面
采取了以下的方法:
1)通过ls -ls /var/www/ 查看该路径能够被访问的用户即用户组,结果发现是root用户,
通过ps auxfw | grep apache,查看到
www-data 18602 0.0 0.1 382176 7020 ? S 13:26 0:00 \_ /usr/sbin/apache2 -k start
发现apache的启动用户为www-data,通过查询发现这是apache默认的一个比较低级别的用户,目的是为了安全,排除了使用root用户启动apache的方案
2) 修改现有apache的权限,使之可以访问/var/www路径
在这一过程中,首先想到的是想要改变apache默认的访问路径,查到在apache.conf中配置了这一路径如下:
<Directory /var/www/>
Options Indexes FollowSymLinks
AllowOverride None
Require all granted
</Directory>
于是将这一路径改到了我放置gerrit的gerritpath路径,但是重启apache之后发现无效,输入http://192.168.134.142:8090/project, 仍然是没有权限访问/var/home/的日志。这个原因到现在也没有想到为什么,哪怕后来知道了可能需要在我自定义的virtualhost中定义该Directory,也仍然报此错误日志。(直到写这篇文章时才想到,我当时在自定义的vritualhost中定义了directory,但是由于整个virtualhost的conf未起作用,所以仍然访问的默认的/var/www路径)
后来没有办法,只能修改gerrit,将其ln -s 到/var/www/project下,输入网址进行访问,发现如下错误日志:
无法在/var/www/project下找到index.html, index.php......。再次求助万能百度,兴冲冲的跑到 /var/www的Directory路径下删除了Indexes的option。再次输入网址,彻底傻眼,服务器倒是连接上了,但是变成了对服务器/var/www/project下文件结构的浏览
4. 回归问题原点,重新分析
对两种不同的现象进行对比分析,思考为什么
在这个过程中万般无奈之下,曾经对输入网址http://192.168.134.143:8090/project进行过如下修改:
http://192.168.134.143/project 返回的是NotFound的错误,即在该网址下找不到80端口下的/project/虚拟路径
http://192.168.134.143:8090 返回的是Forbidden
http://192.168.134.143:8081/project
结果却发现打开了gerrit的一个网址,但是现实的内容确实gerrit configuration错误
但是知道这个时候,却在gerrit的httpd_log中出现了第一次连接上的日志
5. 懵懵懂懂,大致定位问题,学习virtualhost
截止目前遇到的种种现象,发现现象与现象为什么不同无法解释,于是在百度中输入了gerrit.conf的第一行配置关键字“virtualhost”,开始系统地对其进行系统的学习了解。
自此我才了解了,原来在apache中对gerrit的种种配置原来是为了建立一个反向代理的虚拟主机。我们一行行的来进行解释。
先来一段关于虚拟主机的官方解释:
虚拟拟主机是使用特殊的软硬件技术,把一台真实的物理电脑主机分割成多个的逻辑存储单元,每个单元都没有物理实体, 但是每一个逻辑存储单元都能像真实的物理主机一样在网络上工作,具有单独的域名、IP地址(或共享的IP地址)以及完整的Internet服务器功能
一个apache服务器可以创建多个虚拟主机,用于分别处理不同的情况。每个虚拟主机必须有不同的名字,但是只能对应一个唯一的物理IP。
下面贴一段gerrit的在apache上为其进行的配置,其实就是在apache上为其创建了一个虚拟主机
<VirtualHost 192.168.134.143:8090>
ServerName 192.168.134.143 定义了虚拟机的名称,关于详细的定义主机名的方式,可参见“Apache 配置虚拟主机三种方式” (http://www.cnblogs.com/hi-bazinga/archive/2012/04/23/2466605.html)
ProxyRequests Off
ProxyVia Off
ProxyPreserveHost On
# DocumentRoot /home/suweigang/gerrit_reviewsite/
# <Directory "/home/suweigang/gerrit_reviewsite">
# AllowOverride None
# Require all granted
# </Directory>
<Proxy *>
# Order deny,allow
# Allow from all
Require all granted
</Proxy>
<Location "/project/login/">
AuthType Basic
AuthName "Gerrit Code Review"
AuthBasicProvider file
AuthUserFile /etc/apache2/passwords
Require valid-user
</Location>
LogLevel debug
AllowEncodedSlashes On
RedirectMatch ^/project$ /project/
ProxyPass /project/ http://127.0.0.1:8081/project/ 反向代理
ProxyPassReverse /project/ http://127.0.0.1:8081/project/
</VirtualHost>
6. 仍然不起作用,但信心十足,基于现有现象重新排查
反复修改虚拟主机的配置,但是仍然在出现4中的各种现象,由此断定,gerrit本身的配置一定是没有问题的,有问题的一定是反向代理出现了问题。
经过了无数次的对比验证,证明是上述虚拟主机配置其实是没有问题的,可是error_log中仍然报错,脑中灵光一现,是不是整个虚拟主机的配置文件没起效,即没被apache服务器所采用,所以导致反向代理不起作用?fuck!!,重新检查apache中的默认配置,终于在apache.conf中找到如下默认配置:
# Include the virtual host configurations:
IncludeOptional sites-enabled/*.conf
而我的虚拟主机配置文件gerrit.conf却放在了sites-availabe/路径下,当然不会起效果!
修改了虚拟主机的配置路径,重启apache和gerrit,输入网址!
7. 大工告成!