1. ホーム
  2. コース一覧
  3. LinuC Level1 v10.0 対策コース(パート1)
  4. SSHコマンドと認証

中級

LinuC Level1 v10.0 対策コース(パート1)

LinuC Level1 v10.0 対策コース(パート1)4/39

SSHコマンドと認証

今回はsshについて紹介します。sshで接続することは簡単ですが、その裏にあるロジックを理解するのは大変なので、この記事では章を分けて紹介します。まずは概要を理解して実際にsshコマンドでリモートサーバーに接続してみましょう。

ssh(Secure Shell)とは

ネットワークに接続されているサーバーを遠隔操作するための仕組みです。

sshを使用することで安全に遠隔でシステムを操作することができます。サーバーを遠隔操作で管理したいときに頻繁に利用されます。

2000年以前はTelnetやRLogin、rshなどのプロトコルを使い平文でやり取りされていましたが、ネットワーク上で重要な情報が扱われ始めたことから、安全な通信方法としてsshが使用されるようになりました。

OpenSSHとは

OpenSSHとはSSHのオープンソースです。主にUNIX系同士の遠隔操作に利用されます。サーバーとクライアントの両方の機能を持っておりUNIX系にはデフォルトでインストールされています。

項目説明
ssh-keygenSSH用の認証鍵を生成、管理、変換します。
ssh-agent公開鍵の認証に使用される秘密鍵を格納します。
ssh-addサーバーで許可される秘密鍵を一覧に追加します。
~/.ssh/id_rsa および id_rsa.pubRSA秘密鍵とRSA公開鍵です。.pub がついている方がRSA公開鍵になります。
~/.ssh/id_dsa および id_dsa.pubDSA秘密鍵とDSA公開鍵です。.pub がついている方がDSA公開鍵になります。
/etc/ssh_known_hostsクライアントから送られてきた公開鍵を保存するファイルです。
/etc/ssh/ssh_host_rsa_key および ssh_host_rsa_key.pubSSHのバージョン2のRSA秘密鍵とRSA公開鍵です。
/etc/ssh/ssh_host_dsa_key および ssh_host_dsa_key.pubSSHのバージョン2のDSA秘密鍵とDSA公開鍵です。
~/.ssh/authorized_keyssshの公開鍵を接続する設定ファイルです。

暗号アルゴリズム

代表的な暗号アルゴリズムとして以下のようなものが利用されます。

暗号名説明
RSA素因数分解の難しさを利用した暗号アルゴリズムです。
ECDSA楕円曲線状の離散対数問題を安全性の根拠にしたデジタル署名アルゴリズムです。
ED25519RSAよりも安全性と性能が高い楕円曲線署名アルゴリズムです。

ポートフォワーディングについて

SSHではポートフォワーディングが可能であり、以下のように二つの方式が存在します。

  • ローカルフォワード:SSH 接続して、ローカルホスト上の指定された TCP ポートへ接続すると指定されたリモートホスト側のポートに転送する機能。トンネリングと呼ばれています。
  • リモートフォワード:SSH 接続して、リモートホスト上の指定された TCP ポートへ接続すると指定されたローカルホスト側のポートに転送する機能。トンネリングと呼ばれています。

ssh接続

ssh接続には主に2種類ありパスワード認証と公開鍵認証です。最終的には公開鍵認証のみでログインできるようにします。

パスワード認証

パスワード認証はその名の通り、ユーザー名のパスワードでログインする方法です。またデフォルトの認証方法でもあります。

しかしパスワード認証ではセキュリティ的に不十分であるため、実際は公開鍵認証が推奨されています。

(パスワード認証は、色々なサーバで同一パスワードを使い回してしまう可能性があるという点でセキュリティが弱くなる可能性があります。)

公開鍵認証

公開鍵認証はパスワード認証より強固な認証方式です。公開鍵と秘密鍵のペアを使って認証します。詳しい内容は「ssh接続の仕組み」で説明します。今は2種類のカギを使うということだけ覚えていてください。

認証方式の比較

ssh接続と公開鍵認証設定の流れ

  1. ローカル(ホスト)サーバーからリモートサーバーにパスワード認証(パスワードとユーザーネーム)で接続します。
  2. 接続できることが確認出来たら一度戻り、ローカルサーバーで公開鍵と秘密鍵のペアを作成します。
  3. ローカルサーバーで鍵を作成したら、次はリモートサーバーに公開鍵だけを渡します。
  4. リモートサーバーに公開鍵をコピーした後、リモートサーバにログインし、公開鍵をリモートサーバーに登録します。
  5. 登録が完了したら、このリモートサーバに対してパスワード認証ではログインできないようにします。
  6. ログインできないように設定したら、ローカルサーバーに戻り、パスワードではログインできず、秘密鍵を使ってログインすることができたら、公開鍵認証の設定が完了です。

では詳しく解説していきます。

1. リモートサーバーに接続

ローカルサーバーからリモートサーバーに接続する時はsshコマンドを使用します。

ローカルサーバー:~$ ssh ユーザー名@IPアドレス
Are you sure you want to continue connecting (yes/no)? yes
リモートサーバー@IPアドレス's password: password
リモートサーバー:~$

※ユーザー名とパスワードは既に登録されていることが前提となります。

接続しようとすると「本当に接続しますか」と聞かれるので「yes」と入力し、次にパスワードを聞かれたらリモートサーバのユーザのパスワードを入力すると、接続が完了します。※パスワード入力中は入力した文字が画面には出力されません。

2. 公開鍵、秘密鍵の作成

ローカル(ホスト)サーバーに戻り鍵を作成します。鍵を作成する時は ssh-keygenコマンドを使用します。

ローカルサーバー:~$ ssh-keygen -f 鍵を保存したいディレクトリを含めたファイル名
ローカルサーバー:~$ ls 鍵を保存したディレクトリ   # ディレクトリ内を表示 
ファイル名 ファイル名.pub

作成すると保存したディレクトリの中に秘密鍵ファイル「ファイル名」と公開鍵ファイル「ファイル名.pub」が作成されます。(pub = public(公的))

3. リモートサーバーに公開鍵「ファイル名.pub」を渡す

ファイルなどをリモートサーバーに対して送るときはscpコマンドを使います。

ローカルサーバー:~$ scp 鍵を保存したディレクトリ/ファイル名.pub ユーザー名@IPアドレス:~/.ssh/

4. 渡した公開鍵を登録する

登録するにはsshで手動で行う方法と、ssh-copy-idコマンドの2つ方法があります。

sshで手動で登録する

  1. 作成した公開鍵をscpコマンドでリモートサーバーに送信します。この時、送信先をホームディレクトリの下の.sshディレクトリを指定してください。
  2. 送信したらsshコマンドでリモートサーバーにログインし、.sshディレクトリに移動します。
  3. 移動したら、catコマンドでauthorized_keysというファイルに公開鍵の中身をコピーします。(ファイルは自動で作成されます)
  4. ファイルの権限をchmodコマンドで600 にします。(600はファイルの所有者に対して「読み取り権限」、「書き込み権限を与えています」)
  5. 送信したファイルはもう不要なので最後に削除します。
ローカルサーバー:~$ ssh ユーザー名@IPアドレス
Are you sure you want to continue connecting (yes/no)? yes
envader@172.19.1.11's password: password
リモートサーバー:~$ cd .ssh
リモートサーバー:~/.ssh$ cat ファイル名.pub >> authorized_keys
リモートサーバー:~/.ssh$ chmod 600 authorized_keys
リモートサーバー:~/.ssh$ rm -f ファイル名.pub

ssh-copy-idコマンドで登録する

ssh-copy-idコマンドを実行するだけで完了します。 sshコマンドで行った作業をすべて自動で処理してくれます。

ローカルサーバー:~$ ssh-copy-id ユーザー名@IPアドレス
オプション意味
-nテスト実行する(登録はされない)
-i公開鍵を指定する
-p接続時に使用するポート番号を指定する
-o ssh_optionssh接続のオプションを指定する

5. リモートサーバーにパスワード認証でログインできないように設定を変更する。

設定を変更するには、リモートサーバーの /etc/ssh/sshd_configファイル内を変更する必要があります。

リモートサーバー:~$ grep 'PasswordAuthentication ' /etc/ssh/sshd_config
#PasswordAuthentication yes
リモートサーバー:~$ vi /etc/ssh/sshd_config
#PasswordAuthentication yes => PasswordAuthentication no
リモートサーバー:~$ systemctl restart sshd # or sudo reboot

grepコマンドでsshd_configファイル内の「PasswordAuthentication 」に一致する部分を表示します。(PasswordAuthentication はパスワード認証を認めるか決める部分です。) 「PasswordAuthentication no」以外の場合はパスワード認証が認められているのでviコマンドでファイルを開いて編集します。「PasswordAuthentication」の#(コメントアウト)を外して、「yes」を「no」に変更します。 最後に systemctl restart sshd でサービスを再起動します(Envaderの環境ではサーバ毎再起動する必要があるため、 sudo reboot コマンドを利用します)

6. ローカルサーバーに戻りパスワード認証と公開鍵認証の確認

パスワード認証と公開鍵認証の両方でアクセスできるか検証します。

# パスワード認証
ローカルサーバー:~$ ssh ユーザー名@IPアドレス
ローカルサーバー:~$
# 公開鍵認証
ローカルサーバー:~$ ssh -i 鍵を保存したディレクトリ/id_rsa リモートユーザー@IPアドレス
リモートサーバー:~$

パスワード認証ではリモートサーバーにはログインできなくなっていることが確認できます。反対に公開鍵認証でログインできることを確認してみましょう。

sshコマンド

ここではsshコマンドに存在するさまざまなオプションについて解説します。

主なオプション

オプション用途
-lリモートログイン先のユーザー名を指定する
-pリモートログイン先のポート番号を指定する
-i [ファイル名]公開鍵認証方式における秘密鍵を指定する
-C通信データの圧縮を行う
-osshのオプション設定を指定する

-l オプション

リモートマシンにログインする際にログインするユーザーを指定します。

ssh user@hostnameと同じ扱いとなります。

ssh -l user hostname

-p オプション

通常はポート22で接続しますが、ポートスキャンを回避するために接続するポート番号を変更している場合があります。その際には -pオプションでポート番号を指定します。

ssh -p 56789 user@hostname

-i [ファイル名] オプション

公開鍵認証方式でログインする際に秘密鍵を指定してログインするときに使用します。

デフォルトでは、以下の秘密鍵のファイルでログインするようになり、それ以外の秘密鍵でログインする設定にしている場合は -iオプションで秘密鍵のファイル名を指定します。

【デフォルトの秘密鍵ファイル】

※ 鍵生成時のアルゴリズムの種類によって、それに合った秘密鍵が使われます

  • ~/.ssh/id_rsa
  • ~/.ssh/id_dsa
  • ~/.ssh/id_ecdsa
  • ~/.ssh/id_ed25519
ssh -i 鍵のファイルパス user@hostname

-C オプション

回線速度が遅い環境でログインする際に、データを圧縮することで通信速度を上げてログインする場合に指定します。

ただし、ローカル/リモートのCPUが高速であることが条件になり、そうでない場合は逆に遅くなることもあります。

また、回線速度が速い環境なのに圧縮をかけた通信をすると、同様に遅くなります。

したがって、基本的には圧縮はしないでログインします。

ssh -C user@hostname

-o オプション

リモート側にはsshの設定が記載されているファイルがあり、/etc/ssh/sshd_configにあります。

この設定ファイルに記載されている設定と同じ形式で、一時的に設定を変更する時に指定します。

例:公開鍵のチェックを省略したい場合

ssh -o StrictHostKeyChecking=no user@hostname

リモートマシンで設定をデフォルトとしたい場合は、先ほどの/etc/ssh/sshd_configを変更します。

他にもオプションはありますので、ぜひ調べてみてください。

ssh接続まとめ

公開鍵認証でログインするために、公開鍵、秘密鍵の作成をして公開鍵をリモートサーバーに登録し実際に公開鍵認証でログインするまでの流れを紹介しました。

ssh接続の仕組み(公開鍵認証)

前の章ではsshの接続方法について紹介しました。

この章ではssh接続の公開鍵認証の仕組みについて解説していきます。

公開鍵認証

公開鍵認証はsshクライアント(ユーザー)が秘密鍵を使って署名を作成し、署名を受け取ったサーバー側が公開鍵を使って照合し、検証することです。

1. 事前準備

  1. sshクライアントが公開鍵と秘密鍵を作成し、sshサーバーに公開鍵を渡します。
  2. 作成する時、最初にいくつか乱数が生成されてそれをもとに秘密鍵と公開鍵が生成されます。

2. 鍵交換

鍵交換ではセッションを暗号化するために共通鍵を交換します。

  • 鍵交換:DH(E)、ECDH(E)という鍵交換方式が用いられ、これらは公開鍵暗号方式に分類されます。
  • ※共通鍵を公開鍵で暗号化して交換するというようなことは行われていません。
  • DH(E)、ECDH(E)は離散対数問題の困難性によって第三者からの推測を困難にしています。
  • 鍵交換のタイミングで、クライアントはサーバー側のホスト鍵の確認も行います。ホスト鍵はホスト認証で、サーバ側を識別するときに使う鍵です。

3. ユーザー認証

  1. 鍵交換でセッションの暗号化が完了したら、暗号化された同一セッション内でユーザー認証を行います。
  2. ユーザー認証では、sshクライアント(ユーザー)が生成した秘密鍵を利用して署名を作成し、sshサーバーにユーザー名、公開鍵、その他の情報を送信します。
    1. この時、鍵交換の手続きによって共有されたセッションIDも含めて署名を作成します。セッションIDを含めるのは署名を流用させないためです。
    2. セッションIDは毎回値が違うため、署名も毎回違う値となり、流用することができなくなります。
  3. sshサーバは該当するユーザーに受け取った公開鍵が登録されているか照合します。
  4. 照合したら次は署名を検証します。sshサーバはsshクライアントから送付された署名を公開鍵を使用して検証し、検証できれば署名を送ったユーザーが秘密鍵を持っているとして認証します。
  5. 認証されるとssh接続が確立されます。

図解

公開鍵認証のメリット

公開鍵認証のメリットについて解説します

パスワードの使い回しのようなリスクがほとんどなくなります。

公開鍵認証では署名を渡すのに対して、パスワード認証ではパスワードそのものを渡しています。もちろんパスワードはハッシュ化さていますが、仮に渡した相手が悪意のある相手だった場合パスワードが悪用されてしまう恐れがあります。それに対し公開鍵認証の署名はセッションごとに値の違うセッションIDが含まれているため毎回違う値となり悪用が困難になります。また、同じパスワードを使い回すということも必然にほぼ無くなるので人為的なミスも減らすことができます。

しかし、秘密鍵さえあれば他のクライアントからでもssh接続することは可能です。パスワードの入力が必要ないため、接続が簡単になります。

まとめ

今回は、SSH接続の紹介とその仕組みについて解説しました。

SSHは、システムを遠隔操作する際に使用されます。

SSH接続を確立する際には、公開鍵と秘密鍵が使用されます。

公開鍵認証では、秘密鍵によって作成された署名が公開鍵によって認証されます。公開鍵認証に関して誤解している人が多いため、注意が必要です。

問題を解くためには、十分な画面サイズのPC環境をご利用下さい。