根据子域的 RewriteCond 文件夹存在

根据子域的 RewriteCond 文件夹存在

我拥有多个域,希望它们都由一个主机提供服务。有许多用户在此主机上创建他们的项目,这些项目应全部按子域路由。我想在 Apache 配置中设置一些规则,以自动确定文档根目录,但我不知道该怎么做,或者 Apache 是否允许这种“复杂”的重写规则。

文件夹结构应该是这样:

/var/www
| example.org
| - foo
| - - index.html
| - bar
| - - somehiddenfile.txt
| - - public
| - - - index.html
| - www
| - - index.html
| - error.html

在这个例子中,我希望example.orgwww.example.org被路由到/var/www/example.org/www

foo.example.org应路由到/var/www/example.org/foo并且bar.example.org应路由到/var/www/example.org/bar/public。如果存在则应foobar.example.org始终提供服务/var/www/example.org/error.html,否则/var/www/example.org/www也路由到。

现在,由于我不想在每次有人创建新的子域时都创建新的配置(它们通常是通过 A 通配符设置的(*.example.org)),我希望能够尽可能地自动化。

然而,我不知道如何-d在重写条件中使用子域进行检查。RewriteCond /var/www/${HTTP_HOST} !-d我可以做类似的事情,但我没有找到任何关于对拆分主机 (TLD) 和子域执行相同操作的信息。如果可以的话,请告诉我。

答案1

由于每个子域都与不同的内容相关,即指向相应的 DocumentRoot,并具有自己的设置(例如自定义 404 文档),因此您可能想要使用“基于名称”的 VirtualHost 指令(而不是自己在请求中匹配主机)。请参阅Apache 文档有关更多信息,请参阅 VirtualHosts。

基本思路是,您有一个站点列表(www. foo. bar...),其中包含单独的参数(名称、别名、DocRoot、ErrorDoc),并且您需要在 apache conf 文件中为每个站点生成一系列 VirtualHost 声明。然后将生成的文件放在或/etc/httpd/conf.d//etc/apache2/sites-enabled或类似的地方,取决于您的目标操作系统)中

通常对于简单的情况,管理员只需手动编写 Apache 配置即可。但是,如果您要管理的网站不止几个,或者想要定期自动更改它们,那么最简单的方法就是使用模板系统,例如jinja2或者埃鲁比斯,(或者如果您更熟悉,可以使用 bash、python、perl 等来执行,或者甚至使用 Chef 或 Ansible,如果您想走 DevOps 路线!)

我认为您可能仍需要添加重写条件来解决提供正确的 Error.html 的问题,但ServerNameAlias和的主要问题DocumentRoot已经使用模板系统解决了。

如果您有一个通配符域记录并将*.example.org其指向服务器,则将ServerName完成ServerAlias剩下的工作......

基本上,网站结构在 yaml 中是这样的;

---
sites:
- server_name: www.example.org
  server_alias: example.org
  document_root: "/var/www/example.org/www"
- server_name: foo.example.org
  document_root: "/var/www/example.org/foo"
- server_name: bar.example.org
  document_root: "/var/www/example.org/bar/public"
- server_name: foobar.example.org
  document_root: "/var/www/example.org/foobar"
  custom_error: "/error.html"

您可以使用 jinja2 模板将其呈现到 apache 配置文件中。模板看起来类似于以下内容;

{% for site in sites %}
    <VirtualHost *:80  >
      ServerName {{ site.server_name }}
      {% if is defined site.server_alias %}ServerAlias {{ site.server_alias }}{% end if %}
      DocumentRoot {{ document_root }}

      {% if is defined site.custom_error %}ErrorDocument 404  {{ site.custom_error  }}{% endif %}

      <Directory {{ document_root }} >
        Options FollowSymLinks
        AllowOverride FileInfo Options
        Order allow,deny
        Allow from all
      </Directory>
    </VirtualHost>
{% endfor %}

它将为 VirtualHosts 生成一个如下所示的配置;

<VirtualHost *:80  >
  ServerName www.example.org
  ServerAlias example.org
  DocumentRoot /var/www/example.org/www

  <Directory /var/www/example.org/www>
    Options FollowSymLinks
    AllowOverride FileInfo Options
    Order allow,deny
    Allow from all
  </Directory>
</VirtualHost>

<VirtualHost *:80  >
  ServerName foo.example.org
  DocumentRoot /var/www/example.org/foo

  <Directory /var/www/example.org/foo>
    Options FollowSymLinks
    AllowOverride FileInfo Options
    Order allow,deny
    Allow from all
  </Directory>
</VirtualHost>

<VirtualHost *:80  >
  ServerName bar.example.org
  DocumentRoot /var/www/example.org/bar/public
  <Directory /var/www/example.org/bar>
    Options FollowSymLinks
    AllowOverride FileInfo Options
    Order allow,deny
    Allow from all
  </Directory>
</VirtualHost>

<VirtualHost *:80  >
  ServerName foobar.example.org
  DocumentRoot /var/www/example.org/foobar
  ErrorDocument 404 http://www.example.org/error.html
  <Directory /var/www/example.org/bar>
    Options FollowSymLinks
    AllowOverride FileInfo Options
    Order allow,deny
    Allow from all
  </Directory>
</VirtualHost>

基本上,您可以用 yaml(或 json)表达您的需求,然后使用模板工具将其转换为所需的配置。例如,此工具只需获取 j2 文件和 yaml 文件并将其呈现出来;

https://github.com/kolypto/j2cli

这基本上就是 ansible 和 chef 等工具的设计目的,事实上 ansible 使用 jinja2 模板,而 chef 使用 erubis。然而 chef 和 ansible 都相当复杂,如果你想添加其他内容(例如添加 mysql 数据库或配置 SSL 证书),那么它们会很有用,那么你可能会使用 chef/ansible 而不是直接使用模板...

相关内容