完全限定的域名验证



是否有一种快速而肮脏的方法来验证是否输入了正确的FQDN?请记住,没有DNS服务器或Internet连接,因此必须通过regex/awk/sed进行验证。

有什么想法吗?

(?=^.{4,253}$)(^((?!-)[a-zA-Z0-9-]{1,63}(?<!-).)+[a-zA-Z]{2,63}$)

regex充其量只能是类似的东西,而且规则会随着时间的推移而变化。上面的regex是在考虑以下内容的情况下编写的,并且特定于主机名-

主机名由一系列用点连接的标签组成。每个标签的长度为1到63个字符,可能包含:

  • ASCII字母a-z(以不区分大小写的方式)
  • 数字0-9
  • 和连字符('-')

另外:

  • 标签不能以连字符开始或结束(RFC 952)
  • 标签可以以数字开头(RFC 1123)
  • 包含句点的ascii主机名的最大长度为253个字符(不包括尾随句点)(http://blogs.msdn.com/b/oldnewthing/archive/2012/04/12/10292868.aspx)
  • 主机名中不允许使用下划线(但在其他DNS类型中允许使用下划线)

一些假设:

  • TLD至少为2个字符,并且只有a-z
  • 我们希望TLD以上至少1级

结果:有效/无效

  • 911.gov-有效
  • 911-无效(无TLD)
  • a-.com-无效
  • -a.com-无效
  • a.com-有效
  • a.66-无效
  • my_host.com-无效(不受欢迎)
  • 典型主机名33.whatever.co.uk-有效

编辑:John Rix提供了regex的另一种破解方法,使TLD的规范成为可选:

(?=^.{1,253}$)(^(((?!-)[a-zA-Z0-9-]{1,63}(?<!-))|((?!-)[a-zA-Z0-9-]{1,63}(?<!-).)+[a-zA-Z]{2,63})$)
  • 911-有效
  • 911.gov-有效

编辑2:有人要求提供一个在js中工作的版本。它在js中不起作用的原因是js不支持regex look-behind。特别是代码(?<!-)-指定前一个字符不能是连字符。

不管怎样,在这里,它被重写了,没有后备——有点丑,但没有太多

(?=^.{4,253}$)(^((?!-)[a-zA-Z0-9-]{0,62}[a-zA-Z0-9].)+[a-zA-Z]{2,63}$)

你同样可以在约翰·里克斯的版本上进行类似的替换。

编辑3:如果你想允许尾随点-这在技术上是允许的:

(?=^.{4,253}.?$)(^((?!-)[a-zA-Z0-9-]{1,63}(?<!-).)+[a-zA-Z]{2,63}.?$)

我不熟悉拖尾点语法,直到@ChaimKut指出了它们,我做了一些研究

  • http://dns-sd.org./TrailingDotsInDomainNames.html
  • https://jdebp.eu./FGA/web-fully-qualified-domain-name.html

然而,在我使用的各种工具中,使用拖尾点似乎会导致一些不可预测的结果,因此建议我要小心。

如今,随着域名国际化和数千(!)个新的顶级域名,情况变得更加艰难。

简单的部分是,您仍然可以在"上拆分组件&";。

您需要一个可注册TLD的列表。有一个网站:

https://publicsuffix.org/list/effective_tld_names.dat

您只需要检查ICANN认可的。注意一个可注册TLD可以有不止一个组件;co.uk";。

然后是IDN和punycode。域现在是Unicode。例如,

"xn-nnx388a";相当于";臺灣&";。顺便提一下,这两个都是有效的顶级域名。

有关punycode转换代码,请参阅";http://golang.org/src/pkg/net/http/cookiejar/punycode.go"。

检查每个域组件的语法也有新的规则。参见RFC5890https://www.rfc-editor.org/rfc/rfc5890

组件可以是A-标签(仅限ASCII)或Unicode。ASCII标签要么遵循旧语法;xn-";,在这种情况下,他们是一个流氓Unicode字符串的版本。

Unicode的规则非常复杂,在RFC5890中给出了这些规则。这些规则旨在防止字符从左到右和从右到左混合。

对不起,没有简单的答案。

这个正则表达式就是您想要的:

(?=^.{1,254}$)(^(?:(?!d+.)[a-zA-Z0-9_-]{1,63}.?)+(?:[a-zA-Z]{2,})$)

它匹配您的示例域(groupa-zone1appserver.example.com或cod.eu等)

我试着解释一下:

(?=^.{1,254}$)匹配长度在1到254个字符之间的域名(可以以任何字符开头),如果我们假设co.uk是最小长度,它也可能是5254。

(^开始匹配

(?:定义匹配组

(?!d+.)域名不应该由数字组成,因此1234.co.uk或abc.123.uk不被接受,而1a.ko.uk是。

[a-zA-Z0-9_-]域名应由只有a-zA-Z0-9_-的单词组成

{1,63}任何域级别的长度最大为63个字符,(可能是2,63)

+

(?:[a-zA-Z]{2,})$)域名的最后一部分不应后跟任何其他单词,并且必须由至少2个字符的单词a-zA-Z 组成

我们使用此正则表达式来验证出现在野外的域。它涵盖了我所知道的所有实际用例。欢迎新的。根据我们的指导方针,它避免了非捕获组和贪婪匹配。

^(?!.*?_.*?)(?!(?:[w]+?.)?-[w.-]*?)(?![w]+?-.(?:[w.-]+?))(?=[w])(?=[w.-]*?.+[w.-]*?)(?![w.-]{254})(?!(?:.?[w-.]*?[w-]{64,}.)+?)[w.-]+?(?<![w-.]*?.[d]+?)(?<=[w-]{2,})(?<![w-]{25})$

证明和解释:https://regex101.com/r/FLA9Bv/40

验证域时有两种方法可供选择。

根据书籍FQDN匹配(理论定义,在实践中很少遇到):

  • 最大253个字符长(根据RFC-1035/3.1、RFC-2181/11)
  • 每个标签最多63个字符长(根据RFC-1035/3.1、RFC-2181/11)
  • 允许使用任何字符(根据RFC-2181/11)
  • TLD不能全部为数字(根据RFC-3696/2)
  • FQDN可以以完整的形式编写,其中包括根区域(尾随点)

实用/保守的FQDN匹配(实用定义,在实践中预期和支持):

  • 通过与以下例外/添加匹配的书籍
  • 有效字符:[a-zA-Z0-9.-]
  • 标签不能以连字符开头或结尾(根据RFC-952和RFC-1123/2.1)
  • TLD最小长度为2个字符,根据当前现有记录,最大长度为24个字符
  • 与尾随点不匹配

上面的正则表达式既包含书本上的规则,也包含实用规则。

考虑事项#1:

请注意,由于RFC-2181中放宽了要求,DNS标签几乎可以由任何符号组合组成(然而,长度限制仍然存在):

"任何可以用作任何资源记录标签的二进制字符串。DNS协议的实现不得对可使用的标签设置任何限制。特别是,DNS服务器不得拒绝为某个区域提供服务,因为该区域包含某些DNS客户端程序可能无法接受的标签";(https://www.rfc-editor.org/rfc/rfc2181#section-11)

考虑#2:

";还有一个附加规则,它本质上要求顶级域名不全是数字"(https://www.rfc-editor.org/rfc/rfc3696#section-2)

考虑到这两个因素,正确的正则表达式如下所示:

/^(?!://)(?=.{1,255}$)((.{1,63}.){1,127}(?![0-9]*$)[a-z0-9-]+.?)$/i

查看演示@http://regexr.com/3g5j0

以下表达式

(^((?=^.{4,253}$)(((http){0,1}|(http){0,1}|(ftp){0,1}|(ws){0,1})(s{0,1})://){0,1})((((?!-)[pL0-9-]{1,63})(?<!-)(.)){1,})(((?!-)[a-z0-9-]{1,63})(?<!-)((/{0,1}[pLpN?=-]*)+){1})$)

将匹配

https://www.tes1t.com/lets/to?878932572
https://www.test.co.uk/lets/to?878932572
http://www.test.com/lets/to?878932572
http://www.test.co.uk/lets/to?878932572
ftp://www.test.com/lets/to?878932572
subdomain.test.com/lets/to?878932572
subdomain.test.com/lets/to?878932572
subdomain.subdomain.test.net/lets/to?878932572
sub-domain.test.net/lets/to?878932572
sub-domain.test.net/lets-go/to?878932572
www.test.net/lets/to?878932572
www.test-test.com/
www.test-test.com
subdomain.subdomainsubdomainsuèdomainsubdomainsubdomainsubdomainsubdomain.net/let2s/to?=878932572
www.test-test.co.uk
http://www.test-test-.com/test
www.test-teèst.co.uk/lets
www.test-test.co.uk/lets/
www.test-test.co.uk/lets/to?
test-test.co.uk/lets/to?
test-test.co.uk/lets/
test-test.co.uk/lets
test-test.co.uk
http://test.com/lets/to?878932572
https://test.com/lets/to?878932572
ftp://test.com/lets/to?878932572
ftps://test.com/lets/to?878932572
ws://test.com/lets/to?878932572aa
wss://test.com/lets/to?=878932572bar
test.com
subdomain.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.khbdomainsubdomainsubdomain.test.net/lets/to?87893257

但不匹配:

www.-test-fail-.com
www.-test-fail.com
-test-fail.com
test-fail-.com
subdomain.subdomainsubdomainsubdomainsubdomainsubdomainsubdomainsubdomainsubdomainsubdomainsubdomainubdomainsubdomainsubdomain.test.net/lets/to?878932572
subdomain.subdomainsubdomainsubdcnvcnvcnofhfhghgfhvnhj-mainsubdomainsubdohhghghghfhgffgjh-gfhfdhfdghmainsubdocgvhngvnbnbmghghghaihgfjgfnfhfdghgsufghgghghhdfjgffsgfbdomainsubdomainsubdomainsubdomainsubdomainsubdomainsubdomain.test.net/lets/to?878932572
subdomain.test.test..test..test..test..test..test..test..test..test..test..test..test..test..test..test..test..test..test..test..test..test..test..test..test..test..test..test..test..test..test..test.khbdomainsubdomainsubdomain.test.net/lets/to?87893257

最新更新