在配置文件和 .htaccess 中的 Apache 指令中使用 RegEx
Using RegEx in Apache's directives in config files and .htaccess
如果我理解正确,下一段代码中的表达式 .ht*
将匹配所有以 .ht 开头的内容,所以我的 .ht_lalala
是安全的。
<Files ".ht*">
Require all denied
</Files>
但是下一个呢?
(^\.ht|~$|back|BACK|backup|BACKUP$)
匹配文件是否正确:.htaccess
、back
、backup
、BACKUP
?或者下一个会更好
(^\.ht*|back*|BACK*$)
我想了解的是 ~$
在我的代码中(在 RegEx 模式中)的实际含义。我不知道为什么以及什么时候把它放在那里,但我的代码中有它,现在我怀疑它是否正确。
我了解 RegEx 的基本知识,什么是 ^
和 $
,*
表示前面 text/token 中的 0 或 N,但是 ~
在模式内部没有意义,除非它只是一个简单的字符并且它除了字面上匹配 ~
什么都不做。我读过 Apache 文档,我想对于多个匹配 FilesMatch 和 DirectoryMatch 更好,但是正则表达式也可以用于指令:文件和目录,添加 ~ 字符,如文档示例中所述。
<Files ~ "\.(gif|jpe?g|png)$">
#...
</Files>
好吧,我真正想要的是知道如何匹配不同的文件或目录。
还有一件事,我应该转义 .
吗?因为默认 httpd.conf 不这样做。或者它只是 httpd.conf 和 .htaccess 的不同(这对我来说没有意义)
更新
回答我自己的问题,首先我如何与 RegEx 匹配 .ht、.htaccess、.htpasswd、back、BACK、backup、BACKUP我决定在我想隐藏的任何东西的名称中使用 .
(点)。其次,我发现简洁的模式 ^(\..*)$
会完成这项工作,会给我我需要的东西。或 ^\.
因此,如果以后我想隐藏某些内容,我只需在名称的开头添加 .
。
我们开始吧,下一段代码将拒绝从网络访问名称以 .
开头的任何文件和目录(已测试,有效)
RegEx 模式匹配:
<FilesMatch "^\.">
Require all denied
</FilesMatch>
<DirectoryMatch "^\.">
Require all denied
</DirectoryMatch>
并且在精彩的解释中 我的方法,所以我坚持这个(经过测试,有效)
通配符字符串匹配:
<Files ".*">
Require all denied
</Files>
<Directory ".*">
Require all denied
</Directory>
Apache manual 涵盖了这一点。
~
启用正则表达式。没有它,您只能访问通配符 ?
和 *
.
据我所知,Apache 使用正则表达式的 PCRE 风格。
因此,一旦您通过 ~
启用了正则表达式,然后使用 https://regex101.com/r/lPkMHK/1 来测试您编写的正则表达式的行为。
<Files ".ht*">
在此上下文中,.ht*
不是 正则表达式 (regex)。它是一个“wild-card 字符串”,其中 ?
匹配任何单个字符,*
匹配任何字符序列。 (虽然这也是一个有效的正则表达式 - 正则表达式会以不同的方式匹配)。
But what about next one?
(^\.ht|~$|back|BACK|backup|BACKUP$)
这是一个正则表达式(它不能在 <Files>
指令中使用,正如您在上面所写的那样,如果没有启用与 ~
参数匹配的正则表达式模式 - 正如您稍后使用的那样。)
在此正则表达式中,~$
匹配任何以文字 ~
(波浪字符)结尾的字符串。这有时用于标记 backup 个文件。
它也匹配...
- 任何以
.ht
开头的字符串(自然包括 .htaccess
)。
- 任何包含
back
或BACK
或backup
的字符串(匹配backup
显然是多余的)。
- 任何以
BACKUP
结尾的字符串。
因此,这看起来并不像您认为的那样。
Or next will be better instead
(^\.ht*|back*|BACK*$)
虽然这是一个有效的正则表达式,但您显然已经恢复到“wild-card”模式匹配的混合。请记住,在正则表达式中,*
量词匹配 previous 标记 0 次或更多次。它不匹配“任何字符”,如 wild-card 模式匹配。
这仍然匹配“.htaccess”,但这只是因为模式没有锚定。例如,^\.ht*$
(带有 end-of-string 锚点)将 不 匹配“.htaccess”。
<Files ~ "\.(gif|jpe?g|png)$">
使用 Files
指令,~
参数启用正则表达式模式匹配。 (正如您所说。)这与在正则表达式模式本身内部使用 ~
时完全不同。
One more thing, should I escape the .
? Because default httpd.conf doesn't do so. Or it's just different for httpd.conf and .htaccess (which doesn't make sense to me)
我认为你把事情搞混了。在您的第一个示例中,它不是正则表达式,而是“wild-card”模式(如上所述)。在这种情况下,.
不能是 backslash-escaped。它匹配文字 .
(点)。 .
在这里没有特殊含义。只有在需要匹配 正则表达式 .
中的文字点时,才应转义 .
例如,以下是等价的:
# Wild-card string match
<Files ".ht*">
和
# Regex pattern match
<Files ~ "^\.ht">
(但是,最好使用 FilesMatch
而不是 Files ~
以避免混淆。FilesMatch
是“较新”的语法。)
httpd.conf
和.htaccess
在这方面没有区别。
更新:
I found out that laconic pattern ^(\..*)$
will do the job ...
Here we go, next code will deny access from the web to any files and
directories which names start with .
(tested, works)
<FilesMatch "^(\..*)$">
Require all denied
</FilesMatch>
这可以简化。您不需要完全匹配整个文件名。您只需要断言文件名以点开头(这样效率更高)。因此,您不需要 捕获 (带括号的子模式)文件名 - 您没有对它做任何事情。
要使用正则表达式断言文件名以点开头,则只需使用 ^\.
- 仅此而已。例如:
<FilesMatch "^\.">
请记住,正则表达式量词(例如 *
)默认为 greedy,因此您无需遵循 .*
这样的模式匹配文件名时带有 end-of-string 锚点。因此,正则表达式 ^.*$
和 .*
在这种情况下实际上是相同的。两者都匹配整个文件名。 (在此上下文中没有换行符。)
这可以进一步“简化”,方法是根本不使用正则表达式,而是使用带有原始 <Files>
指令的 wild-card 字符串模式。例如,这等同于:
<Files ".*">
注意:这不是正则表达式。它是一个文字点,后跟任意数量的字符(wild-card 语法)。
如果我理解正确,下一段代码中的表达式 .ht*
将匹配所有以 .ht 开头的内容,所以我的 .ht_lalala
是安全的。
<Files ".ht*">
Require all denied
</Files>
但是下一个呢?
(^\.ht|~$|back|BACK|backup|BACKUP$)
匹配文件是否正确:.htaccess
、back
、backup
、BACKUP
?或者下一个会更好
(^\.ht*|back*|BACK*$)
我想了解的是 ~$
在我的代码中(在 RegEx 模式中)的实际含义。我不知道为什么以及什么时候把它放在那里,但我的代码中有它,现在我怀疑它是否正确。
我了解 RegEx 的基本知识,什么是 ^
和 $
,*
表示前面 text/token 中的 0 或 N,但是 ~
在模式内部没有意义,除非它只是一个简单的字符并且它除了字面上匹配 ~
什么都不做。我读过 Apache 文档,我想对于多个匹配 FilesMatch 和 DirectoryMatch 更好,但是正则表达式也可以用于指令:文件和目录,添加 ~ 字符,如文档示例中所述。
<Files ~ "\.(gif|jpe?g|png)$">
#...
</Files>
好吧,我真正想要的是知道如何匹配不同的文件或目录。
还有一件事,我应该转义 .
吗?因为默认 httpd.conf 不这样做。或者它只是 httpd.conf 和 .htaccess 的不同(这对我来说没有意义)
更新
回答我自己的问题,首先我如何与 RegEx 匹配 .ht、.htaccess、.htpasswd、back、BACK、backup、BACKUP我决定在我想隐藏的任何东西的名称中使用 .
(点)。其次,我发现简洁的模式 ^(\..*)$
会完成这项工作,会给我我需要的东西。或 ^\.
.
。
我们开始吧,下一段代码将拒绝从网络访问名称以 .
开头的任何文件和目录(已测试,有效)
RegEx 模式匹配:
<FilesMatch "^\.">
Require all denied
</FilesMatch>
<DirectoryMatch "^\.">
Require all denied
</DirectoryMatch>
并且在精彩的解释中
通配符字符串匹配:
<Files ".*">
Require all denied
</Files>
<Directory ".*">
Require all denied
</Directory>
Apache manual 涵盖了这一点。
~
启用正则表达式。没有它,您只能访问通配符 ?
和 *
.
据我所知,Apache 使用正则表达式的 PCRE 风格。
因此,一旦您通过 ~
启用了正则表达式,然后使用 https://regex101.com/r/lPkMHK/1 来测试您编写的正则表达式的行为。
<Files ".ht*">
在此上下文中,.ht*
不是 正则表达式 (regex)。它是一个“wild-card 字符串”,其中 ?
匹配任何单个字符,*
匹配任何字符序列。 (虽然这也是一个有效的正则表达式 - 正则表达式会以不同的方式匹配)。
But what about next one?
(^\.ht|~$|back|BACK|backup|BACKUP$)
这是一个正则表达式(它不能在 <Files>
指令中使用,正如您在上面所写的那样,如果没有启用与 ~
参数匹配的正则表达式模式 - 正如您稍后使用的那样。)
在此正则表达式中,~$
匹配任何以文字 ~
(波浪字符)结尾的字符串。这有时用于标记 backup 个文件。
它也匹配...
- 任何以
.ht
开头的字符串(自然包括.htaccess
)。 - 任何包含
back
或BACK
或backup
的字符串(匹配backup
显然是多余的)。 - 任何以
BACKUP
结尾的字符串。
因此,这看起来并不像您认为的那样。
Or next will be better instead
(^\.ht*|back*|BACK*$)
虽然这是一个有效的正则表达式,但您显然已经恢复到“wild-card”模式匹配的混合。请记住,在正则表达式中,*
量词匹配 previous 标记 0 次或更多次。它不匹配“任何字符”,如 wild-card 模式匹配。
这仍然匹配“.htaccess”,但这只是因为模式没有锚定。例如,^\.ht*$
(带有 end-of-string 锚点)将 不 匹配“.htaccess”。
<Files ~ "\.(gif|jpe?g|png)$">
使用 Files
指令,~
参数启用正则表达式模式匹配。 (正如您所说。)这与在正则表达式模式本身内部使用 ~
时完全不同。
One more thing, should I escape the
.
? Because default httpd.conf doesn't do so. Or it's just different for httpd.conf and .htaccess (which doesn't make sense to me)
我认为你把事情搞混了。在您的第一个示例中,它不是正则表达式,而是“wild-card”模式(如上所述)。在这种情况下,.
不能是 backslash-escaped。它匹配文字 .
(点)。 .
在这里没有特殊含义。只有在需要匹配 正则表达式 .
.
例如,以下是等价的:
# Wild-card string match
<Files ".ht*">
和
# Regex pattern match
<Files ~ "^\.ht">
(但是,最好使用 FilesMatch
而不是 Files ~
以避免混淆。FilesMatch
是“较新”的语法。)
httpd.conf
和.htaccess
在这方面没有区别。
更新:
I found out that laconic pattern
^(\..*)$
will do the job ...Here we go, next code will deny access from the web to any files and directories which names start with
.
(tested, works)<FilesMatch "^(\..*)$"> Require all denied </FilesMatch>
这可以简化。您不需要完全匹配整个文件名。您只需要断言文件名以点开头(这样效率更高)。因此,您不需要 捕获 (带括号的子模式)文件名 - 您没有对它做任何事情。
要使用正则表达式断言文件名以点开头,则只需使用 ^\.
- 仅此而已。例如:
<FilesMatch "^\.">
请记住,正则表达式量词(例如 *
)默认为 greedy,因此您无需遵循 .*
这样的模式匹配文件名时带有 end-of-string 锚点。因此,正则表达式 ^.*$
和 .*
在这种情况下实际上是相同的。两者都匹配整个文件名。 (在此上下文中没有换行符。)
这可以进一步“简化”,方法是根本不使用正则表达式,而是使用带有原始 <Files>
指令的 wild-card 字符串模式。例如,这等同于:
<Files ".*">
注意:这不是正则表达式。它是一个文字点,后跟任意数量的字符(wild-card 语法)。