Странный сбой при некоторых подключениях к Интернету для ответов rdap с использованием httpClient, но не через почтальона.

Я пытаюсь написать приложение, которое позволит любому пользователю, находящемуся в любой точке мира, получить ответ rdap для соответствующего доменного имени для любого доменного имени на основе официального списка серверов rdap здесь: https://data.iana.org/rdap/dns.json , используя собственное локальное подключение к Интернету.

Однако происходит что-то странное. При использовании моего локального подключения к Интернету (на данный момент расположенного в Юго-Восточной Азии) следующий запрос для google.com (на соответствующем сервере rdap для .com, то есть https://rdap.verisign.com/com/v1/) потерпит неудачу примерно в 80% случаев:

      open System.Net.Http

let httpClient = new HttpClient()
let resp = httpClient.GetAsync($"https://rdap.verisign.com/com/v1/domain/google.com").Result
resp

Вот полученная ошибка:

      System.AggregateException: One or more errors occurred. (The SSL connection could not be established, see inner exception.)
 ---> System.Net.Http.HttpRequestException: The SSL connection could not be established, see inner exception.
 ---> System.IO.IOException: Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host..
 ---> System.Net.Sockets.SocketException (10054): An existing connection was forcibly closed by the remote host.
   --- End of inner exception stack trace ---
   at System.Net.Sockets.Socket.AwaitableSocketAsyncEventArgs.ThrowException(SocketError error, CancellationToken cancellationToken)
   at System.Net.Sockets.Socket.AwaitableSocketAsyncEventArgs.System.Threading.Tasks.Sources.IValueTaskSource<System.Int32>.GetResult(Int16 token)
   at System.Net.Security.SslStream.EnsureFullTlsFrameAsync[TIOAdapter](CancellationToken cancellationToken)
   at System.Runtime.CompilerServices.PoolingAsyncValueTaskMethodBuilder`1.StateMachineBox`1.System.Threading.Tasks.Sources.IValueTaskSource<TResult>.GetResult(Int16 token)
   at System.Net.Security.SslStream.ReceiveBlobAsync[TIOAdapter](CancellationToken cancellationToken)
   at System.Net.Security.SslStream.ForceAuthenticationAsync[TIOAdapter](Boolean receiveFirst, Byte[] reAuthenticationData, CancellationToken cancellationToken)
   at System.Net.Http.ConnectHelper.EstablishSslConnectionAsync(SslClientAuthenticationOptions sslOptions, HttpRequestMessage request, Boolean async, Stream stream, CancellationToken cancellationToken)
   --- End of inner exception stack trace ---
   at System.Net.Http.ConnectHelper.EstablishSslConnectionAsync(SslClientAuthenticationOptions sslOptions, HttpRequestMessage request, Boolean async, Stream stream, CancellationToken cancellationToken)
   at System.Net.Http.HttpConnectionPool.ConnectAsync(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)
   at System.Net.Http.HttpConnectionPool.CreateHttp11ConnectionAsync(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)
   at System.Net.Http.HttpConnectionPool.AddHttp11ConnectionAsync(QueueItem queueItem)
   at System.Threading.Tasks.TaskCompletionSourceWithCancellation`1.WaitWithCancellationAsync(CancellationToken cancellationToken)
   at System.Net.Http.HttpConnectionPool.HttpConnectionWaiter`1.WaitForConnectionAsync(Boolean async, CancellationToken requestCancellationToken)
   at System.Net.Http.HttpConnectionPool.SendWithVersionDetectionAndRetryAsync(HttpRequestMessage request, Boolean async, Boolean doRequestAuth, CancellationToken cancellationToken)
   at System.Net.Http.DiagnosticsHandler.SendAsyncCore(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)
   at System.Net.Http.RedirectHandler.SendAsync(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)
   at System.Net.Http.HttpClient.<SendAsync>g__Core|83_0(HttpRequestMessage request, HttpCompletionOption completionOption, CancellationTokenSource cts, Boolean disposeCts, CancellationTokenSource pendingRequestsCts, CancellationToken originalCancellationToken)
   --- End of inner exception stack trace ---
   at System.Threading.Tasks.Task.ThrowIfExceptional(Boolean includeTaskCanceledExceptions)
   at System.Threading.Tasks.Task`1.GetResultCore(Boolean waitCompletionNotification)
   at FSI_0138.makeRequestWithHeaders(String url)
   at <StartupCode$FSI_0138>.$FSI_0138.main@()
   at System.RuntimeMethodHandle.InvokeMethod(Object target, Void** arguments, Signature sig, Boolean isConstructor)
   at System.Reflection.MethodInvoker.Invoke(Object obj, IntPtr* args, BindingFlags invokeAttr)
   at System.Threading.Tasks.Task.ThrowIfExceptional(Boolean includeTaskCanceledExceptions)
   at System.Threading.Tasks.Task`1.GetResultCore(Boolean waitCompletionNotification)
   at FSI_0138.makeRequestWithHeaders(String url)
   at <StartupCode$FSI_0138>.$FSI_0138.main@()
   at System.RuntimeMethodHandle.InvokeMethod(Object target, Void** arguments, Signature sig, Boolean isConstructor)
   at System.Reflection.MethodInvoker.Invoke(Object obj, IntPtr* args, BindingFlags invokeAttr)

В этом нет ничего интересного, можно легко объяснить проблемами с местным интернет-провайдером, верно?

Однако в почтальоне запрос работает в 100% случаев. Например:

Это никогда не терпит неудачу. Интересный!

Поэтому я подумал о перехвате пакетов в Wireshark. Ниже показано взаимодействие F# с использованием httpClient (мой реальный IP-адрес заменен на «myip»):

      95  2.307971    myip    rdap-1.verisigndns.com  TCP 86  4   63296 → 443 [SYN] Seq=0 Win=64952 Len=0 MSS=1412 WS=256 SACK_PERM=1
106 2.550129    rdap-1.verisigndns.com  myip    TCP 78  4   443 → 63296 [SYN, ACK] Seq=0 Ack=1 Win=1240 Len=0 MSS=1240
107 2.550336    myip    rdap-1.verisigndns.com  TCP 74  4   63296 → 443 [ACK] Seq=1 Ack=1 Win=64952 Len=0
108 2.550804    myip    rdap-1.verisigndns.com  TLSv1.2  253 4   Client Hello
118 3.112553    myip    rdap-1.verisigndns.com  TCP 253 4   [TCP Retransmission] 63296 → 443 [PSH, ACK] Seq=1 Ack=1 Win=64952 Len=179
134 3.832227    myip    rdap-1.verisigndns.com  TCP 253 4   [TCP Retransmission] 63296 → 443 [PSH, ACK] Seq=1 Ack=1 Win=64952 Len=179
159 5.264697    myip    rdap-1.verisigndns.com  TCP 253 4   [TCP Retransmission] 63296 → 443 [PSH, ACK] Seq=1 Ack=1 Win=64952 Len=179
215 7.797828    rdap-1.verisigndns.com  myip    TCP 74  4   443 → 63296 [RST, ACK] Seq=1 Ack=1 Win=24000 Len=0

Как можно видеть, сервер rdap, похоже, игнорирует запросы моих клиентов после успешного установления связи.

Вот сетевой трафик внутри почтальона, который работает:

      19193  526.178083  myip  rdap.verisign.com  TCP  66  98  53194 → 443 [SYN] Seq=0 Win=64240 Len=0 MSS=1460 WS=256 SACK_PERM=1
19199  526.406075  rdap.verisign.com  myip  TCP  58  98  443 → 53194 [SYN, ACK] Seq=0 Ack=1 Win=1480 Len=0 MSS=1412
19200  526.406368  myip  rdap.verisign.com  TCP  54  98  53194 → 443 [ACK] Seq=1 Ack=1 Win=64240 Len=0
19201  526.407322  myip  rdap.verisign.com  TLSv1.3  571  98  Client Hello
19208  526.638776  rdap.verisign.com  myip  TLSv1.3  1454  98  Server Hello, Change Cipher Spec, Application Data
19209  526.639594  rdap.verisign.com  myip  TCP  1454  98  443 → 53194 [ACK] Seq=1401 Ack=518 Win=28944 Len=1400 [TCP segment of a reassembled PDU]
19210  526.639648  myip  rdap.verisign.com  TCP  54  98  53194 → 443 [ACK] Seq=518 Ack=2801 Win=64952 Len=0
19211  526.640264  rdap.verisign.com  myip  TLSv1.3  1003  98  Application Data, Application Data, Application Data
19212  526.641121  myip  rdap.verisign.com  TLSv1.3  368  98  Change Cipher Spec, Application Data, Application Data
19213  526.645057  rdap.verisign.com  myip  TCP  54  98  443 → 53194 [ACK] Seq=1 Ack=518 Win=28944 Len=0
19214  526.645082  myip  rdap.verisign.com  TCP  54  98  [TCP Dup ACK 19212#1] 53194 → 443 [ACK] Seq=832 Ack=3750 Win=64003 Len=0
19219  526.868863  rdap.verisign.com  myip  TLSv1.3  293  98  Application Data
19220  526.870003  rdap.verisign.com  myip  TLSv1.3  1454  98  Application Data
19221  526.870305  myip  rdap.verisign.com  TCP  54  98  53194 → 443 [ACK] Seq=832 Ack=5389 Win=64952 Len=0
19222  526.870775  rdap.verisign.com  myip  TCP  1454  98  443 → 53194 [ACK] Seq=5389 Ack=832 Win=30016 Len=1400 [TCP segment of a reassembled PDU]
19223  526.871672  rdap.verisign.com  myip  TLSv1.3  127  98  Application Data
19224  526.871895  myip  rdap.verisign.com  TCP  54  98  53194 → 443 [ACK] Seq=832 Ack=6863 Win=64952 Len=0
19225  526.878734  myip  rdap.verisign.com  TCP  54  98  [TCP Previous segment not captured] 53194 → 443 [FIN, ACK] Seq=856 Ack=6863 Win=64952 Len=0
19226  526.878795  myip  rdap.verisign.com  TCP  78  98  [TCP Out-Of-Order] 53194 → 443 [PSH, ACK] Seq=832 Ack=6863 Win=64952 Len=24
19231  527.125064  rdap.verisign.com  myip  TCP  60  98  [TCP Dup ACK 19219#1] 443 → 53194 [ACK] Seq=6863 Ack=832 Win=300

Поэтому я подумал, что, возможно, по какой-то причине сервер rdap отклоняет трафик от .NET httpClient, но не от почтальона (хотя это, конечно, не имело бы смысла, поскольку служба rdap должна ожидать, что большинство ее запросов поступит из автоматического источника). , а не ручные запросы почтальона). Я попытался вручную настроить заголовки для репликации почтальона в .NET:

      open System.Net.Http
open System.Net.Http.Headers

let makeRequestWithHeaders (url: string) =
    let httpClient = new HttpClient()
    // Add headers similar to what Postman sends
    httpClient.DefaultRequestHeaders.UserAgent.ParseAdd("PostmanRuntime/7.26.10")
    httpClient.DefaultRequestHeaders.Accept.ParseAdd("application/json")
    httpClient.DefaultRequestHeaders.CacheControl <- CacheControlHeaderValue.Parse("no-cache")

    let response = httpClient.GetAsync(url).Result
    response

let url = "https://rdap.verisign.com/com/v1/domain/google.com"
let resp = makeRequestWithHeaders url
resp

Однако ничего не изменилось (по-прежнему лишь ~20% успеха).

А вот здесь все становится очень странно. Я подключился к VPN-серверу в США (через NordVPN), и теперь код .NET работает 100% времени без каких-либо сбоев (и, конечно же, почтальон тоже работает).

Но если я подключаюсь к некоторым региональным VPN-серверам, возникают аналогичные проблемы, но для разных серверов RDAP! Например, при подключении к Аргентинской VPN через NordVPN https://rdap.verisign.com/com/v1/domain/google.com работает нормально, однако официальный rdap-сервер, например, для .limo не работает ( https ://rdap.identitydigital.services/rdap/ ). Ниже приведен пример ошибочного кода .NET:

      open System.Net.Http

let httpClient = new HttpClient()
let resp = httpClient.GetAsync($"https://rdap.identitydigital.services/rdap/domain/virginia.limo/").Result
resp

(не удается только на VPN-сервере Nord в Аргентине, а не на каком-либо другом сервере или при моем локальном подключении к Интернету).

Итак, я сделал следующие наблюдения относительно официальных серверов RDAP:

  1. Мое локальное подключение к Интернету может нормально запрашивать домены .limo как в .NET, так и в Postman, но только в доменах .com из Postman (а не в .NET).
  2. Сервер NordVPN в Аргентине может нормально запрашивать домены .com как в .NET, так и в Postman, но только в доменах .limo из Postman (а не в .NET).
  3. Сервер NordVPN в США может нормально запрашивать все расширения/домены, не сталкиваясь ни с одним сбоем, как в .NET, так и в Postman.

Эта запутанная серия фактов исключает множество правдоподобных причин, таких как проблемы с httpClient, протоколом SSL и т. д., потому что, если бы это было что-то из этого, то, конечно же, оно всегда должно давать сбой, и переключение на другой IP-адрес и геолокацию не должно Найди решение?

Итак, некоторые RDAP-серверы по какой-то причине отклоняют запросы из определенных географических местоположений иногда, если они приходят от httpClient, но никогда, если они приходят от почтальона? И почему это не одни и те же серверы RDAP, например: официальный сервер .com нормально принимает трафик Аргентины, но иногда отклоняет мой локальный IP-адрес, в то время как официальный rdap-сервер .limo принимает мой локальный трафик нормально, но иногда отклоняет трафик Аргентины.

Это очень сбивает с толку, и мне нужны отзывы о том, в чем здесь может быть проблема? Если это действительно ошибка различных RDAP-серверов и каких-то странных политик, которые они имеют, то я могу списать это на то, что это находится вне моего контроля, но я хотел бы убедиться, что это действительно так, прежде чем делать такой вывод.

Предостережения:

  1. Это не имеет ничего общего с вызовом .Result в GetAsync, который отлично подходит для иллюстрации.
  2. И мое локальное соединение, и аргентинский сервер nordVPN могут прекрасно запрашивать веб-сайты напрямую (как из .NET, так и из почтальона), проблема возникает только при взаимодействии с официальными серверами rdap.

Обновление (19 ноября 2023 г.) – 2 дня спустя

Мое локальное подключение к Интернету сегодня работает нормально для всех запросов, как если бы оно было подключено к VPN NordVPN в США, однако VPN в Аргентине по-прежнему не работает на .limo.

Это все больше похоже на проблемы со сторонними сетями, но где, как и почему я не понимаю.

0 ответов

Другие вопросы по тегам