Я хотів би використовувати клієнтський Javascript для пошуку DNS (ім’я хосту до IP-адреси), як видно з комп’ютера клієнта. Це можливо?
Я хотів би використовувати клієнтський Javascript для пошуку DNS (ім’я хосту до IP-адреси), як видно з комп’ютера клієнта. Це можливо?
Відповіді:
У стандартній бібліотеці javascript немає поняття хостів чи ip-адрес. Тож вам доведеться отримати доступ до якоїсь зовнішньої служби, щоб знайти для вас імена хостів.
Я рекомендую розміщувати cgi-bin, який шукає ip-адресу імені хосту та отримувати доступ до нього через javascript.
Редагувати : Це запитання викликало у мене свербіж, тому я розмістив веб-службу JSONP на Google App Engine, яка повертає ip-адресу клієнтів. Використання:
<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>
Так, проксі-сервери не потрібні.
Чистий JS не може. Якщо у вас є сценарій сервера під тим самим доменом, який його друкує, ви можете надіслати XMLHttpRequest для його читання.
Дуже пізно, але, думаю, багато людей все одно приземляться сюди через "Google Airlines". Сучасний підхід полягає у використанні WebRTC, який не потребує підтримки сервера.
https://hacking.ventures/local-ip-discovery-with-html5-webrtc-security-and-privacy-risk/
Наступний код - це копіювання та вставлення з 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.";
}
Я знаю, що це запитання було задано дуже давно, але я вирішив, що запропоную більш пізню відповідь.
Ви можете надсилати DNS-запити через HTTPS до вирішувачів DNS, які його підтримують. Стандарт для DOH описаний у RFC 8484 .
Це схоже на те, що пропонують усі інші відповіді, лише те, що DoH насправді є протоколом DNS через HTTPS. Це також "запропонований" стандарт Інтернету, і він стає досить популярним. Наприклад, деякі основні браузери або підтримують його, або планують його підтримувати (Chrome, Edge, Firefox), і Microsoft перебуває в процесі вбудовування його в свою операційну систему.
Однією з цілей DoH є:
дозволяючи веб-програмам отримувати доступ до інформації DNS через існуючі API браузера безпечним способом, сумісним із Cross Origin Resource Sharing (CORS)
Існує інструмент з відкритим кодом, спеціально створений для пошуку DNS у веб-програмах, який називається dohjs . Він виконує запити DNS через HTTPS (DoH), як описано в RFC 8484 . Він підтримує як методи GET, так і POST.
Повне розкриття інформації: Я є автором dohjs.
Якщо ви не хочете турбуватися про DNS-формат, Google і Cloudflare пропонують JSON API для DNS через HTTPS.
Приклад коду Javascript для пошуку example.com за допомогою API JSON DOH від Google:
var response = await fetch('https://dns.google/resolve?name=example.com');
var json = await response.json();
console.log(json);
Ось приклади, які RFC дає як для GET, так і для POST (див. Https://tools.ietf.org/html/rfc8484#section-4.1.1 ):
Приклад GET:
Перший приклад запиту використовує GET для запиту "www.example.com".
: method = GET
: схема = https
: Authority = dnsserver.example.net
: path = / dns-query? dns = AAABAAABAAAAAAAAA3d3dwdleGFtcGxlA2NvbQAAAQAB
accept = application / dns-message
Приклад POST:
Той самий запит DNS для "www.example.com" із використанням методу POST буде таким:
: method = POST
: схема = https
: Authority = dnsserver.example.net
: path = / dns-query
accept = application / dns-message
content-type = application / dns-message
content-length = 33<33 байта, представлене наступним шістнадцятковим кодуванням> 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
Ви можете знайти список деяких загальнодоступних засобів вирішення проблем DNS, які підтримують DNS через HTTPS, у кількох місцях:
З вищезазначених ресурсів я б сказав, що список у вікі Curl та список DNSCrypt є, мабуть, найбільш повним та найбільш часто оновлюваним. Сторінка Curl також включає перелік інструментів з відкритим кодом для DoH (сервери, проксі, клієнтські бібліотеки тощо).
Розміщена версія JSONP працює як привабливість, але, схоже, вона перевищує свої ресурси протягом більшості днів вночі (східний час), тому мені довелося створити власну версію.
Ось як я це зробив за допомогою PHP:
<?php
header('content-type: application/json; charset=utf-8');
$data = json_encode($_SERVER['REMOTE_ADDR']);
echo $_GET['callback'] . '(' . $data . ');';
?>
Тоді Javascript точно такий же, як і раніше, тільки не масив:
<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>
Просто як це!
Примітка: Обов’язково очистіть $ _GET, якщо ви використовуєте його в будь-якому громадському середовищі!
Я усвідомлюю, що це старе питання, але моє рішення може допомогти іншим.
Я вважаю, що послуги JSON (P), які роблять це легким, не тривають вічно, але такий JavaScript працює добре для мене на момент написання статті.
<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>
Вищезаписане IP-адресу мого сервера на сторінці, на якій він знаходиться, але сценарій можна змінити, щоб знайти будь-який IP-адресу, змінивши 'zero.eu.org' на інше доменне ім'я. Це можна побачити в дії на моїй сторінці за адресою: http://meon.zero.eu.org/
Існує сторонній сервіс, який надає CORS-зручний REST API для здійснення пошуку DNS з браузера - https://exana.io/tools/dns/
Як багато людей говорили, що вам потрібно скористатися зовнішньою службою і зателефонувати їй. І це дозволить отримати роздільну здатність DNS лише з точки зору сервера.
Якщо це досить добре, і якщо вам просто потрібна роздільна здатність DNS, ви можете використовувати наступний контейнер Docker:
https://github.com/kuralabs/docker-webaiodns
Кінцеві точки:
[GET] /ipv6/[domain]
: Виконайте роздільну здатність DNS для даного домену та поверніть пов'язані адреси IPv6.
{
"addresses": [
"2a01:91ff::f03c:7e01:51bd:fe1f"
]
}
[GET] /ipv4/[domain]
: Виконайте роздільну здатність DNS для даного домену та поверніть пов'язані адреси IPv4.
{
"addresses": [
"139.180.232.162"
]
}
Я рекомендую вам налаштувати свій веб-сервер на зворотний проксі-сервер для контейнера на певній кінцевій точці вашого сервера, що обслуговує ваш Javascript, і викликати його, використовуючи ваші стандартні функції Ajax Javascript.
Існує бібліотека javascript DNS-JS.com, яка робить саме це.
DNS.Query("dns-js.com",
DNS.QueryType.A,
function(data) {
console.log(data);
});
Firefox має вбудований API для цього починаючи з v60, для WebExtensions:
https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/dns/resolve
browser
у Firefox 64 beta не існує, тому мені цікаво, чи було це видалено.
dns
дозвіл, і сценарій не повинен працювати як сценарій змісту (як і знову, там browser.dns
не буде виставлено)
впевнені, ви можете зробити це без використання будь-якого доповнення, лише чистого javascript, використовуючи цей метод dns, browser.dns.resolve("example.com");
але він сумісний лише з FIREFOX 60. Ви можете побачити більше інформації на MDN https://developer.mozilla.org/en-US/docs / Mozilla / Додатки / WebExtensions / API / dns / resolution
Я не думаю, що це дозволяється більшістю браузерів з міркувань безпеки, в чистому контексті JavaScript, як постає питання.
Можливо, я пропустив суть, але у відповідь хлопцеві NAVY ось як браузер може повідомити вам IP-адресу "запитувача" (хоча, можливо, лише їх постачальника послуг).
Помістіть на сторінку тег скрипта, який повинен відображати клієнт, який викликає (на нього вказує src) інший сервер, який не завантажений збалансовано (я розумію, що це означає, що вам потрібен доступ до 2-го сервера, але хостинг сьогодні дешевий, і ви можете налаштуйте це легко та дешево).
Це такий код, який потрібно додати на сторінку клієнта:
На іншому сервері "someServerIown" потрібно мати сторінку ASP, ASPX або PHP, що;
----- містить такий серверний код:
"<% Response.Write (" var clientipaddress = '"& Request.ServerVariables (" REMOTE_ADDR ") &"'; ")%>" (без зовнішніх котировок dbl :-))
---- і записує цей код назад у тег сценарію:
var clientipaddress = '178.32.21.45';
Це ефективно створює змінну Javascript, до якої ви можете отримати доступ за допомогою Javascript на сторінці не менше.
Сподіваємось, ви отримаєте доступ до цього варіанта та запишете значення до елемента керування формою, готового до відправлення назад.
Коли користувач публікує або отримує наступний запит, ваш Javascript та / або форма надсилає значення змінної, яку заповнив для вас "otherServerIown", назад на сервер, на якому ви хотіли б це зробити.
Ось як я обходжу тупий балансир навантаження, який маємо, який маскує IP-адресу клієнта і робить його таким, як у балансира навантаження .... німий ... німий тупий німий!
Я не дав точного рішення, оскільки ситуація у всіх дещо інша. Однак концепція обгрунтована. Крім того, зауважте, якщо ви робите це на сторінці HTTPS, ваш "otherServerIOwn" також повинен доставляти в цій безпечній формі, інакше Клієнт буде попереджений про змішаний вміст. І якщо у вас є https, переконайтеся, що ВСІ ваші сертифікати дійсні, інакше клієнт також отримує попередження.
Сподіваюся, це комусь допоможе! На жаль, на відповідь / внесок пішов рік. :-)
Моя версія така:
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 . ');';
?>
jQuery на сторінці:
var self = this;
$.ajax({
url: this.url + "getip.php",
data: null,
type: 'GET',
crossDomain: true,
dataType: 'jsonp'
}).done( function( json ) {
self.ip = json;
});
Це працює міждоменне. Він може використовувати перевірку стану. Працюємо над цим.
Якщо на клієнті встановлена Java, ви можете зробити щось подібне:
ipAddress = java.net.InetAddress.getLocalHost().getHostAddress();
Крім цього, вам, мабуть, доведеться використовувати сценарій на стороні сервера.