Exemplo n.º 1
0
        private async Task <ReverseDnsResult> Lookup(string ipAddress)
        {
            ReverseDnsResult reverseDnsResult = await _reverseDnsLookup.Lookup(ipAddress);

            if (!reverseDnsResult.ForwardResponses.Any())
            {
                return(new ReverseDnsResult(ipAddress, new List <ReverseDnsResponse> {
                    new ReverseDnsResponse("Unknown", null, "Unknown")
                }));
            }

            if (!reverseDnsResult.ForwardResponses.Any(x => x.IpAddresses.Contains(ipAddress)))
            {
                List <ReverseDnsResponse> responses = reverseDnsResult.ForwardResponses.Select(x => new ReverseDnsResponse("Mismatch", x.IpAddresses, "Mismatch")).ToList();
                return(new ReverseDnsResult(ipAddress, responses));
            }

            foreach (ReverseDnsResponse forwardResponse in reverseDnsResult.ForwardResponses)
            {
                OrganisationalDomain organisationalDomain = await _organisationalDomainProvider.GetOrganisationalDomain(forwardResponse.Host);

                forwardResponse.OrganisationalDomain = organisationalDomain.OrgDomain;
            }

            return(reverseDnsResult);
        }
        public async Task ItShouldReturnEmptyListForBadIpAddress(string ipAddress)
        {
            var reverseDnsLookup    = new ReverseDnsLookup(_dnsResolver, _log);
            ReverseDnsResult result = await reverseDnsLookup.Lookup(ipAddress);

            Assert.That(result.ForwardResponses.Count, Is.EqualTo(0));
            Assert.IsNull(result.OriginalIpAddress);
        }
        public async Task ItShouldLogErrorWhenUnableToDoLookupForPtr(string ipAddress)
        {
            ReverseDnsQueryResponse response = new ReverseDnsQueryResponse(true, "Something has gone wrong!", null);

            A.CallTo(() => _dnsResolver.QueryPtrAsync(A <IPAddress> ._)).Returns(response);

            var reverseDnsLookup = new ReverseDnsLookup(_dnsResolver, _log);

            ReverseDnsResult result = await reverseDnsLookup.Lookup(ipAddress);

            Assert.That(_log.Warnings.Count, Is.EqualTo(1));
            Assert.That(result.ForwardResponses.Count, Is.EqualTo(0));
            Assert.IsNull(result.OriginalIpAddress);
        }
        public async Task ItShouldProcessAllValidLookups(string ipAddress)
        {
            string googleHostName = "google.com";
            string googleIp1      = "192.168.0.1";
            string googleIp2      = "192.168.0.2";

            string yahooHostName = "yahoo.com";
            string yahooIp1      = "192.168.1.1";

            ReverseDnsQueryResponse ptrDnsQueryResponse = new ReverseDnsQueryResponse(false, string.Empty, new List <string>()
            {
                googleHostName, yahooHostName
            });
            ReverseDnsQueryResponse googleAddressDnsQueryResponse = new ReverseDnsQueryResponse(false, string.Empty, new List <string>()
            {
                googleIp1, googleIp2
            });
            ReverseDnsQueryResponse yahooAddressDnsQueryResponse = new ReverseDnsQueryResponse(false, string.Empty, new List <string>()
            {
                yahooIp1
            });

            A.CallTo(() => _dnsResolver.QueryPtrAsync(A <IPAddress> ._)).Returns(ptrDnsQueryResponse);
            A.CallTo(() => _dnsResolver.QueryAddressAsync <ARecord>(googleHostName, QueryType.A)).Returns(googleAddressDnsQueryResponse);
            A.CallTo(() => _dnsResolver.QueryAddressAsync <AaaaRecord>(googleHostName, QueryType.AAAA)).Returns(googleAddressDnsQueryResponse);
            A.CallTo(() => _dnsResolver.QueryAddressAsync <ARecord>(yahooHostName, QueryType.A)).Returns(yahooAddressDnsQueryResponse);
            A.CallTo(() => _dnsResolver.QueryAddressAsync <AaaaRecord>(yahooHostName, QueryType.AAAA)).Returns(yahooAddressDnsQueryResponse);

            var reverseDnsLookup = new ReverseDnsLookup(_dnsResolver, _log);

            ReverseDnsResult reverseDnsResult = await reverseDnsLookup.Lookup(ipAddress);

            Assert.That(_log.Errors.Count, Is.EqualTo(0));
            Assert.That(_log.Warnings.Count, Is.EqualTo(0));

            Assert.That(reverseDnsResult.ForwardResponses.Count, Is.EqualTo(2));
            Assert.That(reverseDnsResult.ForwardResponses[0].Host, Is.EqualTo(googleHostName));
            Assert.That(reverseDnsResult.ForwardResponses[0].IpAddresses.Count, Is.EqualTo(2));
            Assert.That(reverseDnsResult.ForwardResponses[0].IpAddresses[0], Is.EqualTo(googleIp1));
            Assert.That(reverseDnsResult.ForwardResponses[0].IpAddresses[1], Is.EqualTo(googleIp2));
            Assert.That(reverseDnsResult.ForwardResponses[1].Host, Is.EqualTo(yahooHostName));
            Assert.That(reverseDnsResult.ForwardResponses[1].IpAddresses.Count, Is.EqualTo(1));
            Assert.That(reverseDnsResult.ForwardResponses[1].IpAddresses[0], Is.EqualTo(yahooIp1));
        }
        public async Task ItShouldLogErrorWhenValidPtrButFailsOnForwardLookup(string ipAddress)
        {
            ReverseDnsQueryResponse ptrDnsQueryResponse = new ReverseDnsQueryResponse(false, string.Empty, new List <string>()
            {
                "google.com"
            });
            ReverseDnsQueryResponse addressDnsQueryResponse = new ReverseDnsQueryResponse(true, "Something has gone wrong!", null);

            A.CallTo(() => _dnsResolver.QueryPtrAsync(A <IPAddress> ._)).Returns(ptrDnsQueryResponse);
            A.CallTo(() => _dnsResolver.QueryAddressAsync <ARecord>(A <string> ._, QueryType.A)).Returns(addressDnsQueryResponse);
            A.CallTo(() => _dnsResolver.QueryAddressAsync <AaaaRecord>(A <string> ._, QueryType.AAAA)).Returns(addressDnsQueryResponse);

            var reverseDnsLookup = new ReverseDnsLookup(_dnsResolver, _log);

            ReverseDnsResult reverseDnsResult = await reverseDnsLookup.Lookup(ipAddress);

            Assert.That(_log.Warnings.Count, Is.EqualTo(1));
            Assert.That(reverseDnsResult.ForwardResponses.Count, Is.EqualTo(0));
        }
        private async Task <List <(DateTime, ReverseDnsResult)> > GetExistingReverseDnsResults(Stopwatch stopwatch)
        {
            Console.WriteLine($"Querying all reverse dns results");

            List <(DateTime, ReverseDnsResult)> results = new List <(DateTime, ReverseDnsResult)>();
            double tally = 0;

            using (DbDataReader reader = await MySqlHelper.ExecuteReaderAsync(Environment.GetEnvironmentVariable("ReverseDnsConnectionString"), "SELECT * FROM reverse_lookup_results"))
            {
                while (await reader.ReadAsync())
                {
                    ReverseDnsResponse data = JsonConvert.DeserializeObject <List <ReverseDnsResponse> >(reader.GetString("data")).FirstOrDefault();

                    List <ReverseDnsResponse> reverseDnsResponses = null;
                    if (data != null)
                    {
                        List <string> ipAddresses          = data.IpAddresses;
                        string        host                 = data.Host;
                        string        organisationalDomain = data.OrganisationalDomain;

                        reverseDnsResponses = new List <ReverseDnsResponse>
                        {
                            new ReverseDnsResponse(host, ipAddresses, organisationalDomain)
                        };
                    }

                    DateTime date = reader.GetDateTime("date");
                    string   originalIpAddress = reader.GetString("ip_address");

                    ReverseDnsResult reverseDnsResult = new ReverseDnsResult(originalIpAddress, reverseDnsResponses);
                    results.Add((date, reverseDnsResult));

                    tally++;
                    double percentDone = tally / 4500000d;
                    Console.Write($"\rLoaded {tally} = {percentDone:P2}% after {stopwatch.Elapsed.Minutes} mins {stopwatch.Elapsed.Seconds} secs");
                }
            }

            Console.WriteLine($"\nFinished querying all results");

            return(results);
        }
        public async Task ItShouldOnlyProcessValidLookupsAndNotStopWhenInvalid(string ipAddress)
        {
            string googleHostName = "google.com";
            string googleIp1      = "192.168.0.1";
            string yahooHostName  = "yahoo.com";

            ReverseDnsQueryResponse ptrDnsQueryResponse = new ReverseDnsQueryResponse(false, string.Empty, new List <string>()
            {
                googleHostName, yahooHostName
            });
            ReverseDnsQueryResponse host1AddressDnsQueryResponse = new ReverseDnsQueryResponse(false, string.Empty, new List <string>()
            {
                googleIp1
            });
            ReverseDnsQueryResponse host2AaddressDnsQueryResponse = new ReverseDnsQueryResponse(true, "Something has gone wrong!", null);

            A.CallTo(() => _dnsResolver.QueryPtrAsync(A <IPAddress> ._)).Returns(ptrDnsQueryResponse);

            //setup for only host1
            A.CallTo(() => _dnsResolver.QueryAddressAsync <ARecord>(googleHostName, QueryType.A)).Returns(host1AddressDnsQueryResponse);
            A.CallTo(() => _dnsResolver.QueryAddressAsync <AaaaRecord>(googleHostName, QueryType.AAAA)).Returns(host1AddressDnsQueryResponse);

            //setup for only host1
            A.CallTo(() => _dnsResolver.QueryAddressAsync <ARecord>(yahooHostName, QueryType.A)).Returns(host2AaddressDnsQueryResponse);
            A.CallTo(() => _dnsResolver.QueryAddressAsync <AaaaRecord>(yahooHostName, QueryType.AAAA)).Returns(host2AaddressDnsQueryResponse);

            var reverseDnsLookup = new ReverseDnsLookup(_dnsResolver, _log);

            ReverseDnsResult reverseDnsResults = await reverseDnsLookup.Lookup(ipAddress);

            Assert.That(_log.Warnings.Count, Is.EqualTo(1));

            Assert.That(reverseDnsResults.ForwardResponses.Count, Is.EqualTo(1));
            Assert.That(reverseDnsResults.ForwardResponses[0].Host, Is.EqualTo(googleHostName));
            Assert.That(reverseDnsResults.ForwardResponses[0].IpAddresses.Count, Is.EqualTo(1));
            Assert.That(reverseDnsResults.ForwardResponses[0].IpAddresses[0], Is.EqualTo(googleIp1));
        }
        public async Task Handle(ReverseDnsBackfillBatch message)
        {
            Stopwatch stopwatch = Stopwatch.StartNew();

            _log.LogInformation($"Received batch of {message.IpsToBackfill?.Count ?? 0} reverse dns entries to backfill with reverseDns lookups");

            if (message.IpsToBackfill == null || message.IpsToBackfill.Count == 0)
            {
                return;
            }

            foreach (string ipAddress in message.IpsToBackfill)
            {
                DateTime         now = DateTime.UtcNow;
                ReverseDnsResult currentReverseDnsResult = await Lookup(ipAddress);

                List <IpAddressDetails> entries = await _ipAddressAddressDetailsDao.GetIpAddressDetails(ipAddress);

                List <IpAddressDetails> entriesWithReverseDns    = entries.Where(x => x.ReverseDnsResponses != null).ToList();
                List <IpAddressDetails> entriesWithoutReverseDns = entries.Where(x => x.ReverseDnsResponses == null).ToList();

                List <IpAddressDetailsUpdateDto> entriesToUpdate = new List <IpAddressDetailsUpdateDto>();

                foreach (IpAddressDetails existingEntry in entriesWithoutReverseDns)
                {
                    if (entriesWithReverseDns.Any())
                    {
                        IpAddressDetails nearestNeighbour = entriesWithReverseDns.OrderBy(x => Math.Abs(x.Date.Ticks - existingEntry.Date.Ticks)).First();

                        long timeBetweenEntryAndNow = Math.Abs(now.Ticks - existingEntry.Date.Ticks);
                        long timeBetweenEntryAndNearestNeighbour = Math.Abs(nearestNeighbour.Date.Ticks - existingEntry.Date.Ticks);

                        if (timeBetweenEntryAndNearestNeighbour < timeBetweenEntryAndNow)
                        {
                            IpAddressDetailsUpdateDto entryToUpdate = new IpAddressDetailsUpdateDto(
                                existingEntry.IpAddress,
                                existingEntry.Date,
                                nearestNeighbour.ReverseDnsResponses,
                                nearestNeighbour.ReverseDnsLookupTimestamp);

                            entriesToUpdate.Add(entryToUpdate);
                        }
                        else
                        {
                            IpAddressDetailsUpdateDto entryToUpdate = new IpAddressDetailsUpdateDto(
                                existingEntry.IpAddress,
                                existingEntry.Date,
                                currentReverseDnsResult.ForwardResponses,
                                now);

                            entriesToUpdate.Add(entryToUpdate);
                        }
                    }
                    else
                    {
                        IpAddressDetailsUpdateDto entryToUpdate = new IpAddressDetailsUpdateDto(
                            existingEntry.IpAddress,
                            existingEntry.Date,
                            currentReverseDnsResult.ForwardResponses,
                            now);

                        entriesToUpdate.Add(entryToUpdate);
                    }
                }

                await _ipAddressAddressDetailsDao.UpdateReverseDns(entriesToUpdate);
            }

            _log.LogInformation(
                $"Processed batch of {message.IpsToBackfill?.Count} reverse dns entries in {stopwatch.ElapsedMilliseconds} ms");
        }