AdvancedBlockingApp: updated implementation to disable cname cloaking when a domain is allowed. Added support for extended dns error for blocking report.

This commit is contained in:
Shreyas Zare
2023-02-12 12:01:47 +05:30
parent 2fb02674ca
commit 0c9aab4adb

View File

@@ -33,6 +33,7 @@ using System.Threading.Tasks;
using TechnitiumLibrary; using TechnitiumLibrary;
using TechnitiumLibrary.Net; using TechnitiumLibrary.Net;
using TechnitiumLibrary.Net.Dns; using TechnitiumLibrary.Net.Dns;
using TechnitiumLibrary.Net.Dns.EDnsOptions;
using TechnitiumLibrary.Net.Dns.ResourceRecords; using TechnitiumLibrary.Net.Dns.ResourceRecords;
namespace AdvancedBlocking namespace AdvancedBlocking
@@ -418,10 +419,10 @@ namespace AdvancedBlocking
return Task.CompletedTask; return Task.CompletedTask;
} }
public Task<DnsDatagram> ProcessRequestAsync(DnsDatagram request, IPEndPoint remoteEP, DnsTransportProtocol protocol, bool isRecursionAllowed) public async Task<DnsDatagram> ProcessRequestAsync(DnsDatagram request, IPEndPoint remoteEP, DnsTransportProtocol protocol, bool isRecursionAllowed)
{ {
if (!_enableBlocking) if (!_enableBlocking)
return Task.FromResult<DnsDatagram>(null); return null;
IPAddress remoteIP = remoteEP.Address; IPAddress remoteIP = remoteEP.Address;
NetworkAddress network = null; NetworkAddress network = null;
@@ -437,37 +438,63 @@ namespace AdvancedBlocking
} }
if ((groupName is null) || !_groups.TryGetValue(groupName, out Group group) || !group.EnableBlocking) if ((groupName is null) || !_groups.TryGetValue(groupName, out Group group) || !group.EnableBlocking)
return Task.FromResult<DnsDatagram>(null); return null;
DnsQuestionRecord question = request.Question[0]; DnsQuestionRecord question = request.Question[0];
if (!group.IsZoneBlocked(question.Name, out string blockedDomain, out string blockedRegex, out Uri blockListUrl)) if (!group.IsZoneBlocked(question.Name, out bool allowed, out string blockedDomain, out string blockedRegex, out Uri blockListUrl))
return Task.FromResult<DnsDatagram>(null);
if (group.AllowTxtBlockingReport && (question.Type == DnsResourceRecordType.TXT))
{ {
//return meta data if (allowed)
DnsResourceRecord[] answer; {
DnsDatagram internalResponse = await _dnsServer.DirectQueryAsync(question);
return new DnsDatagram(request.Identifier, true, DnsOpcode.StandardQuery, internalResponse.AuthoritativeAnswer, internalResponse.Truncation, request.RecursionDesired, internalResponse.RecursionAvailable, internalResponse.AuthenticData, internalResponse.CheckingDisabled, internalResponse.RCODE, request.Question, internalResponse.Answer, internalResponse.Authority, internalResponse.Additional) { Tag = internalResponse.Tag };
}
return null;
}
string GetBlockingReport()
{
string blockingReport = "source=advanced-blocking-app; group=" + group.Name;
if (blockedRegex is null) if (blockedRegex is null)
{ {
if (blockListUrl is not null) if (blockListUrl is not null)
answer = new DnsResourceRecord[] { new DnsResourceRecord(question.Name, DnsResourceRecordType.TXT, question.Class, 60, new DnsTXTRecordData("source=advanced-blocking-app; group=" + group.Name + "; blockListUrl=" + blockListUrl.AbsoluteUri + "; domain=" + blockedDomain)) }; blockingReport += "; blockListUrl=" + blockListUrl.AbsoluteUri + "; domain=" + blockedDomain;
else else
answer = new DnsResourceRecord[] { new DnsResourceRecord(question.Name, DnsResourceRecordType.TXT, question.Class, 60, new DnsTXTRecordData("source=advanced-blocking-app; group=" + group.Name + "; domain=" + blockedDomain)) }; blockingReport += "; domain=" + blockedDomain;
} }
else else
{ {
if (blockListUrl is not null) if (blockListUrl is not null)
answer = new DnsResourceRecord[] { new DnsResourceRecord(question.Name, DnsResourceRecordType.TXT, question.Class, 60, new DnsTXTRecordData("source=advanced-blocking-app; group=" + group.Name + "; regexBlockListUrl=" + blockListUrl.AbsoluteUri + "; regex=" + blockedRegex)) }; blockingReport += "; regexBlockListUrl=" + blockListUrl.AbsoluteUri + "; regex=" + blockedRegex;
else else
answer = new DnsResourceRecord[] { new DnsResourceRecord(question.Name, DnsResourceRecordType.TXT, question.Class, 60, new DnsTXTRecordData("source=advanced-blocking-app; group=" + group.Name + "; regex=" + blockedRegex)) }; blockingReport += "; regex=" + blockedRegex;
} }
return Task.FromResult(new DnsDatagram(request.Identifier, true, DnsOpcode.StandardQuery, false, false, request.RecursionDesired, isRecursionAllowed, false, false, DnsResponseCode.NoError, request.Question, answer) { Tag = DnsServerResponseType.Blocked }); return blockingReport;
}
if (group.AllowTxtBlockingReport && (question.Type == DnsResourceRecordType.TXT))
{
//return meta data
string blockingReport = GetBlockingReport();
DnsResourceRecord[] answer = new DnsResourceRecord[] { new DnsResourceRecord(question.Name, DnsResourceRecordType.TXT, question.Class, 60, new DnsTXTRecordData(blockingReport)) };
return new DnsDatagram(request.Identifier, true, DnsOpcode.StandardQuery, false, false, request.RecursionDesired, false, false, false, DnsResponseCode.NoError, request.Question, answer) { Tag = DnsServerResponseType.Blocked };
} }
else else
{ {
EDnsOption[] options = null;
if (group.AllowTxtBlockingReport && (request.EDNS is not null))
{
string blockingReport = GetBlockingReport();
options = new EDnsOption[] { new EDnsOption(EDnsOptionCode.EXTENDED_DNS_ERROR, new EDnsExtendedDnsErrorOptionData(EDnsExtendedDnsErrorCode.Blocked, blockingReport)) };
}
DnsResponseCode rcode; DnsResponseCode rcode;
IReadOnlyList<DnsResourceRecord> answer = null; IReadOnlyList<DnsResourceRecord> answer = null;
IReadOnlyList<DnsResourceRecord> authority = null; IReadOnlyList<DnsResourceRecord> authority = null;
@@ -540,7 +567,7 @@ namespace AdvancedBlocking
} }
} }
return Task.FromResult(new DnsDatagram(request.Identifier, true, DnsOpcode.StandardQuery, false, false, request.RecursionDesired, isRecursionAllowed, false, false, rcode, request.Question, answer, authority) { Tag = DnsServerResponseType.Blocked }); return new DnsDatagram(request.Identifier, true, DnsOpcode.StandardQuery, false, false, request.RecursionDesired, false, false, false, rcode, request.Question, answer, authority, null, request.EDNS is null ? ushort.MinValue : _dnsServer.UdpPayloadSize, EDnsHeaderFlags.None, options) { Tag = DnsServerResponseType.Blocked };
} }
} }
@@ -727,7 +754,7 @@ namespace AdvancedBlocking
} }
} }
public bool IsZoneBlocked(string domain, out string blockedDomain, out string blockedRegex, out Uri listUrl) public bool IsZoneBlocked(string domain, out bool allowed, out string blockedDomain, out string blockedRegex, out Uri listUrl)
{ {
domain = domain.ToLower(); domain = domain.ToLower();
@@ -735,6 +762,7 @@ namespace AdvancedBlocking
if (IsZoneFound(_allowed, domain, out _) || IsZoneFound(_allowListZones, domain, out _, out _) || IsMatchFound(_allowedRegex, domain, out _) || IsMatchFound(_regexAllowListZones, domain, out _, out _) || IsZoneAllowed(_adBlockListZones, domain, out _, out _)) if (IsZoneFound(_allowed, domain, out _) || IsZoneFound(_allowListZones, domain, out _, out _) || IsMatchFound(_allowedRegex, domain, out _) || IsMatchFound(_regexAllowListZones, domain, out _, out _) || IsZoneAllowed(_adBlockListZones, domain, out _, out _))
{ {
//found zone allowed //found zone allowed
allowed = true;
blockedDomain = null; blockedDomain = null;
blockedRegex = null; blockedRegex = null;
listUrl = null; listUrl = null;
@@ -745,6 +773,7 @@ namespace AdvancedBlocking
if (IsZoneFound(_blocked, domain, out string foundZone1)) if (IsZoneFound(_blocked, domain, out string foundZone1))
{ {
//found zone blocked //found zone blocked
allowed = false;
blockedDomain = foundZone1; blockedDomain = foundZone1;
blockedRegex = null; blockedRegex = null;
listUrl = null; listUrl = null;
@@ -755,6 +784,7 @@ namespace AdvancedBlocking
if (IsZoneFound(_blockListZones, domain, out string foundZone2, out Uri blockListUrl1)) if (IsZoneFound(_blockListZones, domain, out string foundZone2, out Uri blockListUrl1))
{ {
//found zone blocked //found zone blocked
allowed = false;
blockedDomain = foundZone2; blockedDomain = foundZone2;
blockedRegex = null; blockedRegex = null;
listUrl = blockListUrl1; listUrl = blockListUrl1;
@@ -765,6 +795,7 @@ namespace AdvancedBlocking
if (IsMatchFound(_blockedRegex, domain, out string blockedPattern1)) if (IsMatchFound(_blockedRegex, domain, out string blockedPattern1))
{ {
//found pattern blocked //found pattern blocked
allowed = false;
blockedDomain = null; blockedDomain = null;
blockedRegex = blockedPattern1; blockedRegex = blockedPattern1;
listUrl = null; listUrl = null;
@@ -775,6 +806,7 @@ namespace AdvancedBlocking
if (IsMatchFound(_regexBlockListZones, domain, out string blockedPattern2, out Uri blockListUrl2)) if (IsMatchFound(_regexBlockListZones, domain, out string blockedPattern2, out Uri blockListUrl2))
{ {
//found pattern blocked //found pattern blocked
allowed = false;
blockedDomain = null; blockedDomain = null;
blockedRegex = blockedPattern2; blockedRegex = blockedPattern2;
listUrl = blockListUrl2; listUrl = blockListUrl2;
@@ -785,12 +817,14 @@ namespace AdvancedBlocking
if (App.IsZoneBlocked(_adBlockListZones, domain, out string foundZone3, out Uri blockListUrl3)) if (App.IsZoneBlocked(_adBlockListZones, domain, out string foundZone3, out Uri blockListUrl3))
{ {
//found zone blocked //found zone blocked
allowed = false;
blockedDomain = foundZone3; blockedDomain = foundZone3;
blockedRegex = null; blockedRegex = null;
listUrl = blockListUrl3; listUrl = blockListUrl3;
return true; return true;
} }
allowed = false;
blockedDomain = null; blockedDomain = null;
blockedRegex = null; blockedRegex = null;
listUrl = null; listUrl = null;