ssh コマンド

暗号化の通信のできるSSHのプロトコルを使ってリモートサーバに接続するコマンド。

同様にSSHプロトコルを使うコマンドとしては mosh, sshfs, rsync などがある。

基本の使い方

$ ssh <user>@<hostname>

ちなみに似たようなコマンドとして、mosh

$ mosh <user>@<hostname>

<hostname> と書いてある箇所はホスト名でもIPでも可。

<user>@ の部分はローカルホストのログインユーザ名と同じであるか、 ~/.ssh/config にユーザ名が指定してあれば、省略可。 ~/.ssh/configssh だけでなく、 mosh, sshfs, rsync コマンドからも参照される。

sshコマンドは、後ろにパラメータとしてコマンドを書けば、リモートでコマンドを実行してコマンドが終わったらすぐにSSHを切断させることもできる。リモートへの接続をそれほど意識せずに、実行したいコマンドの先頭に ssh foohost などと付けるだけでリモートでのコマンド実行に置き換わるイメージ。

## リモートのホームディレクトリで ls -al を実行
$ ssh foohost ls -al

## リモートの特定のディレクトリに移動してからで find を実行
$ ssh foohost 'cd ~/foo/bar; find .'

## リモートとローカルとでマシンが刻んでいる時間のずれを大雑把に確認
$ ssh foohost date; date

リモートで実行したコマンドが終了コード0以外を返せば、sshコマンド自体もその終了コードを返す。でも、リモートで実行したコマンドが標準出力と標準エラー出力をしていると、それらは一緒くたになってローカルの端末に対して標準出力される。

HOWTO

ポートが22以外のSSHサーバに接続するには

$ ssh -p <port> <user>@<hostname>

-> mosh, sshfs, rsyncの場合

秘密鍵を個別に指定して接続するには

ssh -i <private_key_file> <user>@<hostname>

moshは

mosh --ssh="ssh -i <private_key_file>" <user>@<hostname>

sshfsは

sshfs -oIdentityFile=<private_key_file> <user>@<hostname>:<remote_path> <local_path>

rsyncは

rsync -e "ssh -i <private_key_file>" <user>@<hostname>:<remote_path> <local_path>

秘密鍵・公開鍵のペアを作るには

以下のコマンドで作れる。

$ ssh-keygen -t rsa -b 4096 -C 'your_email@example.com'

保存先などを質問されるので、答えていく。保存先のデフォルトは ~/.ssh/id_rsa, ~/.ssh/id_rsa.pub になる。

公開鍵をリモートのサーバに簡単に設置するには

cat ~/.ssh/id_rsa.pub | ssh <user>@<hostname> "bash -c \"if [ ! -d ~/.ssh ] ; then mkdir ~/.ssh; fi; if [ -f ~/.ssh/authorized_keys ] ; then cat >> ~/.ssh/authorized_keys; else cat >> ~/.ssh/authorized_keys2; fi\""

このコマンドを実行すると、公開鍵がリモートのサーバに設置される。リモートのサーバにとって初めての公開鍵であれば、パーミッションとかを調整する必要があるかもしれない。ファイル名が authorized_keys だったり authorized_keys2 だったりするのはよくわからない。

sshのオプションの中でbashを起動しているのは、FreeBSDのサーバなどでデフォルトのシェルがcshの場合に、ifの構文が違っていて動かないので、bashを強制するため。

強制的に切断するには

sshコマンドでは、エンターを押した直後に ~. と入力と切断される。エンターを押した直後の ~ は ssh接続自体へのコマンドのプレフィックスとなる。エンターの直後に ~ 自体を端末に入力するには ~~ と2回入力する。

moshコマンドでは、 Ctrl+^ . と入れると、エンターの直後でなくても強制切断される。

SSHが勝手に切断されないようにするには

クライアント側(接続元)の ~/.ssh/config に以下を記述する。

Host *
  ServerAliveInterval 60

ポートフォワードの待ち受けポートに外部から接続できるようにするには

ポートを待ち受ける方のホストの /etc/ssh/sshd_config に以下を書いておく。

GatewayPorts yes

外部からファイアウォールの内側にあるローカルホストの22番に接続できるようにしようと思って、以下のコマンドを実行しても、上記の設定がリモートホスト (remoteA)にないと、8022番ポートに接続できるのは、リモートホスト(remoteA)の中からのみで、第三のホスト(remoteB)からはremoteAの8022番ポートに接続できない。

ssh -R 8022:localhost:22 remoteA

イメージ図

/------------\  /-----------\
|  remoteA   |  |  remoteB  |
|            |  |           |
|  port:8022 |  |           |
\-----||-----/  \-----------/
      ||
      ||
/-----||-----\
|  port:22   |
|            |
|  Local     |
\------------/

iptablesなどでポートが閉じられていたら当然外部からは接続できないので、 iptablesの設定も合わせて確認しておくこと。

-L を使う場合は、上記を設定しても外部からローカルの待受ポートに接続できない。ローカルの待受ポートはデフォルトではローカルからしか接続できないようになっている。外部からも接続できるようにするには、上記設定に加え、sshコマンドのオプションに -g を付ける必要がある。さらに

ssh -L 8022:localhost:22 -g remoteA

リモートのファイルシステムをあたかもローカルにあるかのように見せかけるには

sshfsコマンドを使う。このコマンドはリモートのファイルシステムのルートまたは特定のディレクトリ配下を、ローカルの任意の場所にマウントする。例えば、リモートのファイルをいちいちダウンロード・アップロードしなくても直接ローカルのエディタで編集することできたりする。

リモートでコマンドを実行してすぐにssh切断するには

sshコマンドの最後にコマンドを書けばよい。

$ ssh <user>@<hostname> ls -al

複数のコマンドを使ったり、パイプを使ったりしたければ、コマンド全体をシングルクオートかダブルクオートで囲む。

## リモートの result.txt に結果を保存
$ ssh <user>@<hostname> "foo | bar > result.txt"

## ローカルの result.txt に結果を保存
$ ssh <user>@<hostname> "foo | bar" > result.txt

リモートとの間でファイルをバックアップするには

サーバにある大量のファイルを tar しながら、ローカルにダウンロードするには

$ ssh <user>@<hostname> tar cvzf - <target remote directory> > <local tar file name>

リモートでtarを実行してファイルに書き出すのではなく標準出力に出して、それをsshでそのままローカルに転送し、ローカルでファイルに書き出している。

ローカルにある大量のファイルを tar しながら、リモートにアップロードするには

$ tar czf - <target local directory> | ssh <user>@<hostname> "cat > <remote tar file name>"

途中で途切れてしまった場合に中途半端なアーカイブファイルがリモートに残ってしまうので、いったん一時ファイルに書き出してからリネームしたほうがいいかもしれない。

$ tar czf - ローカルのバックアップ対象ディレクトリ | ssh リモートホスト名 "cat > リモートの一時ファイル名 && mv リモートの一時ファイル名 リモートの保存先tarファイル名"

リモートに特定のファイルが存在するかどうかを確認するには

リモートのファイルの存在確認をするとりあえずの方法の例

if ssh REMOTE_HOST test -e REMOTE_TARGET_FILE_PATH; then
    # ファイルが存在する場合の処理
fi

ただ、これだとssh接続に失敗した場合には存在しない扱いになってしまう。

関連するツール

autossh

sshセッションが切れたときに自動で再接続してくれるツール。 moshを使っていれば問題ないが、 SSH port forwarding を使っている場合は、moshが対応していないので、このツールが便利かもしれない。

mosh

モバイル環境に強くしたssh。

mosh参照。

このサイトは筆者(hydrocul)の個人メモの集合です。すべてのページは永遠に未完成です。
スポンサーリンク