How to get public Ipv6 with nodejs - node.js

I am using nodejs to get ipv4 like
app.get('/getip', (req, res) => {
res.json({
ip: req.headers['x-forwarded-for']
});
});
this work fine for ipv4 but i need to get ipv6 too how can i get public ip of router family ipv6.
I'm using node 7.6.0

This code doesn't get an IPv4 or IPv6 address. It gets the value of the X-Forwarded-For header provided by some frontend server in front of your application. If that server doesn't accept an IPv6 connection, there will be no IPv6 address.

Use this code to fetch User's IPv6 Remote address
const express = require("express");
const bodyParser = require("body-parser");
const app = express();
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.get("/", (req, res) => res.json({
ip: req.ip || req.connection.remoteAddress || 'null',
}));
const listenServer = () => {
console.log('App running on');
};
// Use IPv4 address to listen on IPv4
app.listen(3000, '0.0.0.0', listenServer);
// Use IPv6 address to listen on IPv6.
app.listen(3000, '2401:4900:169e:80c3:11e9:63ba:1f81:d224', listenServer);

Related

Run same Node.js App on IPV4 and IPV6 simultaneously?

I know when I have the hostname as "::" this means the same as "0.0.0.0" in IPV4.
const express = require('express')
const app = express()
const port =80
const host6 = "::";
const host4 = "0.0.0.0";
app.get('/', (req, res) => {
res.send('Hello World!')
})
app.listen(port, host6, () => {
console.log(`Example app listening at http://localhost:${port}`)
})
This App should now be accessible through IPV6 but als IPV4. But devices which don't understand IPV6 can not make the initial request over IPV6, so for them the App is not accessible.
How can I run this App on both IP versions on the same Port 80?
Unconfirmed, but I would try to remove the host from the arguments passed to app.listen and only pass the port, app.listen(port).
Express docs for app.listen state that
This method is identical to Node’s http.Server.listen().
Node's documentation for http.Server.listen state that
This method is identical to server.listen() from net.Server.
Node's documentation for net.Server states that
If host is omitted, the server will accept connections on the unspecified IPv6 address (::) when IPv6 is available, or the unspecified IPv4 address (0.0.0.0) otherwise.

Proxy Issue ENOTFOUND Create-React-App Http-Proxy-Middleware Express

I've run into a new problem when proxy my client requests from CRA to my express API server when in development.
I get the following error message from HPM. And I can see it returns as 504 Gateway Timeout
[HPM] Error occurred while trying to proxy request /api/game/leaderboard from localhost:3000 to http://localhost:5000 (ENOTFOUND) (https://nodejs.org/api/errors.html#errors_common_system_errors)
I'm using the setupProxy.js as follows:
const { createProxyMiddleware } = require('http-proxy-middleware');
module.exports = app => {
console.log('from setupPrxoy.js');
app.use(
'/api/**',
createProxyMiddleware({
target: 'http://localhost:5000',
changeOrigin: true,
})
);
};
That seems to be working fine as I get the following when I start the React dev server:
[HPM] Proxy created: / -> http://localhost:5000
This is my server app.js:
const express = require('express');
const cors = require('cors');
const PORT = process.env.PORT || 5000;
const app = express();
const corsOptions = {
credentials: true,
};
app.use(cors(corsOptions));
app.use(express.json())
app.use(express.urlencoded({extended: true}))
//ROUTES
require('./routes/currentGame')(app);
app.listen(PORT, () => {
console.log(`Server started on ${PORT}`);
});
And that routes file:
const db = require('../models');
module.exports = app => {
app.get('/api/game/leaderboard', async (req, res, next) => {
try {
await db.Entry.find({
gameNumber: 2
})
.limit(50)
.populate('user', 'username')
.sort({ totalScore: 'descending' })
.exec((err, entries) => {
if (err) {
return next(err);
} else {
const leaderboard = [];
entries.forEach(entry => {
let newObj = {
totalScore: entry.totalScore,
username: entry.user.username
};
leaderboard.push(newObj);
});
return res.status(200).json(leaderboard);
}
});
} catch (err) {
return next(err);
}
});
}
The API works fine in the client, it returns the JSON as expected.
I've tried rolling back to older versions of React, React-Dom, React-Scripts and HPM but no luck.
I've tried removing the HPM and using a simple proxy in the package.json on the client side. Didn't work, got a similar message.
So I know the proxy is working (I think)
I've looked up ENOTFOUND and worked out it is some sort of DNS Address Error.
This is what I get when I in the command line
node 5033 [mynamewithheld] 23u IPv4 0x93d5c87aa7d4fbd3 0t0 TCP *:3000 (LISTEN)
node 5035 [mynamewithheld] 23u IPv6 0x93d5c87aa770a0ab 0t0 TCP *:5000 (LISTEN)
I'm wondering if I need to do something with the Header Requests on the server or if the Ports are running differently?
Any help appreciated!!
I think I have narrowed the issue down to hardware.
It doesnt work on 2011 iMac running OS Sierra 10.12.6 which was I was using but tested on 2015 MacBook Air running OS Mojave 10.14.16 and it works.
Beyond knowing that is the issue, any idea how to fix so it works on the iMac?
Make sure localhost is mapped to 127.0.0.1 in your etc/hosts file.

Bind Greenlock to specific ip address?

I've got greenlock express running well in node.js on my Windows server. However, I've added some more IP addresses to the server and find that node.js and greenlock are listening to port 443 on 0.0.0.0, thereby tieing up all the IP addresses.
How do I tell greenlock to listen to port 443 only on one specific IP address?
Is there any configuration value that I can add to this?
var greenlock = require('greenlock-express')
.init({
packageRoot: __dirname,
maintainerEmail: "....",
configDir: './greenlock.d',
cluster: false
});
That's in the examples folder https://git.rootprojects.org/root/greenlock-express.js/src/branch/master/examples/https/server.js
That's the folder you need to be looking at for more advanced uses.
"use strict";
// The WRONG way:
//var https = require('https');
//var httpsServer = https.createServer(tlsOptions, app);
//
// Why is that wrong?
// Greenlock needs to change some low-level http and https options.
// Use glx.httpsServer(tlsOptions, app) instead.
//require("greenlock-express")
require("../../")
.init({
packageRoot: __dirname,
configDir: "./greenlock.d",
maintainerEmail: "jon#example.com",
cluster: false
})
.ready(httpsWorker);
function httpsWorker(glx) {
//
// HTTPS 1.1 is the default
// (HTTP2 would be the default but... https://github.com/expressjs/express/issues/3388)
//
// Get the raw https server:
var httpsServer = glx.httpsServer(null, function(req, res) {
res.end("Hello, Encrypted World!");
});
httpsServer.listen(443, "0.0.0.0", function() {
console.info("Listening on ", httpsServer.address());
});
// Note:
// You must ALSO listen on port 80 for ACME HTTP-01 Challenges
// (the ACME and http->https middleware are loaded by glx.httpServer)
var httpServer = glx.httpServer();
httpServer.listen(80, "0.0.0.0", function() {
console.info("Listening on ", httpServer.address());
});
}
I saw that you left an issue (yesterday?), but I forgot to respond.

nodejs v5.10.1 cannot get my host address anymore?

Why the latest version of nodejs (v5.10.1) cannot get my host address anymore?
express code:
var express = require('express');
var app = express();
// respond with "Hello World!" on the homepage
app.get('/', function (req, res) {
res.send('Hello World!');
});
var server = app.listen(3000, function () {
var host = server.address().address;
var port = server.address().port;
console.log(server.address());
console.log('Example app listening at http://%s:%s', host, port);
});
result:
{ address: '::', family: 'IPv6', port: 3000 }
Example app listening at http://:::3000
It should be:
http://127.0.0.1
Any ideas how I can fix this?
I am on Linux.
Actually, maybe you will see something like
:80
and then
::80
actually this one have a pattern like this:
host:port IPv4
host::port IPv6
127.0.0.1:80 means that using IPv4, listening in 127.0.0.1 in port 80
:80 means that using IPv4 ,listening on all address in port 80
127.0.0.1::80 means that using IPv6, listening in 127.0.0.1 in port 80
and so on.
so, the ::3000 means listening to IPv6 in port 3000
These configuration was done under these variable
var host = server.address().address;
var port = server.address().port;
you can just change the value of these variable to "127.0.0.1" and "80" and see what happens, but most likely your machine still using IPv6 there, if you want to change to IPv4 for your machine, change the setting of your machine under:
Windows: control panel -> network and sharing center -> (your network) -> properties -> setup the IPv4
Linux: i dont have linux machine to test this, but the syntax should be using ifconfig or ipconfig depends on your linux, please refer for something like https://unix.stackexchange.com/questions/34093/static-ipv4-ipv6-configuration-on-centos-6-2
Mac: i dont have mac machine also, should be the same with linux so try to do the same also
I have the same problem, i solved it acessing like an array:
server.address()["port"]
Here a example:
export const onError = (server: Server) => {
console.log(server.address()["port"])
return (error: NodeJS.ErrnoException): void => {
let port: number | string = server.address()["port"];
if (error.syscall !== 'listen') throw error;
let bind = (typeof port === 'string') ? `pipe ${port}` : `port ${port}`;
switch(error.code) {
case 'EACCES':
console.error(`${bind} requires elevated privileges`);
process.exit(1);
break;
case 'EADDRINUSE':
console.error(`${bind} is already in use`);
process.exit(1);
break;
default:
throw error;
}
}
}

Default route using node-http-proxy?

I want to do a simple node.js reverse proxy to host multiple Node.JS applications along with my apache server on the same port 80. So I found this example here
var http = require('http')
, httpProxy = require('http-proxy');
httpProxy.createServer({
hostnameOnly: true,
router: {
'www.my-domain.com': '127.0.0.1:3001',
'www.my-other-domain.de' : '127.0.0.1:3002'
}
}).listen(80);
The problem is that I want to have for example app1.my-domain.com pointing to localhost:3001, app2.my-domain.com pointing to localhost:3002, and all other go to port 3000 for example, where my apache server will be running. I couldn't find anything in the documentation on how to have a "default" route.
Any ideas?
EDIT I want to do that because I have a lot of domains/subdomains handled by my apache server and I don't want to have to modify this routing table each time I have want to add a new subdomain.
For nearly a year, I had successfully used the accepted answer to have a default host, but there's a much simpler way now that node-http-proxy allows for RegEx in the host table.
var httpProxy = require('http-proxy');
var options = {
// this list is processed from top to bottom, so '.*' will go to
// '127.0.0.1:3000' if the Host header hasn't previously matched
router : {
'example.com': '127.0.0.1:3001',
'sample.com': '127.0.0.1:3002',
'^.*\.sample\.com': '127.0.0.1:3002',
'.*': '127.0.0.1:3000'
}
};
// bind to port 80 on the specified IP address
httpProxy.createServer(options).listen(80, '12.23.34.45');
The requires that you do NOT have hostnameOnly set to true, otherwise the RegEx would not be processed.
This isn't baked into node-http-proxy, but it's simple to code:
var httpProxy = require('http-proxy'),
http = require('http'),
addresses;
// routing hash
addresses = {
'localhost:8000': {
host: 'localhost',
port: 8081
},
'local.dev:8000': {
host: 'localhost',
port: 8082
},
'default': {
host: 'xkcd.com',
port: 80
}
};
// create servers on localhost on ports specified by param
function createLocalServer(ports) {
ports.forEach(function(port) {
http.createServer(function (req, res) {
res.writeHead(200, {'Content-Type': 'text/html'});
res.end('<h1>Hello from ' + port + '</h1');
}).listen(port);
});
console.log('Servers up on ports ' + ports.join(',') + '.');
}
createLocalServer([8081, 8082]);
console.log('======================================\nRouting table:\n---');
Object.keys(addresses).forEach(function(from) {
console.log(from + ' ==> ' + addresses[from].host + ':' + addresses[from].port);
});
httpProxy.createServer(function (req, res, proxy) {
var target;
// if the host is defined in the routing hash proxy to it
// else proxy to default host
target = (addresses[req.headers.host]) ? addresses[req.headers.host] : addresses.default;
proxy.proxyRequest(req, res, target);
}).listen(8000);
If you visit localhost on port 8000 it will proxy to localhost port 8081.
If you visit 127.0.0.1 on port 8000 (which is not defined in our routing hash) it will go to the default 'location', namely xkcd.com on port 80.

Resources