Dapatkah saya melakukan pencarian DNS (nama host ke alamat IP) menggunakan Javascript sisi klien?

92

Saya ingin menggunakan Javascript sisi klien untuk melakukan pencarian DNS (nama host ke alamat IP) seperti yang terlihat dari komputer klien. Apakah itu mungkin?

Noah Jacobson
sumber
5
Banyak dari jawaban atas pertanyaan ini tampaknya merekomendasikan melakukan sisi server resolusi. Bergantung pada kasus penggunaan, itu mungkin tidak cukup. Misalnya, jika layanan yang Anda cari menggunakan GSLB, layanan tersebut mungkin mengembalikan IP yang berbeda berdasarkan lokasi pengguna; akibatnya, respons yang diterima kode sisi server kemungkinan besar merupakan respons yang berbeda dari yang akan diterima browser. Meski begitu, saya belum memiliki solusi alternatif bagi mereka yang peduli dengan perbedaan ini.
Ilan Rabinovitch

Jawaban:

35

Tidak ada gagasan tentang host atau alamat ip di perpustakaan standar javascript. Jadi, Anda harus mengakses beberapa layanan eksternal untuk mencari nama host untuk Anda.

Saya merekomendasikan hosting cgi-bin yang mencari alamat ip dari nama host dan mengaksesnya melalui javascript.

Hans Sjunnesson
sumber
26
cgi-bin? Itu sekolah tua. Saya suka itu!
Andrew Hedges
10
Ini benar pada saat penulisan (2008). Ini tidak benar 6 tahun kemudian: Lihat komentar saya tentang WebRTC di halaman yang sama ini. (Sayangnya Google masih menunjuk ke utas ini ketika mencari solusi untuk masalah alamat IP dan itu dapat menempatkan orang ke arah yang salah).
earizon
1
@earizon - jawaban Anda untuk pertanyaan yang berbeda - bagaimana menemukan alamat IP pribadi Anda.
Gene Vayngrib
Masalah melalui CGI dari cloud adalah menemukan IP host intranet yang tidak mungkin dilakukan dari luar. Anda harus menggunakan layanan lokal di mesin atau intranet.
Tzahi Fadida
Ada standar Internet baru yang diusulkan yang memungkinkan Anda mengirim kueri DNS melalui HTTPS (lihat jawaban ini stackoverflow.com/a/58299823/9638991 ). Pada dasarnya, ini pada dasarnya berfungsi sama dengan skrip cgi-bin :) (kecuali itu telah distandarisasi oleh IETF dan banyak perusahaan besar mendukungnya)
kimbo
83

Sunting : Pertanyaan ini membuat saya gatal, jadi saya memasang layanan web JSONP di Google App Engine yang mengembalikan alamat ip klien. Pemakaian:

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

Hore, tidak perlu proxy server.


JS murni tidak bisa. Jika Anda memiliki skrip server di bawah domain yang sama yang mencetaknya, Anda dapat mengirim XMLHttpRequest untuk membacanya.

Zach
sumber
4
Bisakah Anda memposting sumber ke layanan web Anda? Alangkah baiknya menjalankan sebuah contoh.
Apakah
18
Maaf, tetapi harus memberi suara negatif karena menurut saya itu tidak benar-benar menjawab pertanyaan asli. Mereka hanya menginginkan pencarian DNS standar, bukan IP publik pengguna.
Simon East
30

Sangat larut, tapi saya rasa banyak orang masih akan mendarat di sini melalui "Google Airlines". Pendekatan moderm adalah menggunakan WebRTC yang tidak memerlukan dukungan server.

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

Kode selanjutnya adalah copy & paste dari 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.dll
sumber
19
ini memang kemampuan baru yang tidak ada sebelum WebRTC - untuk menemukan alamat IP Anda sendiri. Tapi @noahjacobson mengajukan pertanyaan yang berbeda - pencarian DNS IP dengan nama host dari javascript.
Gene Vayngrib
2
Sangat, sangat menarik, ini adalah bug atau cacat desain, bagaimanapun pada titik tertentu akan diperbaiki jadi tidak baik untuk proyek jangka panjang
e-info128
15

Saya tahu pertanyaan ini telah diajukan sejak lama, tetapi saya pikir saya akan menawarkan jawaban yang lebih baru.

DNS melalui HTTPS (DoH)

Anda dapat mengirim kueri DNS melalui HTTPS ke resolver DNS yang mendukungnya. Standar untuk DOH dijelaskan dalam RFC 8484 .

Ini adalah hal yang mirip dengan yang disarankan semua jawaban lainnya, hanya DoH yang sebenarnya adalah protokol DNS melalui HTTPS. Ini juga merupakan standar Internet yang "diusulkan" dan menjadi sangat populer. Misalnya, beberapa browser utama mendukungnya atau memiliki rencana untuk mendukungnya (Chrome, Edge, Firefox), dan Microsoft sedang dalam proses membangunnya ke dalam sistem operasi mereka.

Salah satu tujuan DoH adalah:

mengizinkan aplikasi web untuk mengakses informasi DNS melalui API browser yang ada dengan cara yang aman sesuai dengan Cross Origin Resource Sharing (CORS)

Ada alat open source yang dibuat khusus untuk melakukan pencarian DNS dari aplikasi web yang disebut dohjs . Itu melakukan DNS melalui kueri wireformat HTTPS (DoH) seperti yang dijelaskan dalam RFC 8484 . Ini mendukung metode GET dan POST.

Pengungkapan penuh: Saya adalah kontributor dohjs.

DNS melalui HTTPS JSON API

Jika Anda tidak ingin repot dengan wireformat DNS, baik Google dan Cloudflare menawarkan JSON API untuk DNS melalui HTTPS.

Contoh kode Javascript untuk mencari example.com dengan JSON DOH API Google:

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

Contoh dari RFC untuk DOH GET dan POST dengan wireformat

Berikut adalah contoh yang diberikan RFC untuk GET dan POST (lihat https://tools.ietf.org/html/rfc8484#section-4.1.1 ):

GET contoh:

Permintaan contoh pertama menggunakan GET untuk meminta "www.example.com".

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

Contoh POST:

Kueri DNS yang sama untuk "www.example.com", menggunakan metode POST adalah:

: metode = POST
: skema = https
: otoritas = dnsserver.example.net
: path = / dns-query
accept = application / dns-message
content-type = application / dns-message
content-length = 33

<33 byte diwakili oleh pengkodean hex berikut> 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

Tempat lain untuk mengirim pertanyaan DOH

Anda dapat menemukan daftar beberapa resolver DNS publik yang mendukung DNS melalui HTTPS di beberapa tempat:

Dari sumber daya di atas, saya akan mengatakan bahwa daftar di wiki Curl dan daftar DNSCrypt mungkin yang paling lengkap dan paling sering diperbarui. Halaman Curl juga menyertakan daftar alat open source untuk DoH (server, proxy, lib klien, dll).

kimbo
sumber
14

Versi JSONP yang dihosting berfungsi seperti pesona, tetapi tampaknya itu melampaui sumber dayanya pada malam hari hampir setiap hari (Waktu Timur), jadi saya harus membuat versi saya sendiri.

Ini adalah bagaimana saya menyelesaikannya dengan PHP:

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

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

Maka Javascriptnya persis sama seperti sebelumnya, hanya saja bukan sebuah 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>

Sederhana seperti itu!

Catatan tambahan: Pastikan untuk membersihkan $ _GET Anda jika Anda menggunakan ini di lingkungan yang terbuka untuk umum!

tcole
sumber
Terima kasih tcole! Hanya apa yang saya cari :)
jClark
Tunggu sebentar, mengapa harus menggunakan $ _GET? seperti yang Anda katakan, ini adalah kerentanan. Tidak dapatkah seseorang menggunakan: echo 'getip ('. $ Data. ');';
deweydb
7
Maaf, tetapi harus memberi suara negatif karena menurut saya itu tidak benar-benar menjawab pertanyaan asli. Mereka hanya menginginkan pencarian DNS standar, bukan IP publik pengguna.
Simon East
2
@Tokopedia Anda mengubah pertanyaan dari pertanyaan berusia 7 tahun. Lakukan apapun yang Anda butuhkan untuk memuaskan diri sendiri ;-)
tcole
2
Saya hanya mengedit pertanyaan asli untuk membuatnya lebih jelas, karena saya baru-baru ini meneliti pertanyaan yang sama, namun untuk beberapa alasan sebagian besar jawaban di sini sebenarnya bukan yang diminta oleh poster asli dan harus diposting di bawah pertanyaan yang berbeda.
Simon East
3

Saya sadar ini adalah pertanyaan lama tetapi solusi saya dapat membantu orang lain.

Saya menemukan bahwa layanan JSON (P) yang membuat ini mudah tidak bertahan selamanya tetapi JavaScript berikut berfungsi dengan baik untuk saya pada saat penulisan.

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

Di atas menulis IP server saya pada halaman tempatnya, tetapi skrip dapat dimodifikasi untuk menemukan IP apa pun dengan mengubah 'zero.eu.org' ke nama domain lain. Ini dapat dilihat beraksi di halaman saya di: http://meon.zero.eu.org/

Neville Hillyer
sumber
Saya tidak dapat memahami cara menemukan alamat ip saya sendiri menggunakan ini: <! - # echo var = "REMOTE_ADDR" -> menurut situs web Anda.
George Carlin
Ini adalah fasilitas 'echo' standar yang tersedia di sebagian besar server web. Lihat: google.co.uk/…
Neville Hillyer
1
Ini mungkin satu-satunya jawaban yang benar-benar menjawab pertanyaan awal dengan benar, bagus. Sayangnya itu tidak sesuai dengan yang terlihat dari bagian komputer klien , yang mungkin (atau mungkin tidak) menjadi persyaratan penting.
Simon East
@ Simon - Di mana dikatakan "seperti yang terlihat dari komputer klien" & mengapa jawaban saya tidak sesuai dengan ini?
Neville Hillyer
1
@Simon - Hal yang bagus tetapi karena biasanya JS sisi klien adalah server yang disediakan, ada kemungkinan besar bahwa penulis / pemilik server akan mengetahui batasan DNS ini - dapat menjadi masalah bagi penulis yang menggunakan server pihak ketiga. Seperti yang ditunjukkan dalam posting di sini perjuangan teknologi yang ada untuk memenuhi semua kendala yang satu ini. Masukan saya dimaksudkan untuk menyampaikan solusi yang menurut saya paling praktis di server saya.
Neville Hillyer
1

Seperti yang dikatakan banyak orang, Anda perlu menggunakan layanan eksternal dan menyebutnya. Dan itu hanya akan memberi Anda resolusi DNS dari perspektif server.

Jika itu cukup bagus dan jika Anda hanya membutuhkan resolusi DNS, Anda dapat menggunakan container Docker berikut:

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

Titik akhir:

[GET] /ipv6/[domain]: Lakukan resolusi DNS untuk domain tertentu dan kembalikan alamat IPv6 terkait.

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

[GET] /ipv4/[domain]: Lakukan resolusi DNS untuk domain tertentu dan kembalikan alamat IPv4 terkait.

 {
     "addresses": [
         "139.180.232.162"
     ]
 }

Rekomendasi saya adalah Anda mengatur server web Anda untuk membalikkan proxy ke wadah pada titik akhir tertentu di server Anda yang melayani Javascript Anda dan menyebutnya menggunakan fungsi Javascript Ajax standar Anda.

Havok
sumber
1

Ada perpustakaan javascript DNS-JS.com yang melakukan hal ini.

DNS.Query("dns-js.com",
    DNS.QueryType.A,
    function(data) {
        console.log(data);
});
Fiach Reid
sumber
1
Masih bukan dari sudut pandang klien. Perpustakaan itu membuat permintaan ke dns-js.com/api.aspx untuk mendapatkan alamat IP yang kemudian menyelesaikan sisi server DNS.
wp-overwatch.com
0

Melakukan ini akan membutuhkan perusakan kotak pasir browser. Cobalah untuk membiarkan server Anda melakukan pencarian dan memintanya dari sisi klien melalui XmlHttp.

Tomalak
sumber
-1

Firefox memiliki API bawaan untuk ini sejak v60, untuk WebExtensions:

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

Saturnus
sumber
Untuk alasan apa pun, browsertidak ada di Firefox 64 beta jadi saya bertanya-tanya apakah itu sudah dihapus.
Kevin Ghadyani
3
@Sawtaytoes: Dipaparkan hanya untuk WebExtensions . Juga perhatikan itu membutuhkan dnsizin dan skrip tidak akan berjalan sebagai skrip konten (karena sekali lagi, browser.dnstidak akan diekspos di sana)
Saturnus
@ Saturnus ini berfungsi dengan baik untuk ekstensi Firefox. Adakah kesempatan untuk melakukan hal yang sama dengan ekstensi Chrome?
drk
-1

tentu Anda dapat melakukannya tanpa menggunakan tambahan apa pun, hanya javascript murni, dengan menggunakan metode dns ini browser.dns.resolve("example.com"); tetapi hanya kompatibel dengan FIREFOX 60 Anda dapat melihat informasi lebih lanjut tentang MDN https://developer.mozilla.org/en-US/docs / Mozilla / Add-ons / WebExtensions / API / dns / selesaikan

Yassine Farroud
sumber
4
Metode ini hanya tersedia dalam konteks WebExtension. Ini tidak dapat digunakan oleh halaman web.
senja -tidak aktif-
-2

Saya tidak berpikir ini diizinkan oleh sebagian besar browser untuk alasan keamanan, dalam konteks JavaScript murni seperti yang ditanyakan oleh pertanyaan.

Nick Craver
sumber
5
Ini bukanlah jawaban. Ini harus menjadi komentar!
trejder
-3

Mungkin saya melewatkan intinya tetapi sebagai balasan kepada NAVY guy di sini adalah bagaimana browser dapat memberi tahu Anda alamat IP 'pemohon' (meskipun mungkin hanya penyedia layanan mereka).

Tempatkan tag skrip di halaman yang akan dirender oleh klien yang memanggil (memiliki src menunjuk ke) server lain yang tidak dimuat seimbang (Saya menyadari bahwa ini berarti Anda memerlukan akses ke server kedua tetapi hosting murah hari ini dan Anda bisa atur ini dengan mudah dan murah).

Ini adalah jenis kode yang perlu ditambahkan ke halaman klien:

Di server lain "someServerIown" Anda harus memiliki halaman ASP, ASPX atau PHP yang;

----- berisi kode server seperti ini:

"<% Response.Write (" var clientipaddress = '"& Request.ServerVariables (" REMOTE_ADDR ") &"'; ")%>" (tanpa tanda kutip dbl luar :-))

---- dan menulis kode ini kembali ke tag skrip:

   var clientipaddress = '178.32.21.45';

Ini secara efektif membuat variabel Javascript yang dapat Anda akses dengan Javascript di halaman tidak kurang.

Mudah-mudahan, Anda mengakses var ini dan menulis nilainya ke kontrol formulir yang siap untuk dikirim kembali.

Ketika pengguna memposting atau mendapatkan permintaan berikutnya, Javascript dan / atau formulir Anda mengirimkan nilai variabel yang telah diisi oleh "otherServerIown" untuk Anda, kembali ke server yang Anda inginkan.

Beginilah cara saya mengatasi penyeimbang beban bodoh yang kami miliki yang menutupi alamat IP klien dan membuatnya tampak seperti penyeimbang Beban .... dumb ... dumb dumb dumb!

Saya belum memberikan solusi yang tepat karena situasi setiap orang sedikit berbeda. Namun, konsepnya masuk akal. Juga, perhatikan jika Anda melakukan ini pada halaman HTTPS "otherServerIOwn" Anda juga harus mengirimkan dalam formulir aman itu jika tidak, Klien akan diberi tahu tentang konten campuran. Dan jika Anda memiliki https, pastikan SEMUA sertifikat Anda valid jika tidak, klien juga mendapat peringatan.

Semoga membantu seseorang! Maaf, butuh waktu setahun untuk menjawab / berkontribusi. :-)

Bill S
sumber
3
Maaf, tetapi harus memberi suara negatif karena menurut saya itu tidak benar-benar menjawab pertanyaan asli. Mereka hanya menginginkan pencarian DNS standar, bukan IP publik pengguna.
Simon East
-4

Versi saya seperti ini:

php di server saya:

<?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 di halaman:

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

}).done( function( json ) {

    self.ip = json;

});

Ini berfungsi lintas domain. Ini bisa menggunakan pemeriksaan status. Sedang mengerjakan itu.

Joeri
sumber
2
Maaf, tetapi harus memberi suara negatif karena menurut saya itu tidak benar-benar menjawab pertanyaan asli. Mereka hanya menginginkan pencarian DNS standar, bukan IP publik pengguna. Kode Anda juga tidak membersihkan $ _GET yang merupakan masalah keamanan besar.
Simon East
@Simon East Saya pikir itu lebih buruk. Sepertinya mereka ingin mencari IP apa pun dengan DNS.
Joeri
@SimonEast Anda tidak dapat membuktikan bahwa ini adalah masalah keamanan karena Anda tidak tahu bagaimana saya mengkompilasi php saya. Ketegasan Anda konyol.
Joeri
-10

Jika klien telah menginstal Java, Anda dapat melakukan sesuatu seperti ini:

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

Selain itu, Anda mungkin harus menggunakan skrip sisi server.

Alex Fort
sumber
8
Mengapa seseorang meningkatkan ini? java! = javascript, ini BUKAN jawaban.
Sven Mawby
2
Ketukan. Siapa disana? (... jeda panjang) Java Applet
mike nelson