示例#1
0
        /// <summary>
        /// Get external ip address of the local machine.
        /// The url should the ip address in text format, and may contain comma separated ip addresses, in which case the last value will be used.
        /// </summary>
        /// <param name="requestMaker">Request maker</param>
        /// <param name="url">Url</param>
        /// <returns>IP address</returns>
        public async Task <System.Net.IPAddress> LookupExternalIPAddressAsync(IHttpRequestMaker requestMaker, string url)
        {
            byte[] bytes = await requestMaker.MakeRequestAsync(new Uri(url));

            string ipString = Encoding.UTF8.GetString(bytes).Split(',').Last().Trim();

            if (System.Net.IPAddress.TryParse(ipString, out System.Net.IPAddress ipAddress))
            {
                if (ipAddress.IsIPv4MappedToIPv6)
                {
                    ipAddress = ipAddress.MapToIPv4();
                }
            }
            else
            {
                ipAddress = System.Net.IPAddress.Loopback;
            }
            return(ipAddress);
        }
        /// <summary>
        /// Get external ip address of the local machine.
        /// The url should the ip address in text format, and may contain comma separated ip addresses, in which case the last value will be used.
        /// </summary>
        /// <param name="requestMaker">Request maker or null for default</param>
        /// <param name="url">Url or null for default</param>
        /// <returns>IP address</returns>
        public async Task <System.Net.IPAddress> LookupExternalIPAddressAsync(IHttpRequestMaker requestMaker = null, string url = null)
        {
            if (string.IsNullOrWhiteSpace(url))
            {
                url = "https://checkip.amazonaws.com";
            }
            byte[]    bytes = null;
            Exception ex    = null;

            // try up to 3 times to get external ip
            for (int i = 0; i < 3; i++)
            {
                try
                {
                    bytes = await(requestMaker ?? this.requestMaker).MakeRequestAsync(new Uri(url));
                    break;
                }
                catch (Exception _ex)
                {
                    ex = _ex;
                    await Task.Delay(600);
                }
            }

            if (bytes is null)
            {
                throw new System.Net.WebException("Unable to get external ip address", ex);
            }
            string ipString = Encoding.UTF8.GetString(bytes).Split(',').Last().Trim();

            if (System.Net.IPAddress.TryParse(ipString, out System.Net.IPAddress ipAddress))
            {
                if (ipAddress.IsIPv4MappedToIPv6)
                {
                    ipAddress = ipAddress.MapToIPv4();
                }
            }
            else
            {
                ipAddress = System.Net.IPAddress.Loopback;
            }
            return(ipAddress);
        }
示例#3
0
        /// <summary>
        /// Get external ip address of the local machine.
        /// The url should the ip address in text format, and may contain comma separated ip addresses, in which case the last value will be used.
        /// </summary>
        /// <param name="requestMaker">Request maker or null for default</param>
        /// <param name="url">Url or null for default</param>
        /// <returns>IP address</returns>
        public async Task <System.Net.IPAddress> LookupExternalIPAddressAsync(IHttpRequestMaker requestMaker = null, string url = null)
        {
            if (string.IsNullOrWhiteSpace(url))
            {
                url = "https://checkip.amazonaws.com";
            }
            byte[] bytes    = await(requestMaker ?? this.requestMaker).MakeRequestAsync(new Uri(url));
            string ipString = Encoding.UTF8.GetString(bytes).Split(',').Last().Trim();

            if (System.Net.IPAddress.TryParse(ipString, out System.Net.IPAddress ipAddress))
            {
                if (ipAddress.IsIPv4MappedToIPv6)
                {
                    ipAddress = ipAddress.MapToIPv4();
                }
            }
            else
            {
                ipAddress = System.Net.IPAddress.Loopback;
            }
            return(ipAddress);
        }
示例#4
0
        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="firewall">The firewall to block with</param>
        /// <param name="whitelistChecker">Whitelist checker</param>
        /// <param name="httpRequestMaker">Http request maker for http uris, can leave null if uri is file</param>
        /// <param name="rulePrefix">Firewall rule prefix</param>
        /// <param name="interval">Interval to check uri for changes</param>
        /// <param name="uri">Uri, can be either file or http(s).</param>
        public IPBanUriFirewallRule(IIPBanFirewall firewall, IIsWhitelisted whitelistChecker, IHttpRequestMaker httpRequestMaker, string rulePrefix,
                                    TimeSpan interval, Uri uri)
        {
            this.firewall         = firewall.ThrowIfNull();
            this.whitelistChecker = whitelistChecker.ThrowIfNull();
            this.httpRequestMaker = httpRequestMaker;
            RulePrefix            = rulePrefix.ThrowIfNull();
            Uri      = uri.ThrowIfNull();
            Interval = (interval.TotalSeconds < 5.0 ? fiveSeconds : interval);

            if (!uri.IsFile)
            {
                // ensure uri ends with slash
                if (!uri.ToString().EndsWith("/"))
                {
                    uri = new Uri(uri.ToString() + "/");
                }
                httpClient = new HttpClient {
                    BaseAddress = uri, Timeout = thirtySeconds
                };
            }
        }
        /// <inheritdoc />
        public async Task HandleBannedIPAddress(string ipAddress, string source, string userName, string osName, string osVersion, string assemblyVersion, IHttpRequestMaker requestMaker)
        {
#if DEBUG
            if (!UnitTestDetector.Running)
            {
                return;
            }
#endif

            if (requestMaker is null)
            {
                return;
            }

            try
            {
                if (!System.Net.IPAddress.TryParse(ipAddress, out System.Net.IPAddress ipAddressObj) ||
                    ipAddressObj.IsInternal())
                {
                    return;
                }

                // submit url to ipban public database so that everyone can benefit from an aggregated list of banned ip addresses
                DateTime now       = IPBanService.UtcNow;
                string   timestamp = now.ToString("o");
                string   url       = $"/IPSubmitBanned?ip={ipAddress.UrlEncode()}&osname={osName.UrlEncode()}&osversion={osVersion.UrlEncode()}&source={source.UrlEncode()}&timestamp={timestamp.UrlEncode()}&userName={userName.UrlEncode()}&version={assemblyVersion.UrlEncode()}";
                using var hasher = SHA256.Create();
                string hash = Convert.ToBase64String(hasher.ComputeHash(Encoding.UTF8.GetBytes(url + IPBanResources.IPBanKey1)));
                url += "&hash=" + hash.UrlEncode();
                url  = BaseUrl + url;
                string timestampUnix = now.ToUnixMillisecondsLong().ToString(CultureInfo.InvariantCulture);
                List <KeyValuePair <string, object> > headers;
                if (PublicAPIKey != null && PublicAPIKey.Length != 0)
                {
                    // send api key and timestamp
                    headers = new List <KeyValuePair <string, object> >
                    {
                        new KeyValuePair <string, object>("X-IPBAN-API-KEY", PublicAPIKey.ToUnsecureString()),
                        new KeyValuePair <string, object>("X-IPBAN-TIMESTAMP", timestampUnix)
                    };
                }
                else
                {
                    headers = null;
                }
                await requestMaker.MakeRequestAsync(new Uri(url), headers : headers);
            }
            catch
            {
                // don't care, this is not fatal
            }
        }
 /// <summary>
 /// Does nothing
 /// </summary>
 /// <param name="ipAddress">N/A</param>
 /// <param name="source">N/A</param>
 /// <param name="userName">N/A</param>
 /// <param name="osName">N/A</param>
 /// <param name="osVersion">N/A</param>
 /// <param name="assemblyVersion">N/A</param>
 /// <param name="requestMaker">N/A</param>
 /// <returns>Completed task</returns>
 Task IBannedIPAddressHandler.HandleBannedIPAddress(string ipAddress, string source, string userName, string osName, string osVersion, string assemblyVersion, IHttpRequestMaker requestMaker)
 {
     // do nothing
     return(Task.CompletedTask);
 }
示例#7
0
 /// <summary>
 /// Constructor
 /// </summary>
 /// <param name="requestMaker">Request maker</param>
 public LocalMachineExternalIPAddressLookupDefault(IHttpRequestMaker requestMaker)
 {
     requestMaker.ThrowIfNull();
     this.requestMaker = requestMaker;
 }
示例#8
0
 /// <summary>
 /// Just returns loopback ip
 /// </summary>
 /// <param name="requestMaker">N/A</param>
 /// <param name="url">N/A</param>
 /// <returns>Loopback ip</returns>
 public Task <IPAddress> LookupExternalIPAddressAsync(IHttpRequestMaker requestMaker = null, string url = null)
 {
     return(Task.FromResult(System.Net.IPAddress.Loopback));
 }
示例#9
0
        /// <inheritdoc />
        public Task HandleBannedIPAddress(string ipAddress, string source, string userName, string osName, string osVersion, string assemblyVersion, IHttpRequestMaker requestMaker)
        {
            if (requestMaker == null)
            {
                return(Task.CompletedTask);
            }

            try
            {
                if (!System.Net.IPAddress.TryParse(ipAddress, out System.Net.IPAddress ipAddressObj) || ipAddressObj.IsInternal())
                {
                    return(Task.CompletedTask);
                }

                // submit url to ipban public database so that everyone can benefit from an aggregated list of banned ip addresses
                string timestamp = IPBanService.UtcNow.ToString("o");
                string url       = $"/IPSubmitBanned?ip={ipAddress.UrlEncode()}&osname={osName.UrlEncode()}&osversion={osVersion.UrlEncode()}&source={source.UrlEncode()}&timestamp={timestamp.UrlEncode()}&userName={userName.UrlEncode()}&version={assemblyVersion.UrlEncode()}";
                string hash      = Convert.ToBase64String(new SHA256Managed().ComputeHash(Encoding.UTF8.GetBytes(url + IPBanResources.IPBanKey1)));
                url += "&hash=" + hash.UrlEncode();
                url  = BaseUrl + url;
                return(requestMaker.MakeRequestAsync(new Uri(url)));
            }
            catch
            {
                // don't care, this is not fatal
                return(Task.CompletedTask);
            }
        }
示例#10
0
        private IPBanConfig(string xml, IDnsLookup dns = null, IDnsServerList dnsList = null, IHttpRequestMaker httpRequestMaker = null)
        {
            this.dns              = dns ?? DefaultDnsLookup.Instance;
            this.dnsList          = dnsList;
            this.httpRequestMaker = httpRequestMaker;

            // deserialize with XmlDocument, the .net core Configuration class is quite buggy
            XmlDocument doc = new XmlDocument();

            doc.LoadXml(xml);
            Xml = xml;
            foreach (XmlNode node in doc.SelectNodes("/configuration/appSettings/add"))
            {
                appSettings[node.Attributes["key"].Value] = node.Attributes["value"].Value;
            }

            GetConfig <int>("FailedLoginAttemptsBeforeBan", ref failedLoginAttemptsBeforeBan, 1, 50);
            GetConfig <bool>("ResetFailedLoginCountForUnbannedIPAddresses", ref resetFailedLoginCountForUnbannedIPAddresses);
            GetConfigArray <TimeSpan>("BanTime", ref banTimes, emptyTimeSpanArray);
            for (int i = 0; i < banTimes.Length; i++)
            {
                // according to documentation, a ban time of 0 should become max ban time
                if (banTimes[i].Ticks <= 0)
                {
                    banTimes[i] = maxBanTimeSpan;
                }
                else
                {
                    banTimes[i] = banTimes[i].Clamp(TimeSpan.FromMinutes(1.0), maxBanTimeSpan);
                }
            }
            GetConfig <bool>("ClearBannedIPAddressesOnRestart", ref clearBannedIPAddressesOnRestart);
            GetConfig <bool>("ClearFailedLoginsOnSuccessfulLogin", ref clearFailedLoginsOnSuccessfulLogin);
            GetConfig <TimeSpan>("ExpireTime", ref expireTime, TimeSpan.Zero, maxBanTimeSpan);
            if (expireTime.TotalMinutes < 1.0)
            {
                expireTime = maxBanTimeSpan;
            }
            GetConfig <TimeSpan>("CycleTime", ref cycleTime, TimeSpan.FromSeconds(5.0), TimeSpan.FromMinutes(1.0), false);
            GetConfig <TimeSpan>("MinimumTimeBetweenFailedLoginAttempts", ref minimumTimeBetweenFailedLoginAttempts, TimeSpan.Zero, TimeSpan.FromSeconds(15.0), false);
            GetConfig <string>("FirewallRulePrefix", ref firewallRulePrefix);

            string whitelistString      = GetConfig <string>("Whitelist", string.Empty);
            string whitelistRegexString = GetConfig <string>("WhitelistRegex", string.Empty);
            string blacklistString      = GetConfig <string>("Blacklist", string.Empty);
            string blacklistRegexString = GetConfig <string>("BlacklistRegex", string.Empty);

            PopulateList(whitelist, whitelistRanges, whitelistOther, ref whitelistRegex, whitelistString, whitelistRegexString);
            PopulateList(blackList, blackListRanges, blackListOther, ref blackListRegex, blacklistString, blacklistRegexString);
            XmlNode node2 = doc.SelectSingleNode("/configuration/ExpressionsToBlock");

            if (node2 != null)
            {
                try
                {
                    expressionsFailure = new XmlSerializer(typeof(EventViewerExpressionsToBlock)).Deserialize(new XmlNodeReader(node2)) as EventViewerExpressionsToBlock;
                }
                catch (Exception ex)
                {
                    expressionsFailure = new EventViewerExpressionsToBlock {
                        Groups = new List <EventViewerExpressionGroup>()
                    };
                    Logger.Error("Failed to load expressions to block", ex);
                }
                if (expressionsFailure != null)
                {
                    foreach (EventViewerExpressionGroup group in expressionsFailure.Groups)
                    {
                        foreach (EventViewerExpression expression in group.Expressions)
                        {
                            expression.Regex = (expression.Regex?.ToString() ?? string.Empty).Trim();
                        }
                    }
                }
            }
            node2 = doc.SelectSingleNode("/configuration/ExpressionsToNotify");
            if (node2 != null)
            {
                try
                {
                    expressionsSuccess = new XmlSerializer(typeof(EventViewerExpressionsToNotify)).Deserialize(new XmlNodeReader(node2)) as EventViewerExpressionsToNotify;
                }
                catch (Exception ex)
                {
                    expressionsSuccess = new EventViewerExpressionsToNotify {
                        Groups = new List <EventViewerExpressionGroup>()
                    };
                    Logger.Error("Failed to load expressions to notify: {0}", ex);
                }
                if (expressionsSuccess != null)
                {
                    foreach (EventViewerExpressionGroup group in expressionsSuccess.Groups)
                    {
                        group.NotifyOnly = true;
                        foreach (EventViewerExpression expression in group.Expressions)
                        {
                            expression.Regex = (expression.Regex?.ToString() ?? string.Empty).Trim();
                        }
                    }
                }
            }
            try
            {
                XmlNode logFilesToParseNode = doc.SelectSingleNode("/configuration/LogFilesToParse");
                if (logFilesToParseNode != null && new XmlSerializer(typeof(IPBanLogFilesToParse)).Deserialize(new XmlNodeReader(logFilesToParseNode)) is IPBanLogFilesToParse logFilesToParse)
                {
                    logFiles = logFilesToParse.LogFiles;
                }
                else
                {
                    logFiles = emptyLogFilesToParseArray;
                }
            }
            catch (Exception ex)
            {
                Logger.Error("Failed to load log files to parse", ex);
                logFiles = emptyLogFilesToParseArray;
            }
            GetConfig <string>("ProcessToRunOnBan", ref processToRunOnBan);
            GetConfig <bool>("UseDefaultBannedIPAddressHandler", ref useDefaultBannedIPAddressHandler);

            string userNameWhitelistString = GetConfig <string>("UserNameWhitelist", string.Empty);

            if (!string.IsNullOrEmpty(userNameWhitelistString))
            {
                foreach (string userName in userNameWhitelistString.Split(','))
                {
                    string userNameTrimmed = userName.Normalize().ToUpperInvariant().Trim();
                    userNameWhitelist.Add(userNameTrimmed);
                }
            }
            string userNameWhitelistRegexString = GetConfig <string>("UserNameWhitelistRegex", string.Empty);

            if (!string.IsNullOrWhiteSpace(userNameWhitelistRegexString))
            {
                userNameWhitelistRegex = new Regex(userNameWhitelistRegexString, RegexOptions.IgnoreCase | RegexOptions.CultureInvariant | RegexOptions.Singleline);
            }
            GetConfig <int>("UserNameWhitelistMinimumEditDistance", ref userNameWhitelistMaximumEditDistance);
            GetConfig <int>("FailedLoginAttemptsBeforeBanUserNameWhitelist", ref failedLoginAttemptsBeforeBanUserNameWhitelist);
            GetConfig <string>("GetUrlUpdate", ref getUrlUpdate);
            GetConfig <string>("GetUrlStart", ref getUrlStart);
            GetConfig <string>("GetUrlStop", ref getUrlStop);
            GetConfig <string>("GetUrlConfig", ref getUrlConfig);
            GetConfig <string>("ExternalIPAddressUrl", ref externalIPAddressUrl);
            GetConfig <string>("FirewallUriRules", ref firewallUriRules);
            if (string.IsNullOrWhiteSpace(firewallUriRules))
            {
                // legacy
                GetConfig <string>("FirewallUriSources", ref firewallUriRules);
            }
            firewallUriRules = (firewallUriRules ?? string.Empty).Trim();

            // parse firewall block rules, one per line
            ParseFirewallBlockRules();
        }