Страницы

Поиск по вопросам

пятница, 14 февраля 2020 г.

Сделать внутри программный аналог HOSTS

#c_sharp #net #dns #httpclient #hosts


Есть необходимость в программе работать с сайтом, чье имя удалено из DNS. Работаю
с помощью классов библиотеки System.Net, а именно HttpClient.
При этом сайт отвергает запросы, в которых вместо имени хоста подставлен IP адрес,
т.е. в запросе должно фигурировать именно имя хоста. 
Частичное решение моей проблемы - занесение нужной записи в файл Hosts, но мне нужно
обеспечить:


контроль за обращением к списку Ip адресов соответствующих имени  
работу в условиях отсутствия админских прав (т.е. невозможности редактировать hosts) 


Вопрос: каким образом сделать так, чтоб внутри программы ресолвинг определенных имен
перехватить и делать самому?
    


Ответы

Ответ 1



Имеется библиотека, которая позволяет создавать прокси DNS сервер в самом C# приложении, который может перехватывать все запросы и направлять их на нужные адреса. Здесь имеется пример создания прокси DNS сервера. Приведу пример использования библиотеки: class Program { static DnsServer _proxyServer; static string _testDomain = "my.blablablakons.com"; static string _redirectIp = "127.0.0.1"; static string _realDnsServer = "8.8.8.8"; static Task StartProxyServer() { // Proxy to google's DNS MasterFile masterFile = new MasterFile(); // Resolve these domain to localhost //masterFile.AddIPAddressResourceRecord("blablablakons.com", _redirectIp); masterFile.AddIPAddressResourceRecord(_testDomain, "127.0.0.1"); _proxyServer = new DnsServer(masterFile, _realDnsServer); // Log every request //_proxyServer.Requested += (request) => Console.WriteLine(request); _proxyServer.Responded += (request, response) => Console.WriteLine("{0} => {1}", request, response); //_proxyServer.Listening += () => Console.WriteLine("Listening started"); //_proxyServer.Errored += (e) => { // Console.WriteLine("Errored: {0}", e); // ResponseException responseError = e as ResponseException; // if (responseError != null) Console.WriteLine(responseError.Response); //}; // Start the server (by default it listents on port 53) return _proxyServer.Listen(); } static async void Do(object data) { CancellationToken token = (CancellationToken)data; HttpClient client = new HttpClient(); client.Timeout = new TimeSpan(0, 0, 5); while (!token.IsCancellationRequested) { try { HttpResponseMessage response = await client.GetAsync(new Uri($"http://{_testDomain}")); } catch(Exception ex) { Console.WriteLine(ex); } await Task.Delay(1000); } } static void Main(string[] args) { Task listenTask = StartProxyServer(); // Start thread for send requests CancellationTokenSource cs = new CancellationTokenSource(); Thread requestThr = new Thread(new ParameterizedThreadStart(Do)); requestThr.Start(cs.Token); Console.WriteLine("All started"); Console.ReadLine(); cs.Cancel(); requestThr.Join(); _proxyServer.Dispose(); listenTask.Wait(); } } Суть работы примера: 1. Создается proxy-сервер, который публикуется на localhost по порту 53(порт по-умолчанию). При создании DNS сервера, основным(реальным) dns-сервером указываем адрес _realDnsServer(8.8.8.8). Те DNS имена, которые не будут найдены в нашем прокси DNS сервере, будут отправляться на этот указанный dns сервер 2. Прописываем для прокси сервера правило резолва требуемого DNS имени(_testDomain = "my.blablabla.com") на некий ip-адрес(_redirectIp = "127.0.0.1"), куда вы хотите отправлять запросы 3. В настройках операционной системы добавляем адрес нашего публикуемого прокси сервера (для простоты, я в настройках сетевого адаптера оставил один DNS адрес 127.0.0.1) 4. Все запросы к нашему DNS серверу логгируем _proxyServer.Requested += (request) => Console.WriteLine(request); 5. Запускаем поток, который раз в 1 секунду с помощью класса HttpClient делает GET запросы по DNS имени my.blablablakons.com. Запускаем приложение. Попытаемся открыть какую-нибудь страницу в браузере. При открытии страницы в браузере видим, что запрос по получению IP адреса открываемой страницы был проксирован через наш опубликованный сервер. Попытаемся открыть страницу my.blablablakons.com. Видим отображение страницы, которую указали в резолве. Таким образом, вы можете гибко из своего приложения управлять, на какие ip-адреса должны уходить ваши запросы, делая запрос по DNS-имени.

Комментариев нет:

Отправить комментарий