使用 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 地址
如何使用 Python 检索 AWS Lambda 公共 IP 地址?