攻撃多すぎ
sshdの待ち受けポートは通常port22とされていますが、port22を狙った攻撃が多すぎです。
以下は@MINOが管理しているサーバへの攻撃のログです。(rootでログインしようとしてパスワードを試している)
Feb 18 12:07:39 localhost sshd[5181]: pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=59.47.5.232 user=root
Feb 18 12:07:39 localhost sshd[5181]: pam_succeed_if(sshd:auth): requirement "uid >= 1000" not met by user "root"
Feb 18 12:07:41 localhost sshd[5181]: Failed password for root from 59.47.5.232 port 57680 ssh2
Feb 18 12:07:42 localhost sshd[5181]: pam_succeed_if(sshd:auth): requirement "uid >= 1000" not met by user "root"
Feb 18 12:07:44 localhost sshd[5181]: Failed password for root from 59.47.5.232 port 57680 ssh2
Feb 18 12:07:44 localhost sshd[5181]: pam_succeed_if(sshd:auth): requirement "uid >= 1000" not met by user "root"
Feb 18 12:07:46 localhost sshd[5181]: Failed password for root from 59.47.5.232 port 57680 ssh2
Feb 18 12:07:47 localhost sshd[5181]: pam_succeed_if(sshd:auth): requirement "uid >= 1000" not met by user "root"
Feb 18 12:07:49 localhost sshd[5181]: Failed password for root from 59.47.5.232 port 57680 ssh2
Feb 18 12:07:49 localhost sshd[5181]: pam_succeed_if(sshd:auth): requirement "uid >= 1000" not met by user "root"
Feb 18 12:07:51 localhost sshd[5181]: Failed password for root from 59.47.5.232 port 57680 ssh2
Feb 18 12:07:52 localhost sshd[5181]: pam_succeed_if(sshd:auth): requirement "uid >= 1000" not met by user "root"
Feb 18 12:07:54 localhost sshd[5181]: Failed password for root from 59.47.5.232 port 57680 ssh2
Feb 18 12:07:54 localhost sshd[5181]: Disconnecting: Too many authentication failures for root [preauth]
Feb 18 12:07:54 localhost sshd[5181]: PAM 5 more authentication failures; logname= uid=0 euid=0 tty=ssh ruser= rhost=59.47.5.232 user=root
Feb 18 12:07:54 localhost sshd[5181]: PAM service(sshd) ignoring max retries; 6 > 3
Feb 18 12:07:56 localhost sshd[5185]: reverse mapping checking getaddrinfo for 232.5.47.59.broad.bx.ln.dynamic.163data.com.cn [59.47.5.232] failed - POSSIBLE BREAK-IN ATTEMPT!
全ポートスキャンされてしまえば、sshdのリッスンポートがバレるのですが、ポートを22から変更することで、port22決め打ちでブルートフォースアタックなどを仕掛けてくる輩を排除することはできます。
こちらのブログでの「ピンポンダッシュが減る」という表現は的を得ているなぁと思いました。 http://d.hatena.ne.jp/ozuma/20150829/1440837066
作業手順を確認 順番大事
ポートを変更すること自体は簡単なことなのですが、セキュリティ上、ファイヤーウォールが関わってくると思いますので、設定する順番が大切になってきます。
SSHで接続しながら作業していることがほとんどだと思いますが、設定の順番を間違えるとSSH接続ができなくなり面倒になります。
今回はサーバ屋さんのVPSなどでCentOS7インストール直後を想定して進めていきます。
おそらくサーバへの最初のSSH接続はrootでパスワードを使った接続になるかと思います。
ここから次の手順で設定を行っていきまぁす。
- 1.鍵を作る(サーバ側でOK)
- 2.手元に秘密鍵、サーバに公開鍵を配置する
- 3.sshd_configにて認証方式を鍵交換方式に絞るよう設定
- 4.sshd_configにてポートを22以外に変更
- 5.ファイヤーウォールでsshd_configに設定したポートを開放する
- 6.sshd再起動
- 7.ファイヤーウォール再起動
sshdの認証方式の限定
まずセキュリティを高めるためにsshdのユーザ認証を鍵交換認証のみにします。
これは拙著の記事を参照してください。 http://pppppp.com
sshd_configの設定
待ち受けポートの変更
次にポートを変更します。 設定はsshdを再起動した後に有効になるので書き換えて保存するだけなら大丈夫です。
sshd_configの設定にport項目があります。
# If you want to change the port on a SELinux system, you have to tell
# SELinux about this change.
# semanage port -a -t ssh_port_t -p tcp #PORTNUMBER
#
#Port 22 ←ここ
#AddressFamily any
#ListenAddress 0.0.0.0
#ListenAddress ::
ここをアンコメントアウトして、ポートを変えます。0〜1023のウェルノウンポート以外であれば何でもOKです。
例では10022にしてみました。
# If you want to change the port on a SELinux system, you have to tell
# SELinux about this change.
# semanage port -a -t ssh_port_t -p tcp #PORTNUMBER
#
Port 10022 ←ここ
#AddressFamily any
#ListenAddress 0.0.0.0
#ListenAddress ::
ファイヤーウォールの穴あけ
sshd_configのポートを変えることでsshd自体の待ち受け(Listen)ポートは変更できましたが(sshdを再起動するまでは有効になっていません)、今度はファイヤーウォール側でもそのポートを開けなくてはなりません。
ファイヤーウォールの穴を開けないといくらsshd_configの設定が正しくても、接続が遮断されてしまいます。(実際にはCentOSインストール直後にはファイヤーウォールにほとんどルールがないので接続できてしまいますが)
firewalldからiptablesに乗り換える(推奨しているわけではないです)
ごめんなさいCentOS7で標準になったfirewalldまだよくわかりません…。
firewalldは内部的にはiptablesが動いているそうなので、だったらiptablesを直に使いたいでデス。
iptables自体は元からインストールされているので使う準備をします。
CentOS7ではsystemdを使った管理になっています。 systemdで使うiptables-services(iptablesを起動させるための定義ファイル)をインストールします。
$ sudo yum -y install iptables-services
firewalldを止めて自動起動から外し、iptablesを自動起動にしてスタートさせます。
$ sudo systemctl stop firewalld.service
$ sudo systemctl mask firewalld.service
$ sudo systemctl enable iptables.service
$ sudo systemctl start iptables.service
これでiptablesが使えるようになります。
iptablesにルールを設定
ルールの追加
CentOS7ではOSインストール直後にはiptablesになんのルールも追加されていません。 ルールを作って、とりあえずssh接続はできる、最低限のファイヤーウォールを作ります。
コマンドラインからルールを追加していく方法がありますが、全体を見渡しにくいので、ファイル上での編集をオススメします。お使いのエディタ等(おらビムだ)で
$ sudo vim /etc/sysconfig/iptables
というファイルを作ります。
もしくは
$ sudo iptables-save
というコマンドで現在有効になっているルールが/etc/sysconfig/iptablesとして保存されます(最初はルールがないので雛形としての役目になるかと思います)。
先ほどsshd_configで設定した新しいポートを開けるべく以下のように設定します。 (sshdのポートの開通以外の部分はお好みです)
*filter
#基本的に外部からのパケットは破棄
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [0:0]
#接続が完了しているパケットは通し
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
#pingは通し
-A INPUT -p icmp -j ACCEPT
#ローカルループバックは通し
-A INPUT -i lo -j ACCEPT
#sshdでつかうport10022の穴あけ
-A INPUT -p tcp -m state --state NEW -m tcp --dport 10022 -j ACCEPT
#それ以外は全部破棄(エラーメッセージは送る)
-A INPUT -j REJECT --reject-with icmp-host-prohibited
-A FORWARD -j REJECT --reject-with icmp-host-prohibited
COMMIT
これでsshd_configで設定した新しいポート(例では10022)にファイヤーウォール側でも穴を開けることができました。
設定反映
設定を反映させるためにsshdとiptablesを再起動させます。
$ sudo systemctl restart sshd.service
$ sudo systemctl restart iptables.service
再度接続・設定が正しく出来たかの確認
設定が全部終わったら、一旦SSH接続を切ります。
そして再度接続してみてください。最初にport22で試してみます。
$ ssh -p22 -i ~/.ssh/id_rsa minoru@hoge
ssh: connect to host mackerel port 22: No route to host
即座に弾かれましたね。iptablesによってしっかりport22は閉じられているようです。
次は新たに設定したport10022にて接続してみます。
$ ssh -p10022 -i ~/.ssh/id_rsa minoru@hoge
Enter passphrase for key '/home/user/.ssh/id_rsa':
Last login: Thu Feb 29 12:59:59 2016 from 192.168.0.12
[minoru@hoge ~]$
10022ではちゃんと接続することができました。sshdのリッスンポートがport10022になっている上に、iptablesで穴あけができている証拠です。
これでsshdのポート変更が完了しました。
補足・ハマりポイント
サーバ屋のポート閉じ機能でハマる
サーバ屋さんによっては、サーバ屋さん側でポートを閉じてくれる(もしくは開放するポートを選ぶ)場合もあります。
@minoruはよくconohaクラウドを使うのですが、conohaでは開放するポートを選ぶことができます。(conohaでは「インバウンド接続許可ポート」と名称しています)
これは自分のサーバの内部のファイヤーウォールではなく、conohaのインフラ側の設定によるものです。
例えばport22だけをconohaの設定で開放している場合、今回試した設定ではSSH接続ができません。port10022はconoha側で閉じられているからです。
conohaの場合、簡易的にウェルノウンポートのいくつかだけを開放するよう設定できますので、今回のようにウェルノウンポート以外のポートであるport10022を開放するには、全ポートを開放するしかありません。
しっかりファイヤーウォールの設定ができており、余計なサービスを動かさないなど気を配ることでインフラ側のポート開放に頼らなくてもいいと思います。(もちろん設定できるならしたことに越したことはないです)
設定が正しいのに接続できない場合は、インフラ側のポートの開け閉めを確認してみてください。
@minoruはconohaの設定でport80しか開放していなかったことがあり、疎通せず一晩中悩んだ経験があります…。
まとめ
@minoruの環境では、ポート変更をしてからsecureログの分量が100分の1くらいになりました。ブルートフォースアタックが全くと言っていいほどなくなったからです。
ログ見やすーい。ByeBye。