Câu hỏi (TL; DR)
Khi gán các cổng động để chuyển tiếp từ xa ( -R
tùy chọn aka ), làm thế nào một tập lệnh trên máy từ xa (ví dụ có nguồn gốc từ .bashrc
) xác định cổng nào được OpenSSH chọn?
Lý lịch
Tôi sử dụng OpenSSH (ở cả hai đầu) để kết nối với máy chủ trung tâm của chúng tôi, mà tôi chia sẻ với nhiều người dùng khác. Đối với phiên từ xa của tôi (bây giờ) tôi muốn chuyển tiếp X, ly và pulseaudio.
Điều quan trọng nhất là chuyển tiếp X, sử dụng -X
tùy chọn. Địa chỉ X được phân bổ được lưu trữ trong biến môi trường DISPLAY
và từ đó tôi có thể xác định cổng TCP tương ứng, trong hầu hết các trường hợp. Nhưng tôi hầu như không cần, vì Xlib vinh danh DISPLAY
.
Tôi cần một cơ chế tương tự cho ly và pulseaudio. Các khái niệm cơ bản cho cả hai dịch vụ tồn tại, dưới dạng các biến môi trường CUPS_SERVER
và PULSE_SERVER
, tương ứng. Dưới đây là ví dụ sử dụng:
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
Vấn đề là thiết lập CUPS_SERVER
và PULSE_SERVER
chính xác.
Chúng tôi sử dụng chuyển tiếp cổng rất nhiều và do đó tôi cần phân bổ cổng động. Phân bổ cổng tĩnh không phải là một lựa chọn.
OpenSSH có một cơ chế phân bổ cổng động trên máy chủ từ xa, bằng cách chỉ định 0
là cổng liên kết để chuyển tiếp từ xa ( -R
tùy chọn). Bằng cách sử dụng lệnh sau, OpenSSH sẽ tự động phân bổ các cổng cho cốc và chuyển tiếp xung.
ssh -X -R0:localhost:631 -R0:localhost:4713 datserver
Khi tôi sử dụng lệnh đó, ssh
sẽ in như sau 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
Có thông tin tôi muốn! Cuối cùng tôi muốn tạo ra:
export CUPS_SERVER=localhost:41273
export PULSE_SERVER=localhost:55710
Tuy nhiên, thông báo "Cổng được phân bổ ..." được tạo trên máy cục bộ của tôi và được gửi tới STDERR
, mà tôi không thể truy cập trên máy từ xa. OpenSSH đủ kỳ lạ dường như không có phương tiện để lấy Thông tin về chuyển tiếp cổng.
Làm cách nào để tôi tìm nạp thông tin đó để đưa nó vào tập lệnh shell để thiết lập đầy đủ CUPS_SERVER
và PULSE_SERVER
trên máy chủ từ xa?
Đường cùng
Điều dễ dàng duy nhất tôi có thể tìm thấy là tăng tính dài dòng sshd
cho đến khi thông tin đó có thể được đọc từ nhật ký. Điều này là không khả thi vì thông tin tiết lộ nhiều thông tin hơn mức có thể truy cập được bởi người dùng không phải root.
Tôi đã suy nghĩ về việc vá OpenSSH để hỗ trợ một chuỗi thoát bổ sung in ra một biểu diễn đẹp của cấu trúc bên trong permitted_opens
, nhưng ngay cả khi đó là những gì tôi muốn, tôi vẫn không thể truy cập tập lệnh thoát khỏi trình khách thoát khỏi phía máy chủ.
Phải có cách tốt hơn
Cách tiếp cận sau đây có vẻ rất không ổn định và bị giới hạn ở một phiên SSH như vậy cho mỗi người dùng. Tuy nhiên, tôi cần ít nhất hai phiên đồng thời như vậy và những người dùng khác thậm chí nhiều hơn. Nhưng tôi đã cố gắng ...
Khi các ngôi sao được căn chỉnh hợp lý, đã hy sinh một hoặc hai con gà, tôi có thể lạm dụng thực tế sshd
không phải là người dùng của mình, nhưng bỏ đặc quyền sau khi đăng nhập thành công, để làm điều này:
lấy danh sách số cổng cho tất cả các ổ cắm nghe thuộc về người dùng của tôi
netstat -tlpen | grep ${UID} | sed -e 's/^.*:\([0-9]\+\) .*$/\1/'
lấy danh sách số cổng cho tất cả các ổ cắm nghe thuộc quy trình người dùng của tôi bắt đầu
lsof -u ${UID} 2>/dev/null | grep LISTEN | sed -e 's/.*:\([0-9]\+\) (LISTEN).*$/\1/'
Tất cả các cổng nằm trong tập đầu tiên, nhưng không phải trong tập thứ hai có khả năng cao là các cổng chuyển tiếp của tôi và thực sự trừ đi các sản lượng của tập hợp
41273
,55710
và6010
; cốc, xung và X, tương ứng.6010
được xác định là cổng X sử dụngDISPLAY
.41273
là cổng cốc, vìlpstat -h localhost:41273 -a
trả về0
.55710
là cổng xung, vìpactl -s localhost:55710 stat
trả về0
. (Nó thậm chí còn in tên máy chủ của khách hàng của tôi!)
(Để thực hiện cài đặt cơ sở I sort -u
và lưu trữ đầu ra từ các dòng lệnh trên và sử dụng comm
để thực hiện cơ chế.)
Pulseaudio cho phép tôi xác định ứng dụng khách và, đối với tất cả ý định và mục đích, điều này có thể đóng vai trò là mỏ neo để phân tách các phiên SSH cần tách biệt. Tuy nhiên, tôi đã không tìm thấy một cách để buộc 41273
, 55710
và 6010
với cùng sshd
quá trình. netstat
sẽ không tiết lộ thông tin đó cho người dùng không root. Tôi chỉ nhận được một -
trong các PID/Program name
cột nơi tôi muốn đọc 2339/54
(trong trường hợp đặc biệt này). Rất gần ...
netstat
sẽ không hiển thị cho bạn PID cho các quy trình bạn không sở hữu hoặc đó là không gian hạt nhân. Ví dụ