I need to fetch the client local IP address from a web application.
For which I am using a standard RTCPeerConnection implementation to fetch. But the ice candidate that is returned does not carry the IP V4 address, but an address that look like a guid: asdf-xxxx-saass-xxxx.local
But surprisingly this chrome extension is able to fetch the same on same machine and browser.
Note: code that I used in web application is same as of the extension
This is the html code for same:
<html>
<head>
<script type="text/javascript" src="https://code.jquery.com/jquery-1.11.1.js"></script>
<script type="text/javascript">
function logit(msg) {
var dt = new Date(); var time = dt.getHours() + ":" + dt.getMinutes() + ":"
+ dt.getSeconds();
console.log(time + " " + msg);
};
function getChromeVersion() {
try {
var raw = navigator.userAgent.match(/Chrom(e|ium)\/([0-9]+)\./);
return raw ? parseInt(raw[2], 10) : false;
} catch (e) {
return null;
}
}
function getChromeManifest() {
return chrome.runtime && typeof chrome.runtime === "function" ? chrome.runtime.getManifest() : {}
}
function getUserIP(callback) {
logit(" getting user local ip ")
getLocalIPs(function (ips) {
logit(" got user local ip : " + ips)
if (ips && ips.length) return callback(ips[0]);
logit(" getting user local ip with stun ")
getLocalIPs(function (ips) {
logit(" got user local ip with stun : " + ips)
if (ips && ips.length) return callback(ips[0])
logit(" cannot get user local ip, returning null ")
callback(null)
}, true, 2000)
})
}
function getLocalIPs(callback, withStun, timeout) {
var ips = [];
var RTCPeerConnection = window.RTCPeerConnection ||
window.webkitRTCPeerConnection || window.mozRTCPeerConnection;
var pc = new RTCPeerConnection({
// Don't specify any stun/turn servers, otherwise you will
// also find your public IP addresses.
// iceServers: [],
iceServers: withStun ? [{ urls: "stun:stun.services.mozilla.com" }] : []
});
var closeAndCallback = function () {
clearTimeout(waitTimeout)
try {
if (pc && pc.close) {
pc.close();
}
} catch (e) { console.log("exception while closing pc, err: %s", err) }
callback(ips);
}
var waitTimeout = timeout ? setTimeout(closeAndCallback, timeout) : null;
// Add a media line, this is needed to activate candidate gathering.
pc.createDataChannel('');
// onicecandidate is triggered whenever a candidate has been found.
pc.onicecandidate = function (e) {
console.log(e)
if (!e.candidate) { // Candidate gathering completed.
pc.close();
closeAndCallback();
return;
}
var ip = /^candidate:.+ (\S+) \d+ typ/.exec(e.candidate.candidate)[1];
if (ips.indexOf(ip) == -1) // avoid duplicate entries (tcp/udp)
ips.push(ip);
};
pc.createOffer(function (sdp) {
pc.setLocalDescription(sdp);
}, function onerror() { });
};
function callThirdParty(server, name) {
var api = server;
logit("Connecting " + server + " ...");
$.ajax({
type: "GET",
url: api,
success: function (data) {
if (data && data['ip']) {
logit("Public IP: " + data['ip']);
}
}, error:
function (request, status, error) {
logit('Response: ' + request.responseText);
logit(' Error: ' + error);
logit(' Status: ' + status);
},
complete: function (data) {
logit(' API Finished: ' + name + " Server!");
}
});
}
document.addEventListener('DOMContentLoaded', function () {
getUserIP(function (ip) { //
ipaddress = ip;
$('#ip2').html(ipaddress);
var manifest = getChromeManifest();
logit(manifest.name);
logit("Version: " + manifest.version);
logit("Chrome Version: " + getChromeVersion());
callThirdParty("https://api.ipify.org?format=json", "ipify.org");
}, 100);
}, false);
</script>
</head>
<p>Public IPs</p>
<div id="ip"></div>
<p>Local IP</p>
<div id="ip2"></div>
<p>Logs</p>
<div id="log"></div>
<div id="log1"></div>
<div id="log2"></div>
</html>
TL;DR
It looks like local addresses are/will be anonymized using mDNS and default setting for the flag would be gradually set to Enabled
for all Chrome users.
For local development take a look here (set to Disable
): chrome://flags/#enable-webrtc-hide-local-ips-with-mdns
Unless someone finds out some clever hack for it, you probably won't be able to revert the change for users of your webapp.
That guid is actually mDNS address. Quick search in newest WebRTC bugs in Chromium https://bugs.chromium.org/p/chromium/issues/list?can=2&q=component%3ABlink%3EWebRTC+ revealed few interesting entries, and there are few StackOverflow questions regarding anonymization not working (like this one: mDNS Support for WebRTC at Google Chrome M74).
Right now I see the effect in Chrome 75 on few computers with Windows 10 - some sites which previously were able to detect local IP flawlessly (http://net.ipcalf.com, https://ipleak.net, https://browserleaks.com/webrtc) now don't display it or show mDNS url instead.
As a sidenote: after enabling the mDNS flag, the extension you've linked wasn't able to detect my exact local IP. Instead, it showed few candidates from /24 address group. Even then, the extension could be privileged in some way, so it wouldn't be affected so much by mDNS anonymization.
来源:https://stackoverflow.com/questions/56543917/unable-to-fetch-ip-v4-address-from-rtcpeerconnection-chrome