Доступ до SSH зсередини та ззовні локальної мережі, використовуючи ту ж команду терміналу


10

У мене є Raspberry Pi (RPi), і я здійснюю віддалені з'єднання з ним за допомогою ssh. Мені вдалося налаштувати ssh правильно, щоб я міг отримати доступ до RPi як з локальної мережі, так і з Інтернету (використовуючи певний порт, який я відкрив на маршрутизаторі).

Припускаючи ім’я користувача johnта RPI з іменем raspi:

Всередині мережі доступ

ssh john@192.168.2.7
ssh john@raspi
ssh raspi

Зовнішній доступ до локальної мережі

ssh -p 1234 john@12.345.67.89
ssh -p 1234 12.345.67.89

Але як я можу просто це зробити ssh raspiза межами своєї локальної мережі ?. Чи є спосіб налаштувати raspi для вказівки на два IP-адреси, один в локальній мережі та один через Інтернет?

Що я в основному хочу, це отримати доступ до моєї RPI поодиноко, незалежно від того, я вдома чи на роботі.


Ви можете запустити DNS-сервер на локальному локальному сервері, який відповідає на запит на ім'я "raspi" з локальною ip-адресою. Тепер для усунення цього імені на іншій зовнішній адресі потрібно буде заповнити це ім’я (динамічний dns) таким чином, щоб воно також було вирішено. Але вам, напевно, знадобиться довша назва, ніж "рашпі".
ChuckCottrill

Дивіться це запитання та відповіді: unix.stackexchange.com/questions/61655/…
slm

Відповіді:


7

Придивившись ближче до свого питання, виявляється, що ви використовуєте один і той же комп’ютер як у мережі, так і за її межами. Я відповідно переглянув свою відповідь:

У ваших ~/.ssh/config, додайте:

Host raspi-wan
    HostName 12.34.56.78
    User john
    Port 1234

Host raspi-lan
    HostName 192.168.1.2
    User john
    Port 22

Тоді ви можете ssh raspi-wanз-за меж локальної мережі або ssh raspi-lanзсередини локальної мережі, не маючи на увазі роботи з DNS-серверами чи редагуванням /etc/hostsдля всіх користувачів, або навіть не потрібно нічого робити як root. Якщо ви хочете, щоб ім’я raspiвирішувалося по-різному, залежно від того, де ви перебуваєте, можливо, знадобиться певна магія сценарію оболонки, щоб виявити вашу мережу та діяти відповідно.


1
Спасибі DopeGhoti, мені дуже подобається ваше рішення включити -wanта -lanпостфікс. Однак моєму ssh не сподобалось Usernameполе (неправильна опція конфігурації). Добре працює без нього.
Аеронаелій

2
Вибачте, правильний синтаксис є User john, ні UserName. Я виправляю свою відповідь, щоб це відобразити, і як тільки ви таким чином встановили свою конфігурацію, ви можете опустити ім'я користувача з sshкомандного рядка.
DopeGhoti

5

Це цілком можливо з використанням лише конфігурації ssh, без використання окремих псевдонімів для lan і wan або створення додаткових портів вперед. (Але вам, природно, потрібен якийсь спосіб виявити, перебуваєте ви в своєму ланці чи ні)

У програмі ~/.ssh/configвам потрібно буде додати щось подібне:

Match host raspi exec "am_i_outside_of_my_lan"
    HostName 12.345.67.89
    Port 1234

Замість am_i_outside_of_my_lanвас захочеться розмістити команду, яка визначає, чи знаходитесь ви в домашній мережі чи ні, і повертається з 0 вихідним кодом, якщо ви знаходитесь поза нею, і ще чимось іншим.

hostУмова, ймовірно , саме за себе, але execстан вимагає деякого пояснення: Це відповідає тільки тоді , коли дана команда повертається з кодом виходу 0, тобто. без помилок.

Інакше кажучи, це означає, що ця host raspiчастина обмежує це правило, коли ви намагаєтесь підключитися до хосту raspi, а exec "am_i_outside_my_lan"далі обмежує його так, що воно застосовується лише під час підключення за межами домашньої мережі. Отже, всередині вашої домашньої мережі ssh user@raspiвиконується саме те, що зазвичай було б, але поза нею правило відповідає, а натомість це еквівалент ssh -p 1234 user@12.345.67.89.

Що стосується того, що використовувати замість am_i_outside_of_my_lan, це повністю залежить від вашої установки. Я пропоную розміщувати команди в окремому сценарії замість того, щоб намагатись записати його в рядку, тому що цитування здається трохи важким, щоб правильно вийти.

Особисто я використав наступний скрипт Python, щоб визначити, чи перебуваю я у власній мережі: (оскільки моє доменне ім’я відповідає локальному ip всередині власної мережі)

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

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

Якщо у вас немає подібних налаштувань, можливо, доведеться зробити щось інше. (Наприклад, ви можете подивитися ім’я бездротової мережі, до якої ви підключені, або навіть запитати якусь послугу "що є моя", щоб отримати зовнішній ip мережі, до якої ви підключені)


Це правильна відповідь; дуже сумно, що інші мають більше голосів.
Джонатан Томер

@JonathanTomer: Ну, якщо чесно, я відповів на це через 3 роки після того, як його запитали, тоді як відповіді з більш високою оцінкою були опубліковані протягом декількох годин, тож це просто випадок "ранній птах отримує хробака": P (у мене також є сказати, що мені дуже подобається специфічний варіант цього загального рішення Елліса Хоага - використання arp є досить розумним, і робить рішення більш загальним, оскільки в команді виявлення мережі не потрібно налаштовуватись на всі налаштування мережі)
Алексі Торхамо

3

На вашому комп'ютері (замикається ІНГ один), ви можете встановити ім'я хоста 12.345.67.89. Відкрийте /etc/hostsфайл та встановіть запис DNS:

12.345.67.89    raspi

Потім ваша машина перетворить "raspi" в "12.345.67.89" як частина локального процесу вирішення DNS. Якщо ви використовуєте кілька машин, зміна повинна бути внесена на кожній з них. Проблема полягає в тому, що для редагування потрібен кореневий доступ /etc/hosts, і ви, можливо, не матимете його скрізь.

Якщо ви хочете, щоб "raspi" було розпізнано автоматично з будь-якого місця, тоді вибачте: неможливо. Це вимагає реєстрації "raspi" як доменного імені, що не може статися, оскільки "raspi" не має TLD і не залежатиме від будь-якого кореневого сервера DNS. Однак ви можете зареєструвати доменне ім’я (скажімо cfbaptista.me, і вказати його на вашу IP-адресу WAN. З деяким переадресацією порту ви зможете отримати доступ до вашого Raspberry Pi за допомогою:

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

(все-таки, це витрачає гроші майже на нічого ...)

Що стосується user@деталі, це залежить від вашого імені для входу на різних машинах. Якщо у вас є однакова назва на підключувальній машині та на віддаленій , то вказувати не потрібно. Якщо ні, вам потрібно вказати, хто ви знаходитесь на віддаленій машині.


Примітка: як зазначено в іншій відповіді, ви можете створити псевдоніми хоста у вашій конфігурації SSH, що, звичайно, не вимагає root.
strugee

Справді! Ось невелике посилання: colleidea.com/blog/archives/2011/02/04/how-to-ssh-aliases
Джон У. Сміт

0

Мета: ssh raspi повинна працювати всередині локальної мережі та в загальнодоступному Інтернеті.

Для цього вам потрібно переконатися, що ім'я відповідає внутрішньому IP-адресу в локальній мережі, а загальнодоступному IP-адресу ззовні.

По-перше, ви повинні отримати доменне ім’я, наприклад raspi.yourdomain.com. Ознайомтеся з http://freedns.arald.org/ щодо безкоштовних доменів для використання хобі. Вкажіть домен на ваш загальнодоступний IP-адресу

Для локальної мережі рекомендую запустити DNSMasq. Відкрита прошивка DD-WRT щільно інтегрується з DNSMasq, використовуючи її для DHCP та DNS. Вам просто потрібно повідомити йому свій пошуковий домен ("yourdomain.com"), і він автоматично призначить імена DNS на основі запитуваного імені кожного клієнта. Щоб виконати цю роботу, слід розпочати зчитування файлу / імені raspi / etc / host raspi.

Після цього налаштування raspi.yourdomain.com має вирішити локальний IP у вашій локальній мережі (просто переконайтеся, що ви використовуєте локальний DNS на всіх своїх машинах).

Тепер ви, мабуть, не хочете виставляти порт 22 в загальнодоступному Інтернеті, оскільки ви отримаєте тонну трафіку снайперів. Таким чином, у вас може бути ваш маршрутизатор, що відкриває raspi: 22, як і інший порт, скажімо, 1234. Щоб використовувати один і той же порт у публічній та внутрішній мережах, ви можете додати до raspi правило перенаправлення портів. У 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'

(Змінити eth0 на ім'я вашого мережевого інтерфейсу , як показано ip linkабо ifconfig, і тисячі двісті тридцять чотири на загальнодоступний порт)

Тепер ви можете ssh -p 1234 raspi.yourdomain.comяк з громадськості, так і з локальної мережі.

Ви можете додати запис до ~ / .ssh / config на вашій клієнтській машині, щоб скоротити це до просто ssh raspi, як згадує @DopeGhoti.

Якщо ви хочете виставити SSH-порти додаткових машин на одній публічній IP-адресі, просто повторіть процес з іншим іменем DNS та загальнодоступним портом. Ура!


0

Ось лаконічна, робоча версія відповіді Алексі Торхамо, використовуючи curl, щоб схопити ваш поточний ip, а потім перевірити, чи відповідає він загальнодоступному ip вашого сервера (тобто ви в тій же локальній мережі).

У вашому ~/.ssh/configдоп

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

Я вважаю ssh , що оброблять усі відповідні директиви для того, щоб теоретично ви мали змогу зробити щось на кшталт того, Match host raspi / User john / HostName 192.168.2.7за яким слід, Match host raspi exec "[[ $(curl -s ipinfo.io/ip) != '12.345.67.89' ]]" / HostName 12.345.67.89 / Port 1234і отримати такий же ефект лише одним curlвикликом, дозволяючи == '12.345.67.89'випадку припускати випадок відмови другого Matchправила exec.
FeRD

(Ви повинні переконатися, що кожен аргумент, зазначений у першому, Matchє однаковим або також вказаним у другому - якщо ви вказали нестандартний Port xxxxу першому Match, а хочете використовувати стандартний порт у другому Match, вам доведеться явно змінити його назад, Port 22щоб він не продовжував використовувати порт xxxx.)
FeRD

0

Якщо припустити, що ваш пристрій має IP 192.168.1. * При підключенні до вашої локальної мережі, ви можете досягти цього за допомогою наступної конфігурації, ~/.ssh/configщоб ви завжди могли використовувати ту саму команду (тільки ssh raspi) для підключення:

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

0

Це рішення передбачає, що у вашій домашній мережі є один маршрутизатор, який, на мою думку, є звичайним випадком.

Додайте до свого ~/.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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.