SSHの設定

SSHの設定に関する記事です。
SSH(Secure Shell)は認証や暗号の技術を使った安全にサーバとクライアント間の通信を行うプロトコルです。
パスワードの入力を含む通信データすべてを暗号化できます。
通信を傍受され改ざんや情報漏洩の可能性は極めて低くなります。

ここでは、さくらのVPSでOSのインストールまで終了している状態から説明します。
標準OSおよびカスタムOSインストールのどちらの場合であっても、OSインストール後に最初にやるべきことになります。
※新規契約した最初の状態は標準OSがセットアップされています。

OSのセットアップが完了しているとさくらのVPSの場合はSSHでの接続が可能になっています。
ただし、かなり制限が緩い設定のため、早急にSSHサーバの設定変更を行うべきです。

OSインストールではコンソール端末が必要だったのでサーバのコントロールパネルから接続しましたが、利便性がよくないので今後の作業はリモート端末ソフトのPuTTYを使用します。
※PuTTYの設定についてはSSHクライアントの設定で記載します。

公開鍵と秘密鍵の作成

暗号に必要な鍵の作成を行います。
鍵はサーバ側に配置する公開鍵とクライアント側に配置する秘密鍵のペアで作成します。
公開鍵が暗号化(符号化)に使用され、秘密鍵が復号化に使用されます。
秘密鍵が人手に渡るとだれでも復号(解読)できることになりますので、秘密鍵の取り扱いには十分注意して本人以外の手に渡らないようにしてください。

PuTTY Key Generator

鍵の作成には、PuTTYに付属のPuTTY Key Generatorを使用しました。
今回はSSHバージョン2 RSA 2048bitの鍵を生成します。

生成(Generate)

PuTTY Key Generatorを起動

Keyの枠内でマウスカーソルを移動させてキーを生成します。

生成

パスフェーズの入力

入力するパスフェーズはSSH接続時に必要になりますので忘れないようにしてください。
通常のログインのパスワードの代わりに使用されますが、パスワードとは異なるものにしてください。

パスフェーズを入力

公開鍵の保存(Save public key:id_rsa.pub)

公開鍵の保存(Save public key)

秘密鍵の保存(Save private key:id_rsa.ppk)

秘密鍵は絶対に他人の手に渡らないように細心の注意をしてください。
例えば、玄関の前の郵便ポストのような場所に家の鍵を入れていたのでは、知っている人であればだれでも家に入れてしまいます。

秘密鍵の保存(Save private key)

以上で、公開鍵(id_rsa.pub)と秘密鍵(id_rsa.ppk)が作成できました。

SSHサーバの設定

カスタムOSインストールでCentOS 7 x86_64を選択し最小構成+開発ツールのインストールを行いました。
まず、openssh-serverがインストールされていることとそのバージョンを確認しておきます。

# rpm -qa openssh-server
openssh-server-6.6.1p1-25.el7_2.x86_64

上記のように表示されればすでにインストールされています。

SELinuxの無効化

SELinuxはセキュリティ管理を担う重要なモジュールですが、慣れていないといろいろと今後の作業で躓く原因になります。
適切な判断のもと、無効化してください。

SELinuxを無効にする

# sestatus
SELinux status:                 enabled
SELinuxfs mount:                /selinux
Current mode:                   enforcing
Mode from config file:          enforcing
Policy version:                 24
Policy from config file:        targeted

# setenforce 0
Permissive

# getenforce
Disabled

# vi /etc/sysconfig/selinux
...
#SELINUX=enforcing
SELINUX=disabled

# reboot

もしくは

# shutdown -r now

※setenforceの実行を追加しました。
setenforce 0でPermissiveになります。この状態ではポリシーの監視はしますがアクセス制限はしませんのでログファイルにエラーメッセージが出力されるのみです。
SELINUX変数の変更だけでリブートしたシステムでは、ファイル作成時に付与されたセキュリティコンテキスト(ファイルパーミッションの11bit目)の影響でアクセス制限によりアクセスが拒否され悩まされました。
ちょうどポリシーが適用されたままの状態と同じに思えました。
このセキュリティコンテキストはSELinuxで無効化した状態で作成したファイルには付与されませんが、一旦、SELinuxを有効化してしまうとOS再起動時にセキュリティコンテキストのラベル付与が行われ非常に時間がかかります。
有効化すると監視対象となっているサービス等は起動しませんので、もちろん変更したSSHサーバも起動しません。

現在の状態を表示し、設定ファイルを編集して無効(disabled)にしています。
このあと、システムの再起動を行うとSELinuxが無効の状態で起動します。

SELinuxの無効化の確認

# sestatus
SELinux status:                 disabled

# getenforce
Disabled
 

どちらのコマンドでも無効(disabled)になっているのが確認できます。
※OSブート時のログファイル(/var/log/messageなど)を一応見ておいたほうが良いかもしれません。

sshdの設定

OpenSSHサーバの標準設定を変更します。
※標準の設定のままですと、悪意のあるユーザが攻撃を行いrootでログインできてしまいます。

変更箇所は次の通りです。(※OpenSSHサーバの設定以外も含んでいます)

  1. sshdサービスポート番号の変更(デフォルト:22)
  2. SSHプロトコルをSSHバージョン2のみにする
  3. rootでの接続を拒否する
  4. パスワードなしでのログインを拒否する
  5. パスワードでのログインを拒否する
  6. 特定のユーザのみ接続を許可する
  7. 管理者ユーザ以外はrootにスイッチユーザできないようにする
  8. 管理者ユーザはwheelグループに追加する

上記1番~7番のうち、5番についてはSSH接続が正常にできたあとの最終的な変更です。
また、7番と8番はsshdの設定とは無関係ですが、3番の設定に関連して、この7番と8番を設定しておかないとsshで接続した端末でrootになれません。

1番から6番までは「/etc/ssh/sshd_config」ファイルを編集します。
※ssh_config(SSHクライアント用の設定ファイル)のほうではありません。

sshdサービスポート番号の変更

Port 1022 

SSHプロトコルをSSHバージョン2のみにする

Protocol 2 

rootでの接続を拒否する

PermitRootLogin no 

パスワードなしでのログインを拒否する

PermitEmptyPasswords no 

パスワードでのログインを許可する

※SSHでの接続が確認できるまで許可にしておきます。

PasswordAuthentication yes 

特定のユーザ(hogehoge)のみ接続を許可する

AllowUsers hogehoge

変更が終わったら保存してファイルを閉じます。

sshdの再起動と状態確認

変更した内容を反映するため、sshdサービスの停止と起動を行っています。
reloadでも反映されると思います。

# systemctl stop sshd
# systemctl start sshd
# systemctl status sshd 

以下のコマンドで接続中と待機中のポート番号一覧を表示できますので、ポート1022/TCPでLISTENになっていることを確認してください。

# ss -antup 

管理者ユーザ以外はrootにスイッチユーザできないようにする

6行目がコメントになっているので有効にします。

auth            required        pam_wheel.so use_uid 

管理者ユーザはwheelグループに追加する

※カスタムOSインストール時に管理者ユーザを作成した場合はすでにwheelグループに追加されています。

# usermod -G wheel hogehoge 

公開鍵の設置

前に作成した公開鍵(id_rsa.pub)をSSHサーバに転送します。
転送の方法はPuTTYに付属のpscpコマンドやsftp、別途WinSCPのようなファイル転送ソフトを使ってもよいですし、PuTTYを使ってリモート操作しているのであれば、サーバ上に新規ファイルを作成し、公開鍵の内容をコピー&ペーストして貼り付けることでも可能です。
今回は、簡単な後者の方法で行いました。
※PuTTY Key Generatorで生成した公開鍵はそのままではOpenSSHでは使用できませんので変換作業が必要です。

まず、SSHで接続するユーザのホームディレクトリへ移動します。
※SSHで接続を許可しているユーザでログインしているとして説明します。

$ cd 
$ mkdir .ssh
$ cd .ssh
$ vi id_rsa.pub
id_rsa.pubファイルの中身をコピーして貼り付け保存します。

次にOpenSSHで利用できるように鍵を変換します。

$ ssh-keygen -i -f id_rsa.pub >> authorized_keys 
$ rm id_rsa.pub

ファイル名authorized_keysは/etc/ssh/sshd_conf内で設定されているファイル名にあわせます。
「>>」を使用しているので、すでにauthorized_keysが存在している場合は上書きではなく追加になります。

上の例では元のファイルは削除しています。

最後にパーミッションの変更をしておいてください。
適切なパーミッションが設定されていないとSSH接続時にアクセス拒否されます。

# chmod 600 *
# cd ../
# chmod 700 .ssh 

※ファイルは読み取り権限、ディレクトリは実行権限が必要です。
※もちろんオーナはログインしているユーザと同じにしてください。

Firewallの設定変更

先ほど、sshdサービスのポート番号を変更しましたので、firewallの設定をそれに併せて変更しないと接続ができません。
設定変更にはfirewall-cmdコマンドを使用します。

現在接続可能なサービス名の確認

# firewall-cmd --list-services
dhcpv6-client ssh 

ここで表示されるsshサービス名はポート22/TCPを使用していた標準の設定です。
現在、sshdサービスは標準の設定(ポート22/TCP)では起動していませんので不要です。
※/etc/servicesファイルを見ればwell knowポートとサービス名の対応が一覧になっています。

現在接続可能なポート番号の確認

# firewall-cmd --list-ports 

何も表示されない場合はポート番号で許可している登録はなしです。

変更前のSSHサーバーのサービスを削除

sshサービス名を登録から削除します。
再起動後にも設定が反映されるようにpermanentオプションを使用します。
ただし、現在のfirewall設定には影響ありません。

# firewall-cmd --permanent --remove-service=ssh
success

変更後のSSHサーバのポート番号を登録

ポート1022/TCPを登録します。
再起動後にも設定が反映されるようにpermanentオプションを使用します。
ただし、現在のfirewall設定には影響ありません。

# firewall-cmd --permanent --add-port=1022/tcp
success 

firewallの設定の再読み込み

これまで変更した内容(parmanentオプションを使った変更)で現在稼働中のfirewallの設定を更新します。

# firewall-cmd --reload
success

すべての情報を表示

 # firewall-cmd --list-all 
public (default, active)
  interfaces: eth0
  sources:
  services: dhcpv6-client
  ports: 1022/tcp
  masquerade: no
  forward-ports:
  icmp-blocks:
  rich rules:

標準のfirewallの設定内容は登録があるものが接続許可され、ないものは拒否される仕組みです。
サービス名で登録されている場合と通信ポート番号で登録されている場合の2通りがあります。
※この設定はネットワークインターフェース:eth0のみに有効です。

以上でSSHサーバの設定は一応完了です。
5番のところは、最後に接続テストが正常であることが確認できたのちに変更します。

SSHクライアントの設定

まず、Windows OSからSSHサーバへの接続を想定して、SSHクライアントにPuTTYとWinSCPを使う場合の設定を記載します。
その他、Android TabletからSSHサーバへの接続を想定して、SSHクライアントにConnect Botを使う場合の設定を記載します。
さらに、さくらのVPSで2台のサーバ間をローカルネットワークで接続していますので、OpenSSHクライアントを使う場合の設定を記載します。

PuTTY(PuTTYjp)の設定

公式サイトはhttp://www.chiark.greenend.org.uk/~sgtatham/putty/になります。
現在の最新バージョンは0.67です。
インストーラ版とポータブル版があります。

非公式のISO2021のパッチ(日本語パッチ)があたったPuTTYjpも存在します。
こちらも最新バージョンは0.67です。
入手はVectorのサイトから可能です。http://hp.vector.co.jp/authors/VA024651/PuTTYkj.html

今回はPuTTYjpのポータブル版を使用します。
ダウンロードしたファイルを解凍し、解凍したフォルダーごとD:\toolsに移動しました。
(移動先は任意です。ポータブル版の場所をD:\tools以下にまとめているのでそうしているだけです)

セッションの基本設定

接続先のホスト名またはIPアドレス(VPSサーバのホスト名)、SSHサービスのポート番号(1022)、接続方式(SSH)を設定します。
※ホスト名で接続する場合はネットワーク上でホスト名からIPアドレスへの名前解決ができる(正引きできる)状態でなければ接続できません。
※さくらのVPSの場合は、DNSに登録されていますので名前解決(正引き)できる状態になっていますが、独自ドメインサービスを利用している場合のサーバー名(ドメイン名)で接続する場合はDNS情報がインターネット上に伝達するまで時間がかかる場合があります。
セッションの基本設定

ウィンドウの設定

接続時のPuTTYウィンドウの画面サイズ(120x76)とスクロールバックの行数(2000)を設定します。
※スクロールバックは表示する行数が画面サイズ以上になった場合に画面がスクロールする際、何行スクロールを戻して表示が可能かに影響します。
ウィンドウの設定

文字セット変換の設定

日本語の表示や入力時に文字化けしないように、サーバ上のユーザ環境変数LANGの設定に合わせます。(UTF-8)
文字コード変換の設定

サーバに送られるデータ

自動ログインのユーザ名にSSH接続を許可したユーザ名を入力します。(user1)
サーバに送られるデータ

SSH接続の設定

SSHプロトコルバージョン2(2のみ)と ASE(SSH-2 only)を設定します。
SSH接続の設定

PuTTYのSSH認証の設定

PuTTY Key Generatorで作成した秘密鍵ファイル(プライベートキーファイル)を登録します。
秘密鍵の設定

セッションの基本設定

最後に「セッションの読み込み、保存、削除」の欄に設定の名前を入力して、保存します。
セッションの基本設定

以上でPuTTYjpの設定が完了です。

パスフレーズの入力に関して

パスフレーズの入力は通常のログインと同じくパスワードを入力する作業と安易にとらえてしまうとパスフレーズなしで鍵を生成したくなる場合もあるかと思います。
パスフレーズは通信を傍受されたのち、攻撃者がパスフレーズを解析する分の時間、猶予がありますので、万が一に備え、パスフレーズを付与することを推奨します。
それでも毎回パスフレーズを入力するのは面倒という方は、pageantを使うとよいでしょう。
PuTTYに付属のpageantを利用するれば、接続のたびにパスフレーズを入力しなくても、pageantに秘密鍵(プライベートキー)を登録しその時にパスフレーズを一緒に保存しておけば、以降の接続の際にパスフレーズの入力を自動化できます。
pagent.exeは起動するとプロセスは常駐していますので、タスクトレイの一覧から選択しNew Sessionで接続先を選択すればサーバへの接続が自動になります。

WinSCPの設定

WinSCPはグラフィカルな操作でコンピュータ間のファイル転送が可能なクライアントソフトウェアです。
外部プログラムにPuTTYを利用することもできますし、ファイルの中身を参照する場合に使用するテキストエディタも好みのエディタを設定することが可能です。

WinSCPについてはhttps://winscp.net/eng/docs/lang:jpをご覧ください。
現在の最新バージョンは5.9.2です。
上記リンク先のダウンロードからソフトウェアのダウンロードが可能です。
インストーラ版とポータブル版があります。
また、日本語対応は別途言語ファイルをダウンロードしてWinSCPにロードすれば日本語表示になります。
言語ファイルはWinSCPのバージョンと言語ファイルのバージョンが一致していないとエラーメッセージが表示されますので、WinSCPの環境設定から言語ファイルのダウンロードサイトにアクセスするのが確実です。

今回はポータブル版をダウンロードしました。バージョンは最新版の5.9.2です。
ZIPで圧縮されているのでOS標準の機能で解凍できると思います。

解凍したフォルダーごとD:\toolsに移動しました。(移動先は任意です。ポータブル版の場所をD:\tools以下にまとめているのでそうしているだけです)

日本語対応

日本語ファイルのダウンロード

WinSCPを起動します。
以下のように標準では英語の表記になっています。
初回起動時

左下にある「Tools」→「Preferences...」を選択し、Preferences画面を表示します。
次に「Environment」の中の「Languages」を選択します。
現在インポートされている言語の一覧と選択されている言語が表示されます。
言語の選択画面

右下にある「Get More ...」ボタンをクリックすると、その他の言語ファイルがダウンロードできるサイトにアクセスします。
そこにある一覧から「Japanese」をダウンロードし、解凍します。
解凍したフォルダーにある「WinSCP.jp」をWinSCP本体があるフォルダーに移動します。
移動後のWinSCPフォルダーは以下のようになります。
日本語ファイルを設置
 

日本語ファイルのロード

WinSCPをいったん終了して再度起動したのち、先ほどと同じ「Languages」の画面を表示すれば、一覧に日本語が追加されています。
日本語を選択しOKで保存します。
日本語を選択

もう一度、WinSCPを再起動すれば日本語表記に変わります。
再起動後の状態

セッションの設定

まず、編集ボタンを押して編集ができるようにします。
次にホスト名、ポート番号、ユーザ名を入力し、「保存」ボタンでとりあえず接続設定を保存します。
保存すると左の画面の一覧に設定が追加されます。
接続の基本設定作成
一覧にある設定名を変更する際は、管理メニューから名前の変更で行います。
※設定変更する際、編集ボタンを設定変更したら保存ボタンを押せば、ログインやツールメニューや管理メニューなどその他の操作ができるようになります。

秘密鍵の設定

詳細な設定は、編集ボタンをクリックした後、その横にある設定メニューから設定を選択して行います。
高度なサイトの設定画面が開きますので、以下のように使用する秘密鍵を設定します。
秘密鍵の設定
設定を変更したので保存ボタンをクリックし保存します。

外部プログラムの使用

WinSCPはSSH端末ソフトやテキストエディタソフトに外部プログラムを設定できます。
その設定は「ツール」→「環境設定」で行います。

テキストエディタの変更

標準設定の内部エディタをポータブル版のサクラエディタに変更します。
エディタを選択したのち追加ボタンをクリックします。
エディタの追加

以下のように、サクラエディタを追加します。
※プログラムファイル(拡張子.exe)を選択します。
サクラエディタを追加

つぎに優先順位を一番上に変更します。
優先順位を変更

外部アプリケーションの変更

続いて、外部アプリケーションにポータブル版のPuTTYjpを設定します。
統合の中になるアプリケーションを選択します。
標準ではインストーラ版のPuTTYの設定になっているのでポータブル版に変更しました。
ポータブル版PuTTYjpに変更
WinSCPからPuTTYjpやサクラエディタを使用できるようになりました。
あと、PuTTYに付属のpegeantを起動してAddKeyを行いパスフェーズを入力し終わっていれば、WinSCPからの接続時のパスフェーズの入力を省略できます。

以上でWinSCPの設定は完了です。

Connect Botの設定

Connect BotはAndroid OS用のSSHクライアントソフトです。
Google Playストアに登録されているのでダウンロードはhttps://play.google.com/store/apps/details?id=org.connectbotから行います。

Connect Bot + Hacker's KeyboardのセットでZ4 Tabletからサーバーへ接続する際に使用しています。
Hacker's Keyboardはソフトウェアキーボードですが、標準の文字入力ソフトと違ってキーボード感覚で文字入力ができます。
Z4 Tabletはbluetoothの同時接続数が2デバイスまでですので、キーボードの代わりにマウスを接続し、ヘッドセットを接続して音楽を聴きながらもしくは通話しながらのほうが便利だと思います。
文字列のコピーのような選択範囲を指定する操作はキーボードよりマウスのほうが便利です。

ここでは簡単な紹介だけにしておきます。

公開鍵管理で鍵の生成が可能

接続に使用する秘密鍵の管理だけでなく、鍵の生成もできるようです。
公開鍵管理

接続前に秘密鍵のアンロック(パスフェーズを入力してアンロックした状態)

秘密鍵のアンロック後

接続した状態

サーバへ接続した状態

カラーは変更できます(スクリーンショットはグレイ系になっています)

OpenSSHクライアントの設定

さくらのVPSで2台のサーバをローカルネットワーク接続して主にファイルの転送に利用します。
このためだけに安全でない方法を構築するほうが面倒で不安なため、SSH接続にしました。

OpenSSHクライアントの確認

まずは、OpenSSHクライアントがインストールされているか念のため確認します。

# rpm -qa openssh-clients
openssh-clients-6.6.1p1-25.el7_2.x86_64 

OpenSSHクライアントの設定を変更

Linuxで使用するSSHクライアントというとscpやsftpになると思います。
OepnSSHサーバで行った変更に合わせてクライアントの設定を変更します。

ホスト名 *.localの設定を追加

/etc/ssh/ssh_configを以下のように変更しました。

Host *.local
        CheckHostIP no
        Port 1022
        Protocol 2

Host *

ssh_configは上から順番にHostに一致した項目が設定されますので、Host  *より前に追加します。
SSH接続に使用するポートはSSHサーバにあわせて1022に設定しています。
この設定をすることでSSH接続時に毎回ポート番号やSSHプロトコルバージョンを指定する必要がなくなります。
SSHプロトコルバージョン2はChipersの設定を使用しますので、優先順位を変更する場合はChipersの設定を追加します。
デフォルトの値はssh_configのコメント行に記載されています。

ホスト名の登録

ローカルネットワーク接続で使用しているネットワークインターフェース(eth1)に割り当てたIPアドレスはどこにもホスト名を設定していないので名前解決ができません。
ローカルネットワーク内で使用できればよいだけなので2台のサーバの/etc/hostsファイルに以下を追加しました。

192.168.0.1 server1 server1.local
192.168.0.2 server2 server2.local 

これで接続時にはホスト名を使用することができるようになります。

scpの例

scpを使ったSSHファイル転送の方法です。
scpはsftpと違ってファイル単位での転送しかできません。また、中断すると転送を継続することができません。

以下はSCPコマンドを使用してserver1からserver2へSSH接続しています。
ユーザ:user1でtest.txtファイルを転送しています。
サーバ側のパスを指定しなかった場合はサーバのユーザホームディレクトリに保存されます。(サーバのパスを省略する場合でも「:」は必要です)

$ scp test.txt user1@server2:test.txt
The authenticity of host '[server2]:11022 ([192.168.0.2]:11022)' can't be established.
ECDSA key fingerprint is 12:34:56:78:9a:bc:de:fg:hi:jk:lm:no:pq:rs:tu:vw.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '[server2]:11022,[192.168.0.2]:11022' (ECDSA) to the list of known hosts.
Enter passphrase for key '/home/user1/.ssh/id_rsa':
test.txt                                                                              100%   47KB  46.7KB/s   00:00

初回接続時はサーバ情報とfinger printが表示されます。(上のfinger printは実際のものとは異なります)
一度接続したサーバのこれらの情報は.ssh/known_hostsファイルに追加されます。
以降、サーバの情報が変更された際にはメッセージが表示されます。
※サーバ上に同じファイル名のファイルがあった場合は上書きされます。

SSHサーバへの接続テスト

SSHクライアントからSSHサーバへ実際に接続してテストを行います。
接続テストの結果、問題がなければ5番の設定変更を行います。

パスワードでのログインを拒否する

PasswordAuthentication no

変更が終わったら変更内容を反映します。

# systemctl reload sshd

長くなりましたが以上でSSH接続に関する設定は完了です。

暗号化技術はいろいろとありますが、それを解読できるかどうかの状況も日々進化しています。
RSA暗号はいまだ効率よく解読する方法が知られていないため、総当たりで計算し解読していくことになります。
その際、暗号化キーのビット長が難易度をさらに高める効果があり、ビット長は2048bitであればこの先もある程度は安全であるとされています。
総当たりでも短時間で解読できるほどにコンピュータの計算性能が向上すれば、もしくは、効率よく解析できる方法が発見されれば、今使っているRSA暗号の2048bitが危険になる日もいずれ訪れます。
2010年くらいにRSA暗号の1024bitが危険であると報じられています。また、共通鍵暗号方式のDES暗号の512bitは2000年までには20時間ほどで解読できる状況になりました。
今ではDESに変わりAESが推奨されている理由です。
今は問題なくてもこの先、効率よく解読できる方法が解明されれば、暗号強度が高い状態といえなくなります。