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

はじめに

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

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

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

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

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

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

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

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

公開鍵の登録 (Linux)

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

$ vi id_rsa.pub

  (Windows 上で公開鍵をメモ帳などで開き, それを vm 上のファイル id_rsa.pub にコピペする)

vm 上で公開鍵の形式を変換して, それを ~/.ssh/authorized_keys に保存する. すでに SSH で接続しているので, .ssh ディレクトリは作られているはずである.

$ cd 

$ mkdir .ssh           

$ chmod 700 .ssh

$ 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 された時の動作

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.1   (末尾に追記)

書式としては, コロンの前にデーモン名 (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 コマンドの引数に与えれば良い.