Всем привет.
Имеем .Net приложение, которое подключается к серверу по локалке через HTTPS.
Имеем проблему на одной из инсталляций: установление соединения занимает три секунды.
Сто стороны сервера имеем self-signed сертификат (S1)
Со стороны клиента тоже имеем сертификат (S2).
Попытка потрассировать System.Net к особому успеху не привела.
Видим, что за, фактически, 0ms у нас происходит весь handshake с обменом сертификатами.
Потом — InitializeSecurityContext().
Следующая запись в логе уже на 3 секунды позже, и там собсно "вот сертификат, соединение установлено".
Следов того, чем System.Net занимается в эти три секунды, в логе нет.
Подключение к серверу браузером отрабатывает за 10-30ms (это без клиентского сертификата). То есть затык не на стороне сервера.
В чём тут может быть дело? Что ещё можно потрассировать?
Подключение идёт по IP адресу; subject сертификата, как видно из лога, произвольный (5c3d720e-2307-4573-9183-5ce5837e5bd5).
Здравствуйте, Sinclair, Вы писали:
S>Всем привет.
Надо еще тайминг трафика, чтобы понять — кто тупит.
По симптомам похоже на то, что кто-то долго проверяет статус сертификата (там CDP недоступных нет случаем?) certutil -URL <файл сертификата> тоже долго отрабатывает?
Здравствуйте, DOOM, Вы писали: DOO>Надо еще тайминг трафика, чтобы понять — кто тупит.
Так а у нас включен verbose для system.net.Sockets. Там весь трафик проходит до показанных записей лога. DOO>По симптомам похоже на то, что кто-то долго проверяет статус сертификата (там CDP недоступных нет случаем?) certutil -URL <файл сертификата> тоже долго отрабатывает?
Ща глянем. Глядеть надо на клиентский или на серверный сертификаты?
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Sinclair, Вы писали:
S>Здравствуйте, DOOM, Вы писали: DOO>>Надо еще тайминг трафика, чтобы понять — кто тупит. S>Так а у нас включен verbose для system.net.Sockets. Там весь трафик проходит до показанных записей лога.
Ну последний-то кто получил пакет и затупил? Клиент? Потом ведь все равно продолжается какой-то сетевой обмен.
DOO>>По симптомам похоже на то, что кто-то долго проверяет статус сертификата (там CDP недоступных нет случаем?) certutil -URL <файл сертификата> тоже долго отрабатывает? S>Ща глянем. Глядеть надо на клиентский или на серверный сертификаты?
Посмотри оба сертификата, но на той стороне, где задержка наблюдается.]
Кстати, еще показательнее будет certutil -f –urlfetch -verify [FilenameOfCertificate] — там должно быть визуально видно, где споткнется.
P.S. На клиентской винде certutil, скорее всего, надо будет поставить отдельно.
Здравствуйте, Sinclair, Вы писали:
S>Следующая запись в логе уже на 3 секунды позже, и там собсно "вот сертификат, соединение установлено". S>Следов того, чем System.Net занимается в эти три секунды, в логе нет.
Здравствуйте, Sinclair, Вы писали:
S>Следующая запись в логе уже на 3 секунды позже, и там собсно "вот сертификат, соединение установлено". S>Следов того, чем System.Net занимается в эти три секунды, в логе нет.
DOO>>>По симптомам похоже на то, что кто-то долго проверяет статус сертификата (там CDP недоступных нет случаем?) certutil -URL <файл сертификата> тоже долго отрабатывает? S>>Ща глянем. Глядеть надо на клиентский или на серверный сертификаты? DOO>Посмотри оба сертификата, но на той стороне, где задержка наблюдается.] DOO>Кстати, еще показательнее будет certutil -f –urlfetch -verify [FilenameOfCertificate] — там должно быть визуально видно, где споткнется.
Ничего не спотыкается, отрабатывает мгновенно.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Sinclair, Вы писали:
S>Ничего не спотыкается, отрабатывает мгновенно.
Ниже тебе еще накидали ссылок на отключение проверки статуса клиентского сертификата на IIS'е (например: https://blogs.msdn.microsoft.com/kaushal/2012/10/15/disable-client-certificate-revocation-crl-check-on-iis/) — попробуй это в отладочных целях.
Нутром чую, что проблема именно в проверке статуса — ибо это синхронная, долгая и невидимая пользователю процедура.
S>В чём тут может быть дело? Что ещё можно потрассировать?
Кроме уже упомянутого certificate revocation check (результат которого, строго говоря, должен кэшироваться), также может иметь место таймаут или ошибка при попытке reverse DNS lookup. Следует проверить и на клиенте, и на сервере, чтобы был правильно настроен DNS, и CN в сертификате имел то же доменное имя, которое возвращается при reverse DNS lookup.
Здравствуйте, DOOM, Вы писали: DOO>Ниже тебе еще накидали ссылок на отключение проверки статуса клиентского сертификата на IIS'е (например: https://blogs.msdn.microsoft.com/kaushal/2012/10/15/disable-client-certificate-revocation-crl-check-on-iis/) — попробуй это в отладочных целях.
Клиентский сертификат проверяется не на IIS, а на удалённой машинке — там Апач, Томкэт, и прочая жава/линукс.
DOO>Нутром чую, что проблема именно в проверке статуса — ибо это синхронная, долгая и невидимая пользователю процедура.
Пока что удалось сузить зону бермудскости путём запуска нашего веб-приложения из-под админа вместо pool identity.
Из этого я делаю вывод, что проблема — в каких-то особенностях конфигурации пульного юзера.
Скорее всего, там какие-нибудь proxy settings показывают в бубеня.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, SkyDance, Вы писали:
S>>В чём тут может быть дело? Что ещё можно потрассировать?
SD>Кроме уже упомянутого certificate revocation check (результат которого, строго говоря, должен кэшироваться), также может иметь место таймаут или ошибка при попытке reverse DNS lookup. Следует проверить и на клиенте, и на сервере, чтобы был правильно настроен DNS, и CN в сертификате имел то же доменное имя, которое возвращается при reverse DNS lookup.
Ну, вот у нас CN сделан GUID-ным, потому что выписывается он автоматически, и в момент генерации ни IP ни hostname для коммуникации неизвестен.
Коммуникация идёт по внутренним IP, поэтому reverse DNS lookup не работает.
Кстати, откуда он может взяться?
я ни разу не видел, чтобы https инфраструктура занималась ерундой типа "а давайте-ка проверим, какое имя сайта мы найдём для https://192.186.50.173/". Вроде бы в таких случаях для фен-шуя надо сертификат выписывать на CN=192.186.50.173, нет?
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Sinclair, Вы писали:
DOO>>Нутром чую, что проблема именно в проверке статуса — ибо это синхронная, долгая и невидимая пользователю процедура. S>Пока что удалось сузить зону бермудскости путём запуска нашего веб-приложения из-под админа вместо pool identity. S>Из этого я делаю вывод, что проблема — в каких-то особенностях конфигурации пульного юзера. S>Скорее всего, там какие-нибудь proxy settings показывают в бубеня.
Запусти от имени юзера pool identity (IWAM_*, ЕМНИП) консоль и точно также попробуй вызвать verify.
Здравствуйте, DOOM, Вы писали: DOO>Запусти от имени юзера pool identity (IWAM_*, ЕМНИП) консоль и точно также попробуй вызвать verify.
Стесняюсь спросить — а как "запустить консоль" от имени виртуального пользователя? Он же сгенерирован IIS-ом, и его пароль никто не знает.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Sinclair, Вы писали:
S>Стесняюсь спросить — а как "запустить консоль" от имени виртуального пользователя? Он же сгенерирован IIS-ом, и его пароль никто не знает.
Мда... Как-то все сильно поменяли в 7-м иисе...
Гуглинг показывает, что наиболее простой способ — написать web-приложение, которое запустит консоль...
Здравствуйте, DOOM, Вы писали: DOO>Гуглинг показывает, что наиболее простой способ — написать web-приложение, которое запустит консоль...
Ага. Ещё осталось научить его показывать консоль интерактивному пользователю, причём через терминал (сервер стоит где-то то ли в Италии то ли в Испании).
А без интерактивности у нас приложение уже есть — как раз то, которое мы отлаживаем.
Пока что проверили пересоздание пула с нуля, в надежде, что тот пользователь просто скопировал какие-то устаревшие настройки. Не помогло.
Есть ещё идея создать пользователя вручную и включить его в нужную группу — всё-таки гонять приложение под админом как-то стрёмно.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Sinclair, Вы писали:
S>Здравствуйте, DOOM, Вы писали: DOO>>Гуглинг показывает, что наиболее простой способ — написать web-приложение, которое запустит консоль... S>Ага. Ещё осталось научить его показывать консоль интерактивному пользователю, причём через терминал (сервер стоит где-то то ли в Италии то ли в Испании).
Что-то явно у тебя со взломом web-серверов не очень
Установи на сервер утилиту NetCat (она идет в составе дистрибутива nmap: https://nmap.org/download.html, но всю жизнь это был самодостаточный экзешник, который просто копируется на нужную машину и работает).
Заставь web приложение выполнить команду: ncat -lv <любой незанятый номер порта> -e cmd.exe — насколько я понимаю, это самое сложное из-за настроек безопасности 7-го ииса (и выше).
Теперь ты можешь хоть телнетом, хоть тем же неткатом прицепиться на сервер, на указанный тобой порт и попасть в cmd.exe, запущенное от имени нужного пользователя.
Если у тебя на сервер есть доступ по RDP, то лучше открыть порт неткат по адресу 127.0.0.1 (команда будет ncat -lv 127.0.0.1 <номер порта> -e cmd.exe) и цепляться из консольного сеанса (это лучше, так как доступ вообще без какой-либо защиты — ни паролей, ни шифрования).
S>Есть ещё идея создать пользователя вручную и включить его в нужную группу — всё-таки гонять приложение под админом как-то стрёмно.
Тоже вариант.
Здравствуйте, DOOM, Вы писали: DOO>Что-то явно у тебя со взломом web-серверов не очень
Да тут как всегда всё упирается в то, что между мной и ответственными за машину ребятками 5 границ зон ответственности: DOO>Установи на сервер утилиту NetCat (она идет в составе дистрибутива nmap: https://nmap.org/download.html, но всю жизнь это был самодостаточный экзешник, который просто копируется на нужную машину и работает).
1. Установка (в том числе и копированием) на сервер заказчика софта требует approval, который занимает от 1 до 6 недель. DOO>Заставь web приложение выполнить команду: ncat -lv <любой незанятый номер порта> -e cmd.exe — насколько я понимаю, это самое сложное из-за настроек безопасности 7-го ииса (и выше).
2. Это нам нужно собрать кастомный билд нашего приложения, и попросить разрешения развернуть его на production сервере. Тут approval workflow гораздо быстрее, т.к. речь идёт о новой версии, а не о новом софте, так что можно уложится за 1-2 недели.
2.1. К счастью, насколько я помню, у нас там full trust, так что по крайней мере есть шанс стартовать процесс. Нам там давно уже копают мозг на тему "а зачем вам такой траст левел", и когда выкопают — это тоже будет no-no. DOO>Теперь ты можешь хоть телнетом, хоть тем же неткатом прицепиться на сервер, на указанный тобой порт и попасть в cmd.exe, запущенное от имени нужного пользователя.
3. Если нас спалят на том, что предложенный "фикс" открывает канал доступа, то будет эскалация эпической силы. Невзирая на технические детали — you must have had approved it with our security team first. DOO>Если у тебя на сервер есть доступ по RDP, то лучше открыть порт неткат по адресу 127.0.0.1 (команда будет ncat -lv 127.0.0.1 <номер порта> -e cmd.exe) и цепляться из консольного сеанса (это лучше, так как доступ вообще без какой-либо защиты — ни паролей, ни шифрования).
4. Да, такой вариант может прокатить, но он требует согласования с security team нас и клиента. Т.е. от 3х до 6 недель. И результат не гарантирован — позиция security team состоит в "нас никогда не наказывают за запреты, в отличие от разрешений", поэтому они в сомнительных случаях предпочитают сразу же отказать, чем разбираться и потенциально огребать результаты инцидента. S>>Есть ещё идея создать пользователя вручную и включить его в нужную группу — всё-таки гонять приложение под админом как-то стрёмно. DOO>Тоже вариант.
Ну вот по-хорошему это всё вообще не наша работа. Проблема наблюдается локально, и должна решаться службой эксплуатации. В жизни, к сожалению, оказывается, что все эти "сертифицированные админы" даже близко к решению проблемы подойти не могут. Зато могут катать на нас жалобы типа "приложение партнёра адски тормозит, потому что его авторы — криворукие уроды".
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Sinclair, Вы писали:
S>1. S>2. S>2.1. S>3. S>4.
Ну еще вариант при таком уровне ответственности и при этом обязательств по саппорту — это согласовать выделение разработческого ландшафта, где будет крутиться копия продуктива открытая для любых изменений
Но сие вопрос уже не технический, чем мог — помог.
Здравствуйте, DOOM, Вы писали: DOO>Но сие вопрос уже не технический, чем мог — помог.
Спасибо за поддержку!
staging у нас тоже есть. Проблема в том, что на нём не воспроизводится!
Вообще, вся вот эта вот около-crypto инфраструктура в винде адски переусложнена. Её сломать можно миллионом способов, и потом ни диагностировать, ни починить невозможно.
В прошлый раз чуть ли не у тех же клиентов не взлетала авторизация в Microsoft Cloud. Уже и так, и эдак — вводим username и пароль, уже заведомо корректные — ан нет, отлуп. Причём с другой машинки всё работало.
Я тогда нашёл способ потрассировать процесс авторизации в Microsoft Office Sign-In Assistant (это, между нами, упес пипиндур.)
И выяснилось, что в винде есть способ назначить разные сеттинги прокси для браузеров и для небраузеров. Угу. Ума не приложу, для чего всё это надо, но факт — netsh winhttp import proxy=ie и всё такое.
А там ещё и ассистант, зараза такая, хитрит, сначала всегда пробуя direct (надо полагать, чтобы обойти какой-то из видов MITM атак), потом прокси из winhttp, а потом уже тот прокси, который все видят в Control Panel -> Internet Options -> Connection.
И каким-то злым умыслом (потому что случайно это невозможно) в качестве прокси для winhttp указывался какой-то говносервер, отвечавший на всё 502.
В итоге логин через браузер работал, а через ассистант — нет. вот это был headbang так headbang. Саппорт Микрософта сдался задолго до netsh — они порекомендовали просто выбросить сервер "раз с другой машины всё работает".
Уйдемте отсюда, Румата! У вас слишком богатые погреба.