如何在Apache中实现适用于所有虚拟主机的全局RewriteCond / RewriteRule?

时间:2021-05-25 20:00:24

The title pretty much says it all. :-) I have lots of virtual hosts and I want to put a single rewriting block at the top of the httpd.conf file that rewrites URLs no matter which virtual host the request might be directed to. How the heck do I do this?

标题基本概括了所有内容。 :-)我有很多虚拟主机,我想在httpd.conf文件的顶部放一个重写块,无论请求可能指向哪个虚拟主机,它都会重写URL。我怎么做到这一点?

I found this but my question is the same: how can I do this without resorting to .htaccess files and performing some other action for each virtual host?

我找到了这个,但我的问题是一样的:如果不诉诸.htaccess文件并为每个虚拟主机执行一些其他操作,我怎么能这样做?

OMGTIA!

7 个解决方案

#1


11  

Specify RewriteOptions InheritDown in the parent scope (such as httpd.conf) to get your rules applied in child Virtual Hosts without modifing them.

在父作用域(例如httpd.conf)中指定RewriteOptions InheritDown,以在子虚拟主机中应用规则而不对其进行修改。

This will only work on Virtual Hosts where the RewriteEngine directive is set to on:

这仅适用于RewriteEngine指令设置为on的虚拟主机:

Note that rewrite configurations are not inherited by virtual hosts. This means that you need to have a RewriteEngine on directive for each virtual host in which you wish to use rewrite rules.

请注意,虚拟主机不会继承重写配置。这意味着您需要为要在其中使用重写规则的每个虚拟主机指定RewriteEngine on指令。

(source)

Apache supports this since 2.4.8 (not available at the time of the original question).

Apache自2.4.8起支持此功能(原始问题时不可用)。

From documentation for RewriteOptions:

从RewriteOptions的文档:

InheritDown

If this option is enabled, all child configurations will inherit the configuration of the current configuration. It is equivalent to specifying RewriteOptions Inherit in all child configurations. See the Inherit option for more details on how the parent-child relationships are handled. Available in Apache HTTP Server 2.4.8 and later.

如果启用此选项,则所有子配置都将继承当前配置的配置。它等同于在所有子配置中指定RewriteOptions Inherit。有关如何处理父子关系的更多详细信息,请参阅继承选项。可在Apache HTTP Server 2.4.8及更高版本中使用。

InheritDownBefore

Like InheritDown above, but the rules from the current scope are applied before rules specified in any child's scope. Available in Apache HTTP Server 2.4.8 and later.

与上面的InheritDown类似,但是当前范围的规则在任何子范围中指定的规则之前应用。可在Apache HTTP Server 2.4.8及更高版本中使用。

IgnoreInherit

This option forces the current and child configurations to ignore all rules that would be inherited from a parent specifying InheritDown or InheritDownBefore. Available in Apache HTTP Server 2.4.8 and later.

此选项强制当前配置和子配置忽略将从父指定InheritDown或InheritDownBefore继承的所有规则。可在Apache HTTP Server 2.4.8及更高版本中使用。

(http://httpd.apache.org/docs/current/mod/mod_rewrite.html#rewriteoptions)

#2


11  

By default, mod_rewrite configuration settings from the main server context are not inherited by virtual hosts. To make the main server settings apply to virtual hosts, you must place the following directives in each <VirtualHost> section:

默认情况下,虚拟主机不会继承主服务器上下文中的mod_rewrite配置设置。要使主服务器设置应用于虚拟主机,必须在每个 部分中放置以下指令:

RewriteEngine On
RewriteOptions Inherit 

click http://httpd.apache.org/docs/2.2/mod/mod_rewrite.html to find more information

单击http://httpd.apache.org/docs/2.2/mod/mod_rewrite.html以查找更多信息

#3


9  

Looks like the simplest possible solution is to add

看起来最简单的解决方案是添加

RewriteOptions inherit

to each VirtualHost directive. This is at least a lot simpler than messing with .htaccess files. Apache is pretty clear on the fact that

每个VirtualHost指令。这比使用.htaccess文件搞乱要简单得多。 Apache非常清楚这一事实

by default, rewrite configurations are not inherited. This means that you need to have a RewriteEngine on directive for each virtual host in which you wish to use it. (http://httpd.apache.org/docs/1.3/mod/mod_rewrite.html)

默认情况下,不会继承重写配置。这意味着您需要为要使用它的每个虚拟主机指定RewriteEngine on指令。 (http://httpd.apache.org/docs/1.3/mod/mod_rewrite.html)

and apparently the way to change the default is via RewriteOptions in the child (vhost or director), so you have to do something in each child.

显然,更改默认值的方法是通过子级中的RewriteOptions(vhost或director),因此您必须在每个子级中执行某些操作。

#4


5  

I've never tested it, so it might not work, but I would try adding an include directive in all of the virtual host blocks to a single file. You would have to change each virtual host configuration block once, but after that, you should have a central place from which to make changes. YMMV.

我从来没有测试它,所以它可能不起作用,但我会尝试在所有虚拟主机块中添加一个include指令到一个文件。您必须更改每个虚拟主机配置块一次,但在此之后,您应该有一个可以进行更改的中心位置。因人而异。

#5


2  

If you're only trying to rewrite something in the domain part of the name, e.g. to fix a common misspelling, you don't even need the 'inherit' option. I setup a no-name virtual host to catch all invalid host names and respell them correctly before redirecting them.

如果您只是尝试重写域名的域名部分,例如要修复常见的拼写错误,你甚至不需要'继承'选项。我设置了一个无名虚拟主机来捕获所有无效的主机名,并在重定向之前正确重新分配它们。

Since this uses redirects, the appropriate virtual host will be found after the rewrites have been applied.

由于这会使用重定向,因此在应用重写后将找到相应的虚拟主机。

Options +Indexes +FollowSymLinks
RewriteEngine on
# If it begins with only domain.com, prepend www and send to www.domain.com
RewriteCond %{HTTP_HOST} ^domain [NC]
RewriteRule ^(.*) http://www.domain.com$1 [L,R=301]

# Correct misspelling in the domain name, applies to any VirtualHost in the domain
# Requires a subdomain, i.e. (serviceXXX.)domain.com, or the prepended www. from above
RewriteCond %{HTTP_HOST} ^([^.]+\.)dommmmmain\.com\.?(:[0-9]*)?$ [NC]
RewriteRule ^(.*) %{HTTP_HOST}$1 [C]
RewriteRule ^([^.]+\.)?domain.com(.*) http://$1domain.com$2 [L,R=301]

# No-name virtual host to catch all invalid hostnames and mod_rewrite and redirect them
<VirtualHost *>
    RewriteEngine on
    RewriteOptions inherit
</VirtualHost>

#6


0  

I've always used a "catch-all" VHost for directives I wanted across the board, like......

我总是使用“全能”VHost来获得我想要的指令,比如......

Listen 80
NameVirtualHost *:80

<VirtualHost *:80>
ErrorLog "/var/log/apache2/error_log"
</VirtualHost>

<VirtualHost *:80>
ServerName alloftherestoftheVHosts.com
DocumentRoot "/ServiceData/.........
............ 

And it's always seemed to work... error logs were getting combined properly, etc...... but it IS possible that this was the result of an earlier / conflicting / like-minded directive.

它总是似乎工作......错误日志正在合理地组合等......但这可能是一个早期/冲突/志同道合的指令的结果。

Personal note.. Whoever dreamed up the Apache configuration schema and syntax was a dingbat, or a group of dingbats, who spent too much time in their cave.... The whole thing should be exorcised and XMLized, or something! Although they are both wildly different... the Hello-Kitty setup process of Cherokee.. to the viciously succinct NGinx config.... are both so much more logical..

个人注意事项。无论是谁想到了Apache配置模式和语法,都是一个dingbat,或者是一群dingbats,他们在洞穴里花了太多时间......整个事情应该被驱除和XML化,或者其他东西!虽然它们两者截然不同......切诺基的Hello-Kitty设置过程......以及恶劣的简洁NGinx配置......都更加符合逻辑。

#7


0  

You may want to use InheritDownBefore to avoid having to add more junk to your vhosts.

您可能希望使用InheritDownBefore来避免向vhost添加更多垃圾。

An example of a global letsencrypt alias:

全局letsencrypt别名的示例:

# letsencrypt
<IfModule alias_module>
    Alias /.well-known/ /var/www/html/.well-known/
</IfModule>
<IfModule mod_rewrite.c>
    # prevent vhost rewrites from killing the alias
    RewriteEngine On
    RewriteOptions InheritDownBefore
    RewriteCond %{REQUEST_URI} ^/\.well\-known
    RewriteRule . - [L,PT]
</IfModule>

Then you can do this in each of your vhosts, with no other directives:

然后你可以在你的每个vhosts中执行此操作,没有其他指令:

<VirtualHost *:80>
    ....
    <IfModule mod_rewrite.c>
        RewriteEngine On
        RewriteRule ^/.*            /index.php [L,PT]
    </IfModule>
</VirtualHost>

#1


11  

Specify RewriteOptions InheritDown in the parent scope (such as httpd.conf) to get your rules applied in child Virtual Hosts without modifing them.

在父作用域(例如httpd.conf)中指定RewriteOptions InheritDown,以在子虚拟主机中应用规则而不对其进行修改。

This will only work on Virtual Hosts where the RewriteEngine directive is set to on:

这仅适用于RewriteEngine指令设置为on的虚拟主机:

Note that rewrite configurations are not inherited by virtual hosts. This means that you need to have a RewriteEngine on directive for each virtual host in which you wish to use rewrite rules.

请注意,虚拟主机不会继承重写配置。这意味着您需要为要在其中使用重写规则的每个虚拟主机指定RewriteEngine on指令。

(source)

Apache supports this since 2.4.8 (not available at the time of the original question).

Apache自2.4.8起支持此功能(原始问题时不可用)。

From documentation for RewriteOptions:

从RewriteOptions的文档:

InheritDown

If this option is enabled, all child configurations will inherit the configuration of the current configuration. It is equivalent to specifying RewriteOptions Inherit in all child configurations. See the Inherit option for more details on how the parent-child relationships are handled. Available in Apache HTTP Server 2.4.8 and later.

如果启用此选项,则所有子配置都将继承当前配置的配置。它等同于在所有子配置中指定RewriteOptions Inherit。有关如何处理父子关系的更多详细信息,请参阅继承选项。可在Apache HTTP Server 2.4.8及更高版本中使用。

InheritDownBefore

Like InheritDown above, but the rules from the current scope are applied before rules specified in any child's scope. Available in Apache HTTP Server 2.4.8 and later.

与上面的InheritDown类似,但是当前范围的规则在任何子范围中指定的规则之前应用。可在Apache HTTP Server 2.4.8及更高版本中使用。

IgnoreInherit

This option forces the current and child configurations to ignore all rules that would be inherited from a parent specifying InheritDown or InheritDownBefore. Available in Apache HTTP Server 2.4.8 and later.

此选项强制当前配置和子配置忽略将从父指定InheritDown或InheritDownBefore继承的所有规则。可在Apache HTTP Server 2.4.8及更高版本中使用。

(http://httpd.apache.org/docs/current/mod/mod_rewrite.html#rewriteoptions)

#2


11  

By default, mod_rewrite configuration settings from the main server context are not inherited by virtual hosts. To make the main server settings apply to virtual hosts, you must place the following directives in each <VirtualHost> section:

默认情况下,虚拟主机不会继承主服务器上下文中的mod_rewrite配置设置。要使主服务器设置应用于虚拟主机,必须在每个 部分中放置以下指令:

RewriteEngine On
RewriteOptions Inherit 

click http://httpd.apache.org/docs/2.2/mod/mod_rewrite.html to find more information

单击http://httpd.apache.org/docs/2.2/mod/mod_rewrite.html以查找更多信息

#3


9  

Looks like the simplest possible solution is to add

看起来最简单的解决方案是添加

RewriteOptions inherit

to each VirtualHost directive. This is at least a lot simpler than messing with .htaccess files. Apache is pretty clear on the fact that

每个VirtualHost指令。这比使用.htaccess文件搞乱要简单得多。 Apache非常清楚这一事实

by default, rewrite configurations are not inherited. This means that you need to have a RewriteEngine on directive for each virtual host in which you wish to use it. (http://httpd.apache.org/docs/1.3/mod/mod_rewrite.html)

默认情况下,不会继承重写配置。这意味着您需要为要使用它的每个虚拟主机指定RewriteEngine on指令。 (http://httpd.apache.org/docs/1.3/mod/mod_rewrite.html)

and apparently the way to change the default is via RewriteOptions in the child (vhost or director), so you have to do something in each child.

显然,更改默认值的方法是通过子级中的RewriteOptions(vhost或director),因此您必须在每个子级中执行某些操作。

#4


5  

I've never tested it, so it might not work, but I would try adding an include directive in all of the virtual host blocks to a single file. You would have to change each virtual host configuration block once, but after that, you should have a central place from which to make changes. YMMV.

我从来没有测试它,所以它可能不起作用,但我会尝试在所有虚拟主机块中添加一个include指令到一个文件。您必须更改每个虚拟主机配置块一次,但在此之后,您应该有一个可以进行更改的中心位置。因人而异。

#5


2  

If you're only trying to rewrite something in the domain part of the name, e.g. to fix a common misspelling, you don't even need the 'inherit' option. I setup a no-name virtual host to catch all invalid host names and respell them correctly before redirecting them.

如果您只是尝试重写域名的域名部分,例如要修复常见的拼写错误,你甚至不需要'继承'选项。我设置了一个无名虚拟主机来捕获所有无效的主机名,并在重定向之前正确重新分配它们。

Since this uses redirects, the appropriate virtual host will be found after the rewrites have been applied.

由于这会使用重定向,因此在应用重写后将找到相应的虚拟主机。

Options +Indexes +FollowSymLinks
RewriteEngine on
# If it begins with only domain.com, prepend www and send to www.domain.com
RewriteCond %{HTTP_HOST} ^domain [NC]
RewriteRule ^(.*) http://www.domain.com$1 [L,R=301]

# Correct misspelling in the domain name, applies to any VirtualHost in the domain
# Requires a subdomain, i.e. (serviceXXX.)domain.com, or the prepended www. from above
RewriteCond %{HTTP_HOST} ^([^.]+\.)dommmmmain\.com\.?(:[0-9]*)?$ [NC]
RewriteRule ^(.*) %{HTTP_HOST}$1 [C]
RewriteRule ^([^.]+\.)?domain.com(.*) http://$1domain.com$2 [L,R=301]

# No-name virtual host to catch all invalid hostnames and mod_rewrite and redirect them
<VirtualHost *>
    RewriteEngine on
    RewriteOptions inherit
</VirtualHost>

#6


0  

I've always used a "catch-all" VHost for directives I wanted across the board, like......

我总是使用“全能”VHost来获得我想要的指令,比如......

Listen 80
NameVirtualHost *:80

<VirtualHost *:80>
ErrorLog "/var/log/apache2/error_log"
</VirtualHost>

<VirtualHost *:80>
ServerName alloftherestoftheVHosts.com
DocumentRoot "/ServiceData/.........
............ 

And it's always seemed to work... error logs were getting combined properly, etc...... but it IS possible that this was the result of an earlier / conflicting / like-minded directive.

它总是似乎工作......错误日志正在合理地组合等......但这可能是一个早期/冲突/志同道合的指令的结果。

Personal note.. Whoever dreamed up the Apache configuration schema and syntax was a dingbat, or a group of dingbats, who spent too much time in their cave.... The whole thing should be exorcised and XMLized, or something! Although they are both wildly different... the Hello-Kitty setup process of Cherokee.. to the viciously succinct NGinx config.... are both so much more logical..

个人注意事项。无论是谁想到了Apache配置模式和语法,都是一个dingbat,或者是一群dingbats,他们在洞穴里花了太多时间......整个事情应该被驱除和XML化,或者其他东西!虽然它们两者截然不同......切诺基的Hello-Kitty设置过程......以及恶劣的简洁NGinx配置......都更加符合逻辑。

#7


0  

You may want to use InheritDownBefore to avoid having to add more junk to your vhosts.

您可能希望使用InheritDownBefore来避免向vhost添加更多垃圾。

An example of a global letsencrypt alias:

全局letsencrypt别名的示例:

# letsencrypt
<IfModule alias_module>
    Alias /.well-known/ /var/www/html/.well-known/
</IfModule>
<IfModule mod_rewrite.c>
    # prevent vhost rewrites from killing the alias
    RewriteEngine On
    RewriteOptions InheritDownBefore
    RewriteCond %{REQUEST_URI} ^/\.well\-known
    RewriteRule . - [L,PT]
</IfModule>

Then you can do this in each of your vhosts, with no other directives:

然后你可以在你的每个vhosts中执行此操作,没有其他指令:

<VirtualHost *:80>
    ....
    <IfModule mod_rewrite.c>
        RewriteEngine On
        RewriteRule ^/.*            /index.php [L,PT]
    </IfModule>
</VirtualHost>