Akses SSH dari dalam dan luar LAN menggunakan perintah terminal yang sama

10

Saya memiliki Raspberry Pi (RPi) dan saya membuat koneksi jarak jauh menggunakan ssh. Saya telah berhasil mengatur ssh dengan benar sehingga saya dapat mengakses RPi baik dari jaringan area lokal dan dari internet (menggunakan port tertentu yang saya buka pada router saya).

Dengan asumsi nama pengguna johndan RPi bernama raspi:

Di dalam akses LAN

ssh [email protected]
ssh john@raspi
ssh raspi

Akses LAN luar

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

Tetapi bagaimana saya bisa melakukannya ssh raspidari luar LAN saya? Apakah ada cara untuk mengkonfigurasi raspi untuk menunjuk ke dua alamat IP, satu di LAN dan satu di internet?

Apa yang saya inginkan pada dasarnya adalah mengakses RPi saya dalam satu cara, tidak peduli apakah saya di rumah atau di kantor.

Aeronaelius
sumber
Anda dapat menjalankan server DNS pada lan lokal Anda yang merespons permintaan nama "raspi" dengan alamat lan ip lokal. Sekarang menyelesaikan nama yang sama ke alamat luar yang berbeda akan mengharuskan nama itu diisi (dns dinamis) sedemikian rupa sehingga juga diselesaikan. Tapi Anda mungkin perlu nama yang lebih panjang dari "raspi".
ChuckCottrill

Jawaban:

7

Melihat pertanyaan Anda lebih dekat, tampaknya Anda menggunakan komputer yang sama dari dalam dan luar LAN. Saya telah merevisi jawaban saya sesuai dengan itu:

Di Anda ~/.ssh/config, tambahkan:

Host raspi-wan
    HostName 12.34.56.78
    User john
    Port 1234

Host raspi-lan
    HostName 192.168.1.2
    User john
    Port 22

Kemudian, Anda dapat ssh raspi-wandari luar LAN, atau ssh raspi-landari dalam LAN tanpa perlu menggunakan server DNS atau mengedit /etc/hostsuntuk semua pengguna, atau bahkan perlu melakukan apa pun sebagai root. Jika Anda ingin nama raspiuntuk diselesaikan secara berbeda tergantung di mana Anda berada, itu mungkin akan memerlukan beberapa keajaiban skrip shell untuk mendeteksi jaringan Anda dan bertindak sesuai.

DopeGhoti
sumber
1
Terima kasih DopeGhoti, saya sangat nyaman dengan solusi Anda untuk menyertakan -wandan -lanpostfix. Namun ssh saya tidak suka Usernamebidang (opsi konfigurasi buruk). Ini bekerja dengan baik tanpa itu.
Aeronaelius
2
Maaf, sintaks yang benar adalah User john, bukan UserName. Saya mengoreksi jawaban saya untuk mencerminkan ini, dan sekali Anda telah mengatur konfigurasi Anda, Anda dapat menghilangkan nama pengguna dari sshbaris perintah.
DopeGhoti
5

Ini bisa dilakukan hanya dengan ssh config, tanpa harus menggunakan alias terpisah untuk lan dan wan atau membuat port tambahan apa pun ke depan. (Tapi Anda secara alami membutuhkan beberapa cara untuk mendeteksi apakah Anda berada di dalam Lan Anda atau tidak)

Di ~/.ssh/config, Anda ingin menambahkan sesuatu seperti ini:

Match host raspi exec "am_i_outside_of_my_lan"
    HostName 12.345.67.89
    Port 1234

Di tempat am_i_outside_of_my_lanAnda akan ingin menempatkan perintah yang menentukan apakah Anda berada di dalam jaringan rumah Anda atau tidak, dan kembali dengan 0 kode keluar jika Anda berada di luarnya, dan yang lainnya sebaliknya.

The hostKondisi ini mungkin cukup jelas, tetapi execkondisi waran beberapa penjelasan: Ini cocok hanya ketika perintah diberikan kembali dengan kode keluar 0, yaitu. tidak ada kesalahan.

Jadi dengan kata lain, apa yang dilakukan adalah host raspibagian membatasi aturan ini ketika Anda mencoba untuk terhubung ke raspi host, dan exec "am_i_outside_my_lan"selanjutnya membatasi sehingga hanya berlaku ketika Anda terhubung dari luar jaringan rumah Anda. Jadi di dalam jaringan rumah Anda ssh user@raspimelakukan persis seperti biasanya, tetapi di luarnya aturannya cocok dan malah setara ssh -p 1234 [email protected].

Adapun apa yang akan digunakan am_i_outside_of_my_lan, itu tergantung sepenuhnya pada pengaturan Anda. Saya sarankan menempatkan perintah dalam skrip yang terpisah daripada mencoba untuk menulisnya inline, karena kutipannya agak sulit untuk dikerjakan dengan benar.

Secara pribadi, saya menggunakan skrip Python berikut untuk mendeteksi apakah saya berada di dalam jaringan saya sendiri: (Karena nama domain saya diputuskan menjadi ip lokal di dalam jaringan saya sendiri)

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

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

Jika Anda tidak memiliki pengaturan serupa, Anda mungkin harus melakukan sesuatu yang lain. (Misalnya, Anda dapat melihat nama jaringan nirkabel yang terhubung dengan Anda, atau bahkan menanyakan layanan apa-apa-ip-saya untuk mendapatkan ip eksternal dari jaringan yang terhubung dengan Anda)

Aleksi Torhamo
sumber
Ini jawaban yang benar; sangat menyedihkan bahwa orang lain memiliki lebih banyak suara.
Jonathan Tomer
@JonathanTomer: Ya, agar adil, saya menjawab ini 3 tahun setelah ditanya, sedangkan jawaban dengan skor lebih tinggi diposting dalam beberapa jam, jadi itu hanya kasus "burung awal mendapat cacing": P (Saya juga punya untuk mengatakan bahwa saya sangat menyukai varian spesifik Ellis Hoag dari solusi umum ini - menggunakan arp cukup pintar, dan membuat solusi lebih umum, karena dalam perintah deteksi jaringan tidak harus disetel untuk setiap pengaturan jaringan)
Aleksi Torhamo
3

Pada komputer Anda (connect- ing satu), Anda dapat mengatur nama host untuk 12.345.67.89. Buka /etc/hostsfile Anda , dan atur entri DNS:

12.345.67.89    raspi

Mesin Anda kemudian akan mengubah "raspi" menjadi "12.345.67.89" sebagai bagian dari proses penyelesaian DNS lokal. Jika Anda menggunakan beberapa mesin, perubahan harus dilakukan pada masing-masing dan setiap mesin tersebut. Masalahnya adalah: ini membutuhkan akses root untuk mengedit /etc/hosts, dan Anda mungkin tidak memilikinya di mana-mana.

Jika Anda ingin "raspi" dikenali secara otomatis dari mana saja, maka maaf: tidak mungkin. Ini akan memerlukan pendaftaran "raspi" sebagai nama domain, yang tidak dapat terjadi karena "raspi" tidak memiliki TLD, dan tidak akan bergantung pada server root DNS apa pun. Namun, Anda dapat mendaftarkan nama domain (katakanlah cfbaptista.me, dan arahkan ke alamat IP WAN Anda. Dengan beberapa penerusan porta, Anda akan dapat mengakses Raspberry Pi Anda dengan:

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

(masih, itu menghabiskan uang untuk hampir tidak ada ...)

Mengenai user@bagian itu, itu tergantung pada nama login Anda pada mesin yang berbeda. Jika Anda memiliki nama yang sama pada mesin penghubung dan pada mesin remote , maka tidak perlu ditentukan. Jika tidak, Anda perlu menentukan siapa Anda pada mesin jarak jauh .

John WH Smith
sumber
Catatan: seperti yang disebutkan dalam jawaban lain, Anda dapat membuat alias host di konfigurasi SSH Anda, yang tentu saja tidak memerlukan root.
strugee
Memang ! Berikut ini sedikit tautan: kolektifidea.com/blog/archives/2011/02/04/how-to-ssh-aliases
John WH Smith
0

Sasaran: ssh raspi harus bekerja di dalam LAN dan di Internet publik.

Untuk melakukan ini, Anda perlu memastikan bahwa nama tersebut memutuskan untuk IP internal pada LAN, dan IP publik dari luar.

Pertama, Anda harus mendapatkan nama domain seperti raspi.yourdomain.com. Lihat http://freedns.afraid.org/ untuk domain gratis untuk penggunaan hobi. Arahkan domain ke IP publik Anda

Untuk LAN, saya sarankan menjalankan DNSMasq. Firmware DD-WRT terbuka terintegrasi erat dengan DNSMasq, menggunakannya untuk DHCP dan DNS. Anda hanya perlu mengatakannya domain pencarian Anda ("domainAnda.com") dan itu akan secara otomatis menetapkan nama DNS berdasarkan pada setiap nama yang diminta klien. Untuk membuatnya bekerja, raspi's / etc / hostname harus membaca raspi.

Setelah ini diatur, raspi.domainanda.com harus menyelesaikan IP lokal di LAN Anda (pastikan Anda menggunakan DNS lokal di semua mesin Anda).

Sekarang, Anda mungkin tidak ingin mengekspos port 22 ke internet publik, karena Anda akan mendapatkan banyak lalu lintas sniffer. Jadi Anda mungkin memiliki router Anda mengekspos raspi: 22 seperti beberapa port lain, katakanlah 1234. Untuk menggunakan port yang sama pada jaringan publik dan internal, Anda dapat menambahkan aturan pengalihan port ke raspi. Di 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'

(ubah eth0 ke nama antarmuka jaringan Anda seperti yang ditunjukkan oleh ip linkatau ifconfig, dan 1234 ke port publik Anda)

Sekarang Anda dapat ssh -p 1234 raspi.yourdomain.comdari publik dan LAN.

Anda dapat menambahkan entri ke ~ / .ssh / config pada mesin klien Anda untuk mempersingkat ini menjadi adil ssh raspi, seperti yang disebutkan oleh @DopeGhoti.

Jika Anda ingin mengekspos port SSH mesin tambahan pada IP publik yang sama, ulangi saja prosesnya dengan nama DNS lain dan port publik. Bersulang!

Eric Drechsel
sumber
0

Inilah jawaban Aleksi Torhamo versi ringkas dan berfungsi menggunakan curl untuk mengambil ip publik Anda saat ini dan kemudian memeriksa apakah cocok dengan ip publik server Anda (yaitu, Anda berada di jaringan lokal yang sama).

Di ~/.ssh/configadd Anda

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
sumber
Saya percaya ssh akan memproses semua arahan yang cocok, secara berurutan, jadi secara teori Anda harus dapat melakukan sesuatu seperti Match host raspi / User john / HostName 192.168.2.7diikuti oleh Match host raspi exec "[[ $(curl -s ipinfo.io/ip) != '12.345.67.89' ]]" / HostName 12.345.67.89 / Port 1234dan mendapatkan efek yang sama dengan hanya satu curldoa, membiarkan == '12.345.67.89'kasus diasumsikan oleh kegagalan Matchaturan kedua exec.
FeRD
(Anda harus memastikan bahwa setiap argumen yang ditentukan dalam argumen pertama Matchadalah sama atau juga ditentukan pada argumen kedua - jika Anda menentukan non-standar Port xxxxdi argumen pertama Match, dan ingin menggunakan port standar di argumen kedua Match, Anda harus secara eksplisit menimpanya kembali dengan Port 22sehingga tidak terus menggunakan port xxxx.)
FeRD
0

Dengan asumsi mesin Anda memiliki IP 192.168.1. * Ketika terhubung ke LAN Anda, Anda dapat mencapainya dengan konfigurasi berikut ~/.ssh/configsehingga Anda selalu dapat menggunakan perintah yang sama (adil ssh raspi) untuk menghubungkan:

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
sumber
0

Solusi ini mengasumsikan bahwa jaringan rumah Anda memiliki satu router yang saya percaya adalah kasus umum.

Tambahkan ke ~/.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
sumber