使用 webRTC 检索客户端计算机的公共 IP 地址

Posted

技术标签:

【中文标题】使用 webRTC 检索客户端计算机的公共 IP 地址【英文标题】:Retrieving Public IP address of a client machine using webRTC 【发布时间】:2019-12-04 10:48:47 【问题描述】:

我们无法获取客户端计算机的公共 IP 地址。它显示在执行代码时 sdp 未定义。下面是代码。

Get current IP in JS (no third party services)

https://github.com/diafygi/webrtc-ips

//get the IP addresses associated with an account
function getIPs(callback)
    var ip_dups = ;

    //compatibility for firefox and chrome
    var RTCPeerConnection = window.RTCPeerConnection
        || window.mozRTCPeerConnection
        || window.webkitRTCPeerConnection;
    var useWebKit = !!window.webkitRTCPeerConnection;

    //bypass naive webrtc blocking using an iframe
    if(!RTCPeerConnection)
        //NOTE: you need to have an iframe in the page right above the script tag
        //
        //<iframe id="iframe" sandbox="allow-same-origin" style="display: none"></iframe>
        //<script>...getIPs called in here...
        //
        var win = iframe.contentWindow;
        RTCPeerConnection = win.RTCPeerConnection
            || win.mozRTCPeerConnection
            || win.webkitRTCPeerConnection;
        useWebKit = !!win.webkitRTCPeerConnection;
    

    //minimal requirements for data connection
    var mediaConstraints = 
        optional: [RtpDataChannels: true]
    ;

    var servers = iceServers: [urls: "stun:stun.services.mozilla.com"];

    //construct a new RTCPeerConnection
    var pc = new RTCPeerConnection(servers, mediaConstraints);

    function handleCandidate(candidate)
        //match just the IP address
        var ip_regex = /([0-9]1,3(\.[0-9]1,3)3|[a-f0-9]1,4(:[a-f0-9]1,4)7)/
        var ip_addr = ip_regex.exec(candidate)[1];

        //remove duplicates
        if(ip_dups[ip_addr] === undefined)
            callback(ip_addr);

        ip_dups[ip_addr] = true;
    

    //listen for candidate events
    pc.onicecandidate = function(ice)

        //skip non-candidate events
        if(ice.candidate)
            handleCandidate(ice.candidate.candidate);
    ;

    //create a bogus data channel
    pc.createDataChannel("");

    //create an offer sdp
    pc.createOffer(function(result)

        //trigger the stun server request
        pc.setLocalDescription(result, function(), function());

    , function());

    //wait for a while to let everything done
    setTimeout(function()
        //read candidate info from local description
        var lines = pc.localDescription.sdp.split('\n');

        lines.forEach(function(line)
            if(line.indexOf('a=candidate:') === 0)
                handleCandidate(line);
        );
    , 1000);


//Test: Print the IP addresses into the console
getIPs(function(ip)console.log(ip););

在执行代码时,我们收到以下错误消息:

'无法读取属性 'sdp' of null'

【问题讨论】:

它说pc.localDescription 为空,为什么你使用setTimeout 而不是pc.setLocalDescription 的回调?可能 1s 是不够的(或者有一些错误,但是你的错误回调什么也没做,所以你不知道) 【参考方案1】:

在撰写本文时,您不能泄露用户的私有 IP 地址。

但是,我发现了一个 github repo webrtc-ip,它可以使用 WebRTC 泄露用户的公共 IP 地址。这很强大,因为您无法跟踪它,因为“网络”选项卡中没有显示任何内容。

遗憾的是,由于逐渐转向 mDNS(至少对于 WebRTC 而言),这种泄漏不适用于私有 IP,这完全在这个伟大的 blog 中。无论如何,这是一个有效的演示:

https://webrtc-ip.herokuapp.com/

我不确定这是否会泄露您的真实 IP 地址(无论代理如何),但请随时进行测试。

如果您查看您引用的存储库,问题清楚地表明该存储库不起作用并且存储库没有得到维护。

【讨论】:

【参考方案2】:

您引用的示例代码已过时,并且它们的演示页面在最新的 Chrome 版本上也不再工作:

https://diafygi.github.io/webrtc-ips/

此外,它似乎使用了某些浏览器不支持的功能。

我不知道您的要求,但是向服务器发送请求以发现客户端的公共 IP 是非常标准的。服务器查看标头(例如 x-forwarded-for,这取决于使用的 Web 服务器)并将其发送回请求者。

还存在诸如Ipregistry(免责声明:我运行该服务)等服务,它们会为您执行此操作并返回更多有趣的信息:客户端 IP 地址、位置、货币、威胁数据等。

【讨论】:

您好 Laurent,实际上我需要找到客户端计算机的公共 IP 地址(例如,如果我在 C# 中使用 X-forwarded-for,我们将在 IIS 服务器中托管后获取服务器 IP 地址,如果我在本地环境中使用 X-forwarded-for,我将获得 IP 地址。但我需要在托管项目后)。但我需要客户端公共 IP 地址。 X-Forwarded-For 标头标识原始 IP 地址。如果在 IIS 服务器上托管您的应用程序后,您获得的 IP 地址不是您的客户端 IP,这很可能是因为中间(在您的客户端和 IIS 服务器之间)有另一个服务器/负载平衡器/前端没有在 X-Forwarded-For 标头中转发您的客户端 IP。 感谢您的回复 Laurent,那么我怎样才能获得客户端机器的公共 IP 地址?如果您知道在托管应用程序后检索客户端的公共 IP 地址,请提供一些示例代码。

以上是关于使用 webRTC 检索客户端计算机的公共 IP 地址的主要内容,如果未能解决你的问题,请参考以下文章

如何通过 Amazon API Gateway (JAVA) 检索用户的公共 IP 地址

为啥 WebRTC 不能与对称 NAT 一起使用?

如何使用 JavaScript 获取本地/内部 IP

如何使用 Python 检索 AWS Lambda 公共 IP 地址?

如何使用 C#.Net 检索我的公共 IP 地址? [复制]

检索 Azure VM 的公共 IP 地址的更简单方法