From 0d21e92711cebf70c85e62ccd53ca4c269365c0d Mon Sep 17 00:00:00 2001 From: Shreyas Zare Date: Sun, 18 Jul 2021 15:34:17 +0530 Subject: [PATCH] SplitHorizonApp: updated app to v1.3 to support custom networks specified by their CIDR network address. --- Apps/SplitHorizonApp/SimpleAddress.cs | 37 +++++++++++++---- Apps/SplitHorizonApp/SimpleCNAME.cs | 44 +++++++++++++++------ Apps/SplitHorizonApp/SplitHorizonApp.csproj | 2 +- 3 files changed, 62 insertions(+), 21 deletions(-) diff --git a/Apps/SplitHorizonApp/SimpleAddress.cs b/Apps/SplitHorizonApp/SimpleAddress.cs index 56339c4b..2349a98b 100644 --- a/Apps/SplitHorizonApp/SimpleAddress.cs +++ b/Apps/SplitHorizonApp/SimpleAddress.cs @@ -57,15 +57,33 @@ namespace SplitHorizon case DnsResourceRecordType.A: case DnsResourceRecordType.AAAA: dynamic jsonAppRecordData = JsonConvert.DeserializeObject(appRecordData); - dynamic jsonAddresses; + dynamic jsonAddresses = null; - if (NetUtilities.IsPrivateIP(remoteEP.Address)) - jsonAddresses = jsonAppRecordData.@private; - else - jsonAddresses = jsonAppRecordData.@public; + foreach (dynamic jsonProperty in jsonAppRecordData) + { + string name = jsonProperty.Name; - if (jsonAddresses == null) - return Task.FromResult(null); + if ((name == "public") || (name == "private")) + continue; + + NetworkAddress networkAddress = NetworkAddress.Parse(name); + if (networkAddress.Contains(remoteEP.Address)) + { + jsonAddresses = jsonProperty.Value; + break; + } + } + + if (jsonAddresses is null) + { + if (NetUtilities.IsPrivateIP(remoteEP.Address)) + jsonAddresses = jsonAppRecordData.@private; + else + jsonAddresses = jsonAppRecordData.@public; + + if (jsonAddresses is null) + return Task.FromResult(null); + } List answers = new List(); @@ -110,7 +128,7 @@ namespace SplitHorizon #region properties public string Description - { get { return "Returns A or AAAA records with different set of IP addresses for clients querying over public and private networks."; } } + { get { return "Returns A or AAAA records with different set of IP addresses for clients querying over public, private, or other specified networks."; } } public string ApplicationRecordDataTemplate { @@ -124,6 +142,9 @@ namespace SplitHorizon ""private"": [ ""192.168.1.1"", ""::1"" + ], + ""10.0.0.0/8"": [ + ""10.1.1.1"" ] }"; } diff --git a/Apps/SplitHorizonApp/SimpleCNAME.cs b/Apps/SplitHorizonApp/SimpleCNAME.cs index 0b6e1cd3..20c30781 100644 --- a/Apps/SplitHorizonApp/SimpleCNAME.cs +++ b/Apps/SplitHorizonApp/SimpleCNAME.cs @@ -51,26 +51,45 @@ namespace SplitHorizon public Task ProcessRequestAsync(DnsDatagram request, IPEndPoint remoteEP, string zoneName, uint appRecordTtl, string appRecordData, bool isRecursionAllowed, IDnsServer dnsServer) { dynamic jsonAppRecordData = JsonConvert.DeserializeObject(appRecordData); - dynamic jsonCname; + dynamic jsonCname = null; - if (NetUtilities.IsPrivateIP(remoteEP.Address)) - jsonCname = jsonAppRecordData.@private; - else - jsonCname = jsonAppRecordData.@public; + foreach (dynamic jsonProperty in jsonAppRecordData) + { + string name = jsonProperty.Name; - if (jsonCname == null) - return Task.FromResult(null); + if ((name == "public") || (name == "private")) + continue; + + NetworkAddress networkAddress = NetworkAddress.Parse(name); + if (networkAddress.Contains(remoteEP.Address)) + { + jsonCname = jsonProperty.Value; + break; + } + } + + if (jsonCname is null) + { + if (NetUtilities.IsPrivateIP(remoteEP.Address)) + jsonCname = jsonAppRecordData.@private; + else + jsonCname = jsonAppRecordData.@public; + + if (jsonCname is null) + return Task.FromResult(null); + } string cname = jsonCname.Value; if (string.IsNullOrEmpty(cname)) return Task.FromResult(null); + DnsQuestionRecord question = request.Question[0]; IReadOnlyList answers; - if (request.Question[0].Name.Equals(zoneName, StringComparison.OrdinalIgnoreCase)) //check for zone apex - answers = new DnsResourceRecord[] { new DnsResourceRecord(request.Question[0].Name, DnsResourceRecordType.ANAME, DnsClass.IN, appRecordTtl, new DnsANAMERecord(cname)) }; //use ANAME + if (question.Name.Equals(zoneName, StringComparison.OrdinalIgnoreCase)) //check for zone apex + answers = new DnsResourceRecord[] { new DnsResourceRecord(question.Name, DnsResourceRecordType.ANAME, DnsClass.IN, appRecordTtl, new DnsANAMERecord(cname)) }; //use ANAME else - answers = new DnsResourceRecord[] { new DnsResourceRecord(request.Question[0].Name, DnsResourceRecordType.CNAME, DnsClass.IN, appRecordTtl, new DnsCNAMERecord(cname)) }; + answers = new DnsResourceRecord[] { new DnsResourceRecord(question.Name, DnsResourceRecordType.CNAME, DnsClass.IN, appRecordTtl, new DnsCNAMERecord(cname)) }; return Task.FromResult(new DnsDatagram(request.Identifier, true, request.OPCODE, true, false, request.RecursionDesired, isRecursionAllowed, false, false, DnsResponseCode.NoError, request.Question, answers)); } @@ -80,7 +99,7 @@ namespace SplitHorizon #region properties public string Description - { get { return "Returns different CNAME record for clients querying over public and private networks. Note that the app will return ANAME record for an APP record at zone apex."; } } + { get { return "Returns different CNAME record for clients querying over public, private, or other specified networks. Note that the app will return ANAME record for an APP record at zone apex."; } } public string ApplicationRecordDataTemplate { @@ -88,7 +107,8 @@ namespace SplitHorizon { return @"{ ""public"": ""api.example.com"", - ""private"": ""api.example.corp"" + ""private"": ""api.example.corp"", + ""10.0.0.0/8"": ""api.intranet.example.corp"" }"; } } diff --git a/Apps/SplitHorizonApp/SplitHorizonApp.csproj b/Apps/SplitHorizonApp/SplitHorizonApp.csproj index d53f4630..eb99bbfa 100644 --- a/Apps/SplitHorizonApp/SplitHorizonApp.csproj +++ b/Apps/SplitHorizonApp/SplitHorizonApp.csproj @@ -4,7 +4,7 @@ net5.0 false true - 1.2 + 1.3 Technitium Technitium DNS Server Shreyas Zare