Периодические ошибки SSL из приложения iOS в бэкэнд AWS Elastic Beanstalk - PullRequest
5 голосов
/ 08 июля 2019

В моем приложении iOS периодически возникали ошибки SSL при отправке HTTPS-запросов к бэкэнду в течение нескольких месяцев.

Описание ошибки:

An SSL error has occurred and a secure connection to the server cannot be made.

Консоль регистрирует в режиме отладки:

2019-07-06 15:12:37.012198+0100 MyApp[37255:12499941] [BoringSSL] nw_protocol_boringssl_input_finished(1543) [C2.1:2][0x159e8e4a0] Peer disconnected during the middle of a handshake. Sending errSSLClosedNoNotify(-9816) alert
2019-07-06 15:12:37.026641+0100 MyApp[37255:12499941] TIC TCP Conn Failed [2:0x280486d00]: 3:-9816 Err(-9816)
2019-07-06 15:12:37.027759+0100 MyApp[37255:12499941] NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9816)
2019-07-06 15:12:37.027839+0100 MyApp[37255:12499941] Task <D5AF17C0-C202-4229-BD52-690EFDB10379>.<1> HTTP load failed (error code: -1200 [3:-9816])
2019-07-06 15:12:37.028016+0100 MyApp[37255:12499941] Task <D5AF17C0-C202-4229-BD52-690EFDB10379>.<1> finished with error - code: -1200
2019-07-06 15:12:37.032759+0100 MyApp[37255:12500041] Task <D5AF17C0-C202-4229-BD52-690EFDB10379>.<1> load failed with error Error Domain=NSURLErrorDomain Code=-1200 "An SSL error has occurred and a secure connection to the server cannot be made." UserInfo={NSErrorFailingURLStringKey=https://api.example.com/v1/example/example?param=example, NSLocalizedRecoverySuggestion=Would you like to connect to the server anyway?, _kCFStreamErrorDomainKey=3, _NSURLErrorFailingURLSessionTaskErrorKey=LocalDataTask <D5AF17C0-C202-4229-BD52-690EFDB10379>.<1>, _NSURLErrorRelatedURLSessionTaskErrorKey=(
    "LocalDataTask <D5AF17C0-C202-4229-BD52-690EFDB10379>.<1>"
), NSLocalizedDescription=An SSL error has occurred and a secure connection to the server cannot be made., NSErrorFailingURLKey=https://api.example.com/v1/example/example?param=example, NSUnderlyingError=0x283ff2160 {Error Domain=kCFErrorDomainCFNetwork Code=-1200 "(null)" UserInfo={_kCFStreamPropertySSLClientCertificateState=0, _kCFNetworkCFStreamSSLErrorOriginalValue=-9816, _kCFStreamErrorDomainKey=3, _kCFStreamErrorCodeKey=-9816}}, _kCFStreamErrorCodeKey=-9816} [-1200]

Ошибка возникает в основном на 3G / 4G, а не на Wi-Fi, и чаще всего возникает при низком уровне сигнала сети.Если это произойдет один раз, это продолжится в течение следующих нескольких запросов, но в конечном итоге снова будет работать вскоре после этого.

На основе аналитики, пользовательских обзоров и отчетов об ошибках пользователей: это затрагивает большой процент пользователей,но не 100% из них.

-

Серверная часть размещена на AWS Elastic Beanstalk.Служил в качестве приложения Docker, использовал прокси-сервер Nginx и несколько экземпляров за балансировщиком нагрузки.

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

Недавно я создал совершенно новую среду Elastic Beanstalk, чтобы посмотреть, поможет ли это.Ранее он использовал Classic Load Balancer, теперь он использует Application Load Balancer.Ранние признаки того, что он уменьшил количество ошибок SSL, но они все еще происходят.

Новый балансировщик нагрузки использует эту политику SSL:

ELBSecurityPolicy-FS-2018-06

, которая определена здесь: https://docs.aws.amazon.com/elasticloadbalancing/latest/application/create-https-listener.html

Следует ли использовать другую политику SSL?

-

В приложении веб-запросы делались с использованием URLSession.shared.dataTask... и т. Д. И я также попробовалиспользуя библиотеку Alamofire , чтобы понять, имеет ли это значение.Это не так.

Мне кажется, что это может быть связано с Apple Transport Transport Security.Тем не менее, так как он периодически прерывается, я не могу понять, как это сделать.

Соответствующие документы Apple находятся внизу этой страницы: https://developer.apple.com/security/

Если вам нужна дополнительная информация, чтобы помочь отладкепожалуйста, дайте мне знать.

-

-

Я добавил большую награду, чтобы привлечь внимание разработчиков iOS (в случае, если это на основе iOSпроблема) и инженеры AWS / DevOps (в случае, если это проблема Elastic Beanstalk).

Я - компетентный разработчик iOS, но не могу не подчеркнуть, насколько я глубоко в DevOps- поэтому был бы признателен за идиотостойкие ответы:)

Также хочу еще раз подчеркнуть, что эта проблема носит прерывистый характер.Это происходит не каждый раз, большинство запросов выполняется без инцидентов.

Спасибо!

Ответы [ 2 ]

3 голосов
/ 08 июля 2019

Отказ от ответственности: Это не ответ на твой вопрос, я просто пытаюсь думать с тобой громко

вот пара моментов, которые я проверю, думая, что это может помочь мне определить основную причину проблемы, предполагая, что у вас есть эта информация или есть возможность ее получить, в противном случае это будет черный ящик, если вы не сможете -дебаг с амазонкой

  • очевидно, что это проблема с прикреплением сертификата

  • проверьте через Wireshark через 3g модем запросы на версию TLS и проверьте требуемые от AWS, например, для них может потребоваться 1.2, а вы отправляете 1.1

  • очень важно проверить строку сертификата на стороне сервера и сравнить ее со стороной клиента вручную; она может быть закодирована по-другому через конвейер соединения

  • до тех пор, пока вы сказали, что это может происходить чаще при медленном соединении, проверьте время ожидания для закрепления сертификата (сервер может получить часть строки сертификата и сравнить ее с той, что имеет, и обнаружит несоответствие из-за задержка соединения)

  • убедитесь, что все экземпляры док-приложения за балансировщиком нагрузки имеют точно такую ​​же версию сертификата, который вы закрепляете

  • проверить статистику версии iOS о том, что их соединения не удалось, и проверки безопасности в этой конкретной версии

0 голосов
/ 12 июля 2019

Вы добавили ключи параметров безопасности транспорта приложения в файл Info.plist?

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>NSAllowsArbitraryLoads</key>
    <true/>
    <key>NSAllowsArbitraryLoadsForMedia</key>
    <true/>
    <key>NSAllowsArbitraryLoadsInWebContent</key>
    <true/>
    <key>NSExceptionDomains</key>
    <dict>
        <key>YOUR_SERVER_COM</key>
        <dict>
            <key>NSExceptionRequiresForwardSecrecy</key>
            <false/>
            <key>NSIncludesSubdomains</key>
            <true/>
        </dict>
        <key>facebook.com</key>
        <dict>
            <key>NSExceptionRequiresForwardSecrecy</key>
            <false/>
            <key>NSIncludesSubdomains</key>
            <true/>
        </dict>
        <key>fbcdn.net</key>
        <dict>
            <key>NSExceptionRequiresForwardSecrecy</key>
            <false/>
            <key>NSIncludesSubdomains</key>
            <true/>
        </dict>
        <key>graph.facebook.com</key>
        <dict>
            <key>NSExceptionRequiresForwardSecrecy</key>
            <false/>
            <key>NSIncludesSubdomains</key>
            <true/>
        </dict>
    </dict>
</dict>
</plist>
...