配置Apache2

之前建立WordPress的时候,没有看Apache2怎么配置,乱配一气,能用就行。前几天发现可能存在安全问题,比如输入一个不存在的URL,Apache2会把目录都列出来,这可不得了。于是花了几天研究了一下Apache2的怎么配置,并且把网站全部推倒重建了一遍,不巧的是由于对MySQL不了解,拷贝了一堆.frm和.ibd文件,以为拷回去就能恢复了,结果仿佛很难恢复,头大了,所以只能根据本地保存的副本,把博客的文章全部重新写了一遍。

基本概念

Apache2是模块(module)化的,可以启用不同的模块,增加功能。另外2.4版本支持配置虚拟主机(virtual host),意思是说一台实际的服务器上能部署多个站点,互不搭介,既可以按不同域名配置虚拟主机,也可以按不同IP地址配置虚拟主机(如果实际服务器有多个IP地址的话)。

关于版本

  • 我用的版本是Apache2.4,和Apache2.2已经有点不同了,不能一概而论。
  • Apache这个东西历史渊源有点深,反正不知道怎么回事,以前的版本叫httpd,所以以前的配置文件名叫httpd.conf。现在的配置文件叫apache2.conf。
  • 在不同系统上配置文件的位置不同。在Ubuntu-16.04中是/etc/apache2/apache2.conf。

配置文件目录结构

  • apache2.conf – 主配置文件。包含(include)了启用的模块,ports.conf,启用的虚拟主机,以及各目录相关、日志文件相关的配置。
  • conf-available, conf-enabled – 目录。前者包含(模块化的)配置文件。后者包含已启用的配置文件,实质上是指向conf-available目录中相应文件的链接。用a2enconf/a2disconf命令能分别启用/禁用的配置文件,所做的事也就是创建/删除软链接。
  • envvars – 顾名思义,环境变量。
  • magic – 魔数?不明觉厉。
  • mods-availablemods-enabled – 目录。类似地,包含所有模块和已被启用的模块。类似地有 a2enmod/a2dismod 命令。
  • ports.conf – 顾名思义,大概是配置端口的。
  • sites-availablesites-enabled – 目录。类似地,包含所有站点(虚拟主机)和已被启用的站点(虚拟主机)。 类似地有 a2ensite/a2dissite 命令 。

配置文件

上下文环境(context)

配置是用指令(directive)写的。指令必须用在对应可用的上下文环境中。根据文档,上下文环境共4种:

  • server config: 即apache2.conf中,但不能在<Directory><VirtualHost>标签中。

  • virtual host: 即<VirtualHost>标签中

  • directory: <Directory><Location><Files><If><Proxy>标签中。

  • .htaccess: 每个目录下的.htaccess文件中。

apache2.conf

apache2.conf中前面几乎不用动它,除非想改一下LogLevel,按照它的注释改就行了。主要改的是<Directory>部分,它里面的指令会对<Directory>所有子目录生效。<Directory>里常见的指令有:

  • Options – 常见选项有FollowSymLinksIndexesFollowSymLinks是如果目录下有符号链接,则允许顺着符号链接访问。Indexes是如果要访问的目录下不存在index.html文件,则显示文件目录结构,所以这个选项一般是不安全的。不需要的选项直接删掉即可,而不要像百度上有些人说的添个-,我试了一下会报格式错误。
  • AllowOverride – 我见过NoneAll选项,表示是否允许目录下的.htaccess文件重载配置文件。
  • Require – 这其实是一个mod_authz_user模块提供的指令,详情参考文档。常见的话是Require All grantedRequire All denied,分别是允许所有请求和拒绝所有请求。拒绝所有请求是用来确保有些目录绝对不允许给人看。不过如果自己的站点要加载这个目录下的资源,同样也会被拒绝。

配置虚拟主机

我会按域名不同配置虚拟主机。比如我的域名是domain.com,现在想让blog.domain.com和store.domain.com两个二级域名指向两个不同的网站。

首先无疑要把这两个域名都解析到实际服务器的IP地址上,否则都是空谈。

然后:

cd /etc/apache2/sites-available
cp 000-default.conf blog.conf
vim blog.conf

开始编辑blog.conf。省略掉注释的话,大概就是这些内容:

# --- 配置虚拟主机 ---
# IP地址:本机的全部IP地址;端口:80
<VirtualHost *:80>
    # 虚拟主机的域名
    ServerName blog.domain.com
    # 域名的别名,可以填多个,以空格分割
    serverAlias zone.domain.com
    # 站长的邮箱
    ServerAdmin site-owner@somemail.com
    # 网站的根目录,可以是任何目录(不一定非要/var/www/html)
    # 当然读写权限要妥善处理
    DocumentRoot /home/blog/public

    # 日志路径
    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/access.log combined

    # 分目录配置
    <Directory /home/wwwblog/site>
        Options FollowSymlinks
        AllowOverride All
        Require all granted
    </Directory>
</VirtualHost>

ServerName是必填的。别人访问blog.domain.com和store.domain.com虽然都访问到你这个IP地址,但是会进入不同的网站,原因就是Apache2会根据ServerNameServerAlias把请求交给不同的虚拟主机。ServerNameServerAlias不能用通配符。ServerNameServerAlias的地位是平等的,如果两个虚拟主机都匹配到了主机名,则在考虑虚拟主机之间的优先级时,不会因为匹配到ServerName还是ServerAlias而产生区别。如果请求的域名没有匹配到任何一个虚拟主机的主机名,则会进入000-default.conf配置的那个主机,因为那个文件它没有填ServerName,比较特殊。所以000-default.conf不要去改它。

DocumentRoot就是网站文档的根目录了。以前傻兮兮地以为只能在/var/www/或者/var/www/html/下。注意路径名称最后一定不要加”/”,这是apache2.conf的注释里特别强调的。

日志路径一般不要改它。

最后是分目录配置,不够还可以再加。标签里面可以放任何指令,只要上下文环境合适。

配置完成,然后再以类似的方法配置store.domain.com的虚拟主机。最后别忘了用a2ensite启用。

.htaccess

.htaccess起始就是对分目录配置,它能做的事情在配置文件的<Directory>里面也都能做,并且会降低性能。所以,除非没有修改配置文件的权限,否则不要用.htaccess。