diff --git a/Common/config/default.json b/Common/config/default.json index bf9a9669..88e6705d 100644 --- a/Common/config/default.json +++ b/Common/config/default.json @@ -39,6 +39,11 @@ "queueconverttask": "dc.converttask", "queueconvertresponse": "dc.convertresponse" }, + "dnscache": { + "enable" : true, + "ttl" : 300, + "cachesize" : 1000 + }, "services": { "CoAuthoring": { "server": { diff --git a/Common/package.json b/Common/package.json index cde73a51..9b56d39c 100644 --- a/Common/package.json +++ b/Common/package.json @@ -9,7 +9,9 @@ "aws-sdk": "^2.4.12", "co": "^4.6.0", "config": "^1.21.0", + "dnscache": "0.0.4", "escape-string-regexp": "^1.0.5", + "ipaddr.js": "^1.2.0", "log4js": "^0.6.38", "mime": "^1.3.4", "mkdirp": "^0.5.1", diff --git a/Common/sources/utils.js b/Common/sources/utils.js index d2a53305..d6ca4278 100644 --- a/Common/sources/utils.js +++ b/Common/sources/utils.js @@ -37,6 +37,13 @@ var request = require('request'); var co = require('co'); var URI = require("uri-js"); const escapeStringRegexp = require('escape-string-regexp'); +const ipaddr = require('ipaddr.js'); +var configDnsCache = config.get('dnscache'); +const dnscache = require('dnscache')({ + "enable": configDnsCache.get('enable'), + "ttl": configDnsCache.get('ttl'), + "cachesize": configDnsCache.get('cachesize'), + }); var constants = require('./constants'); var configIpFilter = config.get('services.CoAuthoring.ipfilter'); @@ -511,11 +518,25 @@ function* pipeFiles(from, to) { yield pipeStreams(fromStream, toStream, true); } exports.pipeFiles = co.wrap(pipeFiles); -function checkIpFilter(hostname) { +function checkIpFilter(ipString, opt_hostname) { var status = 0; - for (var i = 0; i < g_oIpFilterRules.length; ++i) { + var ip4; + var ip6; + if (ipaddr.isValid(ipString)) { + var ip = ipaddr.parse(ipString); + if ('ipv6' == ip.kind()) { + if (ip.isIPv4MappedAddress()) { + ip4 = ip.toIPv4Address().toString(); + } + ip6 = ip.toNormalizedString(); + } else { + ip4 = ip.toString(); + ip6 = ip.toIPv4MappedAddress().toNormalizedString(); + } + } + for (i = 0; i < g_oIpFilterRules.length; ++i) { var rule = g_oIpFilterRules[i]; - if (rule.exp.test(hostname)) { + if ((opt_hostname && rule.exp.test(opt_hostname)) || (ip4 && rule.exp.test(ip4)) || (ip6 && rule.exp.test(ip6))) { if (!rule.allow) { status = cfgIpFilterErrorCode; } @@ -525,3 +546,15 @@ function checkIpFilter(hostname) { return status; } exports.checkIpFilter = checkIpFilter; +function dnsLookup(hostname, options) { + return new Promise(function(resolve, reject) { + dnscache.lookup(hostname, options, function(err, addresses){ + if (err) { + reject(err); + } else { + resolve(addresses); + } + }); + }); +} +exports.dnsLookup = dnsLookup; \ No newline at end of file diff --git a/DocService/package.json b/DocService/package.json index cfb7d4e9..6b87daa7 100644 --- a/DocService/package.json +++ b/DocService/package.json @@ -12,7 +12,6 @@ "express": "^4.14.0", "fakeredis": "^1.0.3", "forwarded": "^0.1.0", - "ipaddr.js": "^1.2.0", "mime": "^1.3.4", "multiparty": "^4.1.2", "mysql": "^2.11.1", diff --git a/DocService/sources/DocsCoServer.js b/DocService/sources/DocsCoServer.js index 180d767f..cd70b343 100644 --- a/DocService/sources/DocsCoServer.js +++ b/DocService/sources/DocsCoServer.js @@ -746,7 +746,8 @@ function* bindEvents(docId, callback, baseUrl, opt_userAction, opt_userData) { oCallbackUrl = parseUrl(callback); bChangeBase = c_oAscChangeBase.All; if (null !== oCallbackUrl) { - if (utils.checkIpFilter(oCallbackUrl.host) > 0) { + var hostIp = yield utils.dnsLookup(oCallbackUrl.host); + if (utils.checkIpFilter(hostIp, oCallbackUrl.host) > 0) { logger.error('checkIpFilter error: docId = %s;url = %s', docId, callback); //todo add new error type oCallbackUrl = null; diff --git a/DocService/sources/server.js b/DocService/sources/server.js index 5b3416c4..1c301e73 100644 --- a/DocService/sources/server.js +++ b/DocService/sources/server.js @@ -105,7 +105,6 @@ if (cluster.isMaster) { const bodyParser = require("body-parser"); const mime = require('mime'); const forwarded = require('forwarded'); - const ipaddr = require('ipaddr.js'); const docsCoServer = require('./DocsCoServer'); const canvasService = require('./canvasservice'); const converterService = require('./converterservice'); @@ -167,13 +166,6 @@ if (cluster.isMaster) { if (cfgIpFilterEseForRequest) { var addresses = forwarded(req); var ipString = addresses[addresses.length - 1]; - //IPv6 -> IPv4 - if (ipaddr.IPv6.isValid(ipString)) { - var ip = ipaddr.IPv6.parse(ipString); - if (ip.isIPv4MappedAddress()) { - ipString = ip.toIPv4Address().toString(); - } - } status = utils.checkIpFilter(ipString); } if (status > 0) { diff --git a/FileConverter/sources/converter.js b/FileConverter/sources/converter.js index a712027e..4dfdb059 100644 --- a/FileConverter/sources/converter.js +++ b/FileConverter/sources/converter.js @@ -167,7 +167,8 @@ function* downloadFile(docId, uri, fileFrom) { var data = null; var downloadAttemptCount = 0; var urlParsed = url.parse(uri); - var filterStatus = utils.checkIpFilter(urlParsed.hostname); + var hostIp = yield utils.dnsLookup(urlParsed.hostname); + var filterStatus = utils.checkIpFilter(hostIp, urlParsed.hostname); if (0 == filterStatus) { while (!res && downloadAttemptCount++ < cfgDownloadAttemptMaxCount) { try {