【问题标题】:Javascript webrtc (STUN) ipv6Javascript webrtc (STUN) ipv6
【发布时间】:2021-01-20 22:08:01
【问题描述】:

当尝试使用公共 STUN 服务器查找我的公共 IP 地址时,它适用于 IPv4,但不适用于 IPv6,无论我使用什么 STUN 服务器。

我只在 Candidate.address 下得到“59aeb370-1d93-44ee-a526-27d639256cf4.local”之类的东西。 有什么方法可以使用 STUN 通过 javascript 获取公共 IPv6?

我使用的代码是:

(不要介意 IPv4 正则表达式;无论如何,整个“候选人”都会记录在控制台中)

var ip_dups = {};

function getRTCPeerConnection () {
    var iframe, content_window, rtc_peer_con = window.RTCPeerConnection || window.mozRTCPeerConnection || window.webkitRTCPeerConnection || window.msRTCPeerConnection;
    return rtc_peer_con || (iframe = document.createElement("iframe"), iframe.style.display = "none", document.body.appendChild(iframe), content_window = iframe.contentWindow, rtc_peer_con = content_window.RTCPeerConnection || content_window.mozRTCPeerConnection || content_window.webkitRTCPeerConnection || content_window.msRTCPeerConnection), rtc_peer_con
};

var n = getRTCPeerConnection();
servers = {
    iceServers: [{
        urls: "stun:stun.l.google.com:19302"
    }]
};  
mediaConstraints = {
    optional: [{
        RTCPChannel: true
    }]
};
        
pc = new n(servers, mediaConstraints);

function handleCandidate(candidate){
    console.log(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];
    if(ip_dups[ip_addr] === undefined) {
        console.log(ip_addr);
        ip_dups[ip_addr] = true;
    }
    pc.close()
}

pc.onicecandidate = function(ice){
    //skip non-candidate events
    console.log(ice)
    if(ice.candidate) {
        handleCandidate(ice.candidate.candidate);
    }
};

pc.createDataChannel("");

void pc.createOffer(function(e) {
    console.log(e)
    console.log(e.sdp)
    pc.setLocalDescription(e, function() {}, function() {})
}, function() {})

编辑:

似乎在某些情况下,在某些网页的控制台内运行代码时,我确实在响应中获得了 IPv6。

但是,例如,当从 chrome incognito 访问同一页面时,它不起作用,所以这不是因为域或类似的东西。

也不涉及任何权限。

那么到底发生了什么?其背后的逻辑是什么?有什么办法可以让我的网页始终让访问者收到他们的 IPv6 地址?

【问题讨论】:

标签: javascript webrtc ipv6 stun


【解决方案1】:

引用一篇关于您的问题的精彩文章:

忽略这一事实,Google 已经将 mDNS 作为一些 Chrome 版本的实验。作为实验,决定了两件事:

  • 它几乎“随机”在用户的 Chrome 浏览器上运行,而无需对用户或正在发生的服务进行任何真正的控制(至少不是自动化和显而易见的)
  • 仅在必须共享本地 IP 地址且未请求摄像头或麦克风许可时添加(仅接收场景)

基本上,Chrome 一直在推出 mDNS IP 混淆功能。这意味着如果您的脚本不调用 getUserMedia,候选行将被混淆。请阅读整篇文章here

旧答案:

由于源自 Chrome 团队的安全问题,IP 地址现在被混淆(隐藏,definition)。如果您查看post you commented 上的日期(2018 年,三年前),您会发现这个问题和解决方案已经过时了。

但是,您可以使用能够可靠地返回用户的 IPv4 地址的 UDP 传输。考虑以下 sn-p:

iceServers: [{
    urls: "stun:stun.l.google.com:19302?transport=udp"
}]

话虽如此,您还可以使用Abstract 之类的第 3 部分 API 可靠地获取用户的 IP 地址(请参阅第 3 方 IP 查找的完整列表here)。或者,您可以使用 Node.js 来做同样的事情。以下是一些相关的代码示例和文章:

How to Get User’s IP Details in ExpressJS - 文章

geoip-lite - Node.js 模块

Node.js 中的简单 ip 检测:

const express = require('express');
const app = express();
const router = express.Router();

router.get('/someroute', (req,res) => {
  const ip = req.headers['x-forwarded-for'] || req.connection.remoteAddress;
  console.log(ip); // ip address of the user
});

app.use('/', router);
app.listen(5000);

(找到here

参考资料:

Wikipedia:

基本协议的基本操作如下:通常在专用网络中运行的客户端向公共 Internet 上的 STUN 服务器发送绑定请求。从服务器的角度来看,STUN 服务器以包含客户端 IP 地址和端口号的成功响应进行响应。 通过异或 (XOR) 映射对结果进行模糊处理,以避免应用层网关转换数据包内容 (ALG),这些网关执行深度数据包检查以尝试执行替代 NAT 遍历方法。

RFC 5389:

XOR-MAPPED-ADDRESS 属性与 MAPPED-ADDRESS 相同 属性,除了自反传输地址被混淆 通过 XOR 函数。

这是最终代码:

var ip_dups = {};

function getRTCPeerConnection () {
    var iframe, content_window, rtc_peer_con = window.RTCPeerConnection || window.mozRTCPeerConnection || window.webkitRTCPeerConnection || window.msRTCPeerConnection;
    return rtc_peer_con || (iframe = document.createElement("iframe"), iframe.style.display = "none", document.body.appendChild(iframe), content_window = iframe.contentWindow, rtc_peer_con = content_window.RTCPeerConnection || content_window.mozRTCPeerConnection || content_window.webkitRTCPeerConnection || content_window.msRTCPeerConnection), rtc_peer_con
};

var n = getRTCPeerConnection();
servers = {
    iceServers: [{
        urls: "stun:stun.l.google.com:19302?transport=udp"
    }]
};  
mediaConstraints = {
    optional: [{
        RTCPChannel: true
    }]
};
        
pc = new n(servers, mediaConstraints);

function handleCandidate(candidate){
    console.log(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];
    if(ip_dups[ip_addr] === undefined) {
        console.log(ip_addr);
        ip_dups[ip_addr] = true;
    }
    pc.close()
}

pc.onicecandidate = function(ice){
    //skip non-candidate events
    console.log(ice)
    if(ice.candidate) {
        handleCandidate(ice.candidate.candidate);
    }
};
// now you have to create a data channel with a name
pc.createDataChannel("fake_data_channel");

void pc.createOffer(function(e) {
    console.log(e)
    console.log(e.sdp)
    pc.setLocalDescription(e, function() {}, function() {})
}, function() {})

【讨论】:

  • 1. “IP 地址现在被混淆了”——是吗?使用上面的代码,IPv4 被很好地接收,没有被混淆或任何东西。 2.我知道我提到的帖子很旧,如果您再次阅读我的上一条评论,您会发现我用过去时(“它曾经收到过”)提及它,并询问从那时起是否有任何变化现在。这是一个旧帖子的事实是问题的一部分。
  • XOR 混淆是无关紧要的。它被发送 XORed 但 javascript API 对其进行了去混淆处理。顺便说一句,在某些情况下,当在某些网页的控制台内运行代码时,我确实在响应中得到了我的 IPv6。但是,例如,当从 chrome incognito 访问同一页面时,它不起作用,所以这不是因为域或类似的东西。也不涉及任何权限。那么到底是怎么回事?其背后的逻辑是什么?有什么办法可以让我的网页始终让访问者收到他们的 IPv6 地址?
  • @RefFil 感谢您的回复!您如何托管此服务器?是纯 HTML、CSS 和 JS 吗?如果没有,您使用的是 PHP 吗?如果您使用 PHP 或 Node.js 等自定义服务器选项,您可以获取用户的 IP 地址并将其设置为 cookie,以便您的 JS 脚本可以读取它。但是,我没有发现任何证据表明 XORed IP 已被用户反混淆,在所有情况下我都发现它已被 STUN 服务器反混淆。此外,我还找到了获取用户 IPv4 地址的工作示例,但是,IPv6 没有。
  • STUN 是不同于 HTTP(S) 的协议,我自己运行它,与网络服务器没有任何关系
  • @RefFil 你给我的代码使用了一个冰服务器。
猜你喜欢
  • 1970-01-01
  • 2015-10-30
  • 1970-01-01
  • 2017-03-12
  • 1970-01-01
  • 1970-01-01
  • 2017-11-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多