Могу ли я выполнить поиск DNS (имя хоста по IP-адресу) с использованием клиентского Javascript?
Я хотел бы использовать Javascript на стороне клиента для выполнения поиска DNS (имя хоста по IP-адресу), как видно из компьютера клиента. Это возможно?
13 ответов
В стандартной библиотеке 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, чтобы прочитать его.
Я знаю, что этот вопрос задавали очень давно, но решил, что предложу более свежий ответ.
DNS через HTTPS (DoH)
Вы можете отправлять 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 через HTTPS JSON API
Если вы не хотите возиться с форматом проводов DNS, Google и Cloudflare предлагают JSON API для DNS через HTTPS.
- Конечная точка Google: https://dns.google/resolve?
- Документы Google JSON API: https://developers.google.com/speed/public-dns/docs/doh/json
- Конечная точка Cloudflare: https://cloudflare-dns.com/dns-query?
- Документация Cloudflare JSON API: https://developers.cloudflare.com/1.1.1.1/dns-over-https/json-format/
Пример кода Javascript для поиска example.com с помощью Google JSON DOH API:
var response = await fetch('https://dns.google/resolve?name=example.com');
var json = await response.json();
console.log(json);
Примеры из RFC для DOH GET и POST с wireformat
Вот примеры RFC для GET и POST (см. https://tools.ietf.org/html/rfc8484):
ПОЛУЧИТЬ пример:
В первом примере запроса GET используется для запроса "www.example.com".
:method = GET
:scheme = https
:author = dnsserver.example.net
: path = / dns-query? dns = AAABAAABAAAAAAAAA3d3dwdleGFtcGxlA2NvbQAAAQAB
accept = application / dns-message
Пример POST:
Тот же DNS-запрос для "www.example.com" с использованием метода POST будет:
:method = POST
:scheme = https
:author = 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 00 03 77 77 77 07 65 78 61 6d 70 6c 65 03 63 6f 6d 00 00 01 00 01
Другие места для отправки запросов DOH
Вы можете найти список некоторых общедоступных DNS-преобразователей, поддерживающих DNS через HTTPS, в нескольких местах:
- DNSCrypt имеет длинный список общедоступных преобразователей DoH и DNSCrypt на своем Github, а также красивую интерактивную версию списка на https://dnscrypt.info/public-servers/
- Википедия - сравнение публичных рекурсивных серверов имён
- Список на вики Curl
- (короткий) список на dnsprivacy.org
Из вышеперечисленных ресурсов я бы сказал, что список вики Curl и список DNSCrypt, вероятно, являются наиболее полными и наиболее часто обновляемыми. Страница Curl также включает список инструментов с открытым исходным кодом для DoH (серверы, прокси, клиентские библиотеки и т. Д.).
Очень поздно, но я думаю, что многие люди все еще будут приземляться здесь через "Авиакомпании Google". Подход Moderm заключается в использовании 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.";
}
Размещенная версия 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, если вы используете его в любой общедоступной среде!
Существует сторонний сервис, который предоставляет CORS-дружественный REST API для поиска DNS из браузера - https://exana.io/tools/dns/
Я знаю, что это старый вопрос, но мое решение может помочь другим.
Я обнаружил, что службы 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/
Для этого существует библиотека javascript DNS-JS.com.
DNS.Query("dns-js.com",
DNS.QueryType.A,
function(data) {
console.log(data);
});
Как говорили многие люди, вам нужно воспользоваться внешней услугой и позвонить ей. И это только даст вам разрешение DNS с точки зрения сервера.
Если это достаточно хорошо и вам нужно только разрешение DNS, вы можете использовать следующий Docker-контейнер:
https://github.com/kuralabs/docker-webaiodns
Endpoints:
[GET] /ipv6/[domain]
: Выполните разрешение DNS для данного домена и верните связанные адреса IPv6.
{
"addresses": [
"2a01:91ff::f03c:7e01:51bd:fe1f"
]
}
[GET] /ipv4/[domain]
: Выполните разрешение DNS для данного домена и верните связанные адреса IPv4.
{
"addresses": [
"139.180.232.162"
]
}
Я рекомендую вам настроить ваш веб-сервер так, чтобы он перенаправлял прокси к контейнеру на определенной конечной точке вашего сервера, обслуживающего ваш Javascript, и вызывал его, используя ваши стандартные функции Javascript Ajax.
Для этого потребуется сломать браузерную песочницу. Попробуйте позволить вашему серверу выполнить поиск и запросить его со стороны клиента через XmlHttp.
Firefox имеет встроенный API для этого начиная с v60, для WebExtensions:
https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/dns/resolve
Уверен , что вы можете сделать это без каких-либо дополнений, просто чистый JavaScript, используя этот метод DNS browser.dns.resolve("example.com");
но он совместим только с FIREFOX 60, вы можете увидеть больше информации на MDN https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/dns/resolve
Я не думаю, что это допускается большинством браузеров по соображениям безопасности, в чистом контексте JavaScript, как задает вопрос.
Моя версия такая:
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;
});
Работает междоменный. Это может использовать проверку статуса. Работаю над этим.
Возможно, я упустил момент, но в ответ парню 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 и / или форма отправляет значение переменной, которую "другой ServerIown" заполнил для вас, обратно на сервер, на котором вы хотели бы его видеть.
Вот как я обхожу бездействующий балансировщик нагрузки, который маскирует IP-адрес клиента и делает его похожим на адрес балансировщика нагрузки.... тупой... тупой тупой тупой!
Я не дал точное решение, потому что ситуация у всех немного другая. Концепция звучит, однако. Кроме того, обратите внимание, что если вы делаете это на странице HTTPS, ваш "otherServerIOwn" также должен доставлять в этой защищенной форме, в противном случае Клиент будет предупрежден о смешанном контенте. И если у вас есть https, убедитесь, что ВСЕ ваши сертификаты действительны, в противном случае клиент также получит предупреждение.
Надеюсь, это поможет кому-то! Извините, потребовался год, чтобы ответить.:-)
Если на клиенте установлена Java, вы можете сделать что-то вроде этого:
ipAddress = java.net.InetAddress.getLocalHost().getHostAddress();
Кроме этого, вам, вероятно, придется использовать скрипт на стороне сервера.