Вопрос или проблема
Что я пытаюсь достичь: Доступ к серверу в локальной сети через OpenVPN
Симптомы: SSH соединение подвисает на SSH2_MSG_KEXINIT
ssh -vvv [email protected]
OpenSSH_8.2p1 Ubuntu-4ubuntu0.2, OpenSSL 1.1.1f 31 Mar 2020
debug1: Reading configuration data /etc/ssh/ssh_config
debug1: /etc/ssh/ssh_config line 19: include /etc/ssh/ssh_config.d/*.conf matched no files
debug1: /etc/ssh/ssh_config line 21: Applying options for *
debug1: Connecting to 10.0.0.101 [10.0.0.101] port 22.
debug1: Connection established.
[...]
debug1: Local version string SSH-2.0-OpenSSH_8.2p1 Ubuntu-4ubuntu0.2
debug1: Remote protocol version 2.0, remote software version OpenSSH_8.2p1 Ubuntu-4ubuntu0.2
debug1: match: OpenSSH_8.2p1 Ubuntu-4ubuntu0.2 pat OpenSSH* compat 0x04000000
debug1: Authenticating to 10.0.0.101:22 as 'emmy'
debug1: SSH2_MSG_KEXINIT sent
^C
Лог сервера:
May 4 16:35:58 emmy sshd[39003]: Connection from 10.10.8.6 port 55592 on 10.0.0.101 port 22 rdomain ""
May 4 16:35:58 emmy sshd[39003]: debug1: Local version string SSH-2.0-OpenSSH_8.2p1 Ubuntu-4ubuntu0.2
May 4 16:35:58 emmy sshd[39003]: debug1: Remote protocol version 2.0, remote software version OpenSSH_8.2p1 Ubuntu-4ubuntu0.2
May 4 16:35:58 emmy sshd[39003]: debug1: match: OpenSSH_8.2p1 Ubuntu-4ubuntu0.2 pat OpenSSH* compat 0x04000000
[...]
May 4 16:35:58 emmy sshd[39003]: debug1: SSH2_MSG_KEXINIT sent [preauth]
May 4 16:35:58 emmy sshd[39003]: debug3: receive packet: type 20 [preauth]
May 4 16:35:58 emmy sshd[39003]: debug1: SSH2_MSG_KEXINIT received [preauth]
May 4 16:35:58 emmy sshd[39003]: debug2: local server KEXINIT proposal [preauth]
[...]
May 4 16:35:58 emmy sshd[39003]: debug2: peer client KEXINIT proposal [preauth]
[...]
May 4 16:35:58 emmy sshd[39003]: debug1: kex: algorithm: curve25519-sha256 [preauth]
May 4 16:35:58 emmy sshd[39003]: debug1: kex: host key algorithm: ecdsa-sha2-nistp256 [preauth]
May 4 16:35:58 emmy sshd[39003]: debug1: kex: client->server cipher: [email protected] MAC: <implicit> compression: none [preauth]
May 4 16:35:58 emmy sshd[39003]: debug1: kex: server->client cipher: [email protected] MAC: <implicit> compression: none [preauth]
May 4 16:35:58 emmy sshd[39003]: debug1: expecting SSH2_MSG_KEX_ECDH_INIT [preauth]
May 4 16:36:09 emmy sshd[39003]: Connection closed by 10.10.8.6 port 55592 [preauth]
[...]
Для меня это звучало как проблема с путём mtu, поэтому я попытался измерить его.
Первая попытка: tracepath
sudo tracepath 10.0.0.101
1?: [LOCALHOST] pmtu 1500
1: DESKTOP-6STOO94.mshome.net 0.218ms
1: DESKTOP-6STOO94.mshome.net 0.165ms
2: no reply
3: no reply
4: no reply
5: [...]
^C
Это кажется не работает. Давайте сначала протестируем подключение:
ping 10.0.0.101
PING 10.0.0.101 (10.0.0.101) 56(84) bytes of data.
64 bytes from 10.0.0.101: icmp_seq=1 ttl=62 time=14.2 ms
64 bytes from 10.0.0.101: icmp_seq=2 ttl=62 time=13.9 ms
64 bytes from 10.0.0.101: icmp_seq=3 ttl=62 time=13.9 ms
64 bytes from 10.0.0.101: icmp_seq=4 ttl=62 time=14.4 ms
64 bytes from 10.0.0.101: icmp_seq=5 ttl=62 time=14.3 ms
64 bytes from 10.0.0.101: icmp_seq=6 ttl=62 time=13.8 ms
64 bytes from 10.0.0.101: icmp_seq=7 ttl=62 time=14.1 ms
64 bytes from 10.0.0.101: icmp_seq=8 ttl=62 time=14.1 ms
^C
--- 10.0.0.101 ping statistics ---
8 packets transmitted, 8 received, 0% packet loss, time 7012ms
rtt min/avg/max/mdev = 13.835/14.087/14.392/0.184 ms
Окей, это, похоже, работает, давайте попробуем узнать путь mtu с помощью traceroute
sudo traceroute -I --mtu 10.0.0.101
traceroute to 10.0.0.101 (10.0.0.101), 30 hops max, 65000 byte packets
1 DESKTOP-6STOO94.mshome.net (192.168.176.65) 0.140 ms F=1500 0.133 ms 0.092 ms
2 * * *
3 * * *
4 * * *
5 [...]^C
Неудача, даже если обычный traceroute работает
sudo traceroute -I 10.0.0.101
[sudo] password for benedikt:
traceroute to 10.0.0.101 (10.0.0.101), 30 hops max, 60 byte packets
1 DESKTOP-6STOO94.mshome.net (192.168.176.65) 0.316 ms 0.284 ms 0.280 ms
2 * * *
3 * * *
4 * * *
5 * * 10.0.0.101 (10.0.0.101) 14.195 ms
Так что мне придётся проверить вручную
ping -M do -s 1500 -c 1 10.0.0.1
PING 10.0.0.1 (10.0.0.1) 1500(1528) bytes of data.
ping: local error: message too long, mtu=1500
--- 10.0.0.1 ping statistics ---
1 packets transmitted, 0 received, +1 errors, 100% packet loss, time 0ms
MTU 1500 очевидно слишком высок. Давайте уменьшать от этого значения:
ping -M do -s 500 -c 1 10.0.0.1
PING 10.0.0.1 (10.0.0.1) 500(528) bytes of data.
--- 10.0.0.1 ping statistics ---
1 packets transmitted, 0 received, 100% packet loss, time 0ms
Отсутсвие ответа странно. Но давайте ещё уменьшим.
ping -M do -s 256 -c 1 10.0.0.1
PING 10.0.0.1 (10.0.0.1) 256(284) bytes of data.
264 bytes from 10.0.0.1: icmp_seq=1 ttl=63 time=14.4 ms
--- 10.0.0.1 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 14.431/14.431/14.431/0.000 ms
Оптимальный размер кажется равен 285. Это объясняет мою проблему. Пакет SSH больше этого размера и ему не разрешено фрагментироваться из соображений безопасности.
Теперь мой вопрос: Как я могу это преодолеть?
Вероятно, у вас включено PMTUD (определение пути MTU), но сообщения ICMP “необходима фрагментация” отбрасываются и не возвращаются на ваш компьютер для корректировки MTU.
Варианты:
- Исправьте путь сети, чтобы не блокировать сообщения ICMP.
- Настройте MTU вручную. В Linux вы можете настроить MTU для маршрута, используя необязательный параметр
mtu
вip route
. Вероятно, вам нужно будет настроить его на обоих концах и/или шлюзах связи. - Используйте MSS clamping (шлюз на пути понижает MSS для TCP-соединений). Это функция многих VPN. Естественно, это исправит только TCP-коммуникацию.
- Отключите PMTU. Это остановит установку битов DF (не фрагментировать) для TCP и UDP-коммуникации, разрешая фрагментацию. Вероятно, вам нужно будет отключить PMTU на обоих концах и/или шлюзах связи. В некоторых случаях могут возникнуть проблемы с фрагментацией.
Вот как я это исправил:
вам нужно убедиться, что MTU, установленное для TUN, меньше, чем MTU, установленное для сетевого интерфейса ssh-сервера. Это можно сделать в 2 шага.
Первый шаг: как только вы определили MTU, которое хотите установить (я использую 1492, чтобы достичь хорошего предела), вы должны установить его на сервере в сетевом порту (назовем его enp3s0). Для этого я использовал NetworkManager через командную строку с помощью:
sudo nmcli c edit enp3s0
nmcli> set 802-3-ethernet.mtu 1492
nmcli> save persistent
nmcli> quit
Перезагрузитесь.
Второй шаг: добавьте следующие строки в конфигурацию сервера openvpn:
tun-mtu 1472
tun-mtu-extra 32
mssfix 1400
Перезагрузитесь.
Теперь все клиенты установят TUN mtu на 1472, а сервер будет иметь сетевое MTU 1492. Это исправит проблему.
.
Ответ или решение
Ваша ситуация, связанная с проблемой доступа к серверу через OpenVPN из-за конфликта с MTU, требует внимательного подхода. Давайте посмотрим на возможные пути решения вашей проблемы с SSH-соединением, которое зависает на стадии SSH2_MSG_KEXINIT.
Диагноз проблемы
Ваша проблема может быть связана с неправильно установленным значением MTU, что приводит к задержкам или блокировке SSH-пакетов. Протокол SSH, из соображений безопасности, может избегать фрагментации пакетов, что вызывает проблемы, особенно когда пути сообщений блокируют ICMP-сообщения "fragmentation needed", необходимые для обнаружения MTU.
Анализ текущей ситуации
- Проблема с MTU: Пакеты SSH, возможно, больше допустимого пути MTU, как вы выяснили, путем тестов с помощью команды
ping
с разными размерами пакетов. - Утилиты проверки: Использованные вами
tracepath
иtraceroute
показали 1500 байт, однако ваш тест сping
показывает, что значение выше 256 байт недопустимо, что подтверждает проблемы с MTU.
Рекомендации для решения проблемы
-
Настройка MTU: Установите MTU, который гарантировано проходит по всему маршруту. Вы уже выделили значение 285 как работоспособный размер. Однако, предложенное значение 1492 часто является хорошим компромиссом для туннелей VPN.
-
Изменение конфигурации сети:
- Настройте сетевой интерфейс сервера с помощью NetworkManager:
sudo nmcli c edit enp3s0 nmcli> set 802-3-ethernet.mtu 1492 nmcli> save persistent nmcli> quit
- Перезагрузите сервер для применения изменений.
- Настройте сетевой интерфейс сервера с помощью NetworkManager:
-
Конфигурация OpenVPN:
- В конфигурации сервера OpenVPN укажите следующие параметры:
tun-mtu 1472 tun-mtu-extra 32 mssfix 1400
- Эти настройки помогут избежать фрагментации пакетов внутри VPN-туннеля.
- В конфигурации сервера OpenVPN укажите следующие параметры:
-
Использование MSS Clamping:
- Это механизм для уменьшения MSS (Maximum Segment Size) на уровне шлюзов, он поможет оптимизировать передачу TCP-пакетов, учтя ограниченные размеры MTU.
Заключение
Проблема, которую вы описываете, требует комплексного подхода, включая корректировку MTU и использование настроек VPN для обеспечения оптимальной передачи данных. Следуйте вышеуказанным шагам, чтобы устранить блокировку при соединении с сервером через SSH через OpenVPN. Надеемся, что это решит ваши проблемы и обеспечит стабильную работу сети.
Если после выполнения всех шагов проблема не исчезнет, рекомендуем провести более глубокую диагностику маршрутов или обратиться к квалифицированному специалисту для более детального аудита вашей сетевой инфраструктуры.