apache - 在配置文件和 .htaccess 的 Apache 指令中使用 RegEx

如果我理解正确,下一个代码中的表达式 .ht* 将匹配以 .ht 开头的所有内容,所以我的 .ht_lalala 是安全的。

<Files ".ht*">
    Require all denied
</Files>

但是下一个呢?

(^\.ht|~$|back|BACK|backup|BACKUP$)

匹配文件是否正确:.htaccessbackbackupBACKUP?否则接下来会更好

(^\.ht*|back*|BACK*$)

我想了解的是 ~$ 在我的代码中的实际含义(在 RegEx 模式中)。我不知道为什么以及何时将它放在那里,但我的代码中有它,现在我怀疑它是否正确。

我知道关于 RegEx 的基本知识,什么是 ^$,并且 * 表示先前文本/标记中的 0 或 N,但 ~ 在模式中没有意义,除非它只是一个简单的字符,除了字面上匹配 ~ 之外什么都不做。我已经阅读了 Apache 文档,我猜想多个匹配 FilesMatch 和 DirectoryMatch 更好,但是正则表达式也可以用于指令:文件和目录,加上 ~ 字符,如文档示例中所述。

<Files ~ "\.(gif|jpe?g|png)$">
    #...
</Files>

好吧,我真正想要的是知道如何匹配不同的文件或目录。

还有一件事,我应该逃避 . 吗?因为默认 httpd.conf 不这样做。或者它只是 httpd.conf 和 .htaccess 不同(这对我来说没有意义)

更新

回答我自己的问题,我如何与 RegEx 中的任何一个匹配 .ht、.htaccess、.htpasswd、back、BACK、backup、BACKUP,首先我决定在名称中使用 .(点)任何我想隐藏的东西。其次,我发现简洁的模式 ^(\..*)$ 可以完成这项工作,会给我我需要的东西。或者 ^\. https://stackoverflow.com/a/72291982/10324990 所以,如果将来我想隐藏一些东西,我只需在名称的开头添加 . 即可。

我们开始吧,下一个代码将拒绝从网络访问任何名称以 . 开头的文件和目录(已测试,有效)

RegEx 模式匹配:

<FilesMatch "^\.">
    Require all denied
</FilesMatch>

<DirectoryMatch "^\.">
    Require all denied
</DirectoryMatch>

在精彩的解释中https://stackoverflow.com/a/72291982/10324990我的方法,所以我坚持这个(经过测试,有效)

通配符字符串匹配:

<Files ".*">
    Require all denied
</Files>

<Directory ".*">
    Require all denied
</Directory>

回答1

<Files ".ht*">

在这种情况下,.ht* 不是正则表达式 (regex)。它是一个“通配符字符串”,其中 ? 匹配任何单个字符,而 * 匹配任何字符序列。 (虽然这也是一个有效的 regex - regex 会以不同的方式匹配)。

但是下一个呢?

(^\.ht|~$|back|BACK|backup|BACKUP$)

这是一个 regex (它不能像你上面写的那样在 <Files> 指令中使用,没有启用与 ~ 参数匹配的 regex 模式 - 正如你稍后使用的那样。)

在这个 regex 中,~$ 匹配任何以文字 ~(波浪字符)结尾的字符串。这有时用于标记备份文件。

它也符合...

  • 任何以 .ht 开头的字符串(自然包括 .htaccess)。
  • 任何包含 backBACKbackup 的字符串(匹配 backup 显然是多余的)。
  • 任何以 BACKUP 结尾的字符串。

因此,这看起来不像你认为它正在做的那样。

否则接下来会更好

(^\.ht*|back*|BACK*$)

虽然这是一个有效的 regex,但您显然已恢复为“通配符”模式匹配的混合。请记住,在 regex 中,* 量词匹配前一个标记 0 次或更多次。它不匹配“任何字符”,如通配符模式匹配。

这仍然匹配“.htaccess”,但只是因为模式没有锚定。例如,^\.ht*$(带有字符串结尾锚)将不匹配“.htaccess”。

<Files ~ "\.(gif|jpe?g|png)$">

使用 Files 指令,~ 参数启用 regex 模式匹配。 (正如您所说。)这与在 regex 模式本身中使用 ~ 时完全不同。

还有一件事,我应该逃避 . 吗?因为默认 httpd.conf 不这样做。或者只是 httpd.conf 和 .htaccess 不同(这对我来说没有意义)

我觉得你把事情搞混了。在您的第一个示例中,它不是 regex,而是“通配符”模式(如上所述)。在这种情况下,. 不得进行反斜杠转义。它匹配文字 .(点)。 . 在这里没有特殊含义。只有当您需要匹配正则表达式中的文字点时,才应转义 .

例如,以下是等价的:

# Wild-card string match
<Files ".ht*">

# Regex pattern match
<Files ~ "^\.ht">

(但是,最好使用 FilesMatch 而不是 Files ~ 以避免任何混淆。FilesMatch 是“较新”的语法。)

httpd.conf.htaccess 在这方面没有区别。

更新:

我发现简洁的模式 ^(\..*)$ 可以完成这项工作......

我们开始吧,接下来的代码将拒绝从网络访问任何名称以 . 开头的文件和目录(经过测试,有效)

<FilesMatch "^(\..*)$">
    Require all denied
</FilesMatch>

这可以简化。您不需要逐字匹配整个文件名。您只需要断言文件名以点开头(这样效率更高)。因此,您不需要捕获(带括号的子模式)文件名 - 您没有对它做任何事情。

要使用 regex 断言文件名以点开头,然后只需使用 ^\. - 仅此而已。例如:

<FilesMatch "^\.">

请记住,默认情况下 regex 量词(例如 *)是贪婪的,因此在匹配文件名时,您不需要遵循像 .* 这样的带有字符串结尾锚点的模式。因此, regex ^.*$.* 在这种情况下实际上是相同的。两者都匹配整个文件名。 (在此上下文中没有换行符。)

这可以通过完全不使用 regex 并使用带有普通 <Files> 指令的通配符字符串模式来进一步“简化”。例如,这与以下内容相同:

<Files ".*">

注意:这不是 regex。它是一个文字点,后跟任意数量的字符(通配符语法)。

回答2

https://httpd.apache.org/docs/2.4/mod/core.html#files 涵盖了这一点。

~ 启用 regex。没有它,您只能访问通配符 ?*

据我所知Apache 使用regex 的PCRE 风格。

因此,一旦您通过 ~ 启用了 regex,然后使用 https://regex101.com/r/lPkMHK/1 来测试您编写的 regex 的行为。

相似文章

最新文章