Пакеты сервера OpenSSL фрагментируются на 270 байт на пакет - PullRequest
2 голосов
/ 16 июня 2020

Проблема
Я пытаюсь проанализировать рукопожатие DTLS 1.2 (через IPv6) с OpenSSL s_server и s_client, захватив его с помощью Wireshark. Рукопожатие работает так, как задумано, но пакеты сервера по какой-либо причине фрагментируются до чрезвычайно маленького размера (270 байт).

Это поток рукопожатия с размером пакета в скобках:

Client                                        | Server
=========================================================================================
Client Hello (233)                            |
                                              | Hello Verify Request (110)
Client Hello (253)                            |
                                              | Server Hello, Certificate (Fragment) (270)
                                              |
                                              | Certificate (Fragment) (270)
                                              | Certificate (Fragment) (270)
                                              | Certificate (Fragment) (270)
                                              | Certificate (Fragment) (270)
                                              | Certificate (Fragment) (270)
                                              | Certificate (Fragment) (270)
                                              | Certificate (Fragment) (270)
                                              | Certificate (Fragment) (270)
                                              |
                                              | Certificate (Reassembled),
                                              | Server Key Exchange (Fragment) (270)
                                              | 
                                              | Server Key Exchange (Reassembled),
                                              | Certificate Request (Fragment) (270)
                                              |
                                              | Certificate Request (Reassembled),
                                              | Server Hello Done (235)
Certificate, Client Key Exchange,             |
Certificate Verify, Change Cipher Spec (1764) |
                                              | Change Cipher Spec,
                                              | Encrypted Handshake Message (129)
                                              :
                                              :

Похоже, что сервер не будет отправлять пакеты длиннее 270 байт. Однако ясно видно, что у клиента нет такого ограничения и он отправляет сертификат клиента одним пакетом.

Как воспроизвести поведение
Открытый терминал (Ubuntu 18.04 ) и используйте эту команду для запуска сервера:

openssl s_server -dtls1_2 -6 -no_ticket -cipher ECDHE-ECDSA-AES128-CCM8 -key <server_private_key>.key.pem -cert <server_certificate>.cert.pem -CAfile <ca_certificate>.cert.pem -Verify 5 -verify_return_error -accept [::1]:4444 -debug

Откройте другой терминал и запустите клиент:

openssl s_client -dtls1_2 -6 -cipher ECDHE-ECDSA-AES128-CCM8 -cert <client_certificate>.cert.pem -key <client_private_key>.key.pem -CAfile <ca_certificate>.cert.pem -verify 5 -verify_return_error -connect [::1]:4444

Проект требует сеанса DTLS по IPv6 без каких-либо билетов. Шифровальный набор должен быть ECDHE-ECDSA-AES128-CCM8, и клиент должен быть проверен сервером.
Чтобы исключить любые ошибки, возникающие в сети, я назначил серверу адрес обратной связи. MTU интерфейса обратной петли составляет 65536 и не должно быть виновником.

Неудачные попытки
Я попытался установить флаги max_send_frag, split_send_frags и read_buf на 9000 на сервере и на клиенте, но это тоже ничего не изменило. Однако при использовании TLS 1.2 это работает без фрагментации сертификата сервера. К сожалению, для нашего проекта требуется D TLS.

1 Ответ

2 голосов
/ 17 июня 2020

Это вызвано тем, что s_server не смог запросить базовый MTU. Причина в том, что по умолчанию s_server не «подключает» базовый сокет к клиенту, и поэтому любые попытки запросить MTU терпят неудачу.

Ответ на эту проблему - использовать «-listen» опция для s_server. Это заставляет s_server приостанавливать рукопожатие после того, как произошло начальное ClientHello, обнаруживает IP-адрес клиента и «подключает» базовый сокет. Тогда запросы MTU завершаются успешно, и вы не видите фрагментацию. Эта опция, возможно, должна быть по умолчанию.

...