Dostęp SSH z wewnętrznej i zewnętrznej sieci LAN za pomocą tego samego polecenia terminala

10

Mam Raspberry Pi (RPi) i nawiązuję z nim zdalne połączenia za pomocą ssh. Udało mi się poprawnie skonfigurować ssh, aby uzyskać dostęp do RPi zarówno z sieci lokalnej, jak iz Internetu (przy użyciu określonego portu, który otworzyłem na routerze).

Zakładając nazwę użytkownika johni RPi o nazwie raspi:

Dostęp do sieci LAN

ssh [email protected]
ssh john@raspi
ssh raspi

Zewnętrzny dostęp do sieci LAN

ssh -p 1234 [email protected]
ssh -p 1234 12.345.67.89

Ale jak mogę to zrobić po prostu ssh raspipoza moją siecią LAN ?. Czy istnieje sposób skonfigurowania raspi tak, aby wskazywał dwa adresy IP, jeden w sieci LAN i jeden przez Internet?

Zasadniczo chcę uzyskać dostęp do moich RPi w jeden sposób, bez względu na to, czy jestem w domu, czy w pracy.

Aeronaelius
źródło
Możesz uruchomić serwer DNS w lokalnej sieci LAN, który odpowiada na żądanie nazwy „raspi” przy użyciu lokalnego adresu IP sieci LAN. Teraz przekształcenie tej samej nazwy na inny adres zewnętrzny wymagałoby wypełnienia tej nazwy (dynamiczne dns) w taki sposób, aby również została rozwiązana. Ale prawdopodobnie będziesz potrzebować dłuższego imienia niż „raspi”.
ChuckCottrill
Zobacz pytania i odpowiedzi: unix.stackexchange.com/questions/61655/…
slm

Odpowiedzi:

7

Patrząc bliżej na swoje pytanie, wydaje się, że używasz tego samego komputera zarówno z sieci LAN, jak i spoza niej. Odpowiednio poprawiłem swoją odpowiedź:

W swoim ~/.ssh/configdodaj:

Host raspi-wan
    HostName 12.34.56.78
    User john
    Port 1234

Host raspi-lan
    HostName 192.168.1.2
    User john
    Port 22

Następnie możesz ssh raspi-wanspoza sieci LAN lub ssh raspi-lanz wnętrza sieci LAN bez potrzeby korzystania z serwerów DNS lub edytowania /etc/hostsdla wszystkich użytkowników, a nawet bez robienia czegokolwiek jako root. Jeśli chcesz, aby nazwa raspizmieniała się w różny sposób w zależności od tego, gdzie jesteś, prawdopodobnie będzie potrzebować trochę magii skryptów powłoki, aby wykryć twoją sieć i odpowiednio działać.

DopeGhoti
źródło
1
Dzięki DopeGhoti, czuję się komfortowo z twoim rozwiązaniem, aby dołączyć a -wani -lanpostfix. Mojemu ssh jednak nie spodobało się Usernamepole (Zła opcja konfiguracji). Bez tego działa dobrze.
Aeronaelius
2
Przepraszam, poprawna składnia to User johnnie UserName. Poprawiam swoją odpowiedź, aby to odzwierciedlić, a kiedy już w ten sposób skonfigurujesz swoją konfigurację, możesz pominąć nazwę użytkownika w sshwierszu poleceń.
DopeGhoti
5

Jest to doskonale wykonalne tylko z konfiguracją ssh, bez konieczności używania osobnych aliasów dla lan i wan lub tworzenia dodatkowego portu do przodu. (Ale oczywiście potrzebujesz sposobu, aby wykryć, czy jesteś w swojej sieci, czy nie)

W ~/.ssh/config, będziesz chciał dodać coś takiego:

Match host raspi exec "am_i_outside_of_my_lan"
    HostName 12.345.67.89
    Port 1234

Zamiast tego am_i_outside_of_my_lanbędziesz chciał umieścić polecenie określające, czy jesteś w sieci domowej, czy nie, i zwraca kod wyjścia 0, jeśli jesteś poza nim, i coś innego.

hostWarunek jest chyba oczywiste, ale execgwarantuje, stan niektórych wyjaśnienie: Pasuje tylko wtedy, gdy podane zwraca polecenie z kodem wyjścia 0, tzn. żaden błąd.

Innymi słowy, to, co to robi, polega na tym, że host raspiczęść ogranicza tę regułę do, gdy próbujesz połączyć się z raspi hosta, a exec "am_i_outside_my_lan"dodatkowo ogranicza ją tak, że ma ona zastosowanie tylko wtedy, gdy łączysz się spoza sieci domowej. Tak więc wewnątrz sieci domowej ssh user@raspidziała dokładnie tak, jak normalnie, ale poza nią reguła jest zgodna, a zamiast niej odpowiada ssh -p 1234 [email protected].

Jeśli chodzi o to, czego użyć zamiast am_i_outside_of_my_lan, zależy to całkowicie od twojej konfiguracji. Sugeruję umieszczenie poleceń w osobnym skrypcie zamiast wpisywania go w wierszu, ponieważ cytowanie wydaje się nieco trudne do poprawnego.

Osobiście użyłem następującego skryptu Python, aby wykryć, czy jestem w mojej własnej sieci: (Ponieważ moja nazwa domeny rozwiązuje się na lokalny adres IP wewnątrz mojej sieci)

#! /usr/bin/env python
import socket, sys

sys.exit(socket.gethostbyname('mydomain.com').startswith('192.168.1.'))

Jeśli nie masz podobnej konfiguracji, być może będziesz musiał zrobić coś innego. (Na przykład możesz spojrzeć na nazwę sieci bezprzewodowej, z którą jesteś podłączony, lub nawet zapytać o usługę what-is-my-ip, aby uzyskać zewnętrzny adres ip sieci, z którą jesteś podłączony)

Aleksi Torhamo
źródło
To jest poprawna odpowiedź; to bardzo smutne, że inni mają więcej głosów.
Jonathan Tomer
@JathanathanTomer: Cóż, szczerze mówiąc, odpowiedziałem na to 3 lata po tym, jak zostało o to poproszone, podczas gdy odpowiedzi o lepszych wynikach zostały opublikowane w ciągu kilku godzin, więc to tylko przypadek „wczesnego ptaka dostaje robaka”: P (mam też powiedzieć, że podoba mi się specyficzny wariant Ellisa Hoaga tego ogólnego rozwiązania - używanie arp jest dość sprytne i sprawia, że ​​rozwiązanie jest bardziej ogólne, ponieważ w wykrywaniu sieci polecenie nie musi być dostrajane dla każdej konfiguracji sieci)
Aleksi Torhamo
3

Na komputerze (łączącym się ) możesz ustawić nazwę hosta 12.345.67.89. Otwórz /etc/hostsplik i ustaw wpis DNS:

12.345.67.89    raspi

Komputer przekształci następnie „raspi” w „12.345.67.89” w ramach lokalnego procesu rozpoznawania DNS. Jeśli korzystasz z kilku komputerów, zmiany należy wprowadzić na każdym z nich. Problem polega na tym, że do edycji potrzebny jest dostęp do konta root /etc/hosts, a może nie być dostępny wszędzie.

Jeśli chcesz, aby „raspi” było rozpoznawane automatycznie z dowolnego miejsca, przepraszam: niemożliwe. Wymagałoby to rejestracji „raspi” jako nazwy domeny, co nie może się zdarzyć, ponieważ „raspi” nie ma TLD i nie zależy od żadnego serwera głównego DNS. Możesz jednak zarejestrować nazwę domeny (powiedzmy cfbaptista.mei wskaż jej adres IP WAN. Po przekierowaniu portów będziesz mieć dostęp do Raspberry Pi za pomocą:

ssh (you@)(raspi.)cfbaptista.me

(ale to wydaje pieniądze za prawie nic ...)

Jeśli chodzi o user@część, zależy to od nazwy logowania na różnych komputerach. Jeśli masz taką samą nazwę na komputerze łączącym i na komputerze zdalnym , nie musisz go określać. Jeśli nie, musisz określić, kto jest na zdalnym komputerze.

John WH Smith
źródło
Uwaga: jak wspomniano w drugiej odpowiedzi, możesz utworzyć aliasy hosta w konfiguracji SSH, co oczywiście nie wymaga rootowania.
strugee
W rzeczy samej ! Oto mały link: kolektywidea.com/blog/archives/2011/02/04/how-to-ssh-aliases
John WH Smith
0

Cel: ssh raspi powinien działać w sieci LAN i w publicznym Internecie.

Aby to zrobić, musisz upewnić się, że nazwa odnosi się do wewnętrznego adresu IP w sieci LAN i publicznego adresu IP z zewnątrz.

Po pierwsze, powinieneś uzyskać nazwę domeny taką jak raspi.yourdomain.com. Sprawdź http://freedns.afraid.org/, aby uzyskać bezpłatne domeny do użytku hobbystycznego. Wskaż domenę na swój publiczny adres IP

W przypadku sieci LAN zalecam uruchomienie DNSMasq. Otwarte oprogramowanie DD-WRT ściśle integruje się z DNSMasq, wykorzystując je do DHCP i DNS. Musisz tylko podać jej domenę wyszukiwania („twojadomena.com”), a ona automatycznie przypisze nazwy DNS na podstawie nazwy żądanej przez każdego klienta. Aby to zadziałało, należy przeczytać nazwę / etc / host rasasy raspi.

Po skonfigurowaniu raspi.twojadomena.com powinien przejść do lokalnego adresu IP w sieci LAN (upewnij się tylko, że używasz lokalnego DNS na wszystkich swoich komputerach).

Teraz prawdopodobnie nie chcesz udostępniać portu 22 publicznemu internetowi, ponieważ dostaniesz mnóstwo ruchu sniffera. Możesz więc mieć router pokazujący raspi: 22 jako inny port, powiedzmy 1234. Aby używać tego samego portu w sieci publicznej i wewnętrznej, możesz dodać regułę przekierowania portów do raspi. W systemie Linux:

sudo iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 1234 -j REDIRECT --to-port 22
sudo sh -c 'iptables-save > /etc/iptables/iptables.rules'

(zmień eth0 na nazwę interfejsu sieciowego, jak pokazano za pomocą ip linklub ifconfig, a 1234 na port publiczny)

Teraz możesz korzystać ssh -p 1234 raspi.yourdomain.comzarówno z publicznego, jak i LAN.

Możesz dodać wpis do ~ / .ssh / config na komputerze klienckim, aby go skrócić, tak ssh raspijak wspomniano w @DopeGhoti.

Jeśli chcesz udostępnić porty SSH dodatkowych komputerów na tym samym publicznym adresie IP, po prostu powtórz proces z inną nazwą DNS i portem publicznym. Twoje zdrowie!

Eric Drechsel
źródło
0

Oto zwięzła, działająca wersja odpowiedzi Aleksiego Torhamo, za pomocą curl, aby pobrać bieżący publiczny adres IP, a następnie sprawdzić, czy odpowiada on publicznemu adresowi IP twojego serwera (tj. Jesteś w tej samej sieci lokalnej).

W swoim ~/.ssh/configdodaniu

Match host raspi exec "[[ $(curl -s ipinfo.io/ip) == '12.345.67.89' ]]"
  User john
  HostName 192.168.2.7

Match host raspi exec "[[ $(curl -s ipinfo.io/ip) != '12.345.67.89' ]]"
  User john
  HostName 12.345.67.89
  Port 1234
Alec Jacobson
źródło
Ja wierzę ssh przetworzy wszystkie pasujące dyrektyw, w porządku, więc teoretycznie powinien być w stanie zrobić coś takiego Match host raspi / User john / HostName 192.168.2.7następuje Match host raspi exec "[[ $(curl -s ipinfo.io/ip) != '12.345.67.89' ]]" / HostName 12.345.67.89 / Port 1234i uzyskać ten sam efekt tylko z jednym curlwezwaniem, pozwalając == '12.345.67.89'przypadek uznać za niepowodzenie druga Matchreguła użytkownika exec.
FeRD
(Jutro musiałbyś upewnić się, że każdy argument podany w pierwszym Matchjest taki sam lub też podany w drugim - jeśli podałeś niestandardowy Port xxxxw pierwszym Match, a chciałeś użyć standardowego portu w drugim Match, trzeba by to jawnie zastąpić, Port 22aby nie używał portu xxxx).
FeRD
0

Zakładając, że twoje urządzenie ma adres IP 192.168.1. * Po podłączeniu do sieci LAN, możesz to osiągnąć za pomocą następującej konfiguracji, ~/.ssh/configdzięki czemu zawsze możesz użyć tego samego polecenia (tylko ssh raspi) do połączenia:

Match Originalhost raspi Exec "ifconfig | grep 192\.168\.1\."
    HostName 192.168.1.2
    User john
    Port 22

Host raspi
    HostName 12.34.56.78
    User john
    Port 1234
Cvuorinen
źródło
0

To rozwiązanie zakłada, że ​​twoja sieć domowa ma jeden router, co moim zdaniem jest częstym przypadkiem.

Dodaj do swojego ~/.ssh/config

Match host raspi exec "test $(arp 192.168.1.1 | awk '{print $4}') = ROUTER_MAC_ADDRESS"
        Hostname 192.168.2.7
        User john

Host raspi
        Hostname 12.345.67.89
        Port 1234
        User john
Ellis Hoag
źródło