I'm creating a web application and in order for it to run, you must have your device 'registered'. The registration process involves entering the IPv4 address of the device you wish to use into a field which updates the database.When accessing the application, it goes through a window.webkitRTCPeerConnection or window.mozRTCPeerConnection check to get the IP address. This works on the latest versions of Chrome and Firefox, but not IE. So, I had to use ActiveX if the IP wasn't obtained from the RTCPeerConnection check.My problem is that I want Safari to be able to run the application, but I can't seem to find anything on how to get the IPv4 address for devices running Safari.To clarify, this web application is not open for general public usage and we'll have complete control over what's installed on devices running the application. (That's my justification for using ActiveX).Any suggestions and/or references to how I can do such a thing would be appreciated.
Please try this way.
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body>
<h4>
Demo for:
<a href="https://github.com/diafygi/webrtc-ips">
https://github.com/diafygi/webrtc-ips
</a>
</h4>
<p>
This demo secretly makes requests to STUN servers that can log your
request. These requests do not show up in developer consoles and
cannot be blocked by browser plugins (AdBlock, Ghostery, etc.).
</p>
<h4>Your local IP addresses:</h4>
<ul></ul>
<h4>Your public IP addresses:</h4>
<ul></ul>
<h4>Your IPv6 addresses:</h4>
<ul></ul>
<iframe id="iframe" sandbox="allow-same-origin" style="display: none"></iframe>
<script>
//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);
}
//insert IP addresses into the page
getIPs(function(ip){
var li = document.createElement("li");
li.textContent = ip;
//local IPs
if (ip.match(/^(192\.168\.|169\.254\.|10\.|172\.(1[6-9]|2\d|3[01]))/))
document.getElementsByTagName("ul")[0].appendChild(li);
//IPv6 addresses
else if (ip.match(/^[a-f0-9]{1,4}(:[a-f0-9]{1,4}){7}$/))
document.getElementsByTagName("ul")[2].appendChild(li);
//assume the rest are public IPs
else
document.getElementsByTagName("ul")[1].appendChild(li);
});
</script>
</body>
</html>
This API can get your IP adress.
https://l2.io/
More advanced solution:
http://dev.maxmind.com/geoip/geoip2/javascript/
This one also supports Safari, according to this: http://dev.maxmind.com/geoip/geoip2/javascript/#Browser_Support
The last one is in my opinion the best one. I use that one in one of my projects.
EDIT:
On safari there is no support yet for WebRTC Connections. So it is not possible to obtain the local IP adress on safari.
The website https://api.ipify.org knows your ip adress. The only thing you have to do is scrape it. You can do that with JavaScript.
var xhttp = new XMLHttpRequest();
xhttp.open("GET", "https://api.ipify.org", false);
xhttp.send();
var ip = xhttp.responseText;
Related
Firefox and Chrome have implemented WebRTC that allow requests to STUN servers be made that will return the local IP address of the client.
The javascript code below outputs the local IP address of the client:
window.RTCPeerConnection = window.RTCPeerConnection || window.mozRTCPeerConnection || window.webkitRTCPeerConnection; //compatibility for firefox and chrome
var pc = new RTCPeerConnection({iceServers:[]}), noop = function(){};
pc.createDataChannel(""); //create a bogus data channel
pc.createOffer(pc.setLocalDescription.bind(pc), noop); // create offer and set local description
pc.onicecandidate = function(ice){ //listen for candidate events
if(!ice || !ice.candidate || !ice.candidate.candidate) return;
var myIP = /([0-9]{1,3}(\.[0-9]{1,3}){3}|[a-f0-9]{1,4}(:[a-f0-9]{1,4}){7})/.exec(ice.candidate.candidate)[1];
console.log('my IP: ', myIP);
pc.onicecandidate = noop;
};
Is it possible to obtain the MAC address also?
No you cannot get the MacAdress with Javascript in the Browser. For very good reasons. It would be a big security risk.
The MAC address uniquely identifies the running computer, cellphone...basically every device, an internal IP does not.
You need to use Electron or Node for that, if you want to do it with Javascript.
Use ARP using any way. You can use OS API or you can spawn command line tool or high level API or library of you favorite programming language.
We are unable get the public IP address of a client machine. It is showing the sdp is undefined while executing the code. Below is the code.
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);});
While executing the code we are getting this error message:
'Cannot read property 'sdp' of null'
The example code you are referencing is outdated and their demo page is no longer working either on recent Chrome versions:
https://diafygi.github.io/webrtc-ips/
Furthermore, it seems to use features that are not supported by some browsers.
I don't know your requirements but it is quite standard to send a request to a server in order to discover the public IP of a client. The server looks at headers (e.g. x-forwarded-for, this depends on the Web server used) and sends it back to the requester.
There also exist services such as Ipregistry (disclaimer: I run the service) that do it for you and return even more interesting information: client IP address, location, currency, threat data, etc.
As of this writing, you cannot leak the private IP address of your users.
However, I found a github repo webrtc-ip which can leak a user's public IP address using WebRTC. This is powerful because you cannot trace it, as nothing is shown in the Networks tab.
Sadly, this leak does not work for private IPs, due to the gradual shift to mDNS (at least for WebRTC), which is completely in this great blog. Regardless, here's a working demo:
https://webrtc-ip.herokuapp.com/
I am not sure if this leaks your true IP address regardless of a proxy, but feel free to test it out.
If you look at the repo you referenced, the issues clearly state that the repo does not work and that the repository is not being maintained.
I am developing websocket server with netty frame work version 4.1.6.
I am using the sample code from netty example site
This is my server source code:
public class WebSocketServer
{
static final int PORT = 4466;
public static void main(String[] args)
{
final SslContext sslCtx;
EventLoopGroup bossGroup = new NioEventLoopGroup(1);
EventLoopGroup workerGroup = new NioEventLoopGroup();
try {
SelfSignedCertificate ssc = new SelfSignedCertificate();
sslCtx = SslContextBuilder.forServer(ssc.certificate(), ssc.privateKey()).build();
ServerBootstrap b = new ServerBootstrap();
b.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class)
.handler(new LoggingHandler(LogLevel.INFO))
.childHandler(new WebSocketServerInitializer(sslCtx));
Channel ch = b.bind(PORT).sync().channel();
System.out.println("Open your web browser and navigate to " +
"http://127.0.0.1:" + PORT + '/');
ch.closeFuture().sync();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}
}
}
An WebSocketServerInitializer source code:
public class WebSocketServerInitializer extends ChannelInitializer<SocketChannel>
{
private static final String WEBSOCKET_PATH = "/websocket";
private final SslContext sslCtx;
public WebSocketServerInitializer(SslContext sslCtx) {
this.sslCtx = sslCtx;
}
#Override
public void initChannel(SocketChannel ch) throws Exception {
ChannelPipeline pipeline = ch.pipeline();
pipeline.addLast(sslCtx.newHandler(ch.alloc()));
pipeline.addLast(new HttpServerCodec());
pipeline.addLast(new HttpObjectAggregator(65536));
pipeline.addLast(new WebSocketServerCompressionHandler());
pipeline.addLast(new WebSocketServerProtocolHandler(WEBSOCKET_PATH, null, true));
// pipeline.addLast(new WebSocketIndexPageHandler(WEBSOCKET_PATH));
pipeline.addLast(new WebSocketFrameHandler());
}
}
This is my Html code:
<html>
<head>
<script type="text/javascript">
// Let us open a web socket
var ws = null;
function WebSocketTest()
{
if ("WebSocket" in window)
{
alert("WebSocket is supported by your Browser!");
// Let us open a web socket
ws = new WebSocket("wss://localhost:4466/websocket");
ws.onopen = function()
{
// Web Socket is connected, send data using send()
ws.send("Message to send");
alert("Message is sent...");
};
ws.onmessage = function (evt)
{
var received_msg = evt.data;
alert(received_msg);
//alert("Message is received...");
};
ws.onclose = function()
{
// websocket is closed.
alert("Connection is closed...");
};
window.onbeforeunload = function(event) {
socket.close();
};
}
else
{
// The browser doesn't support WebSocket
alert("WebSocket NOT supported by your Browser!");
}
}
</script>
</head>
<body>
<div id="sse">
Run WebSocket
</div>
</body>
</html>
I browse the page using Chrome browser and got the following message when I click on the link in the web page.
WebSocket connection to 'wss://localhost:4466/websocket' failed: Error in connection establishment: net::ERR_INSECURE_RESPONSE
According to some discussions here, and the netty websocket sample code, wss must be forwarded by HTTPS. However, when I change the following javascript statement in my web page:
ws = new WebSocket("wss://localhost:4466/websocket");
to
ws = new WebSocket("wss://echo.websocket.org");
It works fine. It make me confusing, Why the site echo.websocket.org can working without https? Why my server cannot? are there something missing in my server source code?
PS: the echo.websocket.org example found in the following url:
http://jsbin.com/muqamiqimu/edit?js,console
Your browser is failing to connect to your websocket server, because it detected it is insecure.
This happens because when the browser tries to connect to your server, it will check the SSL certificate. This certificate is basically a proof that says your server is claiming to be the authoritative server for localhost.
Your server claims this by its certificate, what in your case is signed by itself, that's basically the SelfSignedCertificate class, and it's claiming to be "example.com".
This creates 2 issues:
Your browser connects to localhost, but instead of getting a certificate for localhost, it gets 1 for example.com
Your browser does not trust the signer of the certificate to have the authority to make certificates, causing it to be rejected.
There are multiple ways to solve this:
Getting a valid certificate and hosting your application on a server
This would be the recommended solution for production, depending where you get your valid certificate, it may or may not cost money.
Bypass the certificate warning
By manually going to http://localhost:4466/ you can skip past the certificate warning, and basically this adds a 1 time exception for the certificate rule, till you restart your browser
Configuring google chrome to accept invalid certificates for localhost
While this can be insecure (but not as insecure as turning off all certificate validation), it can be a great way to test ssl on development machines.
You can turn ssl validation of for localhost by going to chrome://flags/#allow-insecure-localhost and turning that option on. Notice that you might be required to set the domain of your certificate to localhost when using this option by calling the new SelfSignedCertificate("localhost"); contructor.
My scenario is to get MAC and IP address of connected PCs not over the Internet But locally in LAN, and I also wanted to store that data into a database.
I searched google and found that we can get these values using Javascript. But I am new to this can someone please elaborate the proper solution?
It is probably the duplicate of this.
You can get the IP Address of the client machine by trying following code:
window.RTCPeerConnection = window.RTCPeerConnection || window.mozRTCPeerConnection || window.webkitRTCPeerConnection; //compatibility for firefox and chrome
var pc = new RTCPeerConnection({iceServers:[]}), noop = function(){};
pc.createDataChannel(""); //create a bogus data channel
pc.createOffer(pc.setLocalDescription.bind(pc), noop); // create offer and set local description
pc.onicecandidate = function(ice){ //listen for candidate events
if(!ice || !ice.candidate || !ice.candidate.candidate) return;
var myIP = /([0-9]{1,3}(\.[0-9]{1,3}){3}|[a-f0-9]{1,4}(:[a-f0-9]{1,4}){7})/.exec(ice.candidate.candidate)[1];
console.log('my IP: ', myIP);
pc.onicecandidate = noop;
};
Although for MAC Address I am not so sure that you can do it using javascript in a web application becuase the MAC address uniquely identifies the client computer so it can be a security issue.
Now if you want some unique identifier to use in your application that uniquely identifies the client's computer you can do some cryptography and use client cookies to store the values.
Although MAC Address can be accessed only in IE and only if user allows the plugin to run through following
function networkInfo(){
var wmi = new ActiveXObject ("WbemScripting.SWbemLocator");
var service = wmi.ConnectServer(".");
e = new Enumerator(service.ExecQuery("SELECT * FROM Win32_NetworkAdapterConfiguration WHERE IPEnabled = True"));
for(; !e.atEnd(); e.moveNext()) {
var s = e.item();
var macAddress = unescape(s.MACAddress);
}
return macAddress;
}
Sources:
- MAC addresses in JavaScript
- How to get client MAC address by using javascript?
- Can You Get A Users Local LAN IP Address Via JavaScript?
How can I get the local client IP using WebRTC.
I don't need the REMOTE_ADDR of the client but his local network IP.
I've seen this before on websites like sharedrop.com, it recognizes computer within the same network using WebRTC.
In PHP I do this to get the clients remote IP:
<?php
echo $_SERVER["REMOTE_ADDR"]; // which would return 72.72.72.175
?>
I looked through stackoverflow but every question is answered using the remote addr.
How can I get my local IP (192.168.1.24 for example) with JavaScript instead of the remote addr.
UPDATE
Unfortunately the below answer no longer works as browsers have changed this behavior due to security concerns. See this StackOverflow Q&A for more details.
where I took code from --> Source
You can find a demo at --> Demo
I have modified the source code, reduced the lines, not making any stun requests since you only want Local IP not the Public IP, the below code works in latest Firefox and Chrome:
window.RTCPeerConnection = window.RTCPeerConnection || window.mozRTCPeerConnection || window.webkitRTCPeerConnection; //compatibility for firefox and chrome
var pc = new RTCPeerConnection({iceServers:[]}), noop = function(){};
pc.createDataChannel(""); //create a bogus data channel
pc.createOffer(pc.setLocalDescription.bind(pc), noop); // create offer and set local description
pc.onicecandidate = function(ice){ //listen for candidate events
if(!ice || !ice.candidate || !ice.candidate.candidate) return;
var myIP = /([0-9]{1,3}(\.[0-9]{1,3}){3}|[a-f0-9]{1,4}(:[a-f0-9]{1,4}){7})/.exec(ice.candidate.candidate)[1];
console.log('my IP: ', myIP);
pc.onicecandidate = noop;
};
what is happening here is, we are creating a dummy peer connection, and for the remote peer to contact us, we generally exchange ice candidates with each other. And reading the ice candiates we can tell the ip of the user.
You can use this version on modern browser (with Promises and async / await)
// minified onliner, 219b
const ip = await new Promise((s,f,c=new RTCPeerConnection(),k='candidate')=>(c.createDataChannel(''),c.createOffer(o=>c.setLocalDescription(o),f),c.onicecandidate=i=>i&&i[k]&&i[k][k]&&c.close(s(i[k][k].split(' ')[4]))))
Or, un-minified:
// cleaned, 363b
const ip = await new Promise((resolve, reject) => {
const conn = new RTCPeerConnection()
conn.createDataChannel('')
conn.createOffer(offer => conn.setLocalDescription(offer), reject)
conn.onicecandidate = ice => {
if (ice && ice.candidate && ice.candidate.candidate) {
resolve(ice.candidate.candidate.split(' ')[4])
conn.close()
}
}
})