Saya memiliki beberapa raspberry pi yang menjalankan Arch Linux (Tanpa GUI) yang perlu saya akses. Pi ini berada di belakang firewall di setiap lokasi unik. Saat ini saya menggunakan openvpn untuk terhubung ke ini tetapi biaya sistem itu mahal per lisensi. Saya menggunakan server akses dari mereka.
Akibatnya, saya mencoba merancang dan menyiapkan sistem yang memungkinkan saya untuk masuk ke server VPN (vps) saya dan menjalankan perintah untuk mencari nama tertentu (OfficeDevice1991) seperti:customcommandsearch "OfficeDevice1991"
dan kemudian mengembalikan alamat IP mesin atau sesuatu yang dapat saya gunakan untuk SSH. Saya juga mencari kemampuan untuk menjalankan perintah untuk membuat daftar setiap perangkat aktif yang terhubung. Ini mencantumkan kembali IP, nama, dan mungkin sudah berapa lama aktif.
Untuk tujuan ini, tentu saja saya perlu membuat sesuatu yang menyertakan nama perangkat (dalam hal ini OfficeDevice1991) dan kemudian pi itu akan dapat terhubung ke server publik vps saya. Dari server publik, saya dapat masuk dan melakukan pencarian di setiap perangkat yang terhubung dengannya dan mengembalikan informasi yang diperlukan untuk masuk ke ssh.
Saya telah melihat ke dalam SSH terbalik dan sejauh ini saya mendapatkan salah satu test pi saya yang terhubung dan dapat diakses dari vps saya menggunakan perintah berikut:
PI:
ssh -fN -R 12345:localhost:22 -i /publickeyfile [email protected] //Pi's command to connect to vpn
VPS:
ssh -p 12345 [email protected] //command for vpn to connect to pi
Ini berfungsi dengan baik, tetapi menggunakan metode ini, jika saya menerapkannya, saya akan mengalami beberapa masalah:
- Saya perlu menyiapkan port unik yang tidak digunakan
- Beberapa cara agar port/terowongan ini tetap terbuka
- Saya perlu membuat sistem untuk mengidentifikasi setiap perangkat. Saya dapat memasukkan setiap port ke nama seperti file teks secara lokal? Akan bermanfaat untuk dapat memasukkannya ke dalam pengaturan ssh untuk setiap perangkat jika memungkinkan. Saya masih perlu memastikan port yang saya gunakan tidak digunakan oleh program lain atau perangkat apa pun yang sudah ada di sana.
Apa yang tidak ingin saya lakukan
-
Periksa port mana yang gratis digunakan untuk setiap RPI
-
Harus mengedit
.ssh/config
secara manual untuk menambahkan nama untuk mewakili setiap port yang ditetapkan ke RPI dari bagian 1 di atas.
Saya menulis ini untuk informasi/bantuan tentang apa yang harus dilakukan untuk tujuan saya.
Adakah yang bisa memberi saya solusi yang sesuai?
Jawaban yang Diterima:
Berikut solusi menggunakan OpenSSH>=6.7 + socat:
-
OpenSSH>=6.7 dapat menggunakan penerusan soket domain Unix
Itu berarti titik akhir terowongan terbalik akan menjadi soket pendengar UNIX, bukan soket pendengar TCP tradisional. Anda kemudian dapat mengelola armada RPI dengan lebih mudah dengan skema penamaan yang mudah:nama soket akan menjadi nama pilihan (dan tetap) RPI, seperti
OfficeDevice1991
. Itu bahkan bisa menjadi properti unik dari RPI selama itu adalah nama file yang valid (karena nama soket unix mematuhi konvensi nama file). Misalnya nama hostnya, alamat MAC ethernet atau kartu wifinya …SSH dapat menangani soket unix untuk terowongan, bukan untuk menghubungkannya sendiri. Ini akan membutuhkan bantuan
ProxyCommand
untuk dapat bekerja sebagai klien unix-socket. socat dapat menangani banyak jenis koneksi, termasuk soket unix.PEMBARUAN:
Ada juga masalah khusus yang harus ditangani:file soket unix tidak dihapus saat keluar bersih, juga tidak akan dihapus misalnya setelah crash. Ini memerlukan opsiStreamLocalBindUnlink=yes
. Awalnya saya tidak menemukan bahwa, seperti namanya, opsi ini harus disetel pada simpul yang membuat soket unix. Jadi pada akhirnya disetel pada klien dengan penerusan lokal (-L
) atau yang lain di server (disshd_config
) dengan penerusan jarak jauh (-R
). OP menemukannya di sana. Solusi ini menggunakan penerusan jarak jauh.Konfigurasi pada VPS:
mkdir /rpi-access
(sebagai root) edit
sshd_config
file (/etc/ssh/sshd_config
). Ini membutuhkan opsi tambahan ini:StreamLocalBindUnlink yes
Bergantung pada opsi default, mungkin juga memerlukan
AllowStreamLocalForwarding yes
UPDATE2:
Juga disetel disshd_config
parameterClientAliveInterval
danClientAliveCountMax
, sehingga memungkinkan untuk mendeteksi pemutusan dalam waktu yang wajar, misalnya:ClientAliveInterval 300 ClientAliveCountMax 2
Koneksi ssh yang basi kemudian harus dideteksi lebih awal di VPS (~10mn dengan contoh), dan proses sshd yang sesuai kemudian akan keluar.
Penggunaan pada RPI:
ssh -fN -R /rpi-access/OfficeDevice1991:localhost:22 -i /privatekeyfile [email protected]
Dalam file konfigurasi ini akan mirip dengan ini:
Host ip User useraccount RemoteForward /rpi-access/OfficeDevice1991:localhost:22 IdentityFile /privatekeyfile
Mengulanginya lagi:
StreamLocalBindUnlink yes
setel disshd
di sisi VPS opsi itu penting:soket yang baru saja dibuat tidak dihapus, bahkan saat keluar normal. Opsi ini memastikan bahwa soket dilepas jika ada sebelum digunakan, sehingga memungkinkan untuk digunakan kembali untuk penyambungan ulang lebih lanjut. Ini juga berarti seseorang tidak dapat menganggap keberadaan soket saja sebagai arti RPI terhubung (tetapi lihat nanti).Sekarang ini memungkinkan untuk dilakukan di VPS:
ssh -o 'ProxyCommand=socat UNIX:/rpi-access/%h -' [email protected]
Sebagai file konfigurasi, mengingat misalnya RPI memiliki semua nama yang dimulai dengan OfficeDevice :
Host OfficeDevice* User rpiuseraccount ProxyCommand socat UNIX:/rpi-access/%h -
-
Untuk menyimpan tautan, cukup gunakan loop
RPI dapat menjalankan loop menghubungkan kembali ssh ke VPS setiap kali koneksi berakhir. Untuk ini tidak boleh menggunakan mode latar belakang (tidak ada
-f
). Mekanisme keepalive juga harus digunakan. TCPKeepAlive (tingkat sistem) atau ServerAliveInterval (tingkat aplikasi) tersedia. Saya pikir TCPKeepAlive hanya berguna di server (sisi yang menerima koneksi), jadi lebih baik gunakan ServerAliveInterval.Nilainya (serta ServerAliveCountMax) mungkin harus disesuaikan tergantung pada berbagai kriteria:firewall menjatuhkan koneksi tidak aktif setelah waktu tertentu, penundaan pemulihan yang diinginkan, tidak menghasilkan lalu lintas yang tidak berguna, … katakanlah 300 detik di sini.
OfficeDevice1991 RPI:
#!/bin/sh while : ; do ssh -N -o ConnectTimeout=30 -o ServerAliveInterval=300 -R /rpi-access/OfficeDevice1991:localhost:22 -i /privatekeyfile [email protected] sleep 5 # avoid flood/DDoS in case of really unexpected issues done
Bahkan jika sisi jarak jauh belum mendeteksi kegagalan konektivitas sebelumnya, dan untuk beberapa waktu lagi koneksi ssh lama masih berjalan,
StreamLocalBindUnlink yes
tetap akan secara paksa menyegarkan soket unix ke koneksi baru. -
sudah ditangani oleh 1.
Tidak ada
customcommandsearch
diperlukan. Dengan pengaturan yang tepat di 1. hanya menggunakanssh OfficeDevice1991
akan terhubung ke OfficeDevice1991.Jika diperlukan di VPS, sebagai
root
pengguna saja, perintah ini:fuser /rpi-access/*
dapat menunjukkan RPI mana yang saat ini terhubung (tentu saja kecuali yang baru saja kehilangan koneksi sebelum terdeteksi). Itu tidak akan menampilkan file soket unix basi karena tidak ada proses yang terkait dengannya.