google-chrome - 无法从 RTCPeerConnection 获取 IP V4 地址 - chrome

标签 google-chrome webrtc rtcpeerconnection

我需要从 Web 应用程序获取客户端本地 IP 地址。

为此,我使用标准 RTCPeerConnection 实现来获取。但是返回的ice候选并不携带IP V4地址,而是一个看起来像guid的地址:asdf-xxxx-saass-xxxx.local

但令人惊讶的是这个chrome extension能够在同一台机器和浏览器上获取相同的内容。

注意:我在网络应用程序中使用的代码与扩展程序的代码相同

这是相同的 html 代码:

<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

看来本地地址将使用 mDNS 进行匿名化,并且该标志的默认设置将逐渐为所有 Chrome 用户设置为启用

对于本地开发,请查看此处(设置为禁用):chrome://flags/#enable-webrtc-hide-local-ips-with-mdns

除非有人找到一些巧妙的技巧,否则您可能无法为您的网络应用程序的用户恢复更改。

<小时/>

该 guid 实际上是 mDNS 地址。快速搜索 Chromium 中最新的 WebRTC bug https://bugs.chromium.org/p/chromium/issues/list?can=2&q=component%3ABlink%3EWebRTC+ 揭示了一些有趣的条目,并且有一些关于匿名化不起作用的 StackOverflow 问题(例如: mDNS Support for WebRTC at Google Chrome M74 )。

现在,我在少数装有 Windows 10 的计算机上看到 Chrome 75 的效果 - 一些以前能够完美检测本地 IP 的网站( http://net.ipcalf.comhttps://ipleak.nethttps://browserleaks.com/webrtc )现在不显示它或显示 mDNS url。

作为旁注:启用 mDNS 标志后,您链接的扩展程序无法检测到我的确切本地 IP。相反,它几乎没有显示来自/24 地址组的候选者。即使如此,扩展程序也可以以某种方式获得特权,因此它不会受到 mDNS 匿名化的太大影响。

<小时/>

编辑(2020 年 3 月):看起来 Firefox 也可以匿名本地 IP。

截至 2020 年 3 月,about:config 页面中有两项设置:

  • media.peerconnection.ice.obfuscate_host_addresses - 设置为 true 时,会将本地 IP 更改为 {uuid}.local
  • media.peerconnection.ice.obfuscate_host_addresses.whitelist - 带有 URL 的字符串,即使启用了混淆,也能够检索真实 IP

我检查了 Firefox 73 和 Developer Edition 74(没有任何可能更改设置的扩展),首先将 obfuscate_host_addresses 设置为 false,而 dev 版本启用了它。

<小时/>

编辑(2020 年 10 月):自 Chrome 86 起,mDNS 设置已启用,并且无法再通过 chrome://flags 禁用(没有可用的此类选项)。

关于google-chrome - 无法从 RTCPeerConnection 获取 IP V4 地址 - chrome,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56543917/

相关文章:

javascript - 我什么时候可以考虑断开 RTCPeerConnection?

javascript - 对等连接停留在 chrome ://webrtc-internals/even after it is disconnected

javascript - 显示与谷歌浏览器中键入的不同的键盘字符

google-chrome - Chrome :The website uses HSTS. 网络错误...此页面稍后可能会正常工作

javascript - Javascript v8 引擎和 Web API

javascript - 在 Chrome 中检测 Alt 键

webrtc - ast_sockaddr_resolve : getaddrinfo(): Name or service not known

android - 如何在 native android 应用程序中使用 WebRTC + Pubnub Api 作为视频聊天客户端

webrtc - 如何在ICE协议(protocol)中验证对?

javascript - 如何更改 Webrtc rtcpMuxPolicy?