Pertanyaan (TL; DR)
Ketika menetapkan port secara dinamis untuk penerusan jarak jauh ( -R
opsi alias ), bagaimana skrip pada mesin jarak jauh (misalnya bersumber dari .bashrc
) menentukan port mana yang dipilih oleh OpenSSH?
Latar Belakang
Saya menggunakan OpenSSH (di kedua ujungnya) untuk terhubung ke server pusat kami, yang saya bagikan dengan banyak pengguna lain. Untuk sesi jarak jauh saya (untuk saat ini) saya ingin meneruskan X, gelas dan pulseaudio.
Yang paling sepele adalah meneruskan X, menggunakan -X
opsi. Alamat X yang dialokasikan disimpan dalam variabel lingkungan DISPLAY
dan dari situ saya dapat menentukan port TCP yang sesuai, dalam banyak kasus, bagaimanapun juga. Tapi saya hampir tidak pernah perlu, karena kehormatan Xlib DISPLAY
.
Saya perlu mekanisme serupa untuk cangkir dan pulseaudio. Dasar-dasar untuk kedua layanan ada , masing-masing dalam bentuk variabel lingkungan CUPS_SERVER
dan PULSE_SERVER
. Berikut adalah contoh penggunaan:
ssh -X -R12345:localhost:631 -R54321:localhost:4713 datserver
export CUPS_SERVER=localhost:12345
lowriter #and I can print using my local printer
lpr -P default -o Duplex=DuplexNoTumble minutes.pdf #printing through the tunnel
lpr -H localhost:631 -P default -o Duplex=DuplexNoTumble minutes.pdf #printing remotely
mpg123 mp3s/van_halen/jump.mp3 #annoy co-workers
PULSE_SERVER=localhost:54321 mpg123 mp3s/van_halen/jump.mp3 #listen to music through the tunnel
Masalahnya adalah pengaturan CUPS_SERVER
dan PULSE_SERVER
benar.
Kami banyak menggunakan penerusan porta dan oleh karena itu saya memerlukan alokasi port dinamis. Alokasi port statis bukan merupakan opsi.
OpenSSH memiliki mekanisme untuk alokasi port dinamis pada server jarak jauh, dengan menetapkan 0
sebagai port-bind untuk penerusan jarak jauh ( -R
opsi). Dengan menggunakan perintah berikut, OpenSSH akan secara dinamis mengalokasikan port untuk cangkir dan penerusan pulsa.
ssh -X -R0:localhost:631 -R0:localhost:4713 datserver
Ketika saya menggunakan perintah itu, ssh
akan mencetak yang berikut ke STDERR
:
Allocated port 55710 for remote forward to 127.0.0.1:4713
Allocated port 41273 for remote forward to 127.0.0.1:631
Ada informasi yang saya inginkan! Pada akhirnya saya ingin menghasilkan:
export CUPS_SERVER=localhost:41273
export PULSE_SERVER=localhost:55710
Namun pesan "Alokasi port ..." dibuat di mesin lokal saya dan dikirim ke STDERR
, yang saya tidak dapat mengaksesnya di mesin jarak jauh. Anehnya, OpenSSH tampaknya tidak memiliki sarana untuk mengambil informasi tentang penerusan porta.
Bagaimana cara mengambil informasi itu untuk dimasukkan ke dalam skrip shell untuk secara memadai mengatur CUPS_SERVER
dan PULSE_SERVER
pada host jarak jauh?
Jalan buntu
Satu-satunya hal mudah yang dapat saya temukan adalah meningkatkan verbositas sshd
sampai informasi itu dapat dibaca dari log. Ini tidak layak karena informasi itu mengungkapkan lebih banyak informasi daripada yang dapat diakses oleh pengguna non-root.
Saya sedang berpikir tentang menambal OpenSSH untuk mendukung urutan pelarian tambahan yang mencetak representasi bagus dari struct internal permitted_opens
, tetapi bahkan jika itu yang saya inginkan, saya masih tidak dapat mengakses skrip mengakses urutan pelarian klien dari sisi server.
Pasti ada cara yang lebih baik
Pendekatan berikut ini tampaknya sangat tidak stabil dan terbatas pada satu sesi SSH per pengguna. Namun, saya membutuhkan setidaknya dua sesi bersamaan dan pengguna lain bahkan lebih. Tapi saya mencoba ...
Ketika bintang-bintang disejajarkan dengan benar, setelah mengorbankan satu atau dua ayam, saya dapat menyalahgunakan fakta yang sshd
tidak dimulai sebagai pengguna saya, tetapi menjatuhkan hak istimewa setelah login berhasil, untuk melakukan ini:
dapatkan daftar nomor port untuk semua soket mendengarkan milik pengguna saya
netstat -tlpen | grep ${UID} | sed -e 's/^.*:\([0-9]\+\) .*$/\1/'
dapatkan daftar nomor port untuk semua soket mendengarkan yang menjadi milik proses pengguna saya mulai
lsof -u ${UID} 2>/dev/null | grep LISTEN | sed -e 's/.*:\([0-9]\+\) (LISTEN).*$/\1/'
Semua port yang ada di set pertama, tetapi tidak di set kedua memiliki kemungkinan tinggi untuk menjadi port forwarding saya, dan memang mengurangi set hasil
41273
,55710
dan6010
; cangkir, nadi dan X, masing-masing.6010
diidentifikasi sebagai port X menggunakanDISPLAY
.41273
adalah port gelas, karenalpstat -h localhost:41273 -a
kembali0
.55710
adalah port pulsa, karenapactl -s localhost:55710 stat
kembali0
. (Bahkan mencetak nama host klien saya!)
(Untuk melakukan set substraksi I sort -u
dan menyimpan output dari baris perintah di atas dan gunakan comm
untuk melakukan substraksi.)
Pulseaudio memungkinkan saya mengidentifikasi klien dan, untuk semua maksud dan tujuan, ini dapat berfungsi sebagai jangkar untuk memisahkan sesi SSH yang perlu dipisahkan. Namun, saya belum menemukan cara untuk mengikat 41273
, 55710
dan 6010
ke sshd
proses yang sama . netstat
tidak akan mengungkapkan informasi itu kepada pengguna non-root. Saya hanya mendapatkan -
di PID/Program name
kolom tempat saya ingin membaca 2339/54
(dalam contoh khusus ini). Sangat dekat ...
netstat
tidak akan menunjukkan PID untuk proses yang tidak Anda miliki atau ruang kernel. Misalnya