SSH の基本: SSH Servers, Clients, and Keys
この記事はこちら (opens in a new tab)を基に、作成しました。メモ用なので、利用される場合、自己責任でお願いします。
序論
SSH は、Linux サーバーにリモートで接続するための主な手段として使用される安全なプロトコルです。 リモート シェルを生成することにより、テキストベースのインターフェイスを提供します。 接続後、ローカル端末に入力したすべてのコマンドはリモート サーバーに送信され、そこで実行されます。
このチートシート形式のガイドでは、目的を達成するために SSH に接続する一般的な方法をいくつか取り上げます。 これは、さまざまな方法でサーバーに接続または構成する方法を知る必要がある場合のクイック リファレンスとして使用できます。
このガイドの使用方法
- SSH 全般に慣れていない場合、または始めたばかりの場合は、まず「SSH の概要」セクションをお読みください。
- 達成しようとしている内容に該当する後続のセクションを使用してください。 ほとんどのセクションは他のセクションに前提されていないため、次の例を独立して使用できます。
- ナビのキーワード検索で検索可能です。
- 指定されたコマンドラインの例をコピーして貼り付け、強調表示された値を独自の値に置き換えます。
SSH の概要
リモート Linux サーバーに接続する最も一般的な方法は、SSH を使用することです。 SSH は Secure Shell の略で、リモートでコマンドを実行し、変更を加え、サービスを構成する安全な方法を提供します。 SSH 経由で接続する場合は、リモート サーバー上に存在するアカウントを使用してログインします。
SSH の仕組み
SSH 経由で接続すると、シェル セッションが開始されます。シェル セッションは、サーバーと対話できるテキストベースのインターフェイスです。 SSH セッションの間、ローカル端末に入力したコマンドはすべて、暗号化された SSH トンネルを通じて送信され、サーバー上で実行されます。
SSH 接続は、クライアント/サーバー モデルを使用して実装されます。 これは、SSH 接続を確立するには、リモート マシンが SSH デーモンと呼ばれるソフトウェアを実行している必要があることを意味します。 このソフトウェアは、特定のネットワーク ポートで接続をリッスンし、接続要求を認証し、ユーザーが正しい資格情報を提供した場合に適切な環境を生成します。
ユーザーのコンピュータには SSH クライアントが必要です。 これは、SSH プロトコルを使用した通信方法を認識し、接続するリモート ホスト、使用するユーザー名、認証に渡す必要がある資格情報に関する情報を提供できるソフトウェアです。 クライアントは、確立したい接続タイプに関する特定の詳細を指定することもできます。
SSH がユーザーを認証する方法
通常、クライアントはパスワード (安全性が低いため推奨されません) または非常に安全な SSH キーを使用して認証します。
パスワードによるログインは暗号化されており、新規ユーザーにとっても理解しやすいものになっています。 ただし、自動化されたボットや悪意のあるユーザーは、パスワードベースのログインを許可するアカウントへの認証を繰り返し試行することが多く、セキュリティの侵害につながる可能性があります。 このため、ほとんどの構成では常に SSH キーベースの認証をセットアップすることをお勧めします。
SSH キーは、認証に使用できる暗号化キーの一致するセットです。 各セットには公開キーと秘密キーが含まれています。 公開キーは心配することなく自由に共有できますが、秘密キーは慎重に保護し、誰にも公開しないようにする必要があります。
SSH キーを使用して認証するには、ユーザーはローカル コンピューター上に SSH キー ペアを持っている必要があります。 リモート サーバーでは、公開キーをユーザーのホーム ディレクトリ内の ~/.ssh/authorized_keys にあるファイルにコピーする必要があります。 このファイルには、このアカウントへのログインが許可されている公開キーのリストが 1 行に 1 つずつ含まれています。
クライアントが SSH キー認証を使用してホストに接続すると、サーバーにこの意図が通知され、どの公開キーを使用するかがサーバーに指示されます。 次に、サーバーは、authorized_keys ファイルで公開キーを確認し、ランダムな文字列を生成し、公開キーを使用して暗号化します。 この暗号化されたメッセージは、関連付けられた秘密キーを使用してのみ復号化できます。 サーバーは、この暗号化されたメッセージをクライアントに送信して、クライアントが関連する秘密キーを実際に持っているかどうかをテストします。
このメッセージを受信すると、クライアントは秘密キーを使用してメッセージを復号化し、明らかにされたランダムな文字列と以前にネゴシエートされたセッション ID を結合します。 次に、この値の MD5 ハッシュを生成し、サーバーに送り返します。 サーバーは元のメッセージとセッション ID をすでに持っているため、それらの値によって生成された MD5 ハッシュを比較し、クライアントが秘密キーを持っている必要があると判断できます。
SSH がどのように動作するかがわかったので、SSH のさまざまな動作方法を示すいくつかの例について説明します。
SSH キーの生成と使用
このセクションでは、クライアント マシンで SSH キーを生成し、公開キーを使用するサーバーに配布する方法について説明します。 今後の接続のセキュリティが強化されるため、これまでにキーを生成したことがない場合は、このセクションから始めると良いでしょう。
SSH キーペアの生成
ローカル コンピューター上で新しい SSH 公開キーと秘密キーのペアを生成することは、パスワードなしでリモート サーバーで認証するための最初のステップです。 正当な理由がない限り、常に SSH キーを使用して認証する必要があります。
RSA、DSA、ECDSA など、多数の暗号アルゴリズムを使用して SSH キーを生成できます。 一般に RSA キーが好まれており、デフォルトのキー タイプです。
ローカル コンピューター上で RSA キー ペアを生成するには、次のように入力します。
$ ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/home/demo/.ssh/id_rsa):
このプロンプトでは、RSA 秘密キーを保存する場所を選択できます。ENTER キーを押してこれをデフォルトのままにし、ユーザーのホーム ディレクトリの .ssh 隠しディレクトリに保存します。 デフォルトの場所を選択したままにすると、SSH クライアントがキーを自動的に検索できるようになります。
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
次のプロンプトでは、秘密キーを保護するために任意の長さのパスフレーズを入力できます。 デフォルトでは、追加のセキュリティ対策として、秘密キーを使用するたびに、ここで設定したパスフレーズを入力する必要があります。 パスフレーズが不要な場合は、ENTER キーを押して空白のままにしてください。 ただし、これにより、秘密キーを制御できる人は誰でもサーバーにログインできるようになることに注意してください。
パスフレーズを入力することを選択した場合、入力中に何も表示されません。 これはセキュリティ上の予防策です。
Output
Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/id_rsa.pub.
The key fingerprint is:
8c:e9:7c:fa:bf:c4:e5:9c:c9:b8:60:1f:fe:1c:d3:8a root@here
The key`s randomart image is:
+--[ RSA 2048]----+
| |
| |
| |
| + |
| o S . |
| o . * + |
| o + = O . |
| + = = + |
| ....Eo+ |
+-----------------+
この手順により、ユーザーのホーム ディレクトリ内の .ssh 隠しディレクトリに RSA SSH キー ペアが生成されました。 これらのファイルは次のとおりです。
- ~/.ssh/id_rsa: 秘密鍵。 このファイルは 共有しないでください。
- ~/.ssh/id_rsa.pub: 関連付けられた公開キー。 これは影響を与えることなく自由に共有できます。
より多くのビット数を持つ SSH キー ペアを生成する
SSH キーはデフォルトで 2048 ビットです。 一般に、セキュリティにはこれで十分であると考えられていますが、より強力なキーを作成するには、より多くのビット数を指定できます。
これを行うには、必要なビット数を指定した -b 引数を含めます。 ほとんどのサーバーは、少なくとも 4096 ビットの長さのキーをサポートしています。 DDOS 保護の目的では、これより長いキーは受け入れられない場合があります。
$ ssh-keygen -b 4096
以前に別のキーを作成していた場合は、以前のキーを上書きするかどうかを尋ねられます。
Overwrite (y/n)?
「はい」を選択すると、以前のキーが上書きされ、そのキーを使用してサーバーにログインできなくなります。 このため、キーの上書きは注意して行ってください。
秘密キーのパスフレーズの削除または変更
秘密キーのパスフレーズを生成し、それを変更または削除したい場合は、簡単に変更または削除できます。
注: パスフレーズを変更または削除するには、元のパスフレーズを知っている必要があります。 キーのパスフレーズを紛失した場合は、対処方法がなく、新しいキー ペアを生成する必要があります。
パスフレーズを変更または削除するには、次のように入力します。
$ ssh-keygen -p
Enter file in which the key is (/root/.ssh/id_rsa):
変更するキーの場所を入力するか、ENTER キーを押してデフォルト値を受け入れることができます。
Enter old passphrase:
変更したい古いパスフレーズを入力します。 新しいパスフレーズの入力を求められます。
Enter new passphrase (empty for no passphrase):
Enter same passphrase again:
ここで、新しいパスフレーズを入力するか、ENTER を押してパスフレーズを削除します。
SSH キーの指紋の表示
各 SSH キー ペアは、キーを一意に識別するために使用できる単一の暗号化「指紋」を共有します。 これはさまざまな状況で役立ちます。
SSH キーの指紋を確認するには、次のように入力します。
$ ssh-keygen -l
Enter file in which the key is (/root/.ssh/id_rsa):
それがキーの正しい位置である場合は ENTER キーを押し、それ以外の場合は変更した位置を入力します。 キーのビット長、指紋、作成されたアカウントとホスト、および使用されたアルゴリズムを含む文字列が提供されます。
Output
4096 8e:c4:82:47:87:c2:26:4b:68:ff:96:1a:39:62:9e:4e demo@test (RSA)
SSH-Copy-ID を使用して公開 SSH キーをサーバーにコピーする
公開キーをサーバーにコピーして、パスワードなしで認証できるようにするには、さまざまな方法が考えられます。
現在、サーバーに対してパスワードベースの SSH アクセスが構成されており、ssh-copy-id ユーティリティがインストールされている場合、これは簡単なプロセスです。 ssh-copy-id ツールは多くの Linux ディストリビューションの OpenSSH パッケージに含まれているため、デフォルトでインストールされる可能性が非常に高くなります。
このオプションがある場合は、次のように入力して公開キーを簡単に転送できます。
$ ssh-copy-id username@remote_host
これにより、リモート システム上のユーザー アカウントのパスワードの入力が求められます。
The authenticity of host '111.111.11.111 (111.111.11.111)' can't be established.
ECDSA key fingerprint is fd:fd:d4:f9:77:fe:73:84:e1:55:00:ad:d6:6d:22:fe.
Are you sure you want to continue connecting (yes/no)? yes
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
demo@111.111.11.111's password:
パスワードを入力すると、~/.ssh/id_rsa.pub キーの内容がユーザー アカウントの ~/.ssh/authorized_keys ファイルの末尾に追加されます。
Output
Number of key(s) added: 1
Now try logging into the machine, with: "ssh 'demo@111.111.11.111'"
and check to make sure that only the key(s) you wanted were added.
これで、パスワードなしでそのアカウントにログインできるようになります。
$ ssh username@remote_host
SSH-Copy-ID を使用せずに公開 SSH キーをサーバーにコピーする
ssh-copy-id ユーティリティを使用できないが、リモート サーバーへのパスワード ベースの SSH アクセスが可能な場合は、別の方法で公開キーの内容をコピーできます。
キーの内容を出力し、それを ssh コマンドにパイプすることができます。 リモート側では、~/.ssh ディレクトリが存在することを確認してから、パイプされたコンテンツを ~/.ssh/authorized_keys ファイルに追加できます。
$ cat ~/.ssh/id_rsa.pub | ssh username@remote_host "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys"
リモート アカウントのパスワードを入力するように求められます。
The authenticity of host '111.111.11.111 (111.111.11.111)' can't be established.
ECDSA key fingerprint is fd:fd:d4:f9:77:fe:73:84:e1:55:00:ad:d6:6d:22:fe.
Are you sure you want to continue connecting (yes/no)? yes
demo@111.111.11.111's password:
パスワードを入力するとキーがコピーされ、パスワードなしでログインできるようになります。
$ ssh username@remote_IP_host
SSH 公開キーをサーバーに手動でコピーする
パスワードベースの SSH アクセスが利用できない場合は、公開キーをリモート サーバーに手動で追加する必要があります。
ローカル マシンで、次のように入力すると、公開キー ファイルの内容を見つけることができます。
$ cat ~/.ssh/id_rsa.pub
Output
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQCqql6MzstZYh1TmWWv11q5O3pISj2ZFl9HgH1JLknLLx44+tXfJ7mIrKNxOOwxIxvcBF8PXSYvobFYEZjGIVCEAjrUzLiIxbyCoxVyle7Q+bqgZ8SeeM8wzytsY+dVGcBxF6N4JS+zVk5eMcV385gG3Y6ON3EG112n6d+SMXY0OEBIcO6x+PnUSGHrSgpBgX7Ks1r7xqFa7heJLLt2wWwkARptX7udSq05paBhcpB0pHtA1Rfz3K2B+ZVIpSDfki9UVKzT8JUmwW6NNzSgxUfQHGwnW7kj4jp4AT0VZk3ADw497M2G/12N0PPB5CnhHf7ovgy6nL1ikrygTKRFmNZISvAcywB9GVqNAVE+ZHDSCuURNsAInVzgYo9xgJDW8wUw2o8U77+xiFxgI5QSZX3Iq7YLMgeksaO4rBJEa54k8m5wEiEE1nUhLuJ0X/vh2xPff6SQ1BL/zkOhvJCACK6Vb15mDOeCSq54Cr7kvS46itMosi/uS66+PujOO+xt/2FWYepz6ZlN70bRly57Q06J+ZJoc9FfBCbCyYH7U/ASsmY095ywPsBo1XQ9PqhnN1/YOorJ068foQDNVpm146mUpILVxmq41Cj55YKHEazXGsdBIbXWhcrRf4G2fJLRcGUr9q8/lERo9oxRm5JFX6TCmj6kmiFqv+Ow9gI0x8GvaQ== demo@test
この値をコピーし、リモート サーバー上の適切な場所に手動で貼り付けることができます。 他の手段 (DigitalOcean Web コンソールなど) を介してリモート サーバーにログインする必要があります。
リモート サーバー上に ~/.ssh ディレクトリが存在しない場合は作成します。
$ mkdir -p ~/.ssh
その後、次のように入力して ~/.ssh/authorized_keys ファイルを作成または追加できます。
$ echo public_key_string >> ~/.ssh/authorized_keys
これで、パスワードなしでリモート サーバーにログインできるようになります。
基本的な接続手順
次のセクションでは、SSH を使用してサーバーに接続する方法に関する基本のいくつかを説明します。
リモートサーバーへの接続
リモート サーバーに接続し、そこでシェル セッションを開くには、ssh コマンドを使用できます。
最も単純な形式では、ローカル マシン上のユーザー名がリモート サーバー上のユーザー名と同じであると想定されます。 これが真の場合、次を使用して接続できます。
$ ssh remote_host
リモート サーバー上のユーザー名が異なる場合は、次のようにリモート ユーザーの名前を渡す必要があります。
$ ssh username@remote_host
新しいホストに初めて接続すると、次のようなメッセージが表示されます。
The authenticity of host '111.111.11.111 (111.111.11.111)' can`t be established.
ECDSA key fingerprint is fd:fd:d4:f9:77:fe:73:84:e1:55:00:ad:d6:6d:22:fe.
Are you sure you want to continue connecting (yes/no)? yes
yesと入力して、リモート ホストの信頼性を受け入れます。
パスワード認証を使用している場合は、ここでリモート アカウントのパスワードの入力を求められます。 SSH キーを使用している場合、秘密キーのパスフレーズが設定されている場合は入力を求められます。設定されていない場合は、自動的にログインされます。
リモートサーバー上で単一のコマンドを実行する
シェル セッションを生成する代わりにリモート サーバー上で単一のコマンドを実行するには、次のように接続情報の後にコマンドを追加します。
$ ssh username@remote_host command_to_run
これにより、リモート ホストに接続し、資格情報で認証され、指定したコマンドが実行されます。 接続はその後すぐに閉じられます。
異なるポートを使用したサーバーへのログイン
デフォルトでは、サーバー上の SSH デーモンはポート 22 で実行されます。SSH クライアントは、接続しようとするときにこれが当てはまると想定します。 SSH サーバーが標準以外のポートでリッスンしている場合 (これについては後のセクションで説明します)、クライアントとの接続時に新しいポート番号を指定する必要があります。
これを行うには、-p オプションでポート番号を指定します。
$ ssh -p port_num username@remote_host
リモート サーバーにログインするたびにこれを行う必要がないようにするには、ローカル コンピューターのホーム ディレクトリ内の ~/.ssh ディレクトリで構成ファイルを作成または編集できます。
次のように入力して、ファイルを編集または作成します。
$ nano ~/.ssh/config
ここでは、ホスト固有の構成オプションを設定できます。 新しいポートを指定するには、次のような形式を使用します。
Host remote_alias
HostName remote_host
Port port_num
これにより、コマンドラインで特定のポート番号を指定せずにログインできるようになります。
パスフレーズの入力を避けるために SSH キーを SSH エージェントに追加する
秘密 SSH キーにパスフレーズがある場合は、それを使用してリモート ホストに接続するたびにパスフレーズの入力を求められます。
これを繰り返し実行する必要を避けるために、SSH エージェントを実行できます。 この小さなユーティリティは、初めてパスフレーズを入力した後に秘密キーを保存します。 これはターミナル セッションの間使用できるため、将来はパスフレーズを再入力せずに接続できるようになります。
これは、SSH 認証情報を転送する必要がある場合にも重要です (後述)。
SSH エージェントを開始するには、ローカル端末セッションに次のように入力します。
$ eval $(ssh-agent)
Output
Agent pid 10891
これにより、エージェント プログラムが開始され、バックグラウンドに配置されます。 次に、秘密キーをエージェントに追加して、エージェントがキーを管理できるようにする必要があります。
$ ssh-add
Enter passphrase for /home/demo/.ssh/id_rsa:
Identity added: /home/demo/.ssh/id_rsa (/home/demo/.ssh/id_rsa)
パスフレーズ (設定されている場合) を入力する必要があります。 その後、ID ファイルがエージェントに追加され、パスフレーズを再入力することなく、キーを使用してサインインできるようになります。
サーバーで使用するための SSH 認証情報の転送
パスワードなしで別のサーバー内からあるサーバーに接続できるようにしたい場合は、SSH キー情報を転送する必要があります。 これにより、ローカル コンピューター上の資格情報を使用して、接続しているサーバーを介して別のサーバーに対して認証できるようになります。
開始するには、SSH エージェントを開始し、SSH キーをエージェントに追加する必要があります (前述を参照)。 これが完了したら、-A オプションを使用して最初のサーバーに接続する必要があります。 これにより、このセッションの認証情報がサーバーに転送されます。
$ ssh -A username@remote_host
ここから、SSH キーでアクセスが許可されている他のホストに SSH 接続できます。 秘密 SSH キーがこのサーバー上にあるかのように接続します。
サーバー側の構成オプション
このセクションには、サーバーの応答方法と許可される接続の種類を形成できる、いくつかの一般的なサーバー側構成オプションが含まれています。
パスワード認証を無効にする
SSH キーが設定、テストされ、正しく動作している場合は、パスワード認証を無効にすることをお勧めします。 これにより、ユーザーはパスワードを使用して SSH にサインインできなくなります。
これを行うには、リモート サーバーに接続し、root または sudo 権限で /etc/ssh/sshd_config ファイルを開きます。
$ sudo nano /etc/ssh/sshd_config
ファイル内で、PasswordAuthentication ディレクティブを検索します。 コメントアウトされている場合はコメントを解除してください。 パスワードによるログインを無効にするには、これを no に設定します。
PasswordAuthentication no
変更を行った後、ファイルを保存して閉じます。 変更を実装するには、SSH サービスを再起動する必要があります。
Ubuntu/Debian の場合:
$ sudo service ssh restart
CentOS/Fedora の場合:
$ sudo service sshd restart
これで、システム上のすべてのアカウントがパスワードを使用して SSH にログインできなくなります。
SSH デーモンが実行されるポートの変更
管理者の中には、SSH が実行されるデフォルトのポートを変更することを推奨する人もいます。 これにより、サーバーが自動ボットから受ける認証試行の回数を減らすことができます。
SSH デーモンがリッスンするポートを変更するには、リモート サーバーにログインする必要があります。 そのユーザーでログインするか、sudo を使用して、リモート システム上の sshd_config ファイルを root 権限で開きます。
$ sudo nano /etc/ssh/sshd_config
内部に入ったら、ポート 22 の仕様を見つけて、使用したいポートを反映するように変更することで、SSH が実行されるポートを変更できます。 たとえば、ポートを 4444 に変更するには、これをファイルに記述します。
#Port 22
Port 4444
完了したら、ファイルを保存して閉じます。 変更を実装するには、SSH デーモンを再起動する必要があります。
Ubuntu/Debian の場合:
$ sudo service ssh restart
CentOS/Fedora の場合:
$ On CentOS/Fedora:
デーモンが再起動したら、ポート番号を指定して認証する必要があります (前のセクションで説明しました)。
SSH で接続できるユーザーを制限する
SSH 経由でログインできるユーザー アカウントを明示的に制限するには、いくつかの異なる方法があり、それぞれに SSH デーモン構成ファイルの編集が含まれます。
リモート サーバー上で、root または sudo 権限を使用してこのファイルを開きます。
$ sudo nano /etc/ssh/sshd_config
ログインを許可するアカウントを指定する最初の方法は、AllowUsers ディレクティブを使用することです。 ファイル内で AllowUsers ディレクティブを検索します。 存在しない場合は、任意の場所に作成します。 ディレクティブの後に、SSH 経由でのログインを許可するユーザー アカウントをリストします。
AllowUsers user1 user2
ファイルを保存して閉じます。 デーモンを再起動して変更を実装します。
Ubuntu/Debian の場合:
$ sudo service ssh restart
CentOS/Fedora の場合:
$ sudo service sshd restart
グループ管理に慣れている場合は、代わりに AllowGroups ディレクティブを使用できます。 この場合は、SSH アクセスを許可するグループを 1 つ追加するだけです (このグループを作成し、一時的にメンバーを追加します)。
AllowGroups sshmembers
ファイルを保存して閉じます。
ここで、次のように入力して、指定したグループに一致するシステム グループ (ホーム ディレクトリなし) を作成できます。
$ sudo groupadd -r sshmembers
必要なユーザー アカウントを必ずこのグループに追加してください。 これは、次のように入力して実行できます。
$ sudo usermod -a -G sshmembers user1
$ sudo usermod -a -G sshmembers user2
次に、SSH デーモンを再起動して、変更を実装します。
Ubuntu/Debian の場合:
$ sudo service ssh restart
CentOS/Fedora の場合:
$ sudo service sshd restart
ルートログインの無効化
多くの場合、sudo 権限を持つ SSH ユーザー アカウントを設定した後、SSH を介した root ログインを完全に無効にすることをお勧めします。
これを行うには、リモート サーバー上で root または sudo を使用して SSH デーモン構成ファイルを開きます。
$ sudo nano /etc/ssh/sshd_config
内部で、PermitRootLogin というディレクティブを検索します。 コメントされている場合は、コメントを解除します。 値を「いいえ」に変更します。
PermitRootLogin no
ファイルを保存して閉じます。 変更を実装するには、SSH デーモンを再起動します。
Ubuntu/Debian の場合:
$ sudo service ssh restart
CentOS/Fedora の場合:
$ sudo service sshd restart
特定のコマンドに対する root アクセスの許可
通常は root アクセスを無効にし、特定のアプリケーションを正しく実行できるようにするために root アクセスを有効にしたい場合があります。 この例としては、バックアップ ルーチンが挙げられます。
これは、アカウントの使用を許可された SSH キーが含まれる root ユーザーの authorized_keys ファイルを通じて実行できます。
このプロセスに使用するローカル コンピューターのキーをサーバー上の root ユーザーの authorized_keys ファイルに追加します (自動プロセスごとに新しいキーを作成することをお勧めします)。 ここでは ssh-copy-id コマンドを使用して説明しますが、他のセクションで説明するキーをコピーする方法のいずれかを使用できます。
$ ssh-copy-id root@remote_host
次に、リモートサーバーにログインします。 authorized_keys ファイル内のエントリを調整する必要があるため、root または sudo アクセスでファイルを開きます。
$ sudo nano /root/.ssh/authorized_keys
アップロードしたキーを含む行の先頭に、このキーが有効なコマンドを定義する command= リストを追加します。 これには、実行可能ファイルへのフルパスと引数が含まれている必要があります。
command="/path/to/command arg1 arg2" ssh-rsa ...
完了したら、ファイルを保存して閉じます。
次に、root または sudo 権限で sshd_config ファイルを開きます。
$ sudo nano /etc/ssh/sshd_config
PermitRootLogin ディレクティブを見つけて、値を Forced-commands-only に変更します。 これにより、キーにコマンドが指定されている場合にのみ、SSH キー ログインで root を使用できるようになります。
PermitRootLogin forced-commands-only
ファイルを保存して閉じます。 SSH デーモンを再起動して、変更を実装します。
Ubuntu/Debian の場合:
$ sudo service ssh restart
CentOS/Fedora の場合:
$ sudo service sshd restart
X アプリケーション表示をクライアントに転送する
SSH デーモンは、サーバー上の X アプリケーションの表示をクライアント マシンに自動的に転送するように構成できます。 これが正しく機能するには、クライアントで X Windows システムが構成され、有効になっている必要があります。
この機能を有効にするには、リモート サーバーにログインし、root または sudo 権限で sshd_config ファイルを編集します。
$ sudo nano /etc/ssh/sshd_config
X11Forwarding ディレクティブを検索します。 コメントアウトされている場合はコメントを解除してください。 必要に応じて作成し、値をyesに設定します。
X11Forwarding yes
ファイルを保存して閉じます。 SSH デーモンを再起動して、これらの変更を実装します。
Ubuntu/Debian の場合:
$ sudo service ssh restart
CentOS/Fedora の場合:
$ sudo service sshd restart
サーバーに接続してアプリケーションの表示を転送するには、接続時にクライアントから -X オプションを渡す必要があります。
$ ssh -X username@remote_host
このセッションを通じてサーバー上で開始されたグラフィカル アプリケーションは、ローカル コンピューターに表示されます。 パフォーマンスは少し遅いかもしれませんが、ピンチの場合は非常に役立ちます。
クライアント側の構成オプション
次のセクションでは、接続のクライアント側で実行できるいくつかの調整に焦点を当てます。
サーバー固有の接続情報の定義
ローカル コンピューターでは、接続するサーバーの一部またはすべてに対して個別の構成を定義できます。 これらは ~/.ssh/config ファイルに保存でき、SSH クライアントが呼び出されるたびにこのファイルが読み取られます。
ローカル コンピューターのテキスト エディターでこのファイルを作成するか、開きます。
$ nano ~/.ssh/config
内部では、Host キーワードとその後にエイリアスを付けて各設定オプションを導入することで、個別の設定オプションを定義できます。 この下でインデントされている部分で、ssh_config man ページにあるディレクティブのいずれかを定義できます。
$ man ssh_config
構成例は次のようになります。
Host testhost
HostName your_domain
Port 4444
User demo
次のように入力するだけで、ユーザー名デモを使用してポート 4444 の your_domain に接続できます。
$ ssh testhost
ワイルドカードを使用して複数のホストと一致させることもできます。 後の一致は以前の一致をオーバーライドする可能性があることに注意してください。 このため、最も一般的な一致を一番上に配置する必要があります。 たとえば、ファイル内にこれを含めることで、your_domain をオーバーライドして、すべての接続で X 転送を許可しないようにデフォルト設定できます。
Host *
ForwardX11 no
Host testhost
HostName your_domain
ForwardX11 yes
Port 4444
User demo
完了したら、ファイルを保存して閉じます。
タイムアウトを避けるために接続を維持する
準備が整う前に SSH セッションから切断された場合は、接続がタイムアウトしている可能性があります。
この状況を回避するために、サーバーにパケットを頻繁に送信するようにクライアントを構成できます。
ローカル コンピューターで、~/.ssh/config ファイルを編集することで、接続ごとにこれを構成できます。 今すぐ開きます:
$ nano ~/.ssh/config
まだ存在しない場合は、ファイルの先頭で、すべてのホストに一致するセクションを定義します。 ServerAliveInterval を「120」に設定すると、2 分ごとにパケットがサーバーに送信されます。 接続を閉じないようにサーバーに通知するには、これで十分です。
# ~/.ssh/config
Host *
ServerAliveInterval 120
完了したら、ファイルを保存して閉じます。
ホストチェックの無効化
デフォルトでは、新しいサーバーに接続するたびに、リモート SSH デーモンのホスト キーの指紋が表示されます。
The authenticity of host '111.111.11.111 (111.111.11.111)' can`t be established.
ECDSA key fingerprint is fd:fd:d4:f9:77:fe:73:84:e1:55:00:ad:d6:6d:22:fe.
Are you sure you want to continue connecting (yes/no)? yes
これは、接続しようとしているホストの信頼性を検証し、悪意のあるユーザーがリモート ホストになりすまそうとしているインスタンスを特定できるように構成されています。
特定の状況では、この機能を無効にすることが必要な場合があります。 注: これは大きなセキュリティ リスクになる可能性があるため、システムをこのように設定する場合は何をしているのかを必ず理解してください。
変更を行うには、ローカル コンピューターで ~/.ssh/config ファイルを開きます。
$ nano ~/.ssh/config
まだ存在しない場合は、ファイルの先頭で、すべてのホストに一致するセクションを定義します。 新しいホストを known_hosts ファイルに自動的に追加するには、StrictHostKeyChecking ディレクティブを no に設定します。 新規または変更されたホストについて警告を出さないようにするには、UserKnownHostsFile を /dev/null に設定します。
Host *
StrictHostKeyChecking no
UserKnownHostsFile /dev/null
他のホストのオプションを逆にすることで、ケースバイケースでチェックを有効にすることができます。 StrictHostKeyChecking のデフォルトは ask です。
Host *
StrictHostKeyChecking no
UserKnownHostsFile /dev/null
Host testhost
HostName your_domain
StrictHostKeyChecking ask
UserKnownHostsFile /home/demo/.ssh/known_hosts
単一の TCP 接続上で SSH を多重化する
状況によっては、新しい TCP 接続の確立に予想以上に時間がかかることがあります。 同じマシンに複数の接続を確立している場合は、多重化を利用できます。
SSH 多重化では、複数の SSH セッションに対して同じ TCP 接続が再利用されます。 これにより、新しいセッションを確立するために必要な作業の一部が削除され、処理が高速化される可能性があります。 接続数を制限することは、他の理由でも役立つ場合があります。
多重化を設定するには、接続を手動で設定することも、利用可能な場合に自動的に多重化を使用するようにクライアントを構成することもできます。 ここでは 2 番目のオプションを説明します。
多重化を構成するには、ローカル マシン上で SSH クライアントの構成ファイルを編集します。
$ nano ~/.ssh/config
ファイルの先頭にワイルドカード ホスト定義がない場合は、ここで (Host * として) 追加します。 ControlMaster、ControlPath、および ControlPersist の値を設定して、多重化構成を確立します。
可能であれば、多重化を自動的に許可できるように、ControlMaster を「auto」に設定する必要があります。 ControlPath は、制御ソケットへのパスを確立します。 最初のセッションでこのソケットが作成され、ユーザー名、ホスト、ポートでラベル付けされているため、後続のセッションでこのソケットを見つけることができます。
ControlPersist オプションを 1 に設定すると、最初のマスター接続をバックグラウンドで実行できるようになります。 1 は、最後の SSH セッションが閉じられてから 1 秒後に TCP 接続が自動的に終了することを指定します。
Host *
ControlMaster auto
ControlPath ~/.ssh/multiplex/%r@%h:%p
ControlPersist 1
完了したら、ファイルを保存して閉じます。 ここで、制御パスで指定したディレクトリを実際に作成する必要があります。
$ mkdir ~/.ssh/multiplex
これで、同じマシンで確立されたセッションはすべて、既存のソケットと TCP 接続を使用しようとします。 最後のセッションが存在する場合、接続は 1 秒後に切断されます。
何らかの理由で多重化構成を一時的にバイパスする必要がある場合は、-S フラグを none で渡すことで実行できます。
$ ssh -S none username@remote_host
SSH トンネルのセットアップ
安全な SSH トンネルを介して他のトラフィックをトンネリングすることは、制限のあるファイアウォール設定を回避する優れた方法です。 また、暗号化されていないネットワーク トラフィックを暗号化する優れた方法でもあります。
サーバーへのローカルトンネリングの構成
SSH 接続を使用すると、ローカル ホストのポートからリモート ホストのポートにトラフィックをトンネリングできます。
ローカル接続は、ローカル コンピュータからリモート ホストを介してネットワークの場所にアクセスする方法です。 まず、リモート ホストへの SSH 接続が確立されます。 リモート サーバーでは、ユーザーが指定した外部 (または内部) ネットワーク アドレスへの接続が確立され、この場所へのトラフィックが指定されたポート上のローカル コンピューターにトンネリングされます。
これは、ファイアウォールをバイパスして、制限の少ないネットワーク環境にトンネリングするためによく使用されます。 もう 1 つの一般的な使用法は、リモートの場所から「localhost 専用」の Web インターフェイスにアクセスすることです。
リモート サーバーへのローカル トンネルを確立するには、接続時に -L パラメーターを使用し、次の 3 つの追加情報を指定する必要があります。
- トンネル接続にアクセスするローカル ポート。
- リモートホストの接続先となるホスト。
- リモートホストを接続するポート。
これらは、-L フラグへの引数として、上記の順序で (コロンで区切って) 与えられます。 また、実行前に SSH をバックグラウンドに移行させる -f フラグと、リモート側でシェルを開いたりプログラムを実行したりしない -N フラグも使用します。
たとえば、リモート ホストのポート 80 で your_domain に接続し、ローカル マシンのポート 8888 で接続を利用できるようにするには、次のように入力します。
$ ssh -f -N -L 8888:your_domain:80 username@remote_host
ここで、ローカル Web ブラウザで 127.0.0.1:8888 を指定すると、ポート 80 の your_domain にあるコンテンツがすべて表示されるはずです。
構文のより一般的なガイドは次のとおりです。
$ ssh -L your_port:site_or_IP_to_access:site_port username@host
接続はバックグラウンドで行われるため、接続を終了するにはその PID を見つける必要があります。 これを行うには、転送したポートを検索します。
$ ps aux | grep 8888
Output
1001 5965 0.0 0.0 48168 1136 ? Ss 12:28 0:00 ssh -f -N -L 8888:your_domain:80 username@remote_host
1001 6113 0.0 0.0 13648 952 pts/2 S+ 12:37 0:00 grep --colour=auto 8888
その後、PID をターゲットにすることでプロセスを強制終了できます。PID は、SSH コマンドに一致する行の 2 列目の番号です。
$ kill 5965
別のオプションは、-f フラグを指定せずに接続を開始することです。 これにより、接続がフォアグラウンドに維持され、転送中にターミナル ウィンドウを使用できなくなります。 この利点は、CTRL-C を入力することでトンネルを簡単に強制終了できることです。
サーバーへのリモート トンネリングの構成
SSH 接続を使用すると、ローカル ホストのポートからリモート ホストのポートにトラフィックをトンネリングできます。
リモート トンネルでは、リモート ホストへの接続が確立されます。 トンネルの作成中に、リモート ポートが指定されます。 リモート ホスト上のこのポートは、ローカル コンピュータから接続されているホストとポートの組み合わせにトンネルされます。 これにより、リモート コンピュータがローカル コンピュータを介してホストにアクセスできるようになります。
これは、外部接続が制限されている内部ネットワークへのアクセスを許可する必要がある場合に役立ちます。 ファイアウォールがネットワーク外への接続を許可している場合、リモート マシンに接続し、そのマシンから内部ネットワーク上の場所にトラフィックをトンネリングできるようになります。
リモート サーバーへのリモート トンネルを確立するには、接続時に -R パラメータを使用し、次の 3 つの追加情報を指定する必要があります。
- リモート ホストがトンネル接続にアクセスできるポート。
- ローカル コンピューターを接続するホスト。
- ローカル コンピュータを接続するポート。
これらは、-R フラグへの引数として、上記の順序で (コロンで区切って) 与えられます。 また、実行前に SSH をバックグラウンドに移行させる -f フラグと、リモート側でシェルを開いたりプログラムを実行したりしない -N フラグも使用します。
たとえば、ローカル コンピューターのポート 80 で your_domain に接続し、リモート ホストのポート 8888 で接続を利用できるようにするには、次のように入力します。
$ ssh -f -N -R 8888:your_domain:80 username@remote_host
ここで、リモート ホストで Web ブラウザを開いて 127.0.0.1:8888 にアクセスすると、ポート 80 の your_domain にあるコンテンツをすべて表示できるようになります。
構文のより一般的なガイドは次のとおりです。
$ ssh -R remote_port:site_or_IP_to_access:site_port username@host
接続はバックグラウンドで行われるため、接続を終了するにはその PID を見つける必要があります。 これを行うには、転送したポートを検索します。
$ ps aux | grep 8888
Output
1001 5965 0.0 0.0 48168 1136 ? Ss 12:28 0:00 ssh -f -N -R 8888:your_domain:80 username@remote_host
1001 6113 0.0 0.0 13648 952 pts/2 S+ 12:37 0:00 grep --colour=auto 8888
次に、SSH コマンドに一致する行の PID (2 番目の列の番号) をターゲットにすることで、プロセスを強制終了できます。
$ kill 5965
別のオプションは、-f フラグを指定せずに接続を開始することです。 これにより、接続がフォアグラウンドに維持され、転送中にターミナル ウィンドウを使用できなくなります。 この利点は、CTRL-C を入力することでトンネルを簡単に強制終了できることです。
リモートサーバーへの動的トンネリングの構成
SSH 接続を使用すると、ローカル ホストのポートからリモート ホストのポートにトラフィックをトンネリングできます。
動的トンネルは、ローカル コンピュータがリモート ホストを介して他のリソースに接続できるという点でローカル トンネルに似ています。 動的トンネルは、単一のローカル ポートを指定するだけでこれを実行します。 トンネリングにこのポートを利用したいアプリケーションは、パケットがトンネルの反対側に正しくリダイレクトされるように、SOCKS プロトコルを使用して通信できる必要があります。
このローカル ポートに渡されるトラフィックはリモート ホストに送信されます。 そこから、SOCKS プロトコルが解釈されて、目的の終了場所への接続が確立されます。 この設定により、SOCKS 対応アプリケーションは、複数の静的トンネルを使用せずに、リモート サーバーを介して任意の数の場所に接続できます。
接続を確立するには、トンネルにアクセスするローカル ポートとともに -D フラグを渡します。 また、実行前に SSH をバックグラウンドに移行させる -f フラグと、リモート側でシェルを開いたりプログラムを実行したりしない -N フラグも使用します。
たとえば、ポート 7777 にトンネルを確立するには、次のように入力します。
$ ssh -f -N -D 7777 username@remote_host
ここから、SOCKS 対応アプリケーション (Web ブラウザなど) を選択したポートに向けることができます。 アプリケーションは、ポートに関連付けられたソケットに情報を送信します。
トラフィックを SOCKS ポートに送信する方法は、アプリケーションによって異なります。 たとえば、Firefox では、一般的な場所は [環境設定] > [詳細設定] > [設定] > [手動プロキシ構成] です。 Chrome では、--proxy-server= フラグを設定してアプリケーションを起動できます。 localhost インターフェイスと転送したポートを使用する必要があります。
接続はバックグラウンドで行われるため、接続を終了するにはその PID を見つける必要があります。 これを行うには、転送したポートを検索します。
$ ps aux | grep 8888
Output
1001 5965 0.0 0.0 48168 1136 ? Ss 12:28 0:00 ssh -f -N -D 7777 username@remote_host
1001 6113 0.0 0.0 13648 952 pts/2 S+ 12:37 0:00 grep --colour=auto 8888
次に、SSH コマンドに一致する行の PID (2 番目の列の番号) をターゲットにすることで、プロセスを強制終了できます。
$ kill 5965
別のオプションは、-f フラグを指定せずに接続を開始することです。 これにより、接続がフォアグラウンドに維持され、転送中にターミナル ウィンドウを使用できなくなります。 この利点は、CTRL-C を入力することでトンネルを簡単に強制終了できることです。
SSH エスケープ コードを使用して接続を制御する
SSH セッション確立後も、端末内から接続を制御することが可能です。 これは、SSH エスケープ コードと呼ばれるものを使用して行うことができます。これにより、セッション内からローカル SSH ソフトウェアと対話できるようになります。
クライアント側からの強制切断 (スタックまたはフリーズしたセッションを終了する方法)
OpenSSH の最も便利な機能の 1 つは、あまり注目されていませんが、セッションの特定の側面を内部から制御できる機能です。
これらのコマンドは、SSH セッション内で ~ 制御文字で開始して実行できます。 制御コマンドは改行の後に最初に入力された場合にのみ解釈されるため、制御コマンドを使用する前に必ず ENTER キーを 1 ~ 2 回押してください。
最も便利なコントロールの 1 つは、クライアントからの切断を開始する機能です。 通常、SSH 接続はサーバーによって閉じられますが、サーバーに問題がある場合、または接続が切断されている場合、これが問題になる可能性があります。 クライアント側の切断を使用すると、クライアントから接続をきれいに閉じることができます。
クライアントから接続を閉じるには、制御文字 (~) とドットを使用します。 接続に問題がある場合は、ターミナル セッションが停止しているように見える状態になる可能性があります。 フィードバックがない場合でもコマンドを入力して、クライアント側の切断を実行します。
$ [ENTER]
$ ~.
接続はすぐに閉じられ、ローカル シェル セッションに戻ります。
SSH セッションをバックグラウンドに置く
OpenSSH の最も便利な機能の 1 つは、あまり注目されていませんが、接続内からセッションの特定の側面を制御できる機能です。
これらのコマンドは、SSH 接続内から ~ 制御文字で開始して実行できます。 制御コマンドは改行の後に最初に入力された場合にのみ解釈されるため、制御コマンドを使用する前に必ず ENTER キーを 1 ~ 2 回押してください。
これにより提供される機能の 1 つは、SSH セッションをバックグラウンドに置くことです。 これを行うには、制御文字 (~) を入力し、タスクをバックグラウンドで行う従来のキーボード ショートカット (CTRL-Z) を実行する必要があります。
$ [ENTER]
$ ~[CTRL-z]
これにより、接続がバックグラウンドに配置され、ローカル シェル セッションに戻ります。 SSH セッションに戻るには、従来のジョブ制御メカニズムを使用できます。
次のように入力すると、最新のバックグラウンド タスクをすぐに再アクティブ化できます。
$ fg
複数のバックグラウンド タスクがある場合は、次のように入力すると、利用可能なジョブを確認できます。
$ jobs
Output
[1]+ Stopped ssh username@some_host
[2] Stopped ssh username@another_host
その後、最初の列のパーセント記号付きのインデックスを使用して、任意のタスクを前面に表示できます。
$ fg %2
既存の SSH 接続でのポート転送オプションの変更
OpenSSH の最も便利な機能の 1 つは、あまり注目されていませんが、接続内からセッションの特定の側面を制御できる機能です。
これらのコマンドは、SSH 接続内から ~ 制御文字で開始して実行できます。 制御コマンドは改行の後に最初に入力された場合にのみ解釈されるため、制御コマンドを使用する前に必ず ENTER キーを 1 ~ 2 回押してください。
これにより、接続がすでに確立された後にユーザーがポート転送構成を変更できるようになります。 これにより、ポート転送ルールをオンザフライで作成または破棄できます。
これらの機能は SSH コマンド ライン インターフェイスの一部であり、セッション中に制御文字 (~) と「C」を使用してアクセスできます。
$ [ENTER]
$ ~C
ssh>
SSH コマンド プロンプトが表示されますが、有効なコマンドのセットは非常に限られています。 使用可能なオプションを確認するには、このプロンプトで「-h」と入力します。 何も返されない場合は、~v を数回使用して SSH 出力の冗長性を高める必要がある場合があります。
$ [ENTER]
$ ~v
$ ~v
$ ~v
$ ~C
$ -h
Commands:
-L[bind_address:]port:host:hostport Request local forward
-R[bind_address:]port:host:hostport Request remote forward
-D[bind_address:]port Request dynamic forward
-KL[bind_address:]port Cancel local forward
-KR[bind_address:]port Cancel remote forward
-KD[bind_address:]port Cancel dynamic forward
ご覧のとおり、適切なオプションを使用すると、任意の転送オプションを簡単に実装できます (詳細については、「転送」セクションを参照してください)。 転送タイプ文字の前に「K」を指定して、関連する「kill」コマンドを使用してトンネルを破棄することもできます。 たとえば、ローカル フォワード (-L) を強制終了するには、-KL コマンドを使用できます。 このために必要なのはポートを指定することだけです。
したがって、ローカル ポート転送を設定するには、次のように入力します。
$ [ENTER]
$ ~C
$ -L 8888:127.0.0.1:80
ローカル コンピュータのポート 8888 が、接続先のホストの Web サーバーと通信できるようになります。 完了したら、次のように入力して前方を破棄できます。
$ [ENTER]
$ ~C
$ -KL 8888
結論
上記の手順では、ほとんどのユーザーが SSH に関して日常的に必要とする情報の大部分をカバーしています。 他にヒントがある場合、またはお気に入りの構成や方法を共有したい場合は、お気軽に以下のコメントをご利用ください。