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); }
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("(-)"); }
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); } }
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; }
/// <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() } }); }
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)); }
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)); }
/// <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("(-)"); }
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)); }
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)}"); } }
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); }
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); }
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); }
// 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); } }