Vhost ip filter express node

I am using vhost with express to manage two subdomains. Everything works well, but I would like to filter the request for one of the subdomains by ip. Do you know if this is possible?

I tried to manage it in the app.js of my subdomain site, but req.connection.remoteAddress and req.ip provided me with the ip of my server.

When I have only one subdomain and I do not use vhost, I have the correct ip, but since I used vhost, I have the ip of my server ...

Here is my folder structure before:

 -- subdomain1/ -- app.js -- views/ 

Here is my new structure:

 -- subdomain1/ -- app.js -- views/ -- subdomain2/ -- app.js -- views/ -- manageSubdomain/ -- app.js 

Here is my code when it works before using vhost and for only one subdomain:

subdomain1 / app.js:

 var express = require('express'); var path = require('path'); var logger = require('morgan'); var cookieParser = require('cookie-parser'); var bodyParser = require('body-parser'); require('body-parser-xml')(bodyParser); var routes = require('./routes/index'); var app = express(); // view engine setup app.set('views', path.join(__dirname, 'views')); app.set('view engine', 'jade'); // uncomment after placing your favicon in /public app.use(logger('dev')); app.use(bodyParser.json()); app.use(bodyParser.urlencoded({ extended: false })); app.use(cookieParser()); app.use(express.static(path.join(__dirname, 'public'))); // Example middleware to get ip app.use(function (req, res) { console.log(req.ip); // it give me the correct IP }); app.use('/', routes); module.exports = app; 

And the file that manages the server until:

 #!/usr/bin/env node /** * Module dependencies. */ var app = require('../app'); var debug = require('debug')('webservicePrestashop:server'); var https = require('https'); var fs = require('fs'); /** * Get port from environment and store in Express. */ var port = normalizePort(process.env.PORT || '443'); app.set('port', port); /** * Create HTTP server. */ //var server = http.createServer(app); var options = { key: fs.readFileSync('/path/to/privkey.pem'), cert: fs.readFileSync('/path/to/fullchain.pem'), ca: fs.readFileSync('/path/to/chain.pem') } var server = https.createServer(options, app); // Redirect from http port 80 to https var http = require('http'); http.createServer(function (req, res) { res.writeHead(301, { "Location": "https://" + req.headers['host'] + req.url }); res.end(); }).listen(80); /** * Listen on provided port, on all network interfaces. */ server.listen(port); /** * Event listener for HTTP server "listening" event. */ function onListening() { var addr = server.address(); var bind = typeof addr === 'string' ? 'pipe ' + addr : 'port ' + addr.port; debug('Listening on ' + bind); } 

Here is my code for managing the subdomain:

manageSubdomain / app.js:

 var express = require('express'); var vhost = require('vhost'); var http = require('http'); var https = require('https'); var fs = require('fs'); var tls = require('tls'); // Gestions des sites const subdomain1 = { app: require('../subdomain1/app'), context: tls.createSecureContext({ key: fs.readFileSync('path/to/privkey.pem').toString(), cert: fs.readFileSync('path/to/privkey.pem/fullchain.pem').toString(), ca: fs.readFileSync('path/to/privkey.pem/chain.pem').toString() }).context }; const subdomain2 = { app: require('../subdomain2/app'), context: tls.createSecureContext({ key: fs.readFileSync('path/to/privkey.pem/privkey.pem').toString(), cert: fs.readFileSync('path/to/privkey.pem/fullchain.pem').toString(), ca: fs.readFileSync('path/to/privkey.pem/chain.pem').toString() }).context }; var sites = { "my.subdomain1.com": subdomain1, "my.subdomain2.com": subdomain2 }; var exp = express(); for (let s in sites) { exp.use(vhost(s, sites[s].app)); } // Redirect du http to https http.createServer(function (req, res) { res.writeHead(301, { "Location": "https://" + req.headers['host'] + req.url }); res.end(); }).listen(80); var secureOpts = { SNICallback: function (domain, cb) { if (typeof sites[domain] === "undefined") { cb(new Error("domain not found"), null); console.log("Error: domain not found: " + domain); } else { cb(null, sites[domain].context); } }, key: fs.readFileSync('path/to/privkey.pem/privkey.pem').toString(), cert: fs.readFileSync('path/to/privkey.pem/fullchain.pem').toString() }; // Création du serveur https var httpsServer = https.createServer(secureOpts, exp); httpsServer.listen(443); 

Now my subdomain1 / app.js is the same as the previous one

+5
source share
1 answer

Have you tried using the req.ip property?

Express documentation says:

Contains the remote IP address of the request.

If the trusted proxy parameter is not evaluated as false, the value of this property is obtained from the leftmost entry in the X-Forwarded-For header. This header can be set by the client or proxy.

To debug your code, add the middleware to register before adding any application to the express object:

 var exp = express(); // ip logging middleware app.use(function (req, res, next) { console.log(req.ip); next(); }); for (let s in sites) { exp.use(vhost(s, sites[s].app)); } 

Then add the same middleware as the first middleware of your applications. This way you can be sure that the problem is caused by the vhost module.

+1
source

Source: https://habr.com/ru/post/1270487/


All Articles