Czy mogę przeprowadzić wyszukiwanie DNS (nazwa hosta na adres IP) przy użyciu JavaScript po stronie klienta?


92

Chciałbym użyć JavaScript po stronie klienta do wyszukania DNS (nazwa hosta do adresu IP) widzianego z komputera klienta. Czy to jest możliwe?


5
Wiele odpowiedzi na to pytanie wydaje się zalecać wykonanie po stronie serwera rozdzielczości. W zależności od przypadku użycia może to być niewystarczające. Na przykład, jeśli wyszukiwana usługa korzysta z GSLB, może zwrócić inny adres IP na podstawie lokalizacji użytkownika; w rezultacie odpowiedź, którą otrzyma kod po stronie serwera, będzie prawdopodobnie inną odpowiedzią niż ta, którą otrzymałaby przeglądarka. Mimo to nie mam jeszcze alternatywnego rozwiązania dla tych, którym zależy na tej różnicy.
Ilan Rabinovitch

Odpowiedzi:


35

W standardowej bibliotece javascript nie ma pojęcia o hostach ani adresach IP. Będziesz więc musiał uzyskać dostęp do zewnętrznej usługi, aby wyszukać nazwy hostów.

Polecam hosting cgi-bin, który wyszukuje adres IP nazwy hosta i uzyskuje do niego dostęp za pomocą javascript.


26
cgi-bin? To stara szkoła. Lubię to!
Andrew Hedges,

10
Było to prawdą w momencie pisania (2008). To nieprawda 6 lat później: zobacz mój komentarz na temat WebRTC na tej samej stronie. (Niestety Google nadal wskazuje na ten wątek, szukając rozwiązania problemu z adresem IP, co może skierować ludzi w złym kierunku).
earizon

1
@earizon - Twoja odpowiedź dotyczy innego pytania - jak odkryć swój prywatny adres IP.
Gene Vayngrib

Problem poprzez CGI z chmury polegałby na wykrywaniu adresów IP hostów intranetowych, co nie jest możliwe z zewnątrz. Musiałbyś skorzystać z usługi lokalnej na komputerze lub w intranecie.
Tzahi Fadida

Jest nowy proponowany standard internetowy, który umożliwia wysyłanie zapytań DNS przez HTTPS (zobacz odpowiedź stackoverflow.com/a/58299823/9638991 ). W rzeczywistości działa w zasadzie tak samo jak skrypt cgi-bin :) (z wyjątkiem tego, że został ustandaryzowany przez IETF i obsługuje go mnóstwo dużych firm)
kimbo

83

Edycja : to pytanie przyprawiło mnie o swędzenie, więc uruchomiłem usługę internetową JSONP w Google App Engine, która zwraca adresy IP klientów. Stosowanie:

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

Tak, nie są potrzebne żadne serwery proxy.


Czysty JS nie może. Jeśli masz skrypt serwera w tej samej domenie, który go drukuje, możesz wysłać XMLHttpRequest, aby go przeczytać.


4
Czy możesz opublikować źródło w swojej usłudze internetowej? Byłoby miło uruchomić instancję.
Will

18
Przepraszam, ale musiałem zagłosować przeciw, ponieważ nie sądzę, aby to faktycznie odpowiadało na pierwotne pytanie. Chcą tylko standardowego wyszukiwania DNS, a nie publicznego adresu IP użytkownika.
Simon East

30

Bardzo późno, ale myślę, że wiele osób nadal będzie tu lądować przez „Google Airlines”. Moderm podejście polega na użyciu WebRTC, który nie wymaga obsługi serwera.

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

Następny kod to skopiuj i wklej z 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
jest to rzeczywiście nowa możliwość, która nie istniała przed WebRTC - aby odkryć własny adres IP. Ale @noahjacobson zadał inne pytanie - wyszukiwanie adresu IP w DNS według nazwy hosta z javascript.
Gene Vayngrib

2
Bardzo, bardzo interesujące, to błąd lub wada projektowa, w każdym razie w pewnym momencie zostanie poprawiona, więc nie nadaje się do długoterminowych projektów
e-info128

15

Wiem, że to pytanie zostało zadane bardzo dawno temu, ale pomyślałem, że dam bardziej aktualną odpowiedź.

DNS przez HTTPS (DoH)

Możesz wysyłać zapytania DNS przez HTTPS do resolverów DNS, które to obsługują. Standard dla DOH jest opisany w RFC 8484 .

To jest podobne do tego, co sugerują wszystkie inne odpowiedzi, tylko że DoH jest w rzeczywistości protokołem DNS przez HTTPS. Jest to również „proponowany” standard internetowy i staje się dość popularny. Na przykład niektóre główne przeglądarki obsługują go lub planują go obsługiwać (Chrome, Edge, Firefox), a firma Microsoft jest w trakcie wbudowywania go w swój system operacyjny.

Jednym z celów DoH jest:

umożliwienie aplikacjom internetowym dostępu do informacji DNS za pośrednictwem istniejących interfejsów API przeglądarek w bezpieczny sposób zgodny z Cross Origin Resource Sharing (CORS)

Istnieje narzędzie typu open source stworzone specjalnie do wyszukiwania DNS z aplikacji internetowych o nazwie dohjs . Czyni DNS za pośrednictwem protokołu HTTPS (DOH) wireformat zapytań w sposób opisany w dokumencie RFC 8484 . Obsługuje metody GET i POST.

Pełne ujawnienie: jestem współtwórcą dohjs.

DNS przez HTTPS JSON API

Jeśli nie chcesz zawracać sobie głowy formatem drutu DNS, zarówno Google, jak i Cloudflare oferują interfejsy API JSON dla DNS przez HTTPS.

Przykładowy kod JavaScript do wyszukania example.com za pomocą Google JSON DOH API:

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

Przykłady z dokumentu RFC dla DOH GET i POST z wireformatem

Oto przykłady podane przez RFC dla GET i POST (patrz https://tools.ietf.org/html/rfc8484#section-4.1.1 ):

POBIERZ przykład:

Pierwsze przykładowe żądanie używa GET do żądania „www.example.com”.

: metoda = GET
: schemat = https
: urząd = dnsserver.example.net
: ścieżka = / dns-query? dns = AAABAAABAAAAAAAAA3d3dwdleGFtcGxlA2NvbQAAAQAB
accept = application / dns-message

Przykład POST:

To samo zapytanie DNS dla „www.example.com” przy użyciu metody POST wyglądałoby tak:

: metoda = POST
: schemat = https
: urząd = dnsserver.example.net
: ścieżka = / dns-query
accept = application / dns-message
content-type = application / dns-message
content-length = 33

<33 bajty reprezentowane przez następujące kodowanie szesnastkowe> 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

Inne miejsca do wysyłania zapytań DOH

Listę niektórych publicznych programów rozpoznawania nazw DNS, które obsługują DNS przez HTTPS, można znaleźć w kilku miejscach:

Spośród powyższych zasobów, powiedziałbym, że lista na wiki Curla i lista DNSCrypt są prawdopodobnie najbardziej kompletne i najczęściej aktualizowane. Strona Curl zawiera również listę narzędzi open source dla DoH (serwery, proxy, biblioteki klienta itp.).


14

Hostowana wersja JSONP działa jak marzenie, ale wygląda na to, że przez większość dni przegląda swoje zasoby w nocy (czas wschodni), więc musiałem stworzyć własną wersję.

Tak to zrobiłem z PHP:

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

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

Następnie JavaScript jest dokładnie taki sam jak poprzednio, ale nie jest tablicą:

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

Proste!

Uwaga dodatkowa: pamiętaj, aby wyczyścić swój $ _GET, jeśli używasz go w jakimkolwiek publicznym środowisku!


Dzięki tcole! Właśnie tego szukałem :)
jClark

Poczekaj chwilę, po co w ogóle używać $ _GET? tak jak powiedziałeś, to jest luka. Nie można po prostu użyć: echo 'getip ('. $ Data. ');';
deweydb

7
Przepraszam, ale musiałem zagłosować przeciw, ponieważ nie sądzę, aby to faktycznie odpowiadało na pierwotne pytanie. Chcą tylko standardowego wyszukiwania DNS, a nie publicznego adresu IP użytkownika.
Simon East

2
@SimonEast Heh. Zmodyfikowałeś pytanie 7-letniego pytania. Zrób wszystko, co musisz, aby się zadowolić ;-)
tcole

2
Po prostu zredagowałem oryginalne pytanie, aby było jaśniejsze, ponieważ ostatnio badałem to samo pytanie, ale z jakiegoś powodu większość odpowiedzi tutaj nie jest w rzeczywistości tym, o co prosił oryginalny plakat i powinno się je zamieścić pod innym pytaniem.
Simon East,

3

Wiem, że to stare pytanie, ale moje rozwiązanie może pomóc innym.

Uważam, że usługi JSON (P), które to ułatwiają, nie trwają wiecznie, ale następujący JavaScript działa dobrze dla mnie w momencie pisania.

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

Powyższe zapisuje adres IP mojego serwera na stronie, na której się znajduje, ale skrypt można zmodyfikować, aby znaleźć dowolny adres IP, zmieniając „zero.eu.org” na inną nazwę domeny. Można to zobaczyć w akcji na mojej stronie pod adresem : http://meon.zero.eu.org/


Nie mogę pojąć, jak znaleźć własny adres IP, używając tego: <! - # echo var = "REMOTE_ADDR" -> zgodnie z Twoją witryną.
George Carlin

Jest to standardowa funkcja „echa” dostępna na większości serwerów WWW. Zobacz: google.co.uk/…
Neville Hillyer

1
Jest to prawdopodobnie jedyna odpowiedź, która właściwie rozwiązuje pierwotne pytanie, dobra robota. Niestety nie spełnia on tego, co widać z części komputera klienta , co może (ale nie musi) być ważnym wymaganiem.
Simon East

@Simon - gdzie jest napisane „widziane z komputera klienta” i dlaczego moja odpowiedź jest niezgodna z tym?
Neville Hillyer

1
@Simon - słuszna uwaga, ale ponieważ zwykle JS po stronie klienta jest dostarczany przez serwer, istnieje duża szansa, że ​​autor / właściciel serwera byłby świadomy tego ograniczenia DNS - może to stanowić problem dla autorów korzystających z serwerów stron trzecich. Jak wskazano w postach tutaj, istniejąca technologia stara się sprostać wszystkim ograniczeniom związanym z tym. Mój wkład miał na celu przedstawienie rozwiązania, które uznałem za najbardziej praktyczne na moim serwerze.
Neville Hillyer


1

Jak wiele osób powiedziało, że musisz skorzystać z usługi zewnętrznej i zadzwonić do niej. A to zapewni ci rozpoznawanie nazw DNS tylko z perspektywy serwera.

Jeśli to wystarczy i potrzebujesz tylko rozpoznawania nazw DNS, możesz użyć następującego kontenera Docker:

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

Punkty końcowe:

[GET] /ipv6/[domain]: Wykonaj rozpoznawanie nazw DNS dla danej domeny i zwróć powiązane adresy IPv6.

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

[GET] /ipv4/[domain]: Wykonaj rozpoznawanie nazw DNS dla danej domeny i zwróć powiązane adresy IPv4.

 {
     "addresses": [
         "139.180.232.162"
     ]
 }

Moim zaleceniem jest skonfigurowanie serwera WWW tak, aby odwracał proxy do kontenera na określonym punkcie końcowym serwera obsługującego JavaScript i wywoływał go przy użyciu standardowych funkcji JavaScript Ajax.



0

Wymagałoby to zerwania piaskownicy przeglądarki. Spróbuj pozwolić swojemu serwerowi na wyszukanie i zażądanie tego po stronie klienta za pośrednictwem XmlHttp.


-1

Firefox ma wbudowany interfejs API od wersji 60 dla WebExtensions:

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


Z jakiegoś powodu browsernie istnieje w Firefox 64 beta, więc zastanawiam się, czy został usunięty.
Kevin Ghadyani

3
@Sawtaytoes: Jest ujawniany tylko dla WebExtensions . Zauważ również, że wymaga dnspozwolenia, a skrypt nie będzie działał jako skrypt zawartości (jak ponownie, browser.dnsnie zostanie tam ujawniony)
Saturnus

@Saturnus Działa to dobrze w przypadku rozszerzeń przeglądarki Firefox. Czy jest jakaś szansa, aby zrobić to samo z rozszerzeniami Chrome?
drk


-2

Nie sądzę, aby było to dozwolone przez większość przeglądarek ze względów bezpieczeństwa, w czystym kontekście JavaScript, jak zadaje pytanie.


5
To nie jest odpowiedź. To powinien być komentarz!
trejder

-3

Może przegapiłem punkt, ale w odpowiedzi dla faceta z NAVY, oto jak przeglądarka może powiedzieć ci adres IP „żądającego” (choć może tylko ich usługodawca).

Umieść tag skryptu na stronie, która ma być renderowana przez klienta, który wywołuje (ma src wskazujący na) inny serwer, który nie jest załadowany w sposób zrównoważony (zdaję sobie sprawę, że oznacza to, że potrzebujesz dostępu do drugiego serwera, ale hosting jest obecnie tani i możesz skonfigurować to łatwo i tanio).

Oto rodzaj kodu, który należy dodać do strony klienta:

Na drugim serwerze „someServerIown” musisz mieć stronę ASP, ASPX lub PHP;

----- zawiera taki kod serwera:

"<% Response.Write (" var clientipaddress = '"& Request.ServerVariables (" REMOTE_ADDR ") &"'; ")%>" (bez zewnętrznych cudzysłowów :-))

---- i zapisuje ten kod z powrotem do tagu script:

   var clientipaddress = '178.32.21.45';

To skutecznie tworzy zmienną Javascript, do której można uzyskać dostęp za pomocą Javascript na stronie.

Miejmy nadzieję, że uzyskasz dostęp do tej zmiennej i zapiszesz wartość w kontrolce formularza gotowej do odesłania.

Kiedy użytkownik wysyła lub odbiera następne żądanie, Twój JavaScript i / lub formularz wysyła wartość zmiennej, którą wypełnił dla Ciebie „otherServerIown”, z powrotem na serwer, na którym chcesz to zrobić.

W ten sposób omijam głupi system równoważenia obciążenia, który maskuje adres IP klienta i sprawia, że ​​wygląda on jak adres modułu równoważenia obciążenia… głupi… głupi głupi!

Nie podałem dokładnego rozwiązania, ponieważ sytuacja u każdego jest trochę inna. Jednak koncepcja jest rozsądna. Pamiętaj również, że jeśli robisz to na stronie HTTPS, Twój „otherServerIOwn” musi również dostarczać w tej bezpiecznej formie, w przeciwnym razie Klient zostanie ostrzeżony o mieszanej zawartości. A jeśli masz https, upewnij się, że WSZYSTKIE twoje certyfikaty są ważne, w przeciwnym razie klient również otrzyma ostrzeżenie.

Mam nadzieję, że to komuś pomoże! Przepraszamy, udzielenie odpowiedzi / przesłanie odpowiedzi zajęło rok. :-)


3
Przepraszam, ale musiałem zagłosować przeciw, ponieważ nie sądzę, aby to faktycznie odpowiadało na pierwotne pytanie. Chcą tylko standardowego wyszukiwania DNS, a nie publicznego adresu IP użytkownika.
Simon East

-4

Moja wersja wygląda tak:

php na moim serwerze:

<?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 na stronie:

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

}).done( function( json ) {

    self.ip = json;

});

Działa w wielu domenach. Przydałoby się sprawdzenie statusu. Pracuję nad tym.


2
Przepraszam, ale musiałem zagłosować przeciw, ponieważ nie sądzę, aby to faktycznie odpowiadało na pierwotne pytanie. Chcą tylko standardowego wyszukiwania DNS, a nie publicznego adresu IP użytkownika. Twój kod nie czyści również $ _GET, co jest dużym problemem bezpieczeństwa.
Simon East

@Simon East Myślę, że jest jeszcze gorzej. Wygląda na to, że chcą wyszukać dowolny adres IP przez DNS.
Joeri

@SimonEast Nie możesz udowodnić, że jest to problem z bezpieczeństwem, ponieważ nie masz pojęcia, jak skompilowałem mój php. Twoja surowość jest po prostu głupia.
Joeri

-10

Jeśli klient ma zainstalowaną Javę, możesz zrobić coś takiego:

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

Poza tym prawdopodobnie będziesz musiał użyć skryptu po stronie serwera.


8
Dlaczego ktoś to popiera? java! = javascript, to NIE jest odpowiedź.
Sven Mawby

2
Puk puk. Kto tam? (... długa pauza) Aplet Java
mike nelson
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.