2016-04-19 3 views
2

У меня есть приложение для Android (4.4.4+), который использует следующие библиотеки:OKHttp Android не подключается к Nginx через http2 alpn

compile 'com.squareup.okhttp3:okhttp:3.2.0' 
compile 'com.squareup.okhttp3:okhttp-urlconnection:3.2.0' 
compile 'com.squareup.okio:okio:1.7.0' 

У меня есть Nginx (версия 1.9.14) скомпилированные с OpenSSL (версия источник 1.0.2g компилируется) использование OpenSSL подтверждено Nginx -V на CentOS 7. Конфигурация Nginx http2 включена для обратного прокси-сервера:

server { 
      listen 443 ssl http2; 
      ssl  on; 
      server_name  mobile.site.com; 
      ssl_certificate   /etc/pki/tls/certs/start_cert.pem; 
      ssl_certificate_key  /etc/pki/tls/certs/start_cert.key; 
      proxy_cache  one; 
      underscores_in_headers on; 
      access_log  /var/log/nginx/ssl.log ssl_custom; 
      location/{ 
        proxy_set_header X-Real-IP $remote_addr; 
        proxy_set_header X-Forwarded-For $remote_addr; 
        proxy_set_header Host $host; 
        proxy_cache_bypass $cookie_nocache $arg_nocache $arg_comment; 
        proxy_pass https://10.10.1.31:443; 
      } 
    } 

Выполнение команды на сервере:

echo | openssl s_client -alpn h2 -connect 

Возвращает:

No client certificate CA names sent 
Peer signing digest: SHA512 
Server Temp Key: ECDH, P-256, 256 bits 
--- 
SSL handshake has read 3718 bytes and written 442 bytes 
--- 
New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES256-GCM-SHA384 
Server public key is 4096 bit 
Secure Renegotiation IS supported 
Compression: NONE 
Expansion: NONE 
ALPN protocol: h2 

Сидя в URL API из любого современного браузера приводит к 2-соединение HTTP/показывая в журналах SSL и HTTP/2 хром надстройки. Предполагая, что HTTP/2 настроен правильно в nginx/OpenSSL.

клиенты Android OKHttp отказываются HTTP/2:

  ConnectionSpec spec = new ConnectionSpec.Builder(ConnectionSpec.MODERN_TLS) 
        .tlsVersions(TlsVersion.TLS_1_2) 
        .build(); 
      okHttpClient = new OkHttpClient.Builder() 
        .followSslRedirects(true) 
        .protocols(Arrays.asList(Protocol.HTTP_2, Protocol.HTTP_1_1)) 
        .connectionSpecs(Collections.singletonList(spec)) 
        .sslSocketFactory(new TLSSocketFactory((SSLSocketFactory) TLSSocketFactory.getDefault())) 
        .retryOnConnectionFailure(true) 
        .connectTimeout(25, TimeUnit.SECONDS) 
        .connectionPool(new ConnectionPool(30, 120, TimeUnit.SECONDS)) 
        .addInterceptor(new AddCookiesInterceptor()) 
        .addInterceptor(new ReceivedCookiesInterceptor()) 
        .build(); 

Я написал пользовательский TLS Оправа Factory, чтобы включить использование TLS 1.2 на < = Android 4.4.4.

TLSv1.2 действительно работает с 4.4.4+ с этой фабрикой сокетов, но я также попытался запустить на 5.0+ с и без фабрики сокетов, без HTTP/2 удачи.

HTTP/2 не работает на kit-kat, lollipop и marshmallow, но работает над предварительным просмотром разработчика «N» (a.k.a. New York Cheesecake). Ошибок не возникает, только когда-либо подключается как HTTP/1.1. У меня возникли проблемы с поиском каких-либо статей, относящихся к OKhttp и HTTP/2, большинство вопросов или вопросов, которые вы можете использовать, просто используют ALPN, но не имеют ресурсов для подробного описания использования. Документация OkHTTP не совсем понятна при использовании HTTP/2 обычаев и развертывания, но на главной странице говорится, что она ее поддерживает. Любая помощь или экспертное руководство будут высоко оценены, даже просто подталкивание в правильном направлении будет огромной помощью. Пожалуйста, дайте мне знать, если я пропустил все, что может помочь в этом процессе, спасибо заранее!

Обновление 1: Я нашел один из вопросов SO, относящихся к этому, с очень расплывчатым ответом: [SO link] How to use http/2 with Okhttp on Android devices? с комментарием, в котором предлагается использовать причал, но только в отношении использования рабочего стола, а не Использование Android.

Update 2: В данной статье показано, что ALPN включен с Android 4.4: https://github.com/http2/http2-spec/wiki/ALPN-Status

Update 3: Была возможность подключения HTTP/2 с использованием +5,0, но не 4.4.4. Мне не нужно идти ниже 4.4.4, поскольку внутренние целевые устройства являются проблемой для http/2, и они работают 4.4.4. Я смог обновить приложение, чтобы использовать протокол безопасности Служб Google Play в качестве соединения сокетов OKHttp, но используемые нами устройства 4.4.4 не включены в Google, поэтому я не могу использовать сокеты безопасности PlayServices.

+0

ли еще некоторое исследование шифров используется пытается найти закономерность: * 4.4.4 *: TLSv1.2 ECDHE-RSA-AES128-SHA - * 5.1.1 *: TLSv1. 2 ECDHE-RSA-AES128-GCM-SHA256 - * 6.0 *: TLSv1.2 ECDHE-RSA-AES128-GCM-SHA256 - * 7.0 *: TLSv1.2 ECDHE-RSA-AES128-GCM-SHA256 - * Chrome/FireFox * : TLSv1.2 ECDHE-RSA-AES128-GCM-SHA256. Только Chrome/FireFox и «7.0 (N)» соединяются с использованием HTTP/2. – DoctorD

+0

Любые обновления по этому вопросу? Могли ли вы получить http2 в 4.4.4 или вы собираетесь использовать другую альтернативу? – Zasz

+0

Я перешел к другим вещам на данный момент, но я хочу вернуться сюда скоро. Я могу посмотреть завтра и посмотреть, что я могу сделать с любыми обновленными библиотеками. – DoctorD

ответ

0

Согласно swankjesse,

Следующие шаги: Не используйте ALPN на Android 4.4 и выше; он там сломан. Восстановите NPN для версий Android, где она была ранее стабильной.

Don't use broken ALPN on Android 4.4

+0

Настоящий вопрос заключался в том, как заставить HTTP2 работать с <5 SDK-устройствами. HTTP2 SPEC показывает, что он должен работать с 4.4, используя NPN или ALPN. К сожалению, NGINX удалил поддержку NPN и использует только ALPN, а OKHTTP удалил поддержку «failback», поэтому они никогда не будут подключаться. – DoctorD

Смежные вопросы