2012-08-04 13 views
17

Gibt es einen schnellen und schmutzigen Weg, um zu validieren, ob der korrekte FQDN eingegeben wurde? Denken Sie daran, dass kein DNS-Server oder keine Internetverbindung besteht, daher muss die Validierung über regex/awk/sed erfolgen.Vollqualifizierte Überprüfung des Domänennamens

Irgendwelche Ideen?

+0

Nicht wirklich .. Zumindest wird es nicht zuverlässig sein. Sie können überprüfen, ob der TLD-Teil gültig ist, indem Sie eine Liste Ihrer eigenen TLDs führen (die auf dem neuesten Stand gehalten werden müssen), aber ansonsten haben Sie kein Glück :) – favoretti

+1

Versuchen Sie es, es ist eine Regex : http://stackoverflow.com/questions/4912520/validate-fqdn-in-c-sharp – tombolinux

+0

gut meine Idee war zu überprüfen, dass der Benutzer einen gültigen DNS-Namen zB groupa-zone1appserver.example.com wie eingegeben hat ein Standard. – Riaan

Antwort

8

Es ist jetzt schwieriger, was mit internationalisierten Domainnamen und mehreren tausend (!) Neuen TLDs.

Der einfache Teil ist, dass Sie die Komponenten noch auf "." Teilen können.

Sie benötigen eine Liste registrierbarer TLDs. Es gibt einen Ort dafür:

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

Sie müssen nur die ICANN anerkannte diejenigen überprüfen. Beachten Sie, dass eine registrierbare TLD mehrere Komponenten enthalten kann, z. B. "co.uk".

Dann gibt es IDN und Punycode. Domänen sind jetzt Unicode. Beispiel:

"xn - nnx388a" entspricht "臺灣". Beides sind übrigens gültige TLDs.

Für den Punycode-Umwandlungscode siehe "http://golang.org/src/pkg/net/http/cookiejar/punycode.go".

Die Überprüfung der Syntax jeder Domänenkomponente enthält ebenfalls neue Regeln. Siehe RFC5890 unter http://tools.ietf.org/html/rfc5890

Komponenten können entweder A-Labels (nur ASCII) oder Unicode sein. ASCII-Beschriftungen folgen entweder der alten Syntax oder beginnen mit "xn--". In diesem Fall sind sie eine punycode Version einer Unicode-Zeichenkette.

Die Regeln für Unicode sind sehr komplex und werden in RFC5890 angegeben. Die Regeln sollen verhindern, dass Zeichen von links nach rechts und von rechts nach links gemischt werden.

Entschuldigung, es gibt keine einfache Antwort.

6

Diese Regex ist, was Sie wollen:

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

Es Ihrem Beispiel Domain übereinstimmen (groupa-zone1appserver.example.com oder cod.eu etc ...)

Ich werde versuchen zu erklären, :

(?=^.{1,254}$) entspricht Domänennamen (die mit einem beliebigen Zeichen beginnen können), die zwischen 1 und 254 Zeichen lang sind, es könnte auch 5,254 sein, wenn wir annehmen, dass co.uk die minimale Länge ist.

(^ Ausgangs Spiel

(?: definieren eine passende Gruppe

(?!\d+\.) der Domain-Name sollte nicht von Zahlen bestehen, so 1234.co.uk abc.123.uk oder nicht, während 1a akzeptiert. ko.uk ja.

[a-zA-Z0-9_\-] den Domänennamen sollten durch Wörter mit nur a-zA-Z0-9_-

{1,63} die Länge jeder Domain-Ebene ist maximal 63 Zeichen,

zusammengesetzt sein (es könnte sein, 2,63)

+ und

(?:[a-zA-Z]{2,})$) der letzte Teil des Domain-Namen von keinem anderen Wort gefolgt werden sollten, und müssen von einem Wort mindestens 2 char a-zA-Z

+1

Möchten Sie die Notation erklären? Was macht es mit 'ac.uk'? Das ist kein gültiger FQDN. es ist eine Middlevel Domain unter der Ländercode TLD. –

+0

aa.com zum Beispiel ist ein fqdn dieser Regex passt nur Strings, die durch Punkte unterteilt sind und die letzte Zeichenfolge ist mindestens 2 char. – tombolinux

+0

Mit einer Regex können Sie nur eine Syntax, nicht eine echte DNS FQDN. – tombolinux

31
bestehen

Regex wird immer eine Annäherung für Dinge wie diese sein, und Regeln ändern sich im Laufe der Zeit. die oben regex wurde mit der folgenden in Verstand geschrieben und ist spezifisch für Host-Namen -

Host-Namen aus einer Reihe von Etiketten mit Punkten verketteten zusammengesetzt sind. Jedes Etikett ist 1 bis 63 Zeichen lang und enthält:

  • die ASCII-Buchstaben A bis Z (in einem Fall insensitive Weise),
  • die Ziffern 0-9,
  • und den Bindestrich ('- ').

Zusätzlich:

  • Etiketten können nicht mit Bindestrichen (RFC 952)
  • Etiketten können mit Zahlen (RFC 1123)
  • max Länge von ascii Hostnamen beginnen mit Punkten 253 Zeichen beginnen oder enden (ohne abschließenden Punkt) (http://blogs.msdn.com/b/oldnewthing/archive/2012/04/12/10292868.aspx)
  • Unterstriche sind in Hostnamen nicht erlaubt (sind aber in anderen DNS-Typen zulässig)

einige Annahmen:

  • TLD mindestens 2 Zeichen und nur az
  • wir mindestens 1 Ebene über TLD wollen

Ergebnisse: gültig/ungültig

  • 911.gov - gültig
  • 911 - ungültig (keine TLD)
  • a-.com - ungültig
  • -a.com - ungültig
  • a.com - gültig
  • A.66 - ungültig
  • my_host.com - ungültig (undescore)
  • typisch -hostname33.whatever.co.uk - gültig

EDIT: John Rix eine alternative Hack des Regex zur Verfügung gestellt, um die Spezifikation eines TLD zu machen optional:

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

EDIT 2: jemand für eine Version gefragt, die in js funktioniert. Der Grund, warum es in js nicht funktioniert, ist, weil js nicht Regex Look hinterher unterstützt. speziell der Code (?<!-) - die angibt, dass das vorherige Zeichen kein Bindestrich sein kann.

wie auch immer, hier ist es ohne die Lookbehind neu geschrieben - ein wenig hässlicher, aber nicht viel

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

Sie ebenfalls einen ähnlichen Ersatz für John Rix-Version machen könnte.

EDIT 3: wenn Sie wollen Hinter Punkte ermöglichen - die technisch erlaubt ist:

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

ich mit nachfolgendem Punkt-Syntax nicht vertraut war bis @ChaimKut sie wies darauf hin, und ich habe einige Nachforschungen

Die Verwendung von abschließenden Punkten scheint jedoch in den verschiedenen Werkzeugen, mit denen ich gespielt habe, etwas unvorhersehbare Ergebnisse zu verursachen, daher würde ich etwas Vorsicht walten lassen.

+1

Hier ist eine (etwas hacky) alternative Version, die auch einen Hostnamen ohne zugehörige Domain validieren würde. Irgendwelche Verbesserungen? '(? = ^. {1,254} $) (^ (((?! -) [a-zA-Z0-9 -] {1,63} (?

+0

@John Rix: Ihre Regex sieht so aus funktioniert, aber viele Leute kopieren/einfügen es wird fehlschlagen, da StackExchange unsichtbare Zeichen in die HTML-Quelle von Kommentaren für Formatierungszwecke einfügt - sehen Sie sich die HTML-Quelle an und lesen Sie http://meta.stackexchange.com/questions/170970/Occasionally- the-unicode-zeichenfolge-u200c-u200b-zwnj-zwsp-is-insert – bkr

+0

Dank @bkr, wusste das nicht. Mag nicht, dass es eine Lösung gibt, aber zumindest hast du diese Falle für Uneingeweihte hier enthüllt! –

1

BETRACHT # 1:

Bitte beachten Sie, dass aufgrund der entspannten Anforderungen in RFC-2181 DNS-Etikett von so ziemlich jede Kombination von Symbolen bestehen kann (jedoch sind die Längenbeschränkungen immer noch da):

" Jede beliebige binäre Zeichenfolge kann als Bezeichnung für einen beliebigen Ressourceneintrag verwendet werden Implementierungen der DNS-Protokolle dürfen den verwendbaren Bezeichnungen keine Einschränkungen auferlegen Insbesondere DNS-Server dürfen die Bereitstellung einer Zone nicht verweigern, da sie Beschriftungen enthält das ist für einige DNS-Client-Programme möglicherweise nicht akzeptabel. "(https://tools.ietf.org/html/rfc2181#section-11)

BETRACHT # 2:

"Es gibt eine zusätzliche Regel, die im Wesentlichen, dass Domain-Namen der obersten Ebene erfordert nicht alle numerischen sein" (https://tools.ietf.org/html/rfc3696#section-2)

Unter Berücksichtigung diese beiden Überlegungen, sieht die richtige Regex wie folgt aus:

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

Siehe Demo @http://regexr.com/3g5j0

Verwandte Themen