Решение состоит в том, чтобы установить значение StreamLocalBindUnlink на да в конфигурации sshd на сервере:sudo sh -c 'echo "StreamLocalBindUnlink yes" >> /etc/ssh/sshd_config'
.
Это происходит потому, что файлы сокетов unix не удаляются автоматически при закрытии сокета. Их нужно очищать вручную при закрытии, если это желательно, вызывая remove
/unlink
с указанием пути к файлу, но openssh этого не делает. Однако, когда я исследовал тему дальше, я пришел к выводу, что «лучшая практика» с сокетами unix заключается в том, чтобы unlink
правильно перед привязкой к нему (. Проверьте этот ответ SO для получения более подробной информации ). ]. И это именно то, что StreamLocalBindUnlink yes
говорит sshd делать.
В справочной странице говорится:
StreamLocalBindUnlink
Specifies whether to remove an existing Unix-domain socket file for local or remote port forwarding before creating a new
one. If the socket file already exists and StreamLocalBindUnlink is not enabled, sshd will be unable to forward the port to
the Unix-domain socket file. This option is only used for port forwarding to a Unix-domain socket file.
The argument must be yes or no. The default is no.
Недостатком этого подхода является то, что повторная привязка к сокету теперь разрешена, даже если старое соединение все еще существует. Кажется, что при этом старый туннель остается висящим там, так что любые существующие TCP-соединения, проходящие через них, остаются нетронутыми, но все новые соединения идут в новый туннель.Кроме того, старый туннель, по-видимому, навсегда и необратимо отсоединен от адреса сокета файловой системы и больше не сможет принимать новые соединения, даже если новый туннель закрыт.
Комментарий А.Б. на самом деле правильный. Мой raspi и текущий raspbian загружают модуль br _netfilter. После его удаления и после перезапуска hostapd все мои клиенты теперь получают действительные адреса IPv4. Вставка модуля снова нарушает функциональность. Спасибо А.Б.!