![Как мне указать ssh подключаться, используя не временный адрес IPv6?](https://rvso.com/image/1703325/%D0%9A%D0%B0%D0%BA%20%D0%BC%D0%BD%D0%B5%20%D1%83%D0%BA%D0%B0%D0%B7%D0%B0%D1%82%D1%8C%20ssh%20%D0%BF%D0%BE%D0%B4%D0%BA%D0%BB%D1%8E%D1%87%D0%B0%D1%82%D1%8C%D1%81%D1%8F%2C%20%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D1%83%D1%8F%20%D0%BD%D0%B5%20%D0%B2%D1%80%D0%B5%D0%BC%D0%B5%D0%BD%D0%BD%D1%8B%D0%B9%20%D0%B0%D0%B4%D1%80%D0%B5%D1%81%20IPv6%3F.png)
Интерфейсы IPv6 (по крайней мере с маршрутизируемыми IP-адресами) обычно имеют временный IP-адрес, который часто меняется и обычно используется для исходящих соединений с целью обеспечения большей конфиденциальности.
Как мне указать ssh не использовать этот адрес, а вместо этого привязаться к невременному для данной попытки исходящего соединения?
Я знаю, что могу использовать -b
опцию привязки к определенному IP-адресу, но это означает, что мне сначала придется искать IP-адрес исходящего интерфейса.
решение1
В Linux ssh должен вызвать setsockopt(IPV6_ADDR_PREFERENCES), чтобы запросить определенный тип адреса. (Это не упоминается в документации Linux setsockopt, но код присутствует в ядре и, по-видимому, соответствует спецификации RFC 5014.)
Поскольку OpenSSH не имеет никаких параметров конфигурации, которые позволили бы вам указать предпочтения адреса, придется прибегнуть к хаку вродеВот этот(только с другим sockopt). Вы можете попробовать попросить разработчиков OpenSSH добавить такую опцию, но они, как правило, не хотят добавлять какие-либо функции ОС, которые OpenBSD также не поддерживает.
Вероятно, проще написать скрипт для получения правильного адреса -b
; например, если вы работаете в Linux, вы можете использовать ip | jq
:
addr=$(ip -json -6 addr ls dev eno1 scope global \
| jq -r ".[].addr_info[]|select(.local)|select(.temporary|not)|.local")
ssh -b $addr ...
Либо полностью отключите временные адреса (расширения конфиденциальности).
Но если вы хотите попытать счастья с LD_PRELOAD
, вы можете протестировать это (я вообще не тестировал; вполне может быть, что это сработает слишком поздно, чтобы оказать какой-либо эффект):
/* gcc -shared -o ipv6pref.so ipv6pref.c */
/* LD_PRELOAD="$HOME/ipv6pref.so" ssh whatever */
#define _GNU_SOURCE
#include <dlfcn.h>
#include <err.h>
#include <netinet/ip.h>
#include <netinet/tcp.h>
#include <sys/socket.h>
int setsockopt(int fd, int level, int name, const void *value, socklen_t len)
{
static int (*real_setsockopt)(int, int, int, const void *, socklen_t);
uint32_t flags = IPV6_PREFER_SRC_PUBLIC;
int r;
if (!real_setsockopt)
real_setsockopt = dlsym(RTLD_NEXT, "setsockopt");
if ((level == SOL_IP && name == IP_TOS) ||
(level == SOL_IPV6 && name == IPV6_TCLASS))
{
/* This is probably the TCP socket that will be used for SSH. */
r = real_setsockopt(fd, IPPROTO_IPV6, IPV6_ADDR_PREFERENCES, &flags, sizeof flags);
if (r != 0)
warn("Could not set address preference");
}
return real_setsockopt(fd, level, name, value, len);
}