WebRTC是什么不说了。
它有个漏洞或者说特性,使得浏览器通过javascript可以获取到客户端的真实IP地址。
不论浏览器开了代理与否。
如何禁用WebRTC
-
FireFox 插件 DisableWebRTC
-
Chrome 插件 WebRTC Network Limiter
如何获取公共的STUN Server
如何检查STUN Server是否有效
相关代码
代码参考了diafygi/webrtc-ips
复制代码,浏览器F12可执行。
function getIPs(callback){
let ip_dups = {};
let ip_regex = /([0-9]{1,3}(\.[0-9]{1,3}){3}|[a-f0-9]{1,4}(:[a-f0-9]{1,4}){7})/
let callbackOnce = function(ip_addr){
if(ip_dups[ip_addr] === undefined)
callback(ip_addr);
ip_dups[ip_addr] = true;
};
//compatibility for firefox and chrome
let RTCPeerConnection = window.RTCPeerConnection
|| window.mozRTCPeerConnection
|| window.webkitRTCPeerConnection;
let 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...
//
let win = iframe.contentWindow;
RTCPeerConnection = win.RTCPeerConnection
|| win.mozRTCPeerConnection
|| win.webkitRTCPeerConnection;
useWebKit = !!win.webkitRTCPeerConnection;
}
//minimal requirements for data connection
let mediaConstraints = {
optional: [{RtpDataChannels: true}]
};
// turn server list https://gist.github.com/sagivo/3a4b2f2c7ac6e1b5267c2f1f59ac6c6b
// to check if the server works - https://webrtc.github.io/samples/src/content/peerconnection/trickle-ice
// let servers = {iceServers: [{urls: "stun:stun.l.google.com:19302"}]};
let servers = {iceServers: [
{urls: "stun:stun.l.google.com:19302"},
// {urls: "stun:stun2.1.google.com:19302"},
// {urls: "stun:stun3.1.google.com:19302"},
// {urls: "stun:stun4.1.google.com:19302"},
// {urls: "stun:stun.sip.us:3478"},
// {urls: "stun:stun:stun.dus.net:3478"},
// {urls: "stun:stun:stun.easyvoip.com:3478"},
// {urls: "stun:stun:stun.easybell.de:3478"},
// {urls: "stun:stun.freecall.com:3478"},
// {urls: "stun:stun.freeswitch.org:3478"},
{urls: "stun:stun.nfon.net:3478"},
]};
//construct a new RTCPeerConnection
let pc = new RTCPeerConnection(servers, mediaConstraints);
function handleCandidate(candidate){
//match just the IP address
const m = candidate.match(ip_regex);
m && callbackOnce(m[0]);
}
//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){
result.sdp.split("\n").forEach(function(t) {
const m = t.match(ip_regex);
m && callbackOnce(m[0]);
});
//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
let 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);});