2021 年度 OSS リテラシー 3 : セキュリティ対策 (ssh)

はじめに

SSH では通信は暗号化されているが, さらにセキュリティを高める方法として, 以下の 2 つがある.

  1. パスワード認証を無効化し公開鍵認証のみにする
  2. SSH 接続が可能なホストを限定する

本手順書では Windows から公開鍵認証でログインできるようにしたのちに, 上記の (1) の手順を行うことにする. (2) は今回はパスする.

なお, SSH はデフォルトでパスワード認証と公開鍵認証の両方をサポートしている.

Windows => Linux 公開鍵認証でのアクセス (Putty の設定)

注意) 公開鍵の設定を始める前に,putty で自分の仮想マシン (VM) にログインしておくこと.この putty のターミナルは本手順ページが全部終わるまでは閉じないこと.トラブルが起きた時に,このターミナルが必要になるので.

公開鍵・秘密鍵の作成 (Windows)

まず Windows で公開鍵・秘密鍵を作成する. 公開鍵と秘密鍵は C: ドライブ以下に学生番号のフォルダを作り, そこに保管すること (そうしないとファイルが消えます = 学校の PC の仕様. USB メモリにも保存しておくと良い).

  • PuTTygen を起動 (C:\Program Files\PuTTY\).
  • "Generate" ボタンを押す. マウスの動きで乱数生成を行うので, PuTTygen のウインドウ上で適当にマウスを動かす.
  • 新たなウインドウが開いたら, "Key_passphrase" と "Confirm passphrase" にパスフレーズを入れる (パスフレーズは自分で考えること. ログインパスワードと同じにしないこと)
  • "Save public key", "Save private key" を順番におして, 公開鍵と秘密鍵を保存する.
    • C: ドライブ直下に学生番号のフォルダを作成し, そこに保存すること.
    • ファイル名はそれぞれ public, private などとする.
  • 保存を終えたら PuTTygen を終了する.

公開鍵の登録 (Linux)

Windows で作成した公開鍵を VM に登録する. Filezila, winscp などを使っても良いが, VM でファイルを新規作成してそこにコピペするのが簡単だと思う.

まず初めに,作成した公開鍵をメモ帳で開く.

次に,ログイン済みの putty のターミナル上で vi で id_rsa.pub というファイルを開き, 自分の公開鍵の内容をコピーする.

$ vi ~/id_rsa.pub

vm 上で公開鍵の形式を変換して, それを ~/.ssh/authorized_keys に保存する. すでに SSH で接続しているので, .ssh ディレクトリは作られているはずであるが, もしも ~/.ssh ディレクトリが存在しない場合は以下のように作成する.

$ mkdir .ssh           

$ chmod 700 .ssh

Windows からコピーした公開鍵を使えるようにするためには,以下のようにする.

$ ssh-keygen -i -f ~/id_rsa.pub >> ~/.ssh/authorized_keys

$ chmod 600 ~/.ssh/authorized_keys

接続テスト (Windows => Linux)

putty から vm へ接続する. メッセージをみて, 公開鍵認証でアクセスできることを確認すること.

  • PuTTy を起動 (C:\Program Files\PuTTY\).
  • Host Name に接続先の IP もしくはホスト名を入力
  • Category から "Connection" => "SSH" => "Auth" を選び, "Private Key file for authentication" の項目に「秘密鍵」を入力する.
  • "Open" を押す.
注) この段階で入力するのはアカウントの「パスワード」でなく公開鍵認証用の「パスフレーズ」.

ssh の設定の修正 (Linux)

パスワード認証の無効化.

ssh でパスワードによる認証を無効にし, 公開鍵認証のみをサポートする.

$ sudo -s

# cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bk

# vi /etc/ssh/sshd_config

  変更箇所は以下の通り.

  #PubkeyAuthentication yes  (変更前)
  PubkeyAuthentication yes   (変更後, コメントアウトを外す)

  # To disable tunneled clear text passwords, change to no here!
  #PasswordAuthentication yes  (変更前)
  PasswordAuthentication no    (変更後, コメントアウトを外し, yes -> no にする)

設定を変更したら ssh サーバを再起動する.

# /etc/init.d/ssh restart        

  [ ok ] Restarting ssh (via systemctl): ssh.service.

# exit
$
Windows 上で「新規に」putty を立ち上げて, ログインできるか確認すること. その際, 今まで使っていた putty のターミナルは閉じないこと. 設定を間違えてログインできなくなる事態を防ぐためである (putty が 2 つ立ち上がった状態にする).

フィルタリング : fail2ban (iptables)

本演習では iptables のフロントエンドとして実装されたソフトウェア fail2ban を用いる. iptables を直接設定するのは初心者には難しいためである.

fail2ban はログを監視し, 特定のパターンに引っかかる動作が記録されたらファイヤウォールに動的にルールを追加して, 通信をブロックする. 例えば ssh のブルトフォース攻撃 (パスワード総当たり攻撃) のように, 頻繁にアクセス & ログイン失敗を繰り返すホストからのアクセスを切断する.

インストールは apt-get で行う.

$ sudo -s

# apt-get update

# apt-get install fail2ban

fail2ban の設定ファイルは /etc/fail2ban/jail.conf および /etc/fail2ban/jail.d/defaults-debian.conf である. 各ポートに対して /etc/fail2ban/filter.d/ 以下にフィルタが用意されている. デフォルトの設定では ssh のみ監視されている.

sshd が監視対象となっていることは, 以下のコマンドを実行すれば確かめられる.

# fail2ban-client status 

  Status
  |- Number of jail:   1
  `- Jail list: sshd

[参考] ban された時の動作

以下は参考資料.何らかの原因で ban された時に実行すれば良い.

fail2ban をインストールしたので, ssh で何度もパスワード入力を誤ると ban される (以下のように ssh コネクションが切られる). デフォルトでは 10 分間接続不可となる.

sky$ ssh XX.XX.XX.XX

  ssh: connect to host 10.138.64.109 port 22: Connection refused

ラズパイで ssh アクセスで ban された IP を確認するためには以下のようにする.

# fail2ban-client status sshd

    Status for the jail: sshd
     |- filter
     |  |- File list:	/var/log/auth.log 
     |  |- Currently failed:	0
     |  `- Total failed:	6
     `- action
        |- Currently banned:	1
        |  `- IP list:	10.164.1.197
        `- Total banned:	1

ban された IP を解除するには以下のようにコマンドをうつ.

# fail2ban-client set sshd unbanip XX.XX.XX.XX (ban された IP)

(参考) TCP Wrapper によるアクセス制限

以下は参考資料.やらなくて良い.

TCP Wrapper を用いて ssh 接続を許可するホストを限定する方法を述べる . 本講義では行わなくて良い.

TCP Wrapper の設定ファイルは /etc/hosts.allow と /etc/hosts.deny の 2 つである. 動作としては /etc/hosts.allow に書かれたアクセスルールが最初に適用され, 次に /etc/hosts.deny に書かれたアクセスルールが適用される.

まず, /etc/hosts.allow において, サーバ sky.epi.it.matsue-ct.jp (10.100.100.1) のみに SSH アクセスの許可を出すことにする.

$ sudo -s

# vi /etc/hosts.allow

  sshd: 10.100.100.6   (末尾に追記)

書式としては, コロンの前にデーモン名 (SSH ならば sshd (ssh daemon)), コロンの後ろにホスト名である. ホスト名には .matsue-ct.jp のように, matsue-ct.jp のドメインを持つ全てのホスト, という書き方もできる.
[注: 書式的にはドメインで書いても良いはずだが, IP で指定しないとうまく動かなかった]

次に, /etc/hosts.deny において, 全てのホストからの接続を禁止する 設定を行う. ALL: ALL とすると, 外部の全てのホストから, 全てのデーモン (ポート) へのアクセスを拒否することとなる.

# vi /etc/hosts.deny

  ALL: ALL     (末尾に追記)

TCP wrapper は再起動は必要なく, 編集したファイルの内容は直ちに適用される.

以上の設定で, sky.epi.it.matsue-ct.jp 以外はラズパイのどのポートにも アクセスできなくなったはずである. 動作確認として, 友人のラズパイに SSH 接続してみよ. 正しく設定されていれば, 以下のように Connection がリセットされ, SSH 接続できないことがわかる.

$ ssh -l pi XX.XX.XX.XX (友人のラズパイの IP)

  ssh_exchange_identification: read: Connection reset by peer

さらに確認として, サーバからはラズパイに対して ssh 接続できることを確かめる.

$ ssh -l jxxxx sky.epi.it.matsue-ct.jp

  ...(略)...

sky:~$ ssh -l hogehoge  XX.XX.XX.XX (自分のラズパイの IP)

   Enter passphrase for key '/home/jxxxx/.ssh/id_rsa':   (パスフレーズ入力) 

   ...(略)...

$          (ラズパイに再度ログイン) 

$ exit     (ラズパイからサーバへ)

sky$ exit  (サーバからラズパイへ)

$ 

課題

  • diff コマンドを用いて ssh の設定ファイル (sshd_config) の変更箇所を表示し, それを wbt にて提出せよ.
    • 上記手順書では, 元ファイルを sshd_config.bk として残している. そのため, sshd_config と sshd_config.bk を diff コマンドの引数に与えれば良い.