Alexandre
Alexandre

Reputation: 7212

arsoft.tools.net(DNS Server) Redirect traffic from one URL to another (DNS forwarding)

Following the documentation of arsoft.tools.net on https://docs.ar-soft.de/arsoft.tools.net/, we just developed a dns server to intercept every request from the network, everything is working fine!

The thing that is slowing us down is: When the client types www.google.com (for example), we want to show or redirect to www.yahoo.com(or an IP address), any clue of how can we achieve that?

There is some people looking for the same solution here: https://arsofttoolsnet.codeplex.com/discussions?searchText=redirect

Tks

UPDATE 1:

So far, this is what I have, but, redirecting is not working:

class Program
{
    static void Main(string[] args)
    {
        using (DnsServer server = new DnsServer(System.Net.IPAddress.Any, 10, 10))
        {
            server.QueryReceived += OnQueryReceived;

            server.Start();

            Console.WriteLine("Press any key to stop server");
            Console.ReadLine();
        }
    }

    static async Task OnQueryReceived(object sender, QueryReceivedEventArgs e)
    {
        DnsMessage query = e.Query as DnsMessage;

        if (query == null)
            return;

        DnsMessage response = query.CreateResponseInstance();
        //response.AnswerRecords.Clear();
        //response.AdditionalRecords.Clear();

        if ((response.Questions.Count == 1))
        {
            // send query to upstream server
            DnsQuestion question = response.Questions[0];

            if (question.Name.ToString().Contains("www.google.com"))
            {
                DnsMessage upstreamResponse = await DnsClient.Default.ResolveAsync(DomainName.Parse("www.yahoo.com"), question.RecordType, question.RecordClass);
                //DnsMessage upstreamResponse = await DnsClient.Default.ResolveAsync(question.Name, question.RecordType, question.RecordClass);

                foreach (DnsRecordBase record in (upstreamResponse.AnswerRecords))
                {
                    response.AnswerRecords.Add(record);
                }
                foreach (DnsRecordBase record in (upstreamResponse.AdditionalRecords))
                {
                    response.AdditionalRecords.Add(record);
                }

                response.ReturnCode = ReturnCode.NoError;
                e.Response = response;
            }
        }
    }
}

Upvotes: 4

Views: 1676

Answers (1)

Alexandre
Alexandre

Reputation: 7212

After some time, here is how to do:

class Program
{
    static void Main(string[] args)
    {
        using (DnsServer server = new DnsServer(System.Net.IPAddress.Any, 10, 10))
        {
            server.QueryReceived += OnQueryReceived;

            server.Start();

            Console.WriteLine("Press any key to stop server");
            Console.ReadLine();
        }
    }

    static async Task OnQueryReceived(object sender, QueryReceivedEventArgs e)
    {
        DnsMessage query = e.Query as DnsMessage;

        if (query == null)
            return;

        DnsMessage response = query.CreateResponseInstance();
        DnsQuestion question = response.Questions[0];
        DnsMessage upstreamResponse = await DnsClient.Default.ResolveAsync(!question.Name.ToString().Contains("www.google.com") ? question.Name : DomainName.Parse("www.yahoo.com"), question.RecordType, question.RecordClass);

        foreach (DnsRecordBase record in upstreamResponse.AnswerRecords)
        {
            response.AnswerRecords.Add(record);
        }
        foreach (DnsRecordBase record in (upstreamResponse.AdditionalRecords))
        {
            response.AdditionalRecords.Add(record);
        }

        response.ReturnCode = ReturnCode.NoError;
        e.Response = response;
    }
}

If you want to point to some ip address:

static async Task OnQueryReceived(object sender, QueryReceivedEventArgs e)
        {
            DnsMessage query = e.Query as DnsMessage;
            if (query == null) return;
            DnsMessage response = query.CreateResponseInstance();

            if (response.Questions.Any())
            {
                DnsQuestion question = response.Questions[0];
                DnsMessage upstreamResponse = await DnsClient.Default.ResolveAsync(question.Name, question.RecordType, question.RecordClass);

                response.AdditionalRecords.AddRange(upstreamResponse.AdditionalRecords);
                response.ReturnCode = ReturnCode.NoError;

                if (!question.Name.ToString().Contains("yourdomain.com"))
                {
                    response.AnswerRecords.AddRange(upstreamResponse.AnswerRecords);
                }
                else
                {
                    response.AnswerRecords.AddRange(
                        upstreamResponse.AnswerRecords
                            .Where(w => !(w is ARecord))
                            .Concat(
                                upstreamResponse.AnswerRecords
                                    .OfType<ARecord>()
                                    .Select(a => new ARecord(a.Name, a.TimeToLive, IPAddress.Parse("192.168.0.199"))) // some local ip address
                            )
                    );
                }

                e.Response = response;
            }
        }

Upvotes: 3

Related Questions