İstemci tarafı Javascript kullanarak bir DNS araması (ana bilgisayar adından IP adresine) gerçekleştirebilir miyim?


92

İstemcinin bilgisayarından görüldüğü gibi bir DNS araması (ana bilgisayar adından IP adresine) gerçekleştirmek için istemci tarafı Javascript kullanmak istiyorum. Mümkün mü?


5
Bu soruya verilen yanıtların çoğu, çözümün sunucu tarafında yapılmasını öneriyor gibi görünüyor. Yeterli olmayabilir kullanım durumuna bağlı olarak. Örneğin, aradığınız hizmet GSLB kullanıyorsa, kullanıcının bulunduğu yere bağlı olarak farklı bir IP döndürebilir; sonuç olarak, sunucu tarafı kodunun aldığı yanıt, tarayıcının alacağından çok daha farklı bir yanıt olacaktır. Bununla birlikte, bu farkı önemseyenler için henüz alternatif bir çözümüm yok.
Ilan Rabinovitch

Yanıtlar:


35

Javascript standart kitaplığında ana bilgisayar veya ip adresi kavramı yoktur. Bu nedenle, sizin için ana bilgisayar adlarını aramak için bazı harici hizmetlere erişmeniz gerekir.

Bir ana bilgisayar adının ip adresini arayan ve buna javascript aracılığıyla erişen bir cgi-bin barındırmanızı öneririm.


26
cgi-bin? Bu eski usul. Bunu sevdim!
Andrew Hedges

10
Bu, yazı yazıldığı sırada doğruydu (2008). 6 yıl sonra bu doğru değil: Aynı sayfadaki WebRTC hakkındaki yorumuma bakın. (Ne yazık ki Google, IP adresi sorununa bir çözüm ararken hala bu konuyu işaret ediyor ve bu da insanları yanlış yöne yönlendirebilir).
earizon

1
@earizon - cevabınız farklı bir soru için - kendi özel IP adresinizi nasıl keşfedebilirsiniz.
Gene Vayngrib

Buluttan CGI aracılığıyla ortaya çıkan sorun, dışarıdan mümkün olmayan intranet ana bilgisayar ips'lerini keşfetmektir. Makine veya intranette yerel bir hizmet kullanmanız gerekir.
Tzahi Fadida

DNS sorgularını HTTPS üzerinden göndermenize olanak tanıyan yeni bir önerilen İnternet standardı var (bu yanıta bakın stackoverflow.com/a/58299823/9638991 ). Gerçekte, temelde bir cgi-bin
betiğiyle

83

Düzenleme : Bu soru bana biraz kaşındı, bu yüzden Google App Engine'e istemcilerin ip adresini döndüren bir JSONP web hizmeti kurdum. Kullanım:

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

Yay, sunucu proxy'sine gerek yok.


Saf JS yapamaz. Aynı etki alanı altında onu yazdıran bir sunucu komut dosyanız varsa, onu okumak için bir XMLHttpRequest gönderebilirsiniz.


4
Kaynağı web servisinize gönderebilir misiniz? Bir örnek çalıştırmak güzel olurdu.
Will

18
Üzgünüm ama asıl soruyu yanıtladığını düşünmediğim için olumsuz oy vermem gerekti. Sadece standart bir DNS araması istiyorlar, kullanıcının genel IP'sini değil.
Simon East

30

Çok geç, ama sanırım birçok insan buraya "Google Havayolları" aracılığıyla inecek. Moderm yaklaşımı, sunucu desteği gerektirmeyen WebRTC kullanmaktır.

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

Sonraki kod, http://net.ipcalf.com/ adresinden kopyalayıp yapıştırmaktır.

// 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
bu gerçekten de WebRTC'den önce mevcut olmayan yeni bir özelliktir - kendi IP adresinizi keşfetmek. Ancak @noahjacobson farklı bir soru sordu - javascript'ten ana bilgisayar adına göre IP'nin DNS araması.
Gene Vayngrib

2
Çok, çok ilginç, bu bir hata veya tasarım hatası, zaten bir noktada düzeltilecek, bu yüzden uzun vadeli projeler için iyi değil
e-info128

16

Bu sorunun çok uzun zaman önce sorulduğunu biliyorum, ancak daha yeni bir cevap vereceğimi düşündüm.

HTTPS üzerinden DNS (DoH)

DNS sorgularını, onu destekleyen DNS çözümleyicilerine HTTPS üzerinden gönderebilirsiniz. DOH standardı, RFC 8484'te açıklanmıştır .

Bu, diğer tüm yanıtların önerdiğine benzer bir şey, yalnızca DoH aslında HTTPS üzerinden DNS protokolüdür. Aynı zamanda "önerilen" bir İnternet standardıdır ve oldukça popüler hale gelmektedir. Örneğin, bazı büyük tarayıcılar ya onu destekliyor ya da destekleme planları var (Chrome, Edge, Firefox) ve Microsoft bunu işletim sistemlerinde oluşturma sürecindedir.

DoH'un amaçlarından biri:

Web uygulamalarının mevcut tarayıcı API'leri aracılığıyla, Cross Origin Resource Sharing (CORS) ile tutarlı bir şekilde DNS bilgilerine erişmesine izin verme

Özellikle dohjs adı verilen web uygulamalarından DNS aramaları yapmak için yapılmış açık kaynaklı bir araç var . It does DNS HTTPS üzerinden de açıklandığı gibi (Sağlık Departmanı) wireformat sorguları RFC 8484 . Hem GET hem de POST yöntemlerini destekler.

Tam açıklama: dohjs'a katkıda bulunuyorum.

HTTPS JSON API'leri üzerinden DNS

DNS wireformat ile uğraşmak istemiyorsanız hem Google hem de Cloudflare, HTTPS üzerinden DNS için JSON API'leri sunar.

Google'ın JSON DOH API'siyle example.com'u aramak için örnek Javascript kodu:

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

DOH GET ve Wireformat ile POST için RFC'den örnekler

RFC'nin hem GET hem de POST için verdiği örnekler aşağıda verilmiştir (bkz. Https://tools.ietf.org/html/rfc8484#section-4.1.1 ):

Örnek alın:

İlk örnek istek, "www.example.com" istemek için GET kullanır.

: yöntem = GET
: düzen = https
: yetki = dnsserver.example.net
: yol = / dns-sorgu? dns = AAABAAABAAAAAAAAAA3d3dwdleGFtcGxlA2NvbQAAAQAB
kabul = uygulama / dns-mesaj

POST örneği:

POST yöntemini kullanan "www.example.com" için aynı DNS sorgusu şöyle olacaktır:

: yöntem = POST
: şema = https
: otorite = dnsserver.example.net
: yol = / dns-sorgu
kabul = uygulama / dns-mesaj
içerik-türü = uygulama / dns-mesaj
içeriği-uzunluğu = 33

<Aşağıdaki hex kodlaması ile temsil edilen 33 bayt> 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

DOH sorgularının gönderileceği diğer yerler

Birkaç yerde HTTPS üzerinden DNS'yi destekleyen bazı genel DNS çözümleyicilerin bir listesini bulabilirsiniz:

Yukarıdaki kaynaklardan Curl'un wiki ve DNSCrypt listesindeki listenin muhtemelen en eksiksiz ve en sık güncellenen olduğunu söyleyebilirim. Curl'un sayfası ayrıca DoH için açık kaynaklı araçların bir listesini (sunucular, proxy'ler, istemci kitaplıkları, vb.) İçerir.


14

Barındırılan JSONP sürümü bir cazibe gibi çalışıyor, ancak çoğu gün (Doğu Saati) gece saatlerinde kaynaklarını kullanıyor gibi görünüyor, bu yüzden kendi sürümümü oluşturmak zorunda kaldım.

PHP ile bunu şu şekilde başardım:

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

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

O zaman Javascript tam olarak öncekiyle aynıdır, bir dizi değil:

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

Bu kadar basit!

Yan not: Herkese açık herhangi bir ortamda kullanıyorsanız $ _GET'inizi temizlediğinizden emin olun!


Teşekkürler tcole! Tam aradığım şey :)
jClark

Bir dakika, neden $ _GET kullanasınız ki? Dediğin gibi bu bir güvenlik açığı. Biri sadece şunu kullanamazdı: echo 'getip ('. $ Data. ');';
deweydb

7
Üzgünüm ama asıl soruyu yanıtladığını düşünmediğim için olumsuz oy vermem gerekti. Sadece standart bir DNS araması istiyorlar, kullanıcının genel IP'sini değil.
Simon East

2
@SimonEast Heh. 7 yıllık bir sorunun sorusunu değiştirdiniz. Kendinizi tatmin etmek için ne gerekiyorsa yapın ;-)
tcole

2
Yakın zamanda aynı soruyu araştırdığımdan, orijinal soruyu daha net hale getirmek için sadece düzenledim, ancak bazı nedenlerden dolayı buradaki yanıtların çoğu, asıl gönderenin istediği şey değil ve farklı bir soru altında gönderilmelidir.
Simon East

3

Bunun eski bir soru olduğunun farkındayım ama benim çözümüm başkalarına yardımcı olabilir.

Bunu kolaylaştıran JSON (P) hizmetlerinin sonsuza kadar sürmediğini ancak aşağıdaki JavaScript'in yazarken benim için iyi çalıştığını görüyorum.

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

Yukarıdakiler, sunucumun IP'sini bulunduğu sayfaya yazar, ancak komut dosyası 'zero.eu.org' başka bir alan adıyla değiştirilerek herhangi bir IP'yi bulmak için değiştirilebilir. Bu, sayfamda eylem halinde görülebilir: http://meon.zero.eu.org/


Bunu kullanarak kendi ip adresimi nasıl bulacağımı anlayamıyorum: <! - # echo var = "REMOTE_ADDR" -> web sitenize göre.
George Carlin

Bu, çoğu web sunucusunda bulunan standart bir "yankı" özelliğidir. Bakınız: google.co.uk/…
Neville Hillyer

1
Bu muhtemelen asıl soruyu doğru bir şekilde ele alan tek cevaptır, aferin. Maalesef , istemcinin bilgisayar kısmından görüldüğü gibi , bu önemli bir gereklilik olabilir (veya olmayabilir).
Simon East

@Simon - "Müşterinin bilgisayarından görüldüğü gibi" nerede yazıyor ve cevabım neden buna uymuyor?
Neville Hillyer

1
@Simon - İyi bir nokta, ancak normalde istemci tarafı JS sunucu tarafından sağlandığından, yazarın / sunucu sahibinin bu DNS sınırlamasının farkında olma olasılığı yüksektir - üçüncü taraf sunucuları kullanan yazarlar için bir sorun olabilir. Buradaki yazılarda belirtildiği gibi, mevcut teknoloji bu konudaki tüm kısıtlamaları karşılama mücadelesi veriyor. Girdiğim, sunucumda en pratik bulduğum çözümü iletmeyi amaçlıyordu.
Neville Hillyer


1

Birçok kişinin dediği gibi, harici bir servis kullanmanız ve onu aramanız gerekiyor. Ve bu size yalnızca sunucu açısından DNS çözümlemesini sağlayacaktır.

Bu yeterince iyiyse ve yalnızca DNS çözümlemesine ihtiyacınız varsa aşağıdaki Docker konteynerini kullanabilirsiniz:

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

Uç noktalar:

[GET] /ipv6/[domain]: Verilen etki alanı için bir DNS çözümlemesi gerçekleştirin ve ilişkili IPv6 adreslerini döndürün.

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

[GET] /ipv4/[domain]: Verilen etki alanı için bir DNS çözümlemesi gerçekleştirin ve ilişkili IPv4 adreslerini döndürün.

 {
     "addresses": [
         "139.180.232.162"
     ]
 }

Benim tavsiyem, web sunucunuzu, Javascript'inize hizmet veren sunucunuzdaki belirli bir uç noktadaki kapsayıcıya proxy'yi ters çevirecek şekilde ayarlamanız ve onu standart Javascript Ajax işlevlerinizi kullanarak çağırmanızdır.



0

Bunu yapmak, tarayıcının korumalı alanını kırmayı gerektirir. Sunucunuzun aramayı yapmasına ve bunu istemci tarafından XmlHttp aracılığıyla istemesine izin vermeye çalışın.


-1

Firefox, WebExtensions için v60'tan beri bunun için yerleşik bir API'ye sahiptir:

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


Sebep ne olursa olsun, browserFirefox 64 beta'da yok, bu yüzden kaldırılıp kaldırılmadığını merak ediyorum.
Kevin Ghadyani

3
@Sawtaytoes: Yalnızca WebExtensions için kullanıma sunulur . Ayrıca dnsizin gerektirdiğini ve betiğin bir içerik betiği olarak çalışmayacağını unutmayın (yine olduğu gibi, browser.dnsorada gösterilmeyecektir)
Saturnus

@Saturnus, bu Firefox eklentileri için iyi çalışıyor. Aynı şeyi Chrome uzantılarıyla bir şekilde yapma şansınız var mı?
drk

-1

bu dns yöntemini kullanarak herhangi bir ekleme yapmadan, sadece saf javascript kullanabileceğinizden emin olabilirsiniz, browser.dns.resolve("example.com"); ancak yalnızca FIREFOX 60 ile uyumludur, MDN https://developer.mozilla.org/en-US/docs adresinde daha fazla bilgi görebilirsiniz. / Mozilla / Add-ons / WebExtensions / API / dns / resol


4
Bu yöntem yalnızca WebExtension bağlamında kullanılabilir. Bir web sayfası tarafından kullanılamaz.
alacakaranlıkta

-2

Sorunun sorduğu gibi saf bir JavaScript bağlamında, güvenlik nedenleriyle çoğu tarayıcı tarafından buna izin verildiğini sanmıyorum.


5
Bu bir cevap değil. Bu bir yorum olmalı!
trejder

-3

Belki de noktayı kaçırdım ama NAVY'ye cevap olarak, tarayıcının size 'talep sahibinin' IP adresini nasıl söyleyebileceğini (belki sadece servis sağlayıcısı olsa da).

Dengeli yüklenmemiş başka bir sunucuyu çağıran (src'yi işaret eden) istemci tarafından oluşturulacak sayfaya bir komut dosyası etiketi yerleştirin (bunun, bu günlerde 2. bir sunucuya erişmeniz gerektiği, ancak barındırmanın ucuz olduğu anlamına geldiğini anlıyorum. bunu kolayca ve ucuza kurun).

Bu, müşteri sayfasına eklenmesi gereken kod türüdür:

Diğer sunucuda "someServerIown" ASP, ASPX veya PHP sayfasına sahip olmanız gerekir;

----- aşağıdaki gibi sunucu kodunu içerir:

"<% Response.Write (" var clientipaddress = '"& Request.ServerVariables (" REMOTE_ADDR ") &"'; ")%>" (dbl tırnak işaretleri olmadan :-))

---- ve bu kodu komut dosyası etiketine geri yazar:

   var clientipaddress = '178.32.21.45';

Bu, sayfadaki Javascript ile erişebileceğiniz bir Javascript değişkeni oluşturur.

Umarım bu değişkene erişirsiniz ve değeri geri göndermeye hazır bir form denetimine yazarsınız.

Kullanıcı bir sonraki talebi gönderip aldığında, Javascript ve / veya formunuz "otherServerIown" ın sizin için doldurduğu değişkenin değerini, istediğiniz sunucuya geri gönderir.

İstemci IP adresini maskeleyen ve onu Yük dengeleyicininki gibi gösteren aptal yük dengeleyiciyi bu şekilde aşıyorum .... aptal ... aptal aptal!

Tam çözümü vermedim çünkü herkesin durumu biraz farklı. Ancak kavram sağlam. Ayrıca, bunu bir HTTPS sayfasında yapıyorsanız, "otherServerIOwn" unuzun da bu güvenli biçimde teslim etmesi gerektiğini unutmayın, aksi takdirde İstemci karma içerik konusunda uyarılır. Ve https'niz varsa, TÜM sertifikalarınızın geçerli olduğundan emin olun, aksi takdirde müşteri de bir uyarı alır.

Umarım birine yardımcı olur! Üzgünüm, yanıtlamak / katkıda bulunmak bir yıl sürdü. :-)


3
Üzgünüm ama asıl soruyu yanıtladığını düşünmediğim için olumsuz oy vermem gerekti. Sadece standart bir DNS araması istiyorlar, kullanıcının genel IP'sini değil.
Simon East

-4

Benim versiyonum şöyle:

sunucumdaki php:

<?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 . ');';
?>

Sayfadaki jQuery:

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

}).done( function( json ) {

    self.ip = json;

});

Alanlar arası çalışır. Durum kontrolü kullanabilir. Üzerinde çalışmak.


2
Üzgünüm ama asıl soruyu yanıtladığını düşünmediğim için olumsuz oy vermem gerekti. Sadece standart bir DNS araması istiyorlar, kullanıcının genel IP'sini değil. Kodunuz ayrıca büyük bir güvenlik sorunu olan $ _GET'i de temizlemiyor.
Simon East

@Simon East Daha da kötü olduğunu düşünüyorum. Herhangi bir IP'yi DNS ile aramak istiyorlar gibi görünüyor.
Joeri

@SimonEast PHP'mi nasıl derlediğime dair hiçbir fikriniz olmadığı için bunun bir güvenlik sorunu olduğunu kanıtlayamazsınız. Katılığınız çok aptalca.
Joeri

-10

İstemcide Java yüklüyse, şöyle bir şey yapabilirsiniz:

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

Bunun dışında, muhtemelen bir sunucu tarafı komut dosyası kullanmanız gerekecektir.


8
Neden birisi buna olumlu oy veriyor? java! = javascript, bu bir yanıt DEĞİLDİR.
Sven Mawby

2
Tık tık. Oradaki kim? (... uzun duraklama) Java Applet
mike nelson
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.