Dlaczego nie mogę ssh do lokalnej nazwy hosta (z pojedynczą etykietą): „ssh: connect to host myserver port 22: Niepoprawny argument”?

0

(Doszedłem do wniosku, że jest to związane nscd; proszę zobaczyć na dole pytania)

Próbuję połączyć się z serwerem bezgłowym za pośrednictwem laptopa; współużytkują przewodowe łącze za pośrednictwem routera bezprzewodowego Linksys i przełącznika Ethernet TP-Link. Korzystam z Arch Linux na obu komputerach, używając do konfiguracji sieci całkiem domyślnej konfiguracji Systemd z dhcpcd.

Po ostatniej aktualizacji systemu na laptopie, podczas próby ssh na serwerze (nazywał to „myserver”), wystąpił następujący błąd:

$ ssh -v -v -F /dev/null myserver
OpenSSH_7.7p1, OpenSSL 1.1.0h  27 Mar 2018
debug1: Reading configuration data /dev/null
debug2: resolving "myserver" port 22
debug2: ssh_connect_direct: needpriv 0
debug1: Connecting to myserver [fe80::9cd8:b045:5974:c5cf] port 22.
debug1: connect to address fe80::9cd8:b045:5974:c5cf port 22: Invalid argument
ssh: connect to host myserver port 22: Invalid argument

Uruchomienie tego samego polecenia z stracepokazuje, że błąd pochodzi z connect:

connect(3, {sa_family=AF_INET6, sin6_port=htons(22), inet_pton(AF_INET6, "fe80::9cd8:b045:5974:c5cf", &sin6_addr), sin6_flowinfo=htonl(0), sin6_scope_id=0}, 28) = -1 EINVAL (Invalid argument)

Jednak ping myserverdziała prawidłowo:

$ ping myserver    
PING myserver(myserver (fe80::9cd8:b045:5974:c5cf)) 56 data bytes
64 bytes from myserver (fe80::9cd8:b045:5974:c5cf%en0): icmp_seq=1 ttl=64 time=0.533 ms
64 bytes from myserver (fe80::9cd8:b045:5974:c5cf%en0): icmp_seq=2 ttl=64 time=0.549 ms

Zazwyczaj mam lokalne namedzapytania DNS, ale błąd występuje nadal, gdy wracam do bezpośredniego używania serwera DNS routera:

$ sudo cat /etc/resolv.conf
# Generated by resolvconf
nameserver 192.168.1.1

Błąd występuje sporadycznie: co kilka minut mogę się pomyślnie połączyć. Kiedy mogę się połączyć, widzę, że connectużywa adresu IPv4:

connect(3, {sa_family=AF_INET, sin_port=htons(22), sin_addr=inet_addr("192.168.1.149")}, 16) = 0

Jednak hostpolecenie pokazuje ten sam adres IPv4, niezależnie od tego, czy połączenie działa, czy jest zerwane:

$ host myserver                   
myserver has address 192.168.1.149

Po przeczytaniu tego pytania pomyślałem o ręcznym określeniu interfejsu ( ssh -v -v -F /dev/null -B en0 myserver). Eliminuje to występujący błąd, ale nie jest to dla mnie trwałe rozwiązanie i nie wyjaśnia, dlaczego błąd nagle się pojawił.

Użyłem whilepętli w mojej powłoce, aby określić czas do najbliższej sekundy, kiedy przejście sshz pracy do pracy nie działa, i odwrotnie, i nie byłem w stanie skorelować tych zdarzeń z niczym na wyjściu journalctl, w tym z dhcpcdkomunikatami.

Pierwotnie opublikowałem to w Inżynierii sieci, gdzie konfiguracja hosta okazuje się być nie na temat. Na tej stronie użytkownik Ricky Beam opublikował częściową odpowiedź:

Cokolwiek robi rozpoznawanie nazw hostów, zwraca lokalne adresy IPv6, które nie są prawidłowe dla wybranego interfejsu - tzn. „Dowolny”. Adresy lokalne dla łącza muszą określać interfejs - np. fe80: ...: 1% eth0

Dlaczego otrzymujesz adres lokalny dla łącza, jest nieznany. Być może osoby zaznajomione z Arch Linux mogą udzielić dalszej pomocy.


Aktualizacja: Wydaje się, że jest to problem z nscd„demonem pamięci podręcznej usługi nazw”, co tłumaczy sporadyczne występowanie problemów (prawdopodobnie związane z wygaśnięciem pamięci podręcznej). Jest to naprawione za pomocą:

sudo systemctl stop nscd.service

Kiedy zatrzymuję ncsd, sshjest w stanie połączyć się przy użyciu lokalnego adresu linku, ale tym razem connectwywołanie określa również mój podstawowy interfejs „en0” i udaje się to:

connect(3, {sa_family=AF_INET6, sin6_port=htons(22), inet_pton(AF_INET6, "fe80::9cd8:b045:5974:c5cf", &sin6_addr), sin6_flowinfo=htonl(0), sin6_scope_id=if_nametoindex("en0")}, 28) = 0
write(2, "debug1: Connection established.\r"..., 33) = 33

Sądzę, że pozostałe pytanie (które mogę zadać osobno) brzmi: czy jest to błąd w nscd i czy powinienem w ogóle używać nscd?

Metamorficzny
źródło
Pytanie brzmi: dlaczego DNS zwraca lokalny adres IPv6 dla nazwy? To gwarantowana ścieżka do nędzy i cierpienia. Użyj ULA lub adresów globalnych.
Michael Hampton
Nie wiem, dlaczego robi to mój DNS, ale znalazłem tymczasową poprawkę w wyłączaniu nscd. A teraz wciąż dostaję adresy lokalne dla lokalnych hostów, ale sshdziała. Zaktualizowałem pytanie ... Wszelkie dalsze spostrzeżenia są mile widziane.
Metamorficzny
Lokalne adresy linków służą głównie do wzajemnego odkrywania się usług w sieci LAN, przeprowadzania automatycznej konfiguracji itp. Poleganie na nich w przypadku „normalnych” rzeczy, takich jak przeglądanie stron internetowych, ssh itp., Jest ogólnie uważane za zły pomysł. Ponownie skonfiguruj sobie prefiks ULA, uzyskaj globalną łączność IPv6 lub jedno i drugie.
Michael Hampton
Nie wiem jak to zrobić. Nie wiedziałem nawet, że moje komputery używają IPv6, dopóki to nie nastąpiło.
Metamorficzny
1
Pierwszym będzie ustawienie w twoim routerze domowym, jeśli nie jest to kompletny kawałek ****. Drugi to coś, o czym musisz krzyczeć na swojego ISP.
Michael Hampton,

Odpowiedzi:

0

Kiedy wprowadziłem Raspberry Pi do sieci, problem ten objawił się w nowy sposób i byłem w stanie go ostatecznie zdiagnozować.

Problem jest związany z systemd-resolved. Wpływa to na innych użytkowników, patrz np. Zapytaj nslookup Ubuntu znajduje ip, ale ping nie działa lub systemd rozwiązany nie pyta serwera dns o domenę lokalną .

Zakładałem, ssh myserverże spowoduje to wyszukiwanie DNS myserver. Jednak tak nie jest w moim systemie, oto domyślne nsswitch.conf:

$ cat /etc/nsswitch.conf
# Name Service Switch configuration file.
# See nsswitch.conf(5) for details.
...
hosts: files mymachines myhostname resolve [!UNAVAIL=return] dns
...

resolveKomponent systemd-resolved, który jest projektem Lennart Poettering do wdrożenia Zeroconf protokołów Multicast DNS i Link-Local Multicast Name Resolution .

[!UNAVAIL=return]Oznacza, że jeśli systemd-resolvedjest dostępny, rozdzielczość hosta DNS jest nie używany. Zwykle nie stanowi to problemu, ponieważ systemd-resolvedmożna również tworzyć zapytania DNS. Jednak najwyraźniej nie robi tego w przypadku nazw hostów z pojedynczą etykietą myserver, nawet gdy serwer DNS znajduje się na moim lokalnym routerze (192.168.1.1). Wynika to z uzasadnienia, że ​​nazwy hostów z pojedynczą etykietą nie powinny być udostępniane sieci zewnętrznej, jak wyjaśnił Lennart w tym wątku Github .

Wyjaśnia to fakt, że host myserverutworzono adres IPv4 (z routera), podczas gdy ssh myserverwytworzono adres IPv6 (z Multicast DNS lub LLNR, nie jestem pewien, który).

Byłem tym zmieszany, ponieważ nigdy nie dowiedziałem się o usłudze Multicast DNS, LLNR lub IPv6. Nigdy nie dowiedziałem się o tych technologiach, ponieważ uważałem, że znane mi technologie IPv4 i DNS są dla mnie wystarczające.

Najwyraźniej systemd-resolvedjest to konieczne nie tylko do tworzenia żądań Zeroconf, ale także do odpowiadania na nie. Raspberry Pi, który wprowadziłem do mojej sieci, został systemd-resolvedz jakiegoś powodu zatrzymany, więc chociaż mogłem wyszukać nazwę hosta za pomocą hosti dig, nie byłem w stanie zobaczyć jej za pośrednictwem sshlub ping:

$ ping raspberrypi
ping: raspberrypi: Name or service not known
[2]$ host raspberrypi
raspberrypi has address 192.168.1.135

Doprowadziło mnie to do pierwszego powyższego raportu o błędzie Ask Ubuntu, który doprowadził mnie do rozwiązania. Jeśli zacznę systemd-resolvedod Pi, to jestem w stanie pingi sshto. Jednak jeśli wyłączę systemd-resolved lokalnie, będę mógł pingi sshdo Pi.

Na razie właśnie wyłączyłem systemd-resolvedna wszystkich moich systemach,

$ sudo systemctl stop systemd-resolved.service
$ sudo systemctl disable systemd-resolved.service

ponieważ wydaje się, że stwarza problemy z GNU libc nscdi ponieważ wymaga ode mnie poznania technologii takich jak IPv6, mDNS i LLNR, których obecnie nie potrzebuję - ponieważ wszystkie moje komputery są podłączone do podstawowego routera konsumenckiego, który zapewnia znane technologie DNS i NAT od razu po wyjęciu z pudełka.

Dzięki tym, którzy skomentowali moje pierwotne pytanie, ale ostatecznie nie było konieczne „skonfigurowanie sobie prefiksu ULA, uzyskanie globalnej łączności IPv6 lub obu” za pośrednictwem ”ustawienia w routerze domowym, jeśli nie jest to kompletny element **** ”lub„ krzyczeć na usługodawcę internetowego ”. Musiałem po prostu wyłączyć niektóre z nowych programów Lennarta, aby oderwać się od krawędzi. Wątek Github ma pewne dyskusje na temat tego, czy oprogramowanie faktycznie działa poprawnie, ale znajduję się w tej samej pozycji, co wielu innych użytkowników: po spędzeniu godzin na ustaleniu, że systemd-resolvedjest to winowajca, wolałbym nie spędzać więcej godzin na próbach zrozumieć, jak to naprawić, gdy wyłączenie jest tak łatwe.

Metamorficzny
źródło
1
Prawdopodobnie nigdy nie będziesz potrzebować LLMNR ani mDNS. Ci będzie potrzebne IPv6. IPv4 umiera powolną, bolesną śmiercią. To powiedziawszy, systemd-resolved to AFAIK kolejny kawałek ****.
Michael Hampton
Biedny Lennart. Chciałem tylko powiedzieć, że podobało mi się używanie jego przydatnego (dla mnie) Systemd do wyłączenia jego niezbyt przydatnego (dla mnie) systemd-rozwiązanego.
Metamorphic