最近,我有一台debian服务器,双网卡,一个用于提供外网服务,一个用于管理,上面部署有apache,部署了四个基于域名的虚拟主机,现在想把其中两个改成让外网可以访问,两个让内网访问,按照一般的操作完成后,发现第二个设置外网访问的虚拟主机访问不了,访问时内容总是跳转到第一个外网虚拟主机上面,当时知道apache如果找不到相应的虚拟主机会以第一个虚拟主机为默认的,但是看配置是没有问题的(表面而已)。
下来讲一下debian安装apache的目录结构,在centos下安装httpd时只要yum -y install httpd.x86_64即可,centos的默认配置都在一个文件中,所有的加载的模块配置和虚拟主机配置都在一个httpd.conf文件中,而debian却是以加载模块和配置文件的形式在,debian的apache安装按成后在/etc/apache2目录下有以下文件:
debian的主配置文件是apache2.conf,httpd.conf是空文件,envvars用来给apache2ctl设置环境变量,ports.conf用来定义主配置文件的监听IP, NameVirtualHost等,mods-available和mods-enabled是两个重要的目录,里面包含了一些apache的扩展模块,mods-available里面是默认的一些apache模块,但并不是所有的都已经加入主配置中,比如要加入rewrite模块,执行a2enmod rewrite即可,这样在mods-enabled目录中就有开启的rewrite模块了(软连接形式),a2dismod可以取消相关模块,sites-available和sites-enabled是配置虚拟主机的,所有的虚拟主机都在sites-available目录下,当需要开启某个虚拟主机时,执行a2ensite filename即可,在sites-enabled目录下就会有相应的文件(软连接)。a2dissite 取消相关虚拟主机。在apache2.conf中会以Include的形式把相关文件夹包含进去。
我的apache都是以域名的虚拟主机,在sites-enabled目录下,每个项目的虚拟主机分别分配一个文件,如下:
格式如下:
<VirtualHost 192.168.2.1:80>
ServerAdmin webmaster@localhost
ServerName test.wai2.com
DocumentRoot /var/www/test.wai2.com
<Directory /var/www/test.wai2.com>
Options -Indexes FollowSymLinks +Execcgi
Order allow,deny allow from all
ErrorLog /var/log/apache2/test.wai2.com_error.log
LogLevel warn
CustomLog /var/log/apache2/test.wai2.com_access.log combined
</Directory>
</VirtualHost>
在四个基于域名的虚拟主机都绑定内网IP时,这种配置访问都很正常,每个虚拟主机一个配置文件也没问题,但是当其中两个绑定内网IP,两个绑定外网IP时就出现了开头说的那种情况,最后把绑定内网IP的虚拟主机的配置文件(test.nei1.com,test.nei3.com)合并到一个文件中,把绑定外网IP的虚拟主机配置文件(test.wai2.com,test.wai4.com)合并到一个文件中,在ports.conf中取消 NameVirtualHost的定义配置,在合并后的每个配置文件的开头插入一行NameVirtualHost IP:80,绑定内网的就写内网IP,绑定外网的就写外网IP,做好DNS后,然后重启apache即可。
测试:
这样就可以即有绑定内网的虚拟主机,也有绑定外网的虚拟主机,且互不影响,在centos下应该不会出现在debian下的这种情况,因为所有的配置都在一个文件中,但是习惯了debian的配置文件格式,且这样每个虚拟主机分开写管理起来方便,所以还不死心,又改成了四个配置文件的格式,并且在每个配置文件的第一行插入NameVirtualHost IP:80的配置,然后启动的时候会有警告NameVirtualHost 外网IP:80 has no VirtualHosts,很奇怪定义了,怎么会没有呢,这样等于就有两个NameVirtualHost 内网IP:80和两个NameVirtualHost 外网IP:80的配置了,但是实验结果却是可以正常访问互不影响的,然后看了一下文档有如下描述:
The namevirtualhost command tells Apache that you will use VirtualHost boxes on a specific IP address. This command is needed only once for each IP address. It is not necessary to repeat the namevirtualhost directive for every VirtualHost box you use as in your example. The directive doesn't define a VirtualHost, it only tells Apache that on that IP address one or more virtual hosts will be present.
恍然大悟啊,同一个IP的NameVirtualHost的只能定义一次,但是如果各取消一个NameVirtualHost的话就又会出现开头的问题,所以为了每次启动时美观一些(没有warn),只好改成两个配置文件,一个绑定内网的,一个绑定外网的。
各位看官有什么好的建议可以提一下,谢谢了。