Mac
Linux
GitHub
AWS
SSH

SSHなるものをよくわからずに使っている人のための手引書

More than 1 year has passed since last update.

SSHなるものをよくわからずに使っている人のための手引書

SSHとは

SSHとは、セキュアな通信を行うためのプロトコルです。

たとえば、HTTP。HTTPを通してブラウザからWebサイトにアクセスし、
コンテンツを閲覧したりWebアプリを利用したりします。
この「HTTP」というのもプロトコルの一種です。
HTTPもSSHもOSI参照モデルと呼ばれる層の最上位、アプリケーションレイヤーに位置しています。

なお、よく聞く「OpenSSH」とは、このSSHのプロトコルを実現するための
有名なソフトウェア(プログラム)のひとつです。
FTPのプロトコルで言うFileZillaとか、そういったイメージです。

このSSHを使うと、リモートサーバに安全にログインできたり、
ファイルをセキュアに送受信することができたりします。

SSHは「Secure Shell」の訳で、リモートシェルに特化しています。
公開鍵認証という仕組みを用いて、セキュアな通信を実現しています。

同じ公開鍵認証を用いる仕組みに、「SSL」というものがあります。
SSLを聞いたことがなくても、「HTTPS」を聞いたことがある人は多いですよね。
「HTTPS」は、「HTTP over SSL/TLS」と呼ばれ、SSLという仕組みを用いて
HTTP通信を行う、というものです。

さて、SSHの説明に戻ります。

最近で言うと、AWSの人気やGithubのユーザ数増加などによって、
あまりセキュリティやそもそもUnix系のコマンドに詳しくない方でも
チュートリアルにしたがって「ssh-keygen」なるコマンドをターミナルにおそるおそる
入力してみたり、なんかわけわからない文字列をコピーしてGithubの設定画面に
コピーしてみたり。。。でもこれ本当に安全なのか、間違って大事なもの(秘密鍵)を
公開してしまってないかとか。。。

そんな背景もあって、SSHがよくわからない人のために、
SSH通信の設定を通して、なるべくわかるように説明してみます。
間違っている箇所や説明が足りない箇所があればぜひ教えて下さい。

SSHのログイン認証には、以下の方法があります。

1. パスワード認証

ユーザ名とパスワードが分かれば誰にでもログインされるので、
SSHの設定ファイルを変更して無効にするのが標準です。

2. 公開鍵認証による接続

事前にローカル側で作成した公開鍵を、ログイン先のサーバに登録することで、
登録された公開鍵に対応した秘密鍵を持っているクライアントのみが接続できます。
「パスワード認証」と比べ事前の準備が必要となりますが、より安全な認証です。

詳細な手順については、後述します。

SSHことはじめ

状態確認:

# sshd(SSHデーモン)が動いていることを確認(CentOSなど)
$ lsof -i:22
$ lsof | grep sshd

# もしくはssh-agent(Macなど)
$ lsof | grep ssh-agend

~/.ssh/known_hosts

一度接続したことのあるサーバのSSHサーバ証明書は、
クライアント側のホームディレクトリの中、~/.ssh/known_hostsに格納されます。

# known_hostsファイルの内容を表示
$ cat ~/.ssh/known_hosts

公開鍵認証について

  1. (クライアント側)公開鍵と秘密鍵を生成
  2. (クライアント側→サーバ側)公開鍵をコピー・サーバ側に設置

1. (クライアント側)公開鍵と秘密鍵を生成

# 公開鍵と秘密鍵を生成
$ ssh-keygen

...

上記コマンドを実行すると、~/.sshディレクトリがまず作成され、
その中に公開鍵(id_rsa.pub)と秘密鍵(id_rsa)が作成されます。

この秘密鍵は誰にも渡さない・公開しないようにしてください
公開鍵の方は、サーバに登録します。テキストファイルなので
中身を確認してみましょう。

$ cat ~/.ssh/id_rsa.pub

なお、ssh-keygenコマンドを実行する際に、暗号のタイプを指定することができます。
暗号の種類には、「rsa1」「rsa」「dsa」から選択できます。

Q. 「rsa1」「rsa」「dsa」。。。なにが違うの?

Type Merit Demerit
RSA1 SSH1で使える SSH1には脆弱性がある
DSA SSH2で使える 鍵長が1024bitと短め
RSA 鍵長が最長4096bitと長め 特に無し

SSH1をサポートする必要がある場合などがあれば、RSA1などが検討候補と入ってくると思いますが、
大抵の場合はRSAで事足りると思いますし、この選択肢の中では一般利用であればRSAが最善策だとだと思われます。
(もちろん加味すべき要因は多々あるかと思いますが。。。)

http://security.stackexchange.com/questions/23383/ssh-key-type-rsa-dsa-ecdsa-are-there-easy-answers-for-which-to-choose-when

Q. 「パスフレーズ」を求められるのはなぜ?

パスフレーズは、秘密鍵を使う際に必要なパスワードです。
万が一秘密鍵が盗まれてしまったり漏洩してしまったりしたとしても、
その秘密鍵を使うためにはパスフレーズが必要なので、
なりすましを防ぐことができます。

念には念を入れる、ということですね。

なお、パスフレーズはのちのち変更することができます。
変更したい場合は、ssh-keygen -pを実行してください。

man ssh-keygenコマンドを実行しマニュアルを開くと、
推奨されるパスフレーズについて、以下の様な記述がされています。

A passphrase is similar to a password, except it
can be a phrase with a series of words, punctuation, numbers, whitespace, or any string of characters you want. Good passphrases are
10-30 characters long, are not simple sentences or otherwise easily guessable (English prose has only 1-2 bits of entropy per character,
and provides very bad passphrases), and contain a mix of upper and lowercase letters, numbers, and non-alphanumeric characters.

  • 10~30文字程度
  • 推測しやすい文章を避ける
  • 大文字小文字、数字、記号を混ぜる

Q. 「randomart」ってなに?

ssh-keygenコマンドを実行して、画面の指示にしたがってパスフレーズを入力すると、
下記のような謎の記号絵図がいきなり出現します。この記号絵図はなんのためにあるのでしょう?

The key's randomart image is:
+--[ RSA 2048]----+
|       o=.       |
|    o  o++E      |
|   + . Ooo.      |
|    + O B..      |
|     = *S.       |
|      o          |
|                 |
|                 |
|                 |
+-----------------+

たとえば、ある日ローカルホスト上の鍵が勝手に変更されていたとしましょう。
しかし、cat ~/.ssh/id_rsaコマンドを実行したところで、
以前と変更されていたかどうか、判断できるでしょうか?
鍵のテキストファイルは、記号だらけでほとんどの人間にとっては
一目見ただけでは変更されたかどうかが判断できません。

そこで導入されたのが、この「randomart」という仕組みです。
鍵を「人間がみやすいように記号絵図にする」ことによって、
ある日突然鍵の中身が書き換えられたとしても判別しやすくする」

ことを目的としています。

なお、このrandomartをログイン時に毎回表示させるためには、設定変更が必要です。
コマンドラインでsshを実行するたびに-o VisualHostKey=yesオプションを付与するか、
~/.ssh/configファイルにVisualHostKey=yesという行を追加してください。

なお、~/.ssh/configファイルは作成されていない場合があります。
その場合は適宜新しく作成してください。作成して保存すると設定は自動で反映されます。
そうすると、毎回sshでログインするたびにrandomartが表示されるようになります。

2. (クライアント側→サーバ側)公開鍵をコピー・サーバ側に設置

次に、クライアント側で生成された公開鍵をサーバ側に設置する必要があります。
この手順の流れの定石は、以下のとおりです。

  1. scpコマンドを使いセキュアにファイルをコピー
  2. ~/.ssh/authorized_keysファイルにコピーした公開鍵の内容を追加
  3. ログイン

1. scpコマンドを使いセキュアにファイルをコピー

まず、「クライアント側からサーバ側に公開鍵をコピー」する必要がありますが、
どのようにコピーすればいいでしょうか?メールを送るわけにも行きませんし、
コピーペーストでできるわけでもありません。

ここでは、scpコマンドという、SSHプロトコルを用いたファイルコピーのための
コマンドを使います。

# クライアント側で
# remote-user-name@server-address:~ とは、
# 「remote-user-nameというユーザー名でserver-addressサーバにログインし、
# ホームディレクトリ(~)に該当ファイルをコピーする」という意味です。
$ scp ~/.ssh/id_rsa.pub remote-user-name@server-address:~

2. ~/.ssh/authorized_keysファイルにコピーした公開鍵の内容を追加

コピーできたら、次はサーバ側での作業です。
まずはSSHコマンドでログインし、公開鍵を設置していきます。

# 2.1. SSHログイン
$ ssh remote-user-name@server-address

# (以下処理はサーバ側)
# 2.2. 公開鍵がコピーされていることを確認
$ cd ~ && cat id_rsa.pub

# 2.3. 「.ssh」ディレクトリを作成・パーミッションを変更
$ mkdir ~/.ssh
$ chmod 700 .ssh

# 2.4. 「~/.ssh/authorized_keys」を作成・パーミッションを変更
$ touch ~/.ssh/authorized_keys
$ chmod 600 ~/.ssh/authorized_keys

# 2.5. 公開鍵を「~/.ssh/authorized_keys」に追加
# (">>"リダイレクトで、上書きではなくファイル内容を追加します)
$ cat ~/id_rsa.pub >> .ssh/authorized_keys

3. ログイン

最後に、公開鍵認証でログインできることを確認してみましょう。
まずは、サーバ側にログインしている場合は、ログアウトします。

# (サーバ側)
$ exit

次に、クライアント側からSSH認証でログインしてみます。

# パスワード認証ではなく公開鍵認証でログインできることを確認
$ ssh remote-user-name@server-address

以上がSSH認証のための準備です。
実は、ssh-copy-idという便利なコマンドを使うと、
サーバ側へのauthrorized_keysの作成やパーミッションの設定など
自動で行ってくれ、非常に便利です。

ですが、仕組みを知らない方は、ぜひ上の手順でひとつひとつ作業を確認しながら
SSH認証について理解を深めていきましょう。

おまけ:SSHコマンド関連逆引レシピ

# コマンドの一部を省略している場合があります
# また、SSH周りで作業するときに使えるコマンドも紹介しています

# IPアドレスを確認する
$ ifconfig

# 鍵ファイル(Identification)を指定してリモートログイン
$ ssh -i ~/.ssh/id_rsa.pub remote-user-name@XX.XX.XX.XX

# デバッグする(verboseモードでログを出力する)
$ ssh -v -i ...