Posso eseguire una ricerca DNS (dal nome host all'indirizzo IP) utilizzando Javascript lato client?


92

Vorrei utilizzare Javascript lato client per eseguire una ricerca DNS (dal nome host all'indirizzo IP) come visto dal computer del client. È possibile?


5
Molte delle risposte a questa domanda sembrano consigliare di utilizzare la risoluzione lato server. A seconda del caso d'uso, potrebbe non essere sufficiente. Ad esempio, se il servizio che stai cercando utilizza GSLB, potrebbe restituire un IP diverso in base a dove si trova l'utente; di conseguenza, è molto probabile che la risposta ricevuta dal codice lato server sia una risposta diversa da quella che il browser avrebbe ricevuto. Detto questo, non ho ancora una soluzione alternativa per coloro che hanno a cuore questa differenza.
Ilan Rabinovitch

Risposte:


34

Non c'è la nozione di host o indirizzi IP nella libreria standard javascript. Quindi dovrai accedere a un servizio esterno per cercare i nomi host per te.

Consiglio di ospitare un cgi-bin che cerca l'indirizzo ip di un nome host e accedervi tramite javascript.


26
cgi-bin? È vecchia scuola. Mi piace!
Andrew Hedges,

10
Questo era vero al momento della scrittura (2008). Questo non è vero 6 anni dopo: vedi il mio commento su WebRTC in questa stessa pagina. (Purtroppo Google punta ancora a questo thread durante la ricerca di una soluzione al problema dell'indirizzo IP e questo può mettere le persone nella direzione sbagliata).
Earizon

1
@earizon - la tua risposta è per una domanda diversa: come scoprire il tuo indirizzo IP privato.
Gene Vayngrib

Il problema tramite CGI dal cloud sarebbe scoprire ips host intranet che non è possibile dall'esterno. Dovresti utilizzare un servizio locale sulla macchina o sull'intranet.
Tzahi Fadida,

C'è un nuovo standard Internet proposto che ti consente di inviare query DNS su HTTPS (vedi questa risposta stackoverflow.com/a/58299823/9638991 ). In tutta la realtà, fondamentalmente funziona come uno script cgi-bin :) (tranne per il fatto che è stato standardizzato dall'IETF e un sacco di grandi aziende lo supportano)
Kimbo

83

Modifica : questa domanda mi ha dato prurito, quindi ho creato un servizio web JSONP su Google App Engine che restituisce l'indirizzo IP del client. Utilizzo:

<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>

Sì, non sono necessari proxy server.


Pure JS non può. Se hai uno script del server nello stesso dominio che lo stampa, puoi inviare un XMLHttpRequest per leggerlo.


4
Potresti pubblicare la fonte sul tuo servizio web? Sarebbe bello eseguire un'istanza.
Il

18
Mi dispiace, ma ho dovuto votare in negativo poiché non penso che risponda effettivamente alla domanda originale. Vogliono solo una ricerca DNS standard, non l'IP pubblico dell'utente.
Simon East

29

Molto tardi, ma immagino che molte persone atterreranno ancora qui tramite "Google Airlines". Un approccio moderno consiste nell'utilizzare WebRTC che non richiede il supporto del server.

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

Il codice successivo è un copia e incolla da 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.";
}   

19
questa è davvero una nuova capacità che non esisteva prima di WebRTC: scoprire il proprio indirizzo IP. Ma @noahjacobson ha posto una domanda diversa: ricerca DNS dell'IP tramite il nome host da javascript.
Gene Vayngrib

2
Molto, molto interessante, è un bug o un difetto di progettazione, comunque ad un certo punto verrà corretto quindi non va bene per i progetti a lungo termine
e-info128

14

La versione JSONP ospitata funziona a meraviglia, ma sembra che durante la notte la maggior parte dei giorni (Eastern Time) vada oltre le sue risorse, quindi ho dovuto creare la mia versione.

Ecco come l'ho realizzato con PHP:

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

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

Quindi il Javascript è esattamente lo stesso di prima, ma non un 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>

Semplice come quella!

Nota a margine: assicurati di pulire il tuo $ _GET se lo usi in qualsiasi ambiente pubblico!


Grazie tcole! Proprio quello che stavo cercando :)
jClark

Aspetta un attimo, perché usare anche $ _GET? come hai detto tu questa è una vulnerabilità. Non si potrebbe semplicemente usare: echo 'getip ('. $ Data. ');';
deweydb

7
Mi dispiace, ma ho dovuto votare in negativo poiché non penso che risponda effettivamente alla domanda originale. Vogliono solo una ricerca DNS standard, non l'IP pubblico dell'utente.
Simon East

2
@ SimonEast Heh. Hai modificato la domanda di una domanda vecchia di 7 anni. Fai tutto ciò di cui hai bisogno per soddisfarti ;-)
tcole

2
Ho semplicemente modificato la domanda originale per renderla più chiara, dato che di recente stavo cercando la stessa domanda, ma per qualche motivo la maggior parte delle risposte qui non sono effettivamente ciò che il poster originale stava chiedendo e dovrebbero essere pubblicate sotto una domanda diversa.
Simon East

14

So che questa domanda è stata posta molto tempo fa, ma ho pensato di offrire una risposta più recente.

DNS su HTTPS (DoH)

È possibile inviare query DNS tramite HTTPS ai risolutori DNS che lo supportano. Lo standard per DOH è descritto in RFC 8484 .

Questa è una cosa simile a ciò che suggeriscono tutte le altre risposte, solo che DoH è effettivamente il protocollo DNS su HTTPS. È anche uno standard Internet "proposto" e sta diventando molto popolare. Ad esempio, alcuni dei principali browser lo supportano o hanno in programma di supportarlo (Chrome, Edge, Firefox) e Microsoft sta per integrarlo nel proprio sistema operativo.

Uno degli scopi di DoH è:

consentendo alle applicazioni Web di accedere alle informazioni DNS tramite le API del browser esistenti in modo sicuro coerente con Cross Origin Resource Sharing (CORS)

C'è uno strumento open source creato appositamente per eseguire ricerche DNS da applicazioni web chiamato dohjs . Lo fa DNS su HTTPS query (DoH) wireformat come descritto nella RFC 8484 . Supporta i metodi GET e POST.

Divulgazione completa: sono un collaboratore di dohjs.

API JSON DNS su HTTPS

Se non vuoi perdere tempo con il wireformat DNS, sia Google che Cloudflare offrono API JSON per DNS su HTTPS.

Esempio di codice Javascript per cercare example.com con l'API JSON DOH di Google:

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

Esempi dalla RFC per DOH GET e POST con wireformat

Di seguito sono riportati gli esempi forniti da RFC sia per GET che per POST (vedere https://tools.ietf.org/html/rfc8484#section-4.1.1 ):

OTTIENI un esempio:

La prima richiesta di esempio utilizza GET per richiedere "www.example.com".

: method = GET
: scheme = https
: authority = dnsserver.example.net
: path = / dns-query? dns = AAABAAABAAAAAAAAA3d3dwdleGFtcGxlA2NvbQAAAQAB
accept = application / dns-message

Esempio POST:

La stessa query DNS per "www.example.com", utilizzando il metodo POST, sarebbe:

: method = POST
: scheme = https
: authority = dnsserver.example.net
: path = / dns-query
accept = application / dns-message
content-type = application / dns-message
content-length = 33

<33 byte rappresentati dalla seguente codifica esadecimale> 00 00 01 00 00 01 00 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

Altri posti per inviare query DOH

Puoi trovare un elenco di alcuni resolver DNS pubblici che supportano DNS su HTTPS in un paio di posti:

Delle risorse di cui sopra, direi che l'elenco sul wiki di Curl e l'elenco DNSCrypt sono probabilmente i più completi e quelli più aggiornati. La pagina di Curl include anche un elenco di strumenti open source per DoH (server, proxy, librerie client, ecc.).


3

Sono consapevole che questa è una vecchia domanda, ma la mia soluzione potrebbe aiutare gli altri.

Trovo che i servizi JSON (P) che lo rendono facile non durano per sempre, ma il seguente JavaScript funziona bene per me al momento della scrittura.

<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>

Quanto sopra scrive l'IP del mio server sulla pagina in cui si trova, ma lo script può essere modificato per trovare qualsiasi IP cambiando 'zero.eu.org' con un altro nome di dominio. Questo può essere visto in azione sulla mia pagina all'indirizzo: http://meon.zero.eu.org/


Non riesco a capire come trovare il mio indirizzo IP usando questo: <! - # echo var = "REMOTE_ADDR" -> secondo il tuo sito web.
George Carlin

Questa è una funzione standard di "eco" disponibile sulla maggior parte dei server web. Vedi: google.co.uk/…
Neville Hillyer

1
Questa è forse l'unica risposta che effettivamente affronta la domanda originale correttamente, ben fatta. Sfortunatamente non aderisce a quanto visto dalla parte del computer del cliente , che può (o non può) essere un requisito importante.
Simon East

@ Simon - Dove dice "visto dal computer del cliente" e perché la mia risposta non è conforme a questo?
Neville Hillyer

1
@ Simon - Buon punto, ma poiché normalmente JS lato client è fornito dal server, ci sono buone possibilità che l'autore / proprietario del server sia a conoscenza di questa limitazione DNS - potrebbe essere un problema per gli autori che utilizzano server di terze parti. Come indicato nei post qui, la tecnologia esistente fatica a soddisfare tutti i vincoli su questo. Il mio contributo aveva lo scopo di trasmettere la soluzione che ho trovato più pratica sul mio server.
Neville Hillyer


1

Come molte persone hanno detto, è necessario utilizzare un servizio esterno e chiamarlo. E questo ti darà solo la risoluzione DNS dal punto di vista del server.

Se è abbastanza buono e se hai solo bisogno della risoluzione DNS, puoi utilizzare il seguente contenitore Docker:

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

Endpoint:

[GET] /ipv6/[domain]: Esegue una risoluzione DNS per un determinato dominio e restituisce gli indirizzi IPv6 associati.

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

[GET] /ipv4/[domain]: Esegue una risoluzione DNS per un determinato dominio e restituisce gli indirizzi IPv4 associati.

 {
     "addresses": [
         "139.180.232.162"
     ]
 }

La mia raccomandazione è di configurare il server Web per eseguire il proxy inverso al contenitore su un particolare endpoint nel server che serve il tuo Javascript e di chiamarlo utilizzando le tue funzioni Ajax Javascript standard.


0

In questo modo è necessario interrompere la sandbox del browser. Prova a lasciare che il tuo server esegua la ricerca e richiedilo dal lato client tramite XmlHttp.


0

C'è una libreria javascript DNS-JS.com che fa proprio questo.

DNS.Query("dns-js.com",
    DNS.QueryType.A,
    function(data) {
        console.log(data);
});

1
Ancora non dal punto di vista del cliente. Quella libreria fa una richiesta a dns-js.com/api.aspx per ottenere l'indirizzo IP che poi risolve il lato server DNS.
wp-overwatch.com

-1

Firefox ha un'API integrata per questo dalla v60, per WebExtensions:

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


Per qualsiasi motivo, browsernon esiste in Firefox 64 beta, quindi mi chiedo se sia stato rimosso.
Sawtaytoes

3
@Sawtaytoes: è esposto solo per WebExtensions . Si noti inoltre che richiede l' dnsautorizzazione e lo script non deve essere eseguito come script di contenuto (come di nuovo, browser.dnsnon sarebbe esposto lì)
Saturnus

@ Saturnus funziona bene per le estensioni di Firefox. C'è qualche possibilità di fare lo stesso con le estensioni di Chrome in qualche modo?
drk


-2

Non penso che ciò sia consentito dalla maggior parte dei browser per motivi di sicurezza, in un contesto JavaScript puro come la domanda chiede.


5
Non è una risposta. Questo dovrebbe essere un commento!
Trejder

-3

Forse ho perso il punto, ma in risposta al ragazzo della NAVY ecco come il browser può dirti l'indirizzo IP del "richiedente" (anche se forse solo il loro fornitore di servizi).

Posiziona un tag script nella pagina che deve essere renderizzato dal client che chiama (ha src che punta) un altro server che non è caricato bilanciato (mi rendo conto che questo significa che devi accedere a un secondo server ma l'hosting è economico in questi giorni e puoi configurarlo in modo semplice ed economico).

Questo è il tipo di codice che deve essere aggiunto alla pagina del cliente:

Sull'altro server "someServerIown" devi avere la pagina ASP, ASPX o PHP che;

----- contiene il codice del server come questo:

"<% Response.Write (" var clientipaddress = '"& Request.ServerVariables (" REMOTE_ADDR ") &"'; ")%>" (senza virgolette dbl esterne :-))

---- e riscrive questo codice nel tag dello script:

   var clientipaddress = '178.32.21.45';

Questo crea efficacemente una variabile Javascript a cui puoi accedere con Javascript sulla pagina non meno.

Si spera che tu acceda a questa var e scriva il valore in un controllo del modulo pronto per essere rispedito.

Quando l'utente invia o riceve la richiesta successiva, il tuo Javascript e / o modulo invia il valore della variabile che "otherServerIown" ha compilato per te, di nuovo al server su cui vorresti che fosse.

È così che aggiro il dumb load balancer che abbiamo che maschera l'indirizzo IP del client e lo fa apparire come quello del load balancer .... dumb ... dumb dumb dumb!

Non ho dato la soluzione esatta perché la situazione di ognuno è leggermente diversa. Il concetto è comunque valido. Inoltre, tieni presente che se lo stai facendo su una pagina HTTPS, anche il tuo "altroServerIOwn" deve fornire in quella forma sicura, altrimenti il ​​Cliente viene avvisato del contenuto misto. E se hai https, assicurati che TUTTI i tuoi certificati siano validi altrimenti anche il client riceve un avviso.

Spero che aiuti qualcuno! Spiacenti, ci è voluto un anno per rispondere / contribuire. :-)


3
Mi dispiace, ma ho dovuto votare in negativo poiché non penso che risponda effettivamente alla domanda originale. Vogliono solo una ricerca DNS standard, non l'IP pubblico dell'utente.
Simon East

-4

La mia versione è così:

php sul mio 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 nella pagina:

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

}).done( function( json ) {

    self.ip = json;

});

Funziona su più domini. Potrebbe utilizzare un controllo dello stato. Ci sto lavorando.


2
Mi dispiace, ma ho dovuto votare in negativo poiché non penso che risponda effettivamente alla domanda originale. Vogliono solo una ricerca DNS standard, non l'IP pubblico dell'utente. Il tuo codice inoltre non disinfetta $ _GET, il che è un grosso problema di sicurezza.
Simon East

@ Simon East Penso che sia anche peggio. Sembra che vogliano cercare qualsiasi IP tramite DNS.
Joeri

@ SimonEast Non puoi provare che si tratti di un problema di sicurezza perché non hai idea di come ho compilato il mio php. La tua severità è semplicemente stupida.
Joeri

-10

Se il client ha Java installato, potresti fare qualcosa del genere:

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

Oltre a questo, probabilmente dovrai usare uno script lato server.


8
Perché qualcuno vota questo? java! = javascript, questa NON è una risposta.
Sven Mawby

2
Knock knock. Chi è là? (... lunga pausa) Applet Java
mike nelson
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.