Added ipBlockedUserRedirect, #3189

Ylian Saint-Hilaire committed Oct 13, 2021 at 19:12 UTC 8012a10fea78f40a00fe5e67948548a9b050d3c8
2 files changed +17 -15
meshcentral-config-schema.json
+10 -8
@@ -128,10 +128,11 @@
128 },
129 "publicPushNotifications": { "type": "boolean", "default": false, "description": "When true, this server uses MeshCentral.com a push notification relay for Android notifications. Push notifications work even if the Android app is not open." },
130 "desktopMultiplex": { "type": "boolean", "default": false, "description": "When true, enabled a server modules that efficiently splits a remote desktop stream to multiple browsers. Also allows slow browsers to not slow down the session for fast ones, this comes at the cost of extra server memory and processing for all remote desktop sessions." },
131 - "userAllowedIP": { "type": [ "string", "array" ] },
132 - "userBlockedIP": { "type": [ "string", "array" ] },
133 - "agentAllowedIP": { "type": [ "string", "array" ] },
134 - "agentBlockedIP": { "type": [ "string", "array" ] },
131 + "ipBlockedUserRedirect" : { "type": "string", "default": null, "description": "If set, a user from a banned IP address will be redirected to this URL." },
132 + "userAllowedIP": { "type": [ "string", "array" ], "default": null, "description": "When set, only users from allowed IP address ranges can connect to the server. Example: \"192.168.2.100,192.168.1.0/24\"" },
133 + "userBlockedIP": { "type": [ "string", "array" ], "default": null, "description": "When set, users from these denied IP address ranges will not be able to connect to the server. Example: \"192.168.2.100,192.168.1.0/24\"" },
134 + "agentAllowedIP": { "type": [ "string", "array" ], "default": null, "description": "When set, only agents from allowed IP address ranges can connect to the server. Example: \"192.168.2.100,192.168.1.0/24\"" },
135 + "agentBlockedIP": { "type": [ "string", "array" ], "default": null, "description": "When set, agents from these denied IP address ranges will not be able to connect to the server. Example: \"192.168.2.100,192.168.1.0/24\"" },
136 "authLog": { "type": "string", "default": null, "description": "File path and name of the authentication log to be created. This log can be parsed by Fail2ban." },
137 "InterUserMessaging": { "type": "array", "uniqueItems": true, "items": { "type": "string" }, "description": "Users in this list are allowed to send and receive inter-user messages. This can be used to implement bots or other software where MeshCentral is used as data transport. See \"interuser\" websocket command in the code." },
138 "manageAllDeviceGroups": { "type": "array", "uniqueItems": true, "items": { "type": "string" }, "description": "Users in this list are allowed to see and manage all device groups within their domain." },
@@ -478,10 +479,11 @@
479 "image": { "type": "string", "default": null, "description": "The filename of a image file in .png format located in meshcentral-data to display in MeshCentral Agent for Android, image should be square and from 64x64 to 128x128." }
480 }
481 },
481 - "userAllowedIP": { "type": "string" },
482 - "userBlockedIP": { "type": "string" },
483 - "agentAllowedIP": { "type": "string" },
484 - "agentBlockedIP": { "type": "string" },
482 + "ipBlockedUserRedirect" : { "type": "string", "default": null, "description": "If set, a user from a banned IP address will be redirected to this URL." },
483 + "userAllowedIP": { "type": [ "string", "array" ], "default": null, "description": "When set, only users from allowed IP address ranges can connect to the server. Example: \"192.168.2.100,192.168.1.0/24\"" },
484 + "userBlockedIP": { "type": [ "string", "array" ], "default": null, "description": "When set, users from these denied IP address ranges will not be able to connect to the server. Example: \"192.168.2.100,192.168.1.0/24\"" },
485 + "agentAllowedIP": { "type": [ "string", "array" ], "default": null, "description": "When set, only agents from allowed IP address ranges can connect to the server. Example: \"192.168.2.100,192.168.1.0/24\"" },
486 + "agentBlockedIP": { "type": [ "string", "array" ], "default": null, "description": "When set, agents from these denied IP address ranges will not be able to connect to the server. Example: \"192.168.2.100,192.168.1.0/24\"" },
487 "userSessionIdleTimeout": { "type": "integer", "default": null, "description": "When set, idle users will be disconnected after a set amounts of minutes." },
488 "userConsentFlags": {
489 "type": "object",
webserver.js
+7 -7
@@ -706,12 +706,12 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
706 */
707
708 // Check if the source IP address is in the IP list, return false if not.
709 - function checkIpAddressEx(req, res, ipList, closeIfThis) {
709 + function checkIpAddressEx(req, res, ipList, closeIfThis, redirectUrl) {
710 try {
711 if (req.connection) {
712 // HTTP(S) request
713 - if (req.clientIp) { for (var i = 0; i < ipList.length; i++) { if (require('ipcheck').match(req.clientIp, ipList[i])) { if (closeIfThis === true) { res.sendStatus(401); } return true; } } }
714 - if (closeIfThis === false) { res.sendStatus(401); }
713 + if (req.clientIp) { for (var i = 0; i < ipList.length; i++) { if (require('ipcheck').match(req.clientIp, ipList[i])) { if (closeIfThis === true) { if (typeof redirectUrl == 'string') { res.redirect(redirectUrl); } else { res.sendStatus(401); } } return true; } } }
714 + if (closeIfThis === false) { if (typeof redirectUrl == 'string') { res.redirect(redirectUrl); } else { res.sendStatus(401); } }
715 } else {
716 // WebSocket request
717 if (res.clientIp) { for (var i = 0; i < ipList.length; i++) { if (require('ipcheck').match(res.clientIp, ipList[i])) { if (closeIfThis === true) { try { req.close(); } catch (e) { } } return true; } } }
@@ -724,12 +724,12 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
724 // Check if the source IP address is allowed, return domain if allowed
725 // If there is a fail and null is returned, the request or connection is closed already.
726 function checkUserIpAddress(req, res) {
727 - if ((parent.config.settings.userblockedip != null) && (checkIpAddressEx(req, res, parent.config.settings.userblockedip, true) == true)) { obj.blockedUsers++; return null; }
728 - if ((parent.config.settings.userallowedip != null) && (checkIpAddressEx(req, res, parent.config.settings.userallowedip, false) == false)) { obj.blockedUsers++; return null; }
727 + if ((parent.config.settings.userblockedip != null) && (checkIpAddressEx(req, res, parent.config.settings.userblockedip, true, parent.config.settings.ipblockeduserredirect) == true)) { obj.blockedUsers++; return null; }
728 + if ((parent.config.settings.userallowedip != null) && (checkIpAddressEx(req, res, parent.config.settings.userallowedip, false, parent.config.settings.ipblockeduserredirect) == false)) { obj.blockedUsers++; return null; }
729 const domain = (req.url ? getDomain(req) : getDomain(res));
730 if (domain == null) { parent.debug('web', 'handleRootRequest: invalid domain.'); try { res.sendStatus(404); } catch (ex) { } return; }
731 - if ((domain.userblockedip != null) && (checkIpAddressEx(req, res, domain.userblockedip, true) == true)) { obj.blockedUsers++; return null; }
732 - if ((domain.userallowedip != null) && (checkIpAddressEx(req, res, domain.userallowedip, false) == false)) { obj.blockedUsers++; return null; }
731 + if ((domain.userblockedip != null) && (checkIpAddressEx(req, res, domain.userblockedip, true, domain.ipblockeduserredirect) == true)) { obj.blockedUsers++; return null; }
732 + if ((domain.userallowedip != null) && (checkIpAddressEx(req, res, domain.userallowedip, false, domain.ipblockeduserredirect) == false)) { obj.blockedUsers++; return null; }
733 return domain;
734 }
735