Exemplo n.º 1
0
        private static IPAddressResourceRecord ConvertIpAddressResourceRecord(string[] l)
        {
            var ip = new IPAddressResourceRecord(new Domain(l[1]), new IPAddress(long.Parse(l[0])), TimeSpan.Parse(l[3]));

            ip.Type = (RecordType)int.Parse(l[2]);
            return(ip);
        }
Exemplo n.º 2
0
        public void WhenSave_AndMasterListContainsIPAddressResourceRecord_AndIsIPv6_ThenEntryIsSaved()
        {
            // Arrange
            var domain = new Domain("stratis.test.com");

            var testResourceRecord = new IPAddressResourceRecord(domain, IPAddress.Parse("2001:db8:85a3:0:0:8a2e:370:7334"));
            var masterFile         = new DnsSeedMasterFile(new List <IResourceRecord> {
                testResourceRecord
            });

            using (var stream = new MemoryStream())
            {
                // Act.
                masterFile.Save(stream);

                // Assert.
                stream.Should().NotBeNull();
                IList <IResourceRecord> resourceRecords = this.ReadResourceRecords(stream);

                resourceRecords.Should().NotBeNull();
                resourceRecords.Should().NotBeNullOrEmpty();

                IList <IPAddressResourceRecord> ipAddressResourceRecords = resourceRecords.OfType <IPAddressResourceRecord>().ToList();
                ipAddressResourceRecords.Should().HaveCount(1);
                ipAddressResourceRecords[0].Name.ToString().Should().Be(domain.ToString());
                ipAddressResourceRecords[0].IPAddress.Equals(testResourceRecord.IPAddress);
            }
        }
        /// <summary>
        /// Refreshes the managed whitelist.
        /// </summary>
        public void RefreshWhitelist()
        {
            this.logger.LogTrace("()");

            DateTimeOffset activePeerLimit = this.dateTimeProvider.GetTimeOffset().AddSeconds(-this.dnsPeerBlacklistThresholdInSeconds);

            var whitelist = this.peerAddressManager.Peers.Where(p => p.Value.LastConnectionHandshake > activePeerLimit).Select(p => p.Value);

            if (!this.fullNodeMode)
            {
                // Exclude the current external ip address from DNS as its not a full node.
                whitelist = whitelist.Where(p => !p.NetworkAddress.Endpoint.Match(this.externalEndpoint));
            }

            IMasterFile masterFile = new DnsSeedMasterFile();

            foreach (PeerAddress whitelistEntry in whitelist)
            {
                Domain domain = new Domain(this.dnsHostName);

                IPAddressResourceRecord resourceRecord = new IPAddressResourceRecord(domain, whitelistEntry.NetworkAddress.Endpoint.Address);
                masterFile.Add(resourceRecord);
            }

            this.dnsServer.SwapMasterfile(masterFile);

            this.logger.LogTrace("(-)");
        }
Exemplo n.º 4
0
        public void WhenSave_AndMasterListContainsIPAddressResourceRecord_AndIsIPv4_ThenEntryIsSaved()
        {
            // Arrange
            Domain domain = new Domain("xels.test.com");

            IPAddressResourceRecord testResourceRecord = new IPAddressResourceRecord(domain, IPAddress.Parse("192.168.0.1"));
            DnsSeedMasterFile       masterFile         = new DnsSeedMasterFile();

            masterFile.Add(testResourceRecord);

            using (MemoryStream stream = new MemoryStream())
            {
                // Act.
                masterFile.Save(stream);

                // Assert.
                stream.Should().NotBeNull();
                IList <IResourceRecord> resourceRecords = this.ReadResourceRecords(stream);

                resourceRecords.Should().NotBeNull();
                resourceRecords.Should().NotBeNullOrEmpty();

                IList <IPAddressResourceRecord> ipAddressResourceRecords = resourceRecords.OfType <IPAddressResourceRecord>().ToList();
                ipAddressResourceRecords.Should().HaveCount(1);
                ipAddressResourceRecords[0].Name.ToString().Should().Be(domain.ToString());
                ipAddressResourceRecords[0].IPAddress.Equals(testResourceRecord.IPAddress);
            }
        }
Exemplo n.º 5
0
        private void ConfigureService()
        {
            _masterFile = new MasterFile();
            var soaoptions = new StartOfAuthorityResourceRecord.Options()
            {
                SerialNumber      = GenerateSerialNumber(),
                RefreshInterval   = new TimeSpan(0, 0, _options.Value.RefreshInterval),
                RetryInterval     = new TimeSpan(0, 0, _options.Value.RetryInterval),
                ExpireInterval    = new TimeSpan(0, 0, _options.Value.ExpireInterval),
                MinimumTimeToLive = new TimeSpan(0, 0, _options.Value.MinTTL)
            };
            var domain = new Domain(_options.Value.Domain);
            var soa    = new StartOfAuthorityResourceRecord(
                domain, domain, domain, soaoptions, new TimeSpan(0, 0, _options.Value.TTL));

            _masterFile.Add(soa);
            var record = new IPAddressResourceRecord(
                new Domain(GetRecordFqdn()), IPAddress.Parse(_options.Value.TargetNormal), new TimeSpan(0, 0, _options.Value.RecordTtl));

            _masterFile.Add(record);
            _server            = new DnsServer(_masterFile, _options.Value.Forwarder);
            _server.Listening += ServerListening;
            _server.Responded += ServerResponded;
            _server.Errored   += ServerErrored;
        }
Exemplo n.º 6
0
 /// <summary>
 /// Writes a <see cref="IPAddressResourceRecord"/> to JSON.
 /// </summary>
 /// <param name="resourceRecord">The <see cref="IPAddressResourceRecord"/> to write.</param>
 /// <returns>The written JSON.</returns>
 private JObject WriteIPAddressResourceRecordJson(IPAddressResourceRecord resourceRecord)
 {
     return(new JObject
     {
         { TypeFieldName, resourceRecord.GetType().Name },
         { IPAddressFieldName, resourceRecord.IPAddress.ToString() },
         { NameFieldName, resourceRecord.Name.ToString() }
     });
 }
Exemplo n.º 7
0
            public Task <IResponse> Resolve(IRequest request, CancellationToken cancellationToken = default(CancellationToken))
            {
                IResponse       response = Response.FromRequest(request);
                IResourceRecord record   = new IPAddressResourceRecord(
                    new Domain("google.com"),
                    IPAddress.Parse("192.168.0.1"));

                response.AnswerRecords.Add(record);
                return(Task.FromResult(response));
            }
Exemplo n.º 8
0
            public Task<IResponse> Resolve(IRequest request) {
                IResponse response = Response.FromRequest(request);
                IResourceRecord record = new IPAddressResourceRecord(
                    new Domain("google.com"),
                    IPAddress.Parse("192.168.0.1"));

                response.AnswerRecords.Add(record);

                return Task.FromResult(response);
            }
        public Task <IResponse> Resolve(IRequest request)
        {
            IResponse response = Response.FromRequest(request);

            response.AuthorativeServer = true;

            foreach (Question question in response.Questions)
            {
                if (question.Type == RecordType.A)
                {
                    string requestDomain = question.Name.ToString().ToLower();
                    string emailDomain   = GetEmailDomain(requestDomain);

                    RequestReceived?.Invoke(this, new RequestEventArgs(response.Id, requestDomain, emailDomain));

                    if (emailDomain != null)
                    {
                        var(isValid, ttl) = GetEmailDomainState(emailDomain);

                        if (isValid)
                        {
                            var soaRecord = new StartOfAuthorityResourceRecord(_dnsServerDomain, _dnsServerDomain, _responsiblePersonDomain, _serial,
                                                                               TimeSpan.FromDays(2), TimeSpan.FromDays(1), TimeSpan.FromDays(30), ttl, TimeSpan.FromDays(14));

                            response.AuthorityRecords.Add(soaRecord);
                            response.ResponseCode = ResponseCode.NameError;

                            ResponseSent?.Invoke(this, new ResponseEventArgs(response.Id, requestDomain, emailDomain, ResponseResult.Valid, ttl));
                        }
                        else
                        {
                            var record = new IPAddressResourceRecord(question.Name, s_loopbackIpAddress, ttl);
                            response.AnswerRecords.Add(record);

                            ResponseSent?.Invoke(this, new ResponseEventArgs(response.Id, requestDomain, emailDomain, ResponseResult.Invalid, ttl));
                        }
                    }
                    else
                    {
                        // Invalid domain name request, cache for 1000 days
                        var ttl       = TimeSpan.FromDays(1000);
                        var soaRecord = new StartOfAuthorityResourceRecord(question.Name, _dnsServerDomain, _responsiblePersonDomain, _serial,
                                                                           TimeSpan.FromDays(2), TimeSpan.FromDays(1), TimeSpan.FromDays(30), ttl, ttl);

                        response.AuthorityRecords.Add(soaRecord);
                        response.ResponseCode = ResponseCode.FormatError;

                        ResponseSent?.Invoke(this, new ResponseEventArgs(response.Id, requestDomain, emailDomain, ResponseResult.Error, ttl));
                    }
                }
            }

            return(Task.FromResult(response));
        }
Exemplo n.º 10
0
        /// <summary>
        /// Refreshes the managed whitelist.
        /// </summary>
        public void RefreshWhitelist()
        {
            this.logger.LogTrace("()");

            this.dnsPeerBlacklistThresholdInSeconds = this.dnsSettings.DnsPeerBlacklistThresholdInSeconds;
            this.dnsHostName  = this.dnsSettings.DnsHostName;
            this.fullNodeMode = this.dnsSettings.DnsFullNode;

            DateTimeOffset activePeerLimit = this.dateTimeProvider.GetTimeOffset().AddSeconds(-this.dnsPeerBlacklistThresholdInSeconds);

            IEnumerable <PeerAddress> whitelist = this.peerAddressManager.Peers.Where(p => p.LastSeen > activePeerLimit);

            if (!this.fullNodeMode)
            {
                // Exclude the current external ip address from DNS as its not a full node.
                whitelist = whitelist.Where(p => !p.Endpoint.Match(this.externalEndpoint));
            }

            IMasterFile masterFile = new DnsSeedMasterFile();

            foreach (PeerAddress whitelistEntry in whitelist)
            {
                if (this.peerBanning.IsBanned(whitelistEntry.Endpoint))
                {
                    this.logger.LogDebug("{0}:{1} is banned, therefore removing from masterfile.", whitelistEntry.Endpoint.Address, whitelistEntry.Endpoint.Port);
                    continue;
                }

                var domain = new Domain(this.dnsHostName);

                // Is this an IPv4 embedded address? If it is, make sure an 'A' record is added to the DNS master file, rather than an 'AAAA' record.
                if (whitelistEntry.Endpoint.Address.IsIPv4MappedToIPv6)
                {
                    IPAddress ipv4Address    = whitelistEntry.Endpoint.Address.MapToIPv4();
                    var       resourceRecord = new IPAddressResourceRecord(domain, ipv4Address);
                    masterFile.Add(resourceRecord);
                }
                else
                {
                    var resourceRecord = new IPAddressResourceRecord(domain, whitelistEntry.Endpoint.Address);
                    masterFile.Add(resourceRecord);
                }
            }

            this.dnsServer.SwapMasterfile(masterFile);

            this.logger.LogTrace("(-)");
        }
Exemplo n.º 11
0
        public Task <IResponse> Resolve(IRequest request)
        {
            IResponse response = Response.FromRequest(request);

            var question = request.Questions.FirstOrDefault(x => x.Name.ToString().Contains("playstation.net"));

            if (question == null)
            {
                return(Task.FromResult <IResponse>(new Response()));
            }

            IResourceRecord record = new IPAddressResourceRecord(question.Name, IPAddress.Parse("192.168.0.254"));

            response.AnswerRecords.Add(record);
            return(Task.FromResult(response));
        }
Exemplo n.º 12
0
        private void LogResponse(IResponse response)
        {
            _logger.LogInformation($"Response: Id:{response.Id}, Query: {response.Questions.Count()}, Answers: {response.AnswerRecords.Count()}, Authority: {response.AuthorityRecords.Count()}, Additional: {response.AdditionalRecords.Count()}.");

            foreach (var question in response.Questions)
            {
                _logger.LogInformation($"  Question: {question.Name}\t{question.Type}");
            }

            foreach (var auth in response.AuthorityRecords)
            {
                if (auth is StartOfAuthorityResourceRecord record)
                {
                    _logger.LogInformation($"  SOA: {record.Name}\t{record.Type}\t{record.MasterDomainName}\t{record.ResponsibleDomainName}");
                }
            }

            foreach (var record in response.AnswerRecords)
            {
                switch (record.Type)
                {
                case RecordType.A:
                case RecordType.AAAA:
                    IPAddressResourceRecord rec = (IPAddressResourceRecord)record;
                    _logger.LogInformation($"  Answer: {record.Name}\t{record.Type}\t{rec.IPAddress}");
                    break;

                case RecordType.NS:
                    NameServerResourceRecord nsrec = (NameServerResourceRecord)record;
                    _logger.LogInformation($"  Answer: {record.Name}\t{record.Type}\t{nsrec.NSDomainName}");
                    break;

                default:
                    _logger.LogInformation($"  Answer: {record.Name}\t{record.Type}\t{Encoding.UTF8.GetString(record.Data)}");
                    break;
                }
            }

            foreach (var record in response.AdditionalRecords)
            {
                _logger.LogInformation($"  Additional: {record.Name}\t{record.Type}\t{Encoding.UTF8.GetString(record.Data)}");
            }
        }
Exemplo n.º 13
0
        public void WhenLoad_AndStreamContainsIPAddressResourceRecord_AndIsIPv6_ThenEntryIsPopulated()
        {
            // Arrange
            var domain = new Domain("stratis.test.com");

            var testResourceRecord = new IPAddressResourceRecord(domain, IPAddress.Parse("2001:db8:85a3:0:0:8a2e:370:7334"));
            var question           = new Question(domain, RecordType.AAAA);

            // Act.
            IList <IResourceRecord> resourceRecords = this.WhenLoad_AndStreamContainsEntry_ThenEntryIsPopulated(testResourceRecord, question);

            // Assert.
            resourceRecords.Should().NotBeNull();
            resourceRecords.Should().NotBeNullOrEmpty();

            IList <IPAddressResourceRecord> ipAddressResourceRecords = resourceRecords.OfType <IPAddressResourceRecord>().ToList();

            ipAddressResourceRecords.Should().HaveCount(1);
            ipAddressResourceRecords[0].Name.ToString().Should().Be(domain.ToString());
            ipAddressResourceRecords[0].IPAddress.Equals(testResourceRecord.IPAddress);
        }
Exemplo n.º 14
0
        public void WhenLoad_AndStreamContainsIPAddressResourceRecord_AndIsIPv4_ThenEntryIsPopulated()
        {
            // Arrange
            Domain domain = new Domain("xels.test.com");

            IPAddressResourceRecord testResourceRecord = new IPAddressResourceRecord(domain, IPAddress.Parse("192.168.0.1"));
            Question question = new Question(domain, RecordType.A);

            // Act.
            IList <IResourceRecord> resourceRecords = this.WhenLoad_AndStreamContainsEntry_ThenEntryIsPopulated(testResourceRecord, question);

            // Assert.
            resourceRecords.Should().NotBeNull();
            resourceRecords.Should().NotBeNullOrEmpty();

            IList <IPAddressResourceRecord> ipAddressResourceRecords = resourceRecords.OfType <IPAddressResourceRecord>().ToList();

            ipAddressResourceRecords.Should().HaveCount(1);
            ipAddressResourceRecords[0].Name.ToString().Should().Be(domain.ToString());
            ipAddressResourceRecords[0].IPAddress.Equals(testResourceRecord.IPAddress);
        }
Exemplo n.º 15
0
        protected virtual async Task <IResponse> ResolveLocal(Request request)
        {
            Response response = Response.FromRequest(request);

            foreach (Question question in request.Questions)
            {
                IList <IResourceRecord> answers = masterFile.Get(question);

                if (answers.Count > 0)
                {
                    Merge(response.AnswerRecords, answers);
                }
                else
                {
                    if (!LocalOnly)
                    {
                        return(await ResolveRemote(request));
                    }
                    else if (RedirectUnknownToLocal && question.Type == RecordType.A)
                    {
                        IPAddress answerIP;
                        IPAddress.TryParse(LocalIP, out answerIP);

                        if (answerIP != null)
                        {
                            IList <IResourceRecord> entries      = new List <IResourceRecord>();
                            IResourceRecord         fakeResponse = new IPAddressResourceRecord(request.Questions[0].Name, answerIP);
                            entries.Add(fakeResponse);
                            Merge(response.AnswerRecords, entries);
                        }
                    }
                }
            }

            return(response);
        }
Exemplo n.º 16
0
        // A request resolver that resolves all dns queries to localhost
        public async Task <IResponse> Resolve(IRequest request, CancellationToken cancellationToken = default)
        {
            try
            {
                IResponse response = Response.FromRequest(request);

                foreach (Question question in response.Questions)
                {
                    if (question.Type == RecordType.SOA || question.Type == RecordType.NS)
                    {
                        var record = new StartOfAuthorityResourceRecord(question.Name, _nsDomains[0], _email,
                                                                        _timeStamp, _ttl, _ttl, _ttl, _ttl, _ttl);
                        response.AuthorityRecords.Add(record);

                        if (question.Type == RecordType.NS)
                        {
                            foreach (var t in _nsDomains)
                            {
                                response.AnswerRecords.Add(new NameServerResourceRecord(question.Name, t, _ttl));
                            }
                        }
                    }

                    if (question.Type == RecordType.TXT)
                    {
                        if (!string.IsNullOrEmpty(_txtUrl))
                        {
                            var httpClient = _clientFactory.CreateClient();
                            // var requestMessage = new HttpRequestMessage(HttpMethod.Get, _txtUrl);
                            var txtResponse = await httpClient.GetAsync(_txtUrl, cancellationToken);

                            List <KeyValue> txtValues = null;
                            if (txtResponse.IsSuccessStatusCode)
                            {
                                // var jsonString = await txtResponse.Content.ReadAsStringAsync();
                                txtValues = await JsonSerializer.DeserializeAsync <List <KeyValue> >(await txtResponse.Content.ReadAsStreamAsync(), cancellationToken : cancellationToken);
                            }

                            if (txtValues != null)
                            {
                                foreach (var keyValue in txtValues)
                                {
                                    if (question.Name.ToString().ToLower().EndsWith(keyValue.key))
                                    {
                                        IList <CharacterString> characterStrings = new List <CharacterString> {
                                            new CharacterString(keyValue.value)
                                        };
                                        response.AnswerRecords.Add(new TextResourceRecord(question.Name, characterStrings, _ttl));
                                    }
                                    else
                                    {
                                        response.AnswerRecords.Add(new TextResourceRecord(question.Name, keyValue.key, keyValue.value, _ttl));
                                    }
                                }
                            }
                        }
                    }

                    var name = question.Name.ToString().ToLower().Split('.');

                    //check the base domain is the same.
                    if (name.Length >= _rootDomainComponents.Length && name
                        .Skip(name.Length - _rootDomainComponents.Length).SequenceEqual(_rootDomainComponents))
                    {
                        // match any static A records.
                        var key = string.Join('.', name.Take(name.Length - _rootDomainComponents.Length));
                        if (_ipAddressRecords.TryGetValue(key, out var ipAddress))
                        {
                            response.AnswerRecords.Add(new IPAddressResourceRecord(question.Name, ipAddress, _ttl));
                        }

                        // query the domain to determine ip.  Format 1-2-3-4.hash.dexih.com
                        var domain = question.Name.ToString().Split(".");
                        if (domain.Length == 4)
                        {
                            if (IPAddress.TryParse(domain[0].Replace('-', '.'), out var iPAddress))
                            {
                                var record = new IPAddressResourceRecord(question.Name, iPAddress, _ttl);
                                response.AnswerRecords.Add(record);
                            }
                        }
                    }
                }

                return(response);
            }
            catch (Exception e)
            {
                _logger?.LogError(e, $"The following error was encountered: {e.Message}.");
                var response = new Response {
                    ResponseCode = ResponseCode.NoError
                };
                return(response);
            }
        }