Kann ich eine DNS-Suche (Hostname zu IP-Adresse) mit clientseitigem Javascript durchführen?

91

Ich möchte clientseitiges Javascript verwenden, um eine DNS-Suche (Hostname zu IP-Adresse) vom Client-Computer aus durchzuführen. Ist das möglich?

Noah Jacobson
quelle
5
Viele der Antworten auf diese Frage scheinen zu empfehlen, die Auflösungsserverseite zu verwenden. Je nach Anwendungsfall reicht das möglicherweise nicht aus. Wenn der Dienst, den Sie suchen, beispielsweise GSLB verwendet, wird möglicherweise eine andere IP zurückgegeben, je nachdem, wo sich der Benutzer befindet. Infolgedessen ist die Antwort, die der serverseitige Code erhält, wahrscheinlich eine andere Antwort als die, die der Browser erhalten hätte. Davon abgesehen habe ich noch keine alternative Lösung für diejenigen, die sich für diesen Unterschied interessieren.
Ilan Rabinovitch

Antworten:

34

In der Javascript-Standardbibliothek gibt es keine Vorstellung von Hosts oder IP-Adressen. Sie müssen also auf einen externen Dienst zugreifen, um nach Hostnamen für Sie zu suchen.

Ich empfehle, einen CGI-Bin zu hosten, der die IP-Adresse eines Hostnamens nachschlägt und über Javascript darauf zugreift.

Hans Sjunnesson
quelle
26
CGI-Bin? Das ist alte Schule. Ich mag das!
Andrew Hedges
10
Dies war zum Zeitpunkt des Schreibens (2008) der Fall. Dies ist 6 Jahre später nicht mehr der Fall: Siehe meinen Kommentar zu WebRTC auf derselben Seite. (Leider verweist Google bei der Suche nach einer Lösung für das IP-Adressproblem immer noch auf diesen Thread, was dazu führen kann, dass Personen in die falsche Richtung weisen.)
Earizon
1
@earizon - Ihre Antwort ist auf eine andere Frage - wie Sie Ihre eigene private IP-Adresse ermitteln können.
Gene Vayngrib
Das Problem über CGI aus der Cloud wäre die Entdeckung von Intranet-Host-IPs, die von außen nicht möglich sind. Sie müssten einen lokalen Dienst auf dem Computer oder im Intranet verwenden.
Tzahi Fadida
Es gibt einen neuen vorgeschlagenen Internetstandard, mit dem Sie DNS-Anfragen über HTTPS senden können (siehe diese Antwort stackoverflow.com/a/58299823/9638991 ). In Wirklichkeit funktioniert es im Grunde genauso wie ein CGI-Bin-Skript :) (außer dass es von der IETF standardisiert wurde und eine
Menge
83

Bearbeiten : Diese Frage hat mich gejuckt, daher habe ich einen JSONP-Webservice in Google App Engine eingerichtet, der die IP-Adresse des Clients zurückgibt. Verwendung:

<script type="application/javascript">
function getip(json){
  alert(json.ip); // alerts the ip address
}
</script>

<script type="application/javascript" src="http://jsonip.appspot.com/?callback=getip"> </script>

Ja, es werden keine Server-Proxys benötigt.


Pure JS kann nicht. Wenn Sie ein Serverskript unter derselben Domäne haben, die es druckt, können Sie eine XMLHttpRequest senden, um es zu lesen.

Zach
quelle
4
Könnten Sie die Quelle in Ihrem Webdienst veröffentlichen? Es wäre schön, eine Instanz auszuführen.
Will
18
Entschuldigung, musste aber abstimmen, da ich nicht glaube, dass es die ursprüngliche Frage tatsächlich beantwortet. Sie möchten nur eine Standard-DNS-Suche, nicht die öffentliche IP des Benutzers.
Simon East
29

Sehr spät, aber ich denke, viele Leute werden immer noch über "Google Airlines" hier landen. Ein moderater Ansatz ist die Verwendung von WebRTC, für das keine Serverunterstützung erforderlich ist.

https://hacking.ventures/local-ip-discovery-with-html5-webrtc-security-and-privacy-risk/

Der nächste Code ist ein Kopieren und Einfügen von http://net.ipcalf.com/

// NOTE: window.RTCPeerConnection is "not a constructor" in FF22/23
var RTCPeerConnection = /*window.RTCPeerConnection ||*/ window.webkitRTCPeerConnection || window.mozRTCPeerConnection;

if (RTCPeerConnection) (function () {
    var rtc = new RTCPeerConnection({iceServers:[]});
    if (window.mozRTCPeerConnection) {      // FF needs a channel/stream to proceed
        rtc.createDataChannel('', {reliable:false});
    };  

    rtc.onicecandidate = function (evt) {
        if (evt.candidate) grepSDP(evt.candidate.candidate);
    };  
    rtc.createOffer(function (offerDesc) {
        grepSDP(offerDesc.sdp);
        rtc.setLocalDescription(offerDesc);
    }, function (e) { console.warn("offer failed", e); }); 


    var addrs = Object.create(null);
    addrs["0.0.0.0"] = false;
    function updateDisplay(newAddr) {
        if (newAddr in addrs) return;
        else addrs[newAddr] = true;
        var displayAddrs = Object.keys(addrs).filter(function (k) { return addrs[k]; }); 
        document.getElementById('list').textContent = displayAddrs.join(" or perhaps ") || "n/a";
    }   

    function grepSDP(sdp) {
        var hosts = []; 
        sdp.split('\r\n').forEach(function (line) { // c.f. http://tools.ietf.org/html/rfc4566#page-39
            if (~line.indexOf("a=candidate")) {     // http://tools.ietf.org/html/rfc4566#section-5.13
                var parts = line.split(' '),        // http://tools.ietf.org/html/rfc5245#section-15.1
                    addr = parts[4],
                    type = parts[7];
                if (type === 'host') updateDisplay(addr);
            } else if (~line.indexOf("c=")) {       // http://tools.ietf.org/html/rfc4566#section-5.7
                var parts = line.split(' '), 
                    addr = parts[2];
                updateDisplay(addr);
            }   
        }); 
    }   
})(); else {
    document.getElementById('list').innerHTML = "<code>ifconfig | grep inet | grep -v inet6 | cut -d\" \" -f2 | tail -n1</code>";
    document.getElementById('list').nextSibling.textContent = "In Chrome and Firefox your IP should display automatically, by the power of WebRTCskull.";
}   
earizon
quelle
19
Dies ist in der Tat eine neue Funktion, die es vor WebRTC noch nicht gab - Ihre eigene IP-Adresse zu ermitteln. Aber @noahjacobson stellte eine andere Frage - DNS-Suche von IP durch den Hostnamen von Javascript.
Gene Vayngrib
2
Sehr, sehr interessant, es ist ein Fehler oder ein Konstruktionsfehler, jedenfalls wird er irgendwann korrigiert, so dass er für langfristige Projekte nicht gut ist
e-info128
14

Die gehostete JSONP-Version funktioniert wie ein Zauber, aber es scheint, dass sie an den meisten Tagen (Eastern Time) in der Nacht über ihre Ressourcen geht, sodass ich meine eigene Version erstellen musste.

So habe ich es mit PHP geschafft:

<?php
header('content-type: application/json; charset=utf-8');

$data = json_encode($_SERVER['REMOTE_ADDR']);
echo $_GET['callback'] . '(' . $data . ');';
?>

Dann ist das Javascript genau das gleiche wie zuvor, nur kein Array:

<script type="application/javascript">
function getip(ip){
    alert('IP Address: ' + ip);
}
</script>

<script type="application/javascript" src="http://www.anotherdomain.com/file.php?callback=getip"> </script>

So einfach ist das!

Randnotiz: Reinigen Sie Ihr $ _GET unbedingt, wenn Sie es in einer öffentlich zugänglichen Umgebung verwenden!

tcole
quelle
Danke tcole! Genau das, wonach ich gesucht habe :)
jClark
Moment mal, warum überhaupt $ _GET verwenden? Wie Sie sagten, ist dies eine Sicherheitslücke. Könnte man nicht einfach verwenden: echo 'getip ('. $ Data. ');';
Deweydb
7
Entschuldigung, musste aber abstimmen, da ich nicht glaube, dass es die ursprüngliche Frage tatsächlich beantwortet. Sie möchten nur eine Standard-DNS-Suche, nicht die öffentliche IP des Benutzers.
Simon East
2
@ SimonEast Heh. Sie haben die Frage einer 7 Jahre alten Frage geändert. Tun Sie alles, was Sie brauchen, um sich selbst zu befriedigen
;-)
2
Ich habe lediglich die ursprüngliche Frage bearbeitet, um sie klarer zu machen, da ich kürzlich dieselbe Frage untersucht habe. Aus irgendeinem Grund sind die meisten Antworten hier jedoch nicht das, wonach das ursprüngliche Poster gefragt hat, und sollten unter einer anderen Frage veröffentlicht werden.
Simon East
12

Ich weiß, dass diese Frage vor sehr langer Zeit gestellt wurde, aber ich dachte, ich würde eine neuere Antwort anbieten.

DNS über HTTPS (DoH)

Sie können DNS-Abfragen über HTTPS an DNS-Resolver senden, die dies unterstützen. Der Standard für DOH ist in RFC 8484 beschrieben .

Dies ist ähnlich wie in allen anderen Antworten, nur dass DoH tatsächlich das DNS-Protokoll über HTTPS ist. Es ist auch ein "vorgeschlagener" Internetstandard und wird immer beliebter. Einige große Browser unterstützen es beispielsweise oder haben Pläne, es zu unterstützen (Chrome, Edge, Firefox), und Microsoft ist dabei, es in ihr Betriebssystem zu integrieren.

Einer der Zwecke von DoH ist:

Ermöglichen, dass Webanwendungen über vorhandene Browser-APIs auf DNS-Informationen zugreifen können, und zwar auf sichere Weise im Einklang mit CORS (Cross Origin Resource Sharing)

Es gibt ein Open-Source-Tool, das speziell für DNS-Lookups von Webanwendungen namens dohjs entwickelt wurde . Es führt DNS über HTTPS (DoH) -Drahtformatabfragen durch, wie in RFC 8484 beschrieben . Es unterstützt sowohl GET- als auch POST-Methoden.

Vollständige Offenlegung: Ich trage zu Dohjs bei.

DNS über HTTPS-JSON-APIs

Wenn Sie sich nicht mit dem DNS-Drahtformat beschäftigen möchten, bieten sowohl Google als auch Cloudflare JSON-APIs für DNS über HTTPS an.

Beispiel-Javascript-Code zum Nachschlagen von example.com mit der JSON DOH-API von Google:

var response = await fetch('https://dns.google/resolve?name=example.com');
var json = await response.json();
console.log(json);

Beispiele aus dem RFC für DOH GET und POST mit Wireformat

Hier sind die Beispiele, die der RFC sowohl für GET als auch für POST gibt (siehe https://tools.ietf.org/html/rfc8484#section-4.1.1 ):

GET Beispiel:

Die erste Beispielanforderung verwendet GET, um "www.example.com" anzufordern.

: method = GET
: Schema = https
: Authority = dnsserver.example.net
: Pfad = / dns-Abfrage? dns = AAABAAABAAAAAAAAA3d3dwdleGFtcGxlA2NvbQAAAQAB
accept = application / dns-message

POST-Beispiel:

Dieselbe DNS-Abfrage für "www.example.com" unter Verwendung der POST-Methode lautet:

: Methode = POST
: Schema = https
: Autorität = dnsserver.example.net
: Pfad = / DNS-Abfrage
akzeptieren = Anwendung / DNS-Nachricht
Inhaltstyp = Anwendung / DNS-Nachricht
Inhalt-Länge = 33

<33 Bytes, dargestellt durch die folgende Hex-Codierung> 00 00 01 00 00 01 00 00 00 00 00 03 77 77 77 07 65 78 61 6d 70 6c 65 03 63 6f 6d 00 00 01 00 01

Andere Orte zum Senden von DOH-Anfragen

Eine Liste einiger öffentlicher DNS-Resolver, die DNS über HTTPS unterstützen, finden Sie an mehreren Stellen:

Von den oben genannten Ressourcen würde ich sagen, dass die Liste in Curls Wiki und die DNSCrypt-Liste wahrscheinlich die vollständigste und am häufigsten aktualisierte sind. Die Seite von Curl enthält auch eine Liste von Open Source-Tools für DoH (Server, Proxys, Client-Bibliotheken usw.).

Kimbo
quelle
3

Ich bin mir bewusst, dass dies eine alte Frage ist, aber meine Lösung kann anderen helfen.

Ich finde, dass die JSON (P) -Dienste, die dies einfach machen, nicht ewig dauern, aber das folgende JavaScript funktioniert zum Zeitpunkt des Schreibens gut für mich.

<script type="text/javascript">function z (x){ document.getElementById('y').innerHTML=x.query }</script>
<script type='text/javascript' src='http://ip-api.com/json/zero.eu.org?callback=z'></script>

Das Obige schreibt die IP meines Servers auf die Seite, auf der er sich befindet, aber das Skript kann geändert werden, um eine beliebige IP zu finden, indem 'zero.eu.org' in einen anderen Domainnamen geändert wird. Dies kann in Aktion auf meiner Seite unter http://meon.zero.eu.org/ gesehen werden.

Neville Hillyer
quelle
Ich kann nicht verstehen, wie ich meine eigene IP-Adresse damit finden kann: <! - # echo var = "REMOTE_ADDR" -> gemäß Ihrer Website.
George Carlin
Dies ist eine Standard-Echo-Funktion, die auf den meisten Webservern verfügbar ist. Siehe: google.co.uk/…
Neville Hillyer
1
Dies ist möglicherweise die einzige Antwort, die die ursprüngliche Frage richtig und gut angeht. Leider entspricht es nicht dem vom Computer aus gesehenen Computerteil des Kunden , was eine wichtige Anforderung sein kann (oder auch nicht).
Simon East
@Simon - Wo steht "vom Computer des Kunden aus gesehen" und warum stimmt meine Antwort nicht damit überein?
Neville Hillyer
1
@Simon - Guter Punkt, aber da normalerweise clientseitiges JS vom Server bereitgestellt wird, besteht eine gute Chance, dass der Autor / Server-Besitzer diese DNS-Einschränkung kennt - könnte ein Problem für Autoren sein, die Server von Drittanbietern verwenden. Wie in den Beiträgen hier angegeben, bemüht sich die vorhandene Technologie, alle Einschränkungen in diesem Fall zu erfüllen. Meine Eingabe sollte die Lösung vermitteln, die ich auf meinem Server als am praktischsten empfunden habe.
Neville Hillyer
3

Es gibt einen Drittanbieter-Service, der eine CORS-freundliche REST-API zur Durchführung von DNS-Suchvorgängen über den Browser bereitstellt - https://exana.io/tools/dns/

user670908
quelle
1

Wie viele Leute sagten, müssen Sie einen externen Dienst nutzen und ihn anrufen. Und das bringt Ihnen nur die DNS-Auflösung aus der Serverperspektive.

Wenn das gut genug ist und Sie nur eine DNS-Auflösung benötigen, können Sie den folgenden Docker-Container verwenden:

https://github.com/kuralabs/docker-webaiodns

Endpunkte:

[GET] /ipv6/[domain]: Führen Sie eine DNS-Auflösung für eine bestimmte Domäne durch und geben Sie die zugehörigen IPv6-Adressen zurück.

 {
     "addresses": [
         "2a01:91ff::f03c:7e01:51bd:fe1f"
     ]
 }

[GET] /ipv4/[domain]: Führen Sie eine DNS-Auflösung für eine bestimmte Domäne durch und geben Sie die zugehörigen IPv4-Adressen zurück.

 {
     "addresses": [
         "139.180.232.162"
     ]
 }

Ich empfehle, dass Sie Ihren Webserver so einrichten, dass er den Proxy für den Container auf einem bestimmten Endpunkt Ihres Servers, der Ihr Javascript bereitstellt, umkehrt und ihn mit Ihren Standard-Javascript-Ajax-Funktionen aufruft.

Havok
quelle
0

Dazu müsste die Browser-Sandbox beschädigt werden. Versuchen Sie, Ihren Server die Suche durchführen zu lassen, und fordern Sie dies von der Clientseite über XmlHttp an.

Tomalak
quelle
0

Es gibt eine Javascript-Bibliothek DNS-JS.com , die genau dies tut.

DNS.Query("dns-js.com",
    DNS.QueryType.A,
    function(data) {
        console.log(data);
});
Fiach Reid
quelle
1
Immer noch nicht aus Sicht des Kunden. Diese Bibliothek fordert dns-js.com/api.aspx an, die IP-Adresse zu erhalten, die dann die serverseitige DNS auflöst.
wp-overwatch.com
-1

Firefox verfügt seit v60 über eine integrierte API für WebExtensions:

https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/dns/resolve

Saturnus
quelle
Aus irgendeinem Grund browsergibt es in Firefox 64 Beta nicht, daher frage ich mich, ob das entfernt wurde.
Sawtaytoes
3
@Sawtaytoes: Es ist nur für WebExtensions verfügbar . Beachten Sie auch, dass eine dnsGenehmigung erforderlich ist und das Skript nicht als Inhaltsskript ausgeführt werden darf (wie browser.dnsauch hier nicht
Saturnus
@ Saturnus dies funktioniert gut für Firefox-Erweiterungen. Gibt es eine Chance, dasselbe mit Chrome-Erweiterungen zu tun?
drk
-1

Sicher, Sie können dies tun, ohne einen Zusatz zu verwenden, nur reines Javascript. browser.dns.resolve("example.com"); Wenn Sie diese DNS- Methode verwenden , diese jedoch nur mit FIREFOX 60 kompatibel ist, finden Sie weitere Informationen unter MDN https://developer.mozilla.org/en-US/docs / Mozilla / Add-Ons / WebExtensions / API / DNS / Resolution

Yassine Farroud
quelle
4
Diese Methode ist nur im Kontext einer WebExtension verfügbar. Es kann nicht von einer Webseite verwendet werden.
Abenddämmerung -inaktiv-
-2

Ich denke nicht, dass dies von den meisten Browsern aus Sicherheitsgründen in einem reinen JavaScript-Kontext erlaubt ist, wie die Frage stellt.

Nick Craver
quelle
5
Es ist keine Antwort. Dies sollte ein Kommentar sein!
Trejder
-3

Vielleicht habe ich den Punkt verpasst, aber als Antwort auf NAVY kann der Browser Ihnen die IP-Adresse des Anforderers mitteilen (wenn auch vielleicht nur dessen Dienstanbieter).

Platzieren Sie ein Skript-Tag auf der Seite, die vom Client gerendert werden soll, der einen anderen Server aufruft (auf den src verweist), der nicht ausgeglichen geladen ist einfach und kostengünstig einrichten).

Dies ist die Art von Code, die der Client-Seite hinzugefügt werden muss:

Auf dem anderen Server "someServerIown" muss die ASP-, ASPX- oder PHP-Seite vorhanden sein.

----- enthält folgenden Servercode:

"<% Response.Write (" var clientipaddress = '"& Request.ServerVariables (" REMOTE_ADDR ") &"'; ")%>" (ohne die externen dbl-Anführungszeichen :-))

---- und schreibt diesen Code zurück in das Skript-Tag:

   var clientipaddress = '178.32.21.45';

Dadurch wird effektiv eine Javascript-Variable erstellt, auf die Sie mit Javascript auf der Seite nicht weniger zugreifen können.

Hoffentlich greifen Sie auf diese Variable zu und schreiben den Wert in ein Formularsteuerelement, das zum Zurücksenden bereit ist.

Wenn der Benutzer die nächste Anfrage stellt oder erhält, sendet Ihr Javascript und / oder Formular den Wert der Variablen, die der "otherServerIown" für Sie ausgefüllt hat, zurück an den Server, auf dem Sie ihn haben möchten.

So komme ich um den dummen Load Balancer herum, der die Client-IP-Adresse maskiert und sie als die des Load Balancers erscheinen lässt ... dumm ... dumm dumm dumm!

Ich habe nicht die genaue Lösung angegeben, weil die Situation bei jedem etwas anders ist. Das Konzept ist jedoch solide. Beachten Sie außerdem, dass Ihr "otherServerIOwn", wenn Sie dies auf einer HTTPS-Seite tun, auch in dieser sicheren Form liefern muss, da der Client sonst auf gemischte Inhalte aufmerksam gemacht wird. Und wenn Sie https haben, stellen Sie sicher, dass ALLE Ihre Zertifikate gültig sind, andernfalls erhält der Client auch eine Warnung.

Hoffe es hilft jemandem! Entschuldigung, es hat ein Jahr gedauert, um zu antworten / beizutragen. :-)

Bill S.
quelle
3
Entschuldigung, musste aber abstimmen, da ich nicht glaube, dass es die ursprüngliche Frage tatsächlich beantwortet. Sie möchten nur eine Standard-DNS-Suche, nicht die öffentliche IP des Benutzers.
Simon East
-4

Meine Version ist wie folgt:

PHP auf meinem Server:

<?php
    header('content-type: application/json; charset=utf-8');

    $data = json_encode($_SERVER['REMOTE_ADDR']);


    $callback = filter_input(INPUT_GET, 
                 'callback',
                 FILTER_SANITIZE_STRING, 
                 FILTER_FLAG_ENCODE_HIGH|FILTER_FLAG_ENCODE_LOW);
    echo $callback . '(' . $data . ');';
?>

jQuery auf der Seite:

var self = this;
$.ajax({
    url: this.url + "getip.php",
    data: null,
    type: 'GET',
    crossDomain: true,
    dataType: 'jsonp'

}).done( function( json ) {

    self.ip = json;

});

Es funktioniert domänenübergreifend. Es könnte eine Statusprüfung verwenden. Daran arbeiten.

Joeri
quelle
2
Entschuldigung, musste aber abstimmen, da ich nicht glaube, dass es die ursprüngliche Frage tatsächlich beantwortet. Sie möchten nur eine Standard-DNS-Suche, nicht die öffentliche IP des Benutzers. Ihr Code bereinigt auch nicht das $ _GET, was ein großes Sicherheitsproblem darstellt.
Simon East
@ Simon East Ich denke, es ist noch schlimmer. Sieht so aus, als wollten sie jede IP per DNS nachschlagen.
Joeri
@SimonEast Sie können nicht beweisen, dass es sich um ein Sicherheitsproblem handelt, da Sie keine Ahnung haben, wie ich mein PHP kompiliert habe. Deine Strenge ist einfach albern.
Joeri
-10

Wenn auf dem Client Java installiert ist, können Sie Folgendes tun:

ipAddress = java.net.InetAddress.getLocalHost().getHostAddress();

Ansonsten müssen Sie wahrscheinlich ein serverseitiges Skript verwenden.

Alex Fort
quelle
8
Warum stimmt jemand dafür? java! = javascript, das ist KEINE Antwort.
Sven Mawby
2
Klopf klopf. Wer ist da? (... lange Pause) Java Applet
Mike Nelson