Кэш сеанса TLS
Q: Я использую NSURLConnection для доступа к двум HTTPS URLs на том же сервере. Я хочу использовать уникальные клиентские идентификационные данные для каждого соединения. Когда я получаю доступ к первому URL, я получаю запрос аутентификации, позволяющий мне предоставлять корректные клиентские идентификационные данные, но когда я тогда получаю доступ к второму URL, я не получаю запросов аутентификации. Как я могу получить запрос аутентификации для этого второго соединения?
A: Я использую NSURLConnection для доступа к двум HTTPS URLs на том же сервере. Я хочу использовать уникальные клиентские идентификационные данные для каждого соединения. Когда я получаю доступ к первому URL, я получаю запрос аутентификации, позволяющий мне предоставлять корректные клиентские идентификационные данные, но когда я тогда получаю доступ к второму URL, я не получаю запросов аутентификации. Как я могу получить запрос аутентификации для этого второго соединения?
При доступе к URL через HTTPS Вы фактически используете HTTP по TLS (Безопасность транспортного уровня, развитие SSL, Уровня защищенных сокетов). Вы не получаете вторую проблему, потому что второе соединение снова использует сеанс TLS, установленный первым. Для понимания этой проблемы необходимо понять что-то о TLS само, и как она реализована на Mac OS X и iOS.
Открытие сеанса TLS является в вычислительном отношении дорогим (потому что оно включает работу с большими асимметричными ключами), таким образом, TLS имеет механизм, чтобы избежать выполнять эту работу для каждого соединения. Соединение TLS может или установить новый сеанс, или оно может попытаться возобновить существующий сеанс, где возобновление существующего сеанса является намного более дешевым, чем запуск нового. Клиент TLS может поэтому повысить производительность путем поддержания кэша существующих сеансов и многократного использования их, когда это является надлежащим.
Базовый код TLS и Mac OS X и iOS, Безопасного Транспорта, поддерживает такой кэш. Этот кэш сеанса TLS реализован независимо в каждом процессе. При большинстве обстоятельств кэш сеанса TLS работает прозрачно для ускорения соединений TLS, но в некоторых случаях он может вызвать проблемы. В этом случае Ваше второе соединение снова использовало сеанс TLS первого соединения, и таким образом у Вас нет возможности предоставить новые клиентские идентификационные данные для второго соединения.
Поскольку кэширование может произойти на различных уровнях в штабеле NSURLConnection, прежде, чем попытаться работать вокруг проблемы кэша сеанса TLS, это - хорошая идея подтвердить, что это - фактически первопричина. Можно сделать это путем использования факта, что записи кэша сеанса TLS сохраняются в течение приблизительно 10 минут. Таким образом, если проблема все еще происходит, когда второе соединение следует за первым соединением на 9 минут, но уходит, если задержка составляет 11 минут, возможности состоят в том, что кэш сеанса TLS виноват.
Нет никакого прямого способа сбросить кэш сеанса TLS (кроме завершить сам процесс), и при этом нет способа сказать NSURLConnection не использовать его (r. 8957312). Единственное разумное обходное решение должно изменить Ваше соединение таким способом, которым второе соединение не поражает (в смысле «удачного обращения в кэш») запись кэша, создаваемую первым соединением. Чтобы сделать это, необходимо понять формат ключа кэша сеанса TLS, используемый NSURLConnection или, более точно, CFSocketStream, лежащий в основе NSURLConnection.
В отсутствие прокси ключ кэша сеанса TLS содержит целевой IP-адрес, целевой порт и целевое имя DNS, например, {131.39.46.209:47873}devforums.apple.com. Следовательно, изменяя IP-адрес, порт или имя DNS вызовет неудачное обращение в кэш сеанса TLS и позволит Вашему второму соединению получать проблемы аутентификации TLS. В то время как маловероятно, что Вы будете в состоянии изменить компонент IP-адреса ключа кэша сеанса TLS, порт и компоненты имени DNS являются потенциальными кандидатами обходного решения. Например:
Если Ваши два соединения представляют совсем другие операции, Вы могли бы полагать, что конфигурирование Вашего сервера послушало на двух различных портах. Например, если первое соединение для регистрации, и второе соединение для передачи данных, у Вас может быть два экземпляра Вашего сервера, один для регистрации и один для передачи данных, каждый слушающий на их собственном порту. Большинство серверов HTTP просто сконфигурировать таким образом.
Если Вы управляете пространством имен DNS сервера, Вы могли бы сконфигурировать то пространство имен, чтобы гарантировать, что каждое соединение переходит к уникальному адресу DNS. Скажем, Ваш сервер в настоящее время в
myapp.example.com. Вы могли сконфигурировать свой сервер DNS для отображения всех имен в том домене (*.myapp.example.com) к Вашему серверу. У Ваших клиентов могла тогда быть каждая цель соединения уникальное имя в том пространстве имен, таким образом избегая любого шанса, соединение поразит кэш сеанса TLS. Например, первое соединение Вашего клиента могло бы предназначатьсяs464287123.myapp.example.com, его второе соединениеs338233934.myapp.example.com, и т.д., все из которых перенаправляются Вашим сервером DNS кmyapp.example.com.Оба из предыдущих предложений требуют, чтобы Вы реконфигурировали сервер в некотором роде. Если Вы не имеете никакого контроля над сервером, Ваши опции скорее ограничиваются. Одно трусливое обходное решение должно добавить точку (». «) к имени DNS Вы соединяетесь с. Если Вы не знакомы с подробными данными DNS, имя, заканчивающееся в точке, считается полностью определенным доменным именем (FQDN), тогда как имена, не заканчивающиеся в точке (частично квалифицированные доменные имена, PQDN), могут быть разрешены путем добавления некоторого домена по умолчанию. Например,
devforums.apple.com.(отметьте запаздывающую точку), FQDN для DevForums, но, то, когда Вы в Apple и домене DNS по умолчанию,apple.com., можно обратиться к нему через PQDNdevforums.Оказывается, что имя хоста от URL, который Вы даете NSURLConnection, передает, неизмененный, через многие уровни CFNetwork, пока это в конечном счете не формирует компонент Безопасного Транспортного ключа кэша сеанса TLS. Таким образом, если у Вас есть программа, сначала соединившаяся с
devforums.apple.com.(с запаздывающей точкой) и затем подключенный сdevforums.apple.com(без запаздывающей точки), каждое соединение получит проблемы аутентификации TLS.Очевидный недостаток этого подхода - то, что он не масштабируется; Вы не можете только продолжить добавлять точки!
История версии документа
| Дата | Примечания |
|---|---|
| 10.02.2011 | Новый документ, описывающий, как кэш сеанса TLS влияет на Подключения HTTPS, которым нужны различные параметры TLS. |