Lợi ích của việc không phân bổ một thiết bị đầu cuối trong ssh là gì?


66

Thỉnh thoảng tôi sẽ làm một cái gì đó như

ssh user@host sudo thing

và tôi được nhắc nhở rằng ssh không phân bổ giả giả theo mặc định. Tại sao không? Lợi ích tôi sẽ mất nếu tôi aliased sshđể ssh -t?


1
> Tôi được nhắc nhở rằng ssh không phân bổ psuedo-tty Điều gì xảy ra? Nó sẽ làm phong phú thêm câu hỏi để hiểu vấn đề là gì.
Không khí

5
@Air Không có vấn đề gì tôi đã cố gắng khắc phục. Có một sự lựa chọn trong cách thực hiện ssh mà tôi đang cố gắng hiểu. Câu hỏi rất rõ ràng và câu trả lời của Andrew B giải quyết câu hỏi độc đáo. Câu trả lời có thể được tóm tắt như thế này: chạy ssh -tluôn là xấu vì nó có thể khiến một số lệnh bị phá vỡ theo những cách kỳ lạ. Trong khi đó, việc chạy một lệnh cần PTY mà không có một kết quả trong một thông báo lỗi rõ ràng rằng bạn cần một thiết bị đầu cuối.
Chas. Owens

Câu trả lời:


73

Sự khác biệt chính là khái niệm tương tác . Nó tương tự như chạy các lệnh cục bộ bên trong tập lệnh, so với việc tự gõ chúng ra. Điều khác biệt ở chỗ một lệnh từ xa phải chọn mặc định và không tương tác là an toàn nhất. (và thường là trung thực nhất)

STDIN

  • Nếu PTY được phân bổ, các ứng dụng có thể phát hiện ra điều này và biết rằng nó an toàn để nhắc người dùng nhập thêm mà không phá vỡ mọi thứ. Có nhiều chương trình sẽ bỏ qua bước nhắc người dùng nhập liệu nếu không có thiết bị đầu cuối, và đó là một điều tốt. Nó sẽ làm cho các kịch bản treo không cần thiết khác.
  • Đầu vào của bạn sẽ được gửi đến máy chủ từ xa trong suốt thời gian của lệnh. Điều này bao gồm các chuỗi kiểm soát. Mặc dù Ctrl-cngắt thường làm cho vòng lặp trên lệnh ssh bị ngắt ngay lập tức, thay vào đó các chuỗi điều khiển của bạn sẽ được gửi đến máy chủ từ xa. Điều này dẫn đến một nhu cầu "đập" tổ hợp phím để đảm bảo rằng nó đến khi điều khiển rời khỏi lệnh ssh, nhưng trước khi lệnh ssh tiếp theo bắt đầu.

Tôi sẽ thận trọng không sử dụng ssh -ttrong các tập lệnh không giám sát, chẳng hạn như crons. Một shell không tương tác yêu cầu một lệnh từ xa hành xử tương tác cho đầu vào là yêu cầu tất cả các loại rắc rối.

Bạn cũng có thể kiểm tra sự hiện diện của thiết bị đầu cuối trong tập lệnh shell của riêng bạn. Để kiểm tra STDIN với các phiên bản bash mới hơn:

# fd 0 is STDIN
[ -t 0 ]; echo $?

TUYỆT VỜI

  • Khi răng cưa sshđến ssh -t, bạn có thể mong đợi để có được một lợi nhuận vận chuyển thêm trong dòng kết thúc của bạn. Nó có thể không hiển thị với bạn, nhưng nó ở đó; nó sẽ hiển thị như ^Mkhi đường ống đến cat -e. Sau đó, bạn phải dành nỗ lực bổ sung để đảm bảo rằng mã điều khiển này không được gán cho các biến của bạn, đặc biệt nếu bạn sẽ chèn đầu ra đó vào cơ sở dữ liệu.
  • Cũng có rủi ro là các chương trình sẽ cho rằng chúng có thể khiến đầu ra không thân thiện với việc chuyển hướng tệp. Thông thường nếu bạn chuyển hướng STDOUT sang một tệp, chương trình sẽ nhận ra rằng STDOUT của bạn không phải là thiết bị đầu cuối và bỏ qua bất kỳ mã màu nào. Nếu chuyển hướng STDOUT là từ đầu ra của máy khách ssh và có PTY được liên kết với đầu cuối của máy khách, các chương trình từ xa không thể phân biệt như vậy và bạn sẽ kết thúc với rác đầu cuối trong tệp đầu ra của mình. Chuyển hướng đầu ra đến một tệp ở đầu xa của kết nối vẫn hoạt động như mong đợi.

Đây là thử nghiệm bash tương tự như trước đó, nhưng đối với STDOUT:

# fd 1 is STDOUT
[ -t 1 ]; echo $?

Mặc dù có thể giải quyết các vấn đề này, nhưng chắc chắn bạn sẽ quên thiết kế các tập lệnh xung quanh chúng. Tất cả chúng ta làm tại một số điểm. Các thành viên trong nhóm của bạn cũng có thể không nhận ra / nhớ rằng bí danh này được đặt đúng chỗ, điều này sẽ tạo ra vấn đề cho bạn khi họ viết các tập lệnh sử dụng bí danh của bạn.

Aliasing sshđể ssh -tđược rất nhiều trường hợp bạn sẽ được vi phạm các nguyên tắc thiết kế của ít nhất ngạc nhiên ; mọi người sẽ gặp phải những vấn đề họ không mong đợi và có thể không hiểu điều gì gây ra chúng.


9
Người ta gần như có ấn tượng rằng tôi đã làm việc trong một nhóm đã làm điều này ...
Andrew B

Ở phạm vi được bao phủ bởi câu trả lời này, thật tuyệt vời. Nhưng câu hỏi có phạm vi rộng hơn, về cơ bản muốn biết TẤT CẢ sự khác biệt (những gì mong đợi). Thông tin bổ sung: Ở cấp độ quy trình, -t sẽ ĐẦU TIÊN phân bổ một tty và THEN chạy shell (trên đường đi, tìm nguồn / etc / profile và ~ / .bash_profile) và THEN chạy lệnh. Nếu không có -t, ssh sẽ CÀI ĐẶT nguồn các tệp env khác nhau (/etc/bash.bashrc, sau đó ~ / .bashrc) và THEN chạy lệnh của bạn. Điều này có nghĩa là bạn có thể thấy các hành vi rất khác nhau trong mỗi hành vi: ngắn hơn $ PATH, có thể là lỗi bash 'unary' vì var ENV mà bạn cho là không có ...
Scott Prive

@Crossfit Chúng tôi đề cập đến chủ đề về vỏ đăng nhập so với ý kiến ​​của câu trả lời khác, nhưng chúng tôi đã không đi sâu vào sự khác biệt về môi trường vì OP đã xem xét câu hỏi được trả lời cho nhu cầu cụ thể của họ. Xin vui lòng thêm chi tiết nơi bạn thấy phòng để làm như vậy vì nó có thể giúp những người khác đến hỏi đáp này.
Andrew B

33

SSH thoát ký tự và chuyển các tệp nhị phân

Một lợi thế mà chưa được đề cập trong câu trả lời khác là khi hoạt động mà không có một giả thiết bị đầu cuối , SSH thoát khỏi nhân vật như ~Cđang không được hỗ trợ ; điều này giúp các chương trình chuyển các tệp nhị phân có thể chứa các chuỗi này trở nên an toàn.

Bằng chứng của khái niệm

Sao chép tệp nhị phân bằng thiết bị đầu cuối giả:

$ ssh -t anthony@remote_host 'cat /usr/bin/free' > ~/free
Connection to remote_host closed.

Sao chép tệp nhị phân mà không sử dụng thiết bị đầu cuối giả:

$ ssh anthony@remote_host 'cat /usr/bin/free' > ~/free2

Hai tệp không giống nhau:

$ diff ~/free*
Binary files /home/anthony/free and /home/anthony/free2 differ

Cái được sao chép bằng thiết bị đầu cuối giả bị hỏng:

$ chmod +x ~/free*
$ ./free
Segmentation fault

trong khi cái khác thì không:

$ ./free2
             total       used       free     shared    buffers     cached
Mem:       2065496    1980876      84620          0      48264    1502444
-/+ buffers/cache:     430168    1635328
Swap:      4128760        112    4128648

Truyền tệp qua SSH

Điều này đặc biệt quan trọng đối với các chương trình như scphoặc rsyncsử dụng SSH để truyền dữ liệu. Đây mô tả chi tiết về cách thức giao thức SCP việc giải thích cách các giao thức SCP bao gồm một hỗn hợp của các thông điệp giao thức văn bản và dữ liệu tập tin nhị phân.


OpenSSH giúp bảo vệ bạn khỏi chính bạn

Điều đáng chú ý là ngay cả khi -tcờ được sử dụng, sshứng dụng khách OpenSSH sẽ từ chối phân bổ thiết bị đầu cuối giả nếu phát hiện ra rằng stdinluồng của nó không phải là thiết bị đầu cuối:

$ echo testing | ssh -t anthony@remote_host 'echo $TERM'
Pseudo-terminal will not be allocated because stdin is not a terminal.
dumb

Bạn vẫn có thể buộc ứng dụng khách OpenSSH phân bổ thiết bị đầu cuối giả với -tt:

$ echo testing | ssh -tt anthony@remote_host 'echo $TERM'
xterm

Trong cả hai trường hợp, nó (một cách hợp lý) không quan tâm nếu stdouthoặc stderrđược chuyển hướng:

$ ssh -t anthony@remote_host 'echo $TERM' >| ssh_output
Connection to remote_host closed.

2
Đó là một điểm rất thú vị mà tôi chưa xem xét, cảm ơn vì đã thêm câu trả lời này!
Jenny D nói Phục hồi lại

4

Trên máy chủ từ xa, chúng ta phải thực hiện với cài đặt này:

/etc/sudoers
...
Defaults requiretty

Không có sudo

$ ssh -T user@host echo -e 'foo\\nbar' | cat -e
foo$
bar$

Và với sudo

$ ssh -T user@host sudo echo -e 'foo\\nbar' | cat -e
sudo: sorry, you must have a tty to run sudo

Với sudo, chúng tôi nhận được thêm tiền vận chuyển

$ ssh -t user@host sudo echo -e 'foo\\nbar' | cat -e
foo^M$
      bar^M$
            Connection to localhost closed.

Giải pháp là để vô hiệu hóa các dịch xuống dòng để vận chuyển trở lại-newline vớistty -onlcr

$ ssh -t user@host stty -onlcr\; sudo echo -e 'foo\\nbar' | cat -e
foo$
    bar$
        Connection to localhost closed.

1
Đẹp nhưng đầu ra được thụt vào /: Bạn có biết nếu bạn có thể tự động vận chuyển-trả lại nó (giống như unix) không?
Boop

1

Hãy suy nghĩ về khả năng tương thích ngược.

Hai chế độ chính của ssh là đăng nhập tương tác với lệnh tty và lệnh được chỉ định mà không có tty, vì đó là các khả năng chính xác rloginrshtương ứng. ssh cần thiết để cung cấp siêu bộ rlogin/ rshtính năng để thành công thay thế.

Vì vậy, mặc định đã được quyết định trước khi ssh ra đời. Các kết hợp như "Tôi muốn chỉ định một lệnh nhận được một tty" phải được truy cập với các tùy chọn mới. Hãy vui mừng vì ít nhất chúng ta tùy chọn đó bây giờ, không giống như khi chúng ta đang sử dụng rsh. Chúng tôi đã không đánh đổi bất kỳ tính năng hữu ích nào để có được kết nối được mã hóa. Chúng tôi có các tính năng tiền thưởng!


0

Từ man ssh:

 -t      Force pseudo-tty allocation.  This can be used to execute arbi-
         trary screen-based programs on a remote machine, which can be
         very useful, e.g. when implementing menu services.  Multiple -t
         options force tty allocation, even if ssh has no local tty.

Điều này cho phép bạn có được một "vỏ" các loại cho máy chủ từ xa. Đối với các máy chủ không cấp quyền truy cập shell nhưng cho phép SSH (nghĩa là Github là một ví dụ đã biết về quyền truy cập SFTP), sử dụng cờ này sẽ khiến máy chủ từ chối kết nối của bạn.

Shell cũng có tất cả các biến môi trường của bạn (như $PATH) vì vậy việc thực thi các script thường cần một tty để làm việc.


1
Điều này không trả lời câu hỏi. Tôi đã biết cách phân bổ một giả. Tôi muốn biết lý do tại sao tôi không nên luôn luôn phân bổ một.
Chas. Owens

1
@ Chas.Owens Bởi vì, như tôi đã chỉ ra trong câu trả lời, một số máy chủ SSH không cho phép truy cập tty và nó sẽ hủy kết nối nếu bạn yêu cầu một máy chủ từ máy chủ.
Nathan C

5
Tôi nghĩ rằng bạn có thể nhận được một số thuật ngữ của bạn nhầm lẫn. Nó không phải là vỏ đơn giản vì PTY được liên kết với nó. Có ba loại shell: non-interactive, interactive, và login. loginlà một đặc tính bổ sung của hai loại vỏ khác. Các hoán vị của ba điều này xác định tập tin nào có nguồn gốc khi đăng nhập, do đó ảnh hưởng đến cách môi trường sẽ được khởi tạo. (các biến, như bạn đã đề cập)
Andrew B

3
@AndrewB Bạn nói đúng ... Tôi cũng đã học được điều gì đó từ câu hỏi này. :)
Nathan C
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.