Ошибки WebSocket при использовании TLS (но не без)
У меня есть веб-приложение, которое использует WebSockets для связи между браузером и сервером. Когда служит ws
все работает как задумано. Если я изменю протокол на wss
в основном все работает как положено (большинство сообщений передается от клиента к серверу или наоборот), но иногда я получаю одну из следующих ошибок в консоли Chrome:
"Could not decode a text frame as UTF-8."
или же
"Invalid frame header"
... в этот момент Chrome освобождает соединение.
Я наблюдал это как при подаче wss
непосредственно с сервера (работает на.NET, использует SuperWebSocket) и в конфигурации, где сервер использует ws
и Apache's mod_proxy_wstunnel
отменить прокси к этому с помощью wss
протокол. Я также настроил простой "эхо-сервер" в той же конфигурации Apache и не наблюдаю проблему; это наводит меня на мысль, что в данных, которые мы передаем в SuperWebSocket API, есть что- то забавное. (Сообщения, которые вызывают ошибку, действительны в кодировке UTF-8, и, опять же, эта проблема не отображается при обслуживании через ws
.)
Я в растерянности из-за того, что изменение протокола может вызвать такую проблему, что приводит меня к моему вопросу:
Существуют ли случаи, когда фрейм WebSocket может быть действительным при отправке без TLS, но будет поврежден при отправке с TLS?
1 ответ
Существуют ли случаи, когда фрейм WebSocket может быть действительным при отправке без TLS, но будет поврежден при отправке с TLS?
Нет, wss:// - это то же самое, что и ws://, только то, что он не использует обычный TCP, а TCP+TLS. Сам протокол WebSockets не знает, работает ли он внутри обычного TCP-соединения или TLS-защищенного TCP-соединения. Это похоже на https:// против http://.
Но соединение TLS более чувствительно к повреждению данных. То есть, если какой-то человек посередине изменяет пакеты должным образом, простой ws:// не заметит, а wss: // выкрикнет, потому что была обнаружена модификация пакета. Но вы должны получить сообщение об ошибке на уровне соединения (т. Е. Разрыв соединения или подобное), а не на уровне WebSockets, как в вашем случае (неверный заголовок фрейма).
Я понятия не имею, что вы используете в качестве бэкэнда WebSockets, но я бы предположил, что проблема лежит там. Из-за дополнительного уровня TLS wss: // может вести себя немного по-разному в отношении синхронизации и буферизации данных внутри сервера, поэтому могут возникнуть условия гонки, которые более вероятны при использовании wss: // по сравнению с ws://.