I am building a complex SPA using Polymer to replicate an Access Application. I want to use http2 to avoid the maintenance nightmare of merging source files to get appropriate performance.
I have built myself the start of the application, log in via a sql server database. and am now starting to debug things.
I am trying to retrieve the clientip address using answers I have found on here
var ip = req.headers['x-forwarded-for'] ||
req.connection.remoteAddress ||
req.socket.remoteAddress ||
req.connection.socket.remoteAddress;
but unfortunately at this point the server crashes. Digging around with the debugger (given req is the request object) there is no 'x-forwarded-for'header, no connection object (except inside socket) and this is what kills this statement as can't access remoteAddress of undefined. But I cannot find a remoteaddress field in any object derived from req.
I am using https://github.com/molnarg/node-http2 which appears to be the only implementation around. There is some mention of endpoint.js library in the documentation but the links are broken, so I have no idea how to access an endpoint object.
In order to get the correct certificates, I am using the ones from pastrial.hartley-consultants.com and changed my in house dns server to give me my development machine as its ip address. I am accessing it via a browser on the same machine. So client and server machines should both have 192.168.0.xx IP addresses which just happen to be the same.
So question is - where is the IP address of the client exposed to the server (or indeed is it in http2)
The simple answer is it is in req.remoteAddress
Related
I am using the ip library of npm.
I have two config files, one for React and one for Node, for the same application.
const ip = require('ip');
console.log(ip.address());
This returns different ip addresses for the React config file(inside the src folder-127.0.0.1) and Node server file(outside the src folder - IPv4 address).
The issue is that I am pretty sure that I ran the exact same code earlier and it gave me the same ip addresses for both as then I was able to access my webpages. I need the same ip to make requests to my node backend, I cannot afford it in production. Are there other definite methods of doing this?
You get different ip results because 2 method call ip.address() are using different network interfaces.
To make ip.address() return identical result, you can pass network interface name as the first parameter, such as en0:
const ip = require('ip');
console.log(ip.address('en0'));
p.s. To get all current networks interface names, os.networkInterfaces() can be used.
Update: OP try to get IP address in React code, in browser side. This is mission impossible. Otherwise, it would bring huge security problem.
Update 2: OP don't want to store endpoint IP address in frontend code for security reason, neither want to retrieve the IP address first (network overhead issue). In this case, you can make a proxy in server. All frontend know is interacting with current server, the data exchange is delivered by server as:
Browser <--> Server <--> Various endpoint IP
The steps are:
The server (that host the frontend code) get request from browser
Server check which endpoint would be used for that client
Server send the request to specific endpoint
Server get response from endpoint
Server return the response in above step to browser
I want to host a web app with node.js on a Linux virtual machine using the the HTTP module.
As the app will be visualising sensitive data I want to ensure it can only be accessed from PCs on the same LAN.
My understanding is that using the HTTP module a web server is created that's initially only accessible by other PCs on the same LAN. I've seen that either by tunnelling or portforwarding a node.js server can be exposed if desired.
Question
Are there any other important considerations/ways the server could be accessed externally?
Is there a particular way I can setup a node.js server to be confident that it's only accessible to local traffic?
It really depends what you are protecting against.
For example, somebody on your LAN could port forward your service using something like ngrok. There are a few things you can check for:
In this case the header x-forwarded-for is set. So, to protect against this you can check for this header on the incoming request, and if set you can reject the request.
The host header is also set and will indicate how the client referred to your service - if it is as you expect (maybe a direct local LAN address such as 192.168.0.xxx:3000) then all is OK, if not (I ran ngrok on a local service and got something of the form xxxxxxxx.ngrok.io) then reject it.
Of course a malicious somebody could create their own server to redirect requests. The only way there is to put in usernames and passwords or similar. At least you then known who is (allegedly) accessing your service and do something about it.
However, if you are not trying to pretect against a malicious internal actor, then you should be good as you are - I can't think of any way (unless there is a security hole in your LAN) for your service to be made public without somebody actively setting that up.
My last suggestion would be to use something like express rather than the http module by itself. It really does make life a lot simpler. I use it a lot for just this kind of simple internal server.
Thought I'd add a quick example. I've tested this with ngrok and it blocks access via the public address but works find via localhost. Change the host test to whatever local address (or addresses) you want to serve this service from.
const express=require('express');
const app=express();
app.use((req,res,next)=>{
if (req.headers.host!=='localhost:3000' || req.headers['x-forwarded-for']){
res.status(403).send('Invalid access!');
} else next();
});
app.get('/',(req,res)=>res.send('Hello World!'));
app.listen(3000,()=>{
console.log('Service started. Try it at http://localhost:3000/');
});
I would prefer using nginx as a proxy here and rely on nginx' configuration to accept traffic from local LAN to the node.js web server. If this is not possible, a local firewall would be the best tool for the job.
My application is running on ec2 instance. we are using node.js for server side code. We are using socket.io, express to connect the client side code.I have a requirement to capture user's browser ip and send it to server side code.
i have tried the below code but it is giving me the server IP details.
io.sockets.on('connection', function (socket) {
var socketId = socket.id;
var clientIp = socket.handshake.headers;
console.log('connection :', socket.request.connection._peername);
console.log(socket.request.client._peername.address);
console.log(clientIp);
});
Is there any ways to capture the user's browser IP, it will be great help.
I appreciate your suggestions.
In your client side code, you cannot tell what IP address you will be connecting from.
On the server side (express server), you can easily grab the remote IP address from the request, like so:
console.log(req.connection.remoteAddress);
Note that just like any other server, this only tells where you see the connection coming from - the user might be using a VPN, or behind a corporate firewall, etc., in which case the IP address may not have much meaning. Whether this matters to you depends on why you are trying to collect it (logging or something more meaningful).
Don't forget that if your express app is behind a web server (like nginx), you may need to look at the forwarded-for header instead - see related S.O. question How to get remote client address.
we are not yet using nginx. we are just running with nohup command in the background to up the server in ec2. I tried using the below command
console.log(request.socket.remoteAddress)
it gives me the server side ip not the client side ip. We are using this app :8000/index.html in our local system. i want to capture the local system ip. This console.log(req.connection.remoteAddress) gives me TypeError: Cannot read property 'remoteAddress' of undefined
I deployed my .NET CORE solution in AZURE environment (PAAS).I used following code snippet there to get client's ip address
dtoItem.LogIP = HttpContext.Connection.RemoteIpAddress.ToString();
I used standard .net core libraries and did necessary changes into Startup.cs as well
app.UseForwardedHeaders(new ForwardedHeadersOptions
{
ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto,
RequireHeaderSymmetry = false,
});
I believe I have implemented everything in correct manner. But still I haven't got accurate client IP address. I am always getting client's public IP instead of his private IP. Since this can be repeated (Same office 2 users have same public IP) I need client's private IP instead of his public IP.
Is it possible to get private IP address in PAAS solution. If it is not possible, is there a way to track client's PC information. (Such as IP Address, MAC address).
Is it possible to get private IP address in PAAS solution?
No it is not possible as shared in this SO post and this answer address this about MACAddress
On the client side javascript, there is no API exposed to get the IPAddress(obviously due to security consideration) .Then you can get the IPAddress on the server side but typically if you are accessing internet from your company,it would go through the corporate proxy and the Ipaddress seen by the server will never be the actual client IP but the proxy server's address. So this is limited on the server side as server only sees the proxy (public IP address).
If it is not possible, is there a way to track client's PC information. (Such as IP Address, MAC address) ?
What you can reliably track is the user agent. Breaking the user agent down, we get the some information about browser ,OS versions. But user agent can easily be spoofed with some browser extension .
If you are looking for browser finger printing or tracking ,have a
look at Panopticlick which shows some more information like
fonts > installed, screen resolution,plugins installed etc to track
any client. fingerprintjs2 javascript library helps to track
using 26 parameters as of today
There is no straight forward answer to this. The thread shared by Rob has some great insights. However, one needs to understand that a lot can happen to the request before it reaches the server. The intermediary networking devices can manipulate the TCP headers so it may not reflect the correct IP Address that you need.
From a solution perspective, this might be perfectly possible, if you develop your own client and log this information somewhere so that you can track it. Otherwise there is no reliable way to get this information.
I have stumbled upon the following code:
return req.headers['x-forwarded-for'] ||
req.connection.remoteAddress ||
req.socket.remoteAddress ||
req.connection.socket.remoteAddress;
I know it is supposed to return the ip where the request came from. But I'd like to know the difference between connection.remoteAddress, socket.remoteAddress, connection.socket.remoteAddress and headers['x-forwarded-for'].
req.headers['x-forwarded-for'] checks for the HTTP header x-forwarded-for, which is a header that is usually set by reverse proxies when they pass a request to the web server.
The scenario is that clients/browsers connect to the proxy, and the proxy connects to the web server. However, because the web server is interested in the IP-address of the client, and not the IP-address of the proxy, this information has to be passed from proxy to web server somehow. That's done by using this header (or with the more recent Forwarded header). It's probably better to rely on a module like forwarded-http to properly handle the different proxy headers that are used to pass client-IP's.
req.connection.remoteAddress and req.socket.remoteAddress refer to the exact same thing, because both req.connection and req.socket are the same object. That object is a net.Socket instance that represents the (HTTP) connection. That instance has a .remoteAddress property.
req.connection.socket may be something that was used in older Node.js versions; in current versions it doesn't seem to exist.