SSHのポート番号を変える

SSHの認証方式を、パスワード認証を禁止して公開鍵認証にすれば、SSHのポートからクラックされるリスクはかなり減る。しかし、外部からポートスキャンをされるたびにCPU負荷がかかるとのことなので、攻撃の対象になりやすいSSHはポート番号を変更しておくのが定番のようだ。

今日は以下のことを試してみる。サーバーはさくらインターネットVPSCentOS)。

  1. デフォルトのSSHポート(22番)へのアクセス状況を調べる
  2. SSHのポート番号を変更する

1. デフォルトのSSHポート(22番)へのアクセス状況を調べる

Linuxのセキュリティ関連のログは、/var/log/secureに記録される。lessコマンドでファイルを開いてみる。ちなみに、lessコマンドを終了するには「q」をタイプする。「/キーワード」をタイプすればファイル内の文字列検索もできる。

$ sudo -i # rootになる
# less /var/log/secure
...
Nov  6 00:54:12 サーバー名 sshd[1752]: Invalid user hashimoto from 220.227.121.180
Nov  6 00:54:12 サーバー名 sshd[1752]: Address 220.227.121.180 maps to report.ksrtc.in, but this does not map back to the address - POSSIBLE BREAK-IN ATTEMPT!
Nov  6 00:54:12 サーバー名 sshd[1753]: input_userauth_request: invalid user hashimoto
Nov  6 00:54:12 サーバー名 sshd[1752]: pam_unix(sshd:auth): check pass; user unknown
Nov  6 00:54:12 サーバー名 sshd[1752]: pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=220.227.121.180 
Nov  6 00:54:12 サーバー名 sshd[1752]: pam_succeed_if(sshd:auth): error retrieving information about user hashimoto
Nov  6 00:54:13 サーバー名 sshd[1752]: Failed password for invalid user hashimoto from 220.227.121.180 port 38485 ssh2
Nov  6 00:54:13 サーバー名 sshd[1753]: Received disconnect from 220.227.121.180: 11: Bye Bye
...
Nov  6 00:55:05 サーバー名 sshd[1782]: Invalid user chikafuji from 220.227.121.180
Nov  6 00:55:05 サーバー名 sshd[1782]: Address 220.227.121.180 maps to report.ksrtc.in, but this does not map back to the address - POSSIBLE BREAK-IN ATTEMPT!
Nov  6 00:55:05 サーバー名 sshd[1783]: input_userauth_request: invalid user chikafuji
Nov  6 00:55:05 サーバー名 sshd[1782]: pam_unix(sshd:auth): check pass; user unknown
Nov  6 00:55:05 サーバー名 sshd[1782]: pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=220.227.121.180 
Nov  6 00:55:05 サーバー名 sshd[1782]: pam_succeed_if(sshd:auth): error retrieving information about user chikafuji
Nov  6 00:55:07 サーバー名 sshd[1782]: Failed password for invalid user chikafuji from 220.227.121.180 port 49114 ssh2
Nov  6 00:55:08 サーバー名 sshd[1783]: Received disconnect from 220.227.121.180: 11: Bye Bye
...

適当なユーザー名とパスワードで手当たり次第に接続を試みられているっぽい。同様の接続がサーバーを立ててから6日間で12536件も。怖すぎ…。
ログの意味を調べてみた。

# 攻撃者のIPアドレスとドメイン名の正引き、逆引き結果が違う
Address 220.227.121.180 maps to report.ksrtc.in, but this does not map back to the address - POSSIBLE BREAK-IN ATTEMPT!

DNSIPアドレス(220.227.121.180)からドメイン名(report.ksrtc.in)を逆引きした結果と、ドメイン名からIPアドレスを正引きした結果が違うということ。これでどうして「POSSIBLE BREAK-IN ATTEMPT!(攻撃の可能性あり!)」と言えるのか? ちょっとだけ調べてみると、メールサーバーでは逆引きした結果と正引きした結果が違うとスパムメールと判定することは割と多いみたい。逆引きと正引きの結果を変えることは攻撃者にとってどんなメリットがあるのかを調べてみたが、すぐには見つけられなかった。攻撃者が本当のドメイン名を知られないようにするためかなぁ…。

# PAMで認証エラー
Nov  6 00:54:12 サーバー名 sshd[1752]: pam_unix(sshd:auth): check pass; user unknown
Nov  6 00:54:12 サーバー名 sshd[1752]: pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=220.227.121.180 
Nov  6 00:54:12 サーバー名 sshd[1752]: pam_succeed_if(sshd:auth): error retrieving information about user hashimoto

PAMはとは、Pluggable Authentication Moduleの略で、UNIXで共通化されている認証モジュールのようだ。このPAMから認証エラーのメッセージが出ている。

# パスワードでSSH2接続に失敗
Nov  6 00:54:13 サーバー名 sshd[1752]: Failed password for invalid user hashimoto from 220.227.121.180 port 38485 ssh2

これが重要。ログの最後にssh2とあるので、攻撃者はSSH2をパスワード認証で接続を試みていることがわかる。

2. SSHのポート番号を変更する

JFEテクノリサーチ株式会社さんのサイトがわかりやすいので参考になる。

以下の手順になる。

  1. 現在使われていないポートを調べて、新しいポート番号を決める
  2. SSHの設定ファイルにポート番号を追加する
  3. サービスの設定ファイルのポート番号を変更する
  4. iptablesファイヤーウォール)の設定ファイルを変更する
  5. 動作確認
(1) 現在使われていないポートを調べて、新しいポート番号を決める

変更するポートは、現在使われていなくて、かつ今後も使われる可能性が少ないものにする必要がある。
現在使われていないポートを調べるには、以下のコマンドを実行する。

[user@server ~]$ netstat -antu
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address               Foreign Address             State       
tcp        0      0 127.0.0.1:25                0.0.0.0:*                   LISTEN      # 25番ポート(SMTP)
tcp        0      0 :::80                       :::*                        LISTEN      # 80番ポート(HTTP)
tcp        0      0 :::22                       :::*                        LISTEN      # 22番ポート(SSH)
tcp        0    380 ::ffff:49.212.106.174:22    ::ffff:180.11.197.81:52561  ESTABLISHED # 22番ポートが接続中
udp        0      0 49.212.106.174:123          0.0.0.0:*                               
udp        0      0 127.0.0.1:123               0.0.0.0:*                               
udp        0      0 0.0.0.0:123                 0.0.0.0:*                               
udp        0      0 fe80::5054:ff:fe04:136:123  :::*                                    
udp        0      0 ::1:123                     :::*                                    
udp        0      0 :::123                      :::* 

まだapacheしか入れていないので、ほとんどのポートが使われていませんね。オプションは、-aはdisplay all sockets (default: connected)、-nはdon't resolve names、-tはTCPを表示、-uはUDPを表示するという意味。

規定のポートも使わないようにする。0から1023 までの範囲は Well Known Portsとして決められているので使わない。1024から49151まではRegistered Portsと呼ばれ、様々なサービスが定義されているので使わない方が望ましい。9152から65535についてはDynamic or/and Private Portsと呼ばれていて、アプリケーションで勝手に使うためのものみたい。

(2) SSHの設定ファイルにポート番号を追加する

以下のコマンドを実行する。

$ sudo vi /etc/ssh/sshd_config
  #Port 22          # コメントアウト
  Port 任意の番号   # ポート番号を追加する

$ sudo /etc/init.d/sshd restart
(3) サービスの設定ファイルのポート番号を変更する

以下のコマンドを実行する。(僕の環境では、このファイルを編集しなくても新しいポート番号で接続できた。)

$ sudo vi /etc/services
  #ssh            22/tcp          SSH Remote Login Protocol   # コメントアウトする
  #ssh            22/udp          SSH Remote Login Protocol   # コメントアウトする
  
  ssh            ポート番号/tcp          SSH Remote Login Protocol # 追加
  ssh            ポート番号/udp          SSH Remote Login Protocol # 追加
(4) iptablesファイヤーウォール)の設定ファイルを変更する

以下のコマンドを実行する。

$ sudo vi /etc/sysconfig/iptables
  # -A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 22    -j ACCEPT    # コメントアウト、または次の行のように書き換え
  -A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport ポート番号 -j ACCEPT # 新規追加
$ sudo /etc/rc.d/init.d/iptables restart
(5) 動作確認

新しいポートでSSH2接続でログインできることを確認する。また、古いポート(22番)でログインできないことを確認する。注意事項としては、既存の接続を残したまま新規接続を試すこと。設定が間違っている状態で接続を切ってしまうと、もう接続できなくなってしまって困るから。