![임시가 아닌 IPv6 주소를 사용하여 연결하도록 ssh에 어떻게 알릴 수 있습니까?](https://rvso.com/image/1703325/%EC%9E%84%EC%8B%9C%EA%B0%80%20%EC%95%84%EB%8B%8C%20IPv6%20%EC%A3%BC%EC%86%8C%EB%A5%BC%20%EC%82%AC%EC%9A%A9%ED%95%98%EC%97%AC%20%EC%97%B0%EA%B2%B0%ED%95%98%EB%8F%84%EB%A1%9D%20ssh%EC%97%90%20%EC%96%B4%EB%96%BB%EA%B2%8C%20%EC%95%8C%EB%A6%B4%20%EC%88%98%20%EC%9E%88%EC%8A%B5%EB%8B%88%EA%B9%8C%3F.png)
IPv6 인터페이스(적어도 라우팅 가능한 IP 포함)에는 일반적으로 임시 IP 주소가 있으며, 이는 자주 변경되며 일반적으로 더 많은 개인 정보 보호를 제공하기 위해 아웃바운드 연결에 사용됩니다.
ssh에게 이 주소를 사용하지 않고 대신 특정 아웃바운드 연결 시도에 대해 임시가 아닌 주소에 바인딩하도록 지시하려면 어떻게 해야 합니까?
특정 IP 주소에 바인딩하는 옵션을 사용할 수 있다는 것을 알고 있지만 -b
이는 먼저 아웃바운드 인터페이스의 IP 주소를 조회해야 함을 의미합니다.
답변1
Linux에서 ssh는 특정 주소 유형을 요청하려면 setockopt(IPV6_ADDR_PREFERENCES)를 호출해야 합니다. (이것은 Linux setockopt 문서에는 언급되지 않았지만 코드는 커널에 존재하며 RFC 5014 사양과 일치하는 것 같습니다.)
OpenSSH에는 주소 기본 설정을 지정할 수 있는 구성 옵션이 없으므로 다음과 같은 해킹이어야 합니다.이 하나(다른 소켓을 사용하는 경우에만). OpenSSH 개발자에게 이러한 옵션을 추가하도록 요청할 수 있지만 일반적으로 OpenBSD가 지원하지 않는 OS 기능을 추가하는 것을 원하지 않습니다.
에 대한 올바른 주소를 얻기 위해 무언가를 스크립트하는 것이 더 쉬울 것입니다 -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);
}