web-dev-qa-db-ja.com

sshで端末を割り当てないことの利点は何ですか?

時々私は次のようなことをします

ssh user@Host Sudo thing

また、sshはデフォルトでは疑似ttyを割り当てないことに注意してください。なぜそうではないのですか? sshssh -tにエイリアス化すると、どのようなメリットが失われますか?

68
Chas. Owens

主な違いは、interactivityの概念です。コマンドをローカルでスクリプト内で実行するのと似ていますが、コマンドを自分で入力するのと同じです。リモートコマンドはデフォルトを選択する必要があり、非対話型が最も安全であるという点で異なります。 (そして通常最も正直です)

STDIN

  • PTYが割り当てられている場合、アプリケーションはこれを検出し、問題を壊すことなくユーザーに追加入力を促すのが安全であることを認識できます。端末が存在しない場合にユーザーに入力を求めるステップをスキップする多くのプログラムがあり、それは良いことです。そうしないと、スクリプトが不必要にハングします。
  • コマンドの実行中、入力はリモートサーバーに送信されます。これには制御シーケンスが含まれます。 Ctrl-cブレークは通常、sshコマンドのループを即座にブレークさせますが、制御シーケンスはリモートサーバーに送信されます。これにより、sshコマンドの制御が終了したとき、次のsshコマンドが始まる前に確実にキーストロークが到達するように、「打つ」必要があります。

Cronなどの無人スクリプトでssh -tを使用しないように注意します。リモートコマンドに入力のために対話的に動作するように要求する非対話型シェルは、あらゆる種類の問題を要求します。

独自のシェルスクリプトで端末の存在をテストすることもできます。新しいバージョンのbashでSTDINをテストするには:

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

STDOUT

  • sshssh -tにエイリアス化すると、行末で余分なキャリッジリターンが得られることが期待できます。それはあなたには見えないかもしれませんが、そこにあります。 ^Mにパイプすると、cat -eとして表示されます。次に、特にその出力をデータベースに挿入する場合は、この制御コードが変数に割り当てられないようにするための追加の労力を費やす必要があります。
  • また、プログラムがファイルリダイレクトに適さない出力をレンダリングできると想定するリスクもあります。通常、STDOUTをファイルにリダイレクトする場合、プログラムはSTDOUTが端末ではないことを認識し、カラーコードを省略します。 STDOUTリダイレクトがsshクライアントの出力からであり、クライアントのリモートエンドに関連付けられたPTYがある場合、リモートプログラムはそのような区別を行うことができず、出力ファイルに最終的なゴミができる。接続のリモートエンドにあるファイルに出力をリダイレクトしても、期待どおりに機能するはずです。

これは以前と同じbashテストですが、STDOUTの場合です。

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

これらの問題を回避することは可能ですが、それらを回避するスクリプトの設計を忘れることになります。私たち全員がある時点で行います。チームメンバーは、このエイリアスが設定されていることを認識または覚えていない場合があり、エイリアスを使用するスクリプトを作成すると問題が発生します。

sshからssh -tへのエイリアスは、 最小の驚き ;の設計原則に違反することになる場合がほとんどです。人々は予期しない問題に遭遇し、それらの原因を理解していない可能性があります。

73
Andrew B

SSHエスケープ文字とバイナリファイルの転送

他の回答で言及されていない利点の1つは、疑似端末なしでを操作する場合、SSHエスケープ文字です。 ~Cなどはサポートされていません;これにより、プログラムがこれらのシーケンスを含む可能性のあるバイナリファイルを転送することが安全になります。

コンセプトの証明

疑似端末を使用してバイナリファイルをコピーします。

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

疑似端末を使用せずにバイナリファイルをコピーします。

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

2つのファイルは同じではありません:

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

疑似端末でコピーされたものは壊れています:

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

もう一方はそうではありません:

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

SSHを介したファイルの転送

これは、データ転送にSSHを使用するscprsyncなどのプログラムで特に重要です。これは SCPプロトコルの仕組みの詳細な説明 は、SCPプロトコルがテキストプロトコルメッセージとバイナリファイルデータの混合でどのように構成されるかを説明しています。


OpenSSHはあなたをあなた自身から保護するのに役立ちます

-tフラグが使用されている場合でも、OpenSSH sshクライアントは、stdinストリームがターミナルでないことを検出した場合、疑似ターミナルの割り当てを拒否することに注意してください。

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

OpenSSHクライアントに-ttを使用して疑似端末を強制的に割り当てることもできます。

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

どちらの場合も、stdoutまたはstderrがリダイレクトされるかどうかは(賢明に)気になりません。

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

リモートホストでは、次の設定を行う必要があります。

/etc/sudoers
...
Defaults requiretty

須藤なし

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

そして須藤と

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

Sudoでは追加のキャリッジリターンを取得します

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

解決策は、stty -onlcrを使用して改行をキャリッジリターン-改行に変換を無効にすることです。

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

下位互換性について考えます。

Sshの2つの主なモードは、ttyを使用した対話型ログインと、ttyを使用しない指定コマンドです。これらはそれぞれrloginrshの正確な機能であるためです。 sshはrlogin/rsh機能のスーパーセットを提供して、置き換えとして成功する必要がありました。

したがって、デフォルトはsshが生まれる前に決定されました。 「コマンドを指定したいand get tty」のような組み合わせは、新しいオプションでアクセスする必要がありました。 rshを使用していたときとは異なり、少なくともhaveこのオプションを今は喜んでください。暗号化された接続を取得するために役立つ機能をトレードオフしませんでした。ボーナス機能を手に入れました!

1
user193597

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.

これにより、リモートサーバーへの「シェル」のようなものを取得できます。 notを実行するサーバーでシェルアクセスを許可し、SSHを許可する場合(つまり、GithubはSFTPアクセスの既知の例です)、このフラグを使用すると、サーバーが接続を拒否します。

シェルにはすべての環境変数($PATHなど)も含まれているため、スクリプトを実行するには、通常ttyが必要です。

0
Nathan C