自宅サーバにSSHでログインを試みる形跡が多数確認されました。
その数、なんと月間8万件。
アクセスログ(/var/log/auth.log)からアクセス元は特定できるので、iptablesにルールを追加することで対策はできそうです。
しかし、アクセス元のIPアドレスを確認すると、400個以上ありました。
これは、さすがに手で入力できない、ということでスクリプトを書いてやってみたいと思います。
Contents
前回までのおさらい
自宅サーバのセキュリティを考えた結果、攻撃者のIPアドレスを確認し、itablesにアクセス拒否のルールを追加するのが有効だと考えました。
冒頭にも書いたように、攻撃者は複数のIPアドレスを使って攻撃を仕掛けてくるので、一括登録するためのスクリプトで対処したいと思います。
iptablesの設定
iptablesを使う以上、基本的なルール追加・削除について触れておきます。
ルールの追加
攻撃者のIPアドレスが分かったら、iptablesにルールを追加します。
例えば、私のことが好きな41.141.248.196をブロックする場合、以下コマンドで追加します。
1 2 |
# INPUTにルールを追加 iptables -A INPUT -s 41.141.248.196 -j drop |
こういった感じで、全てのIPアドレスについてルールを追加していっても良いのですが、そうすると他の目的で設定したルールと区別がつきにくくなるので、こんな場合はチェインを使って設定します。
例えば、DENY-IPというチェインを作って、そこにルールを追加する場合は以下のように設定します。
1 2 3 4 5 6 7 8 |
# チェインを作成 iptables -N DENY-IP # DENY-IPにルールを追加 iptables -A DENY-IP -s 41.141.248.196 -j drop # INPUTにDENY-IPを紐づける iptables -A INPUT -j DENY-IP |
上記2つの設定は同じ振る舞いをしますが、後者はDENY-IPにルールを追加していくため、他の目的のルールと区別しやすいという利点があります。
ルール削除
一方で、ルールを削除する場合は以下のコマンドで削除します。
チェインを使っていない場合:
1 2 |
# INPUTにルールを削除 iptables -D INPUT -s 41.141.248.196 -j drop |
チェイン(DENY-IP)を使っている場合:
1 2 3 4 5 6 7 8 |
# INPUTに紐づけたDENY-IPを削除 iptables -D INPUT -j DENY-IP # DENY-IPのルールを削除(初期化) iptables -F DENY-IP # チェインを削除 iptables -X DENY-IP |
これで、何もなかったことになります。
スクリプトでルールを操作する時の注意点
スクリプトでiptablesを操作する際の注意点があります。
それは、追加したルールはそのまま登録されるということです。
例えば、拒否したい2つのIPアドレス(xxx.xxx.xxx.xxxとyyy.yyy.yyy.yyy)があったとします。
この際、誤ってINPUTにxxx.xxx.xxx.xxxのルールを2回追加したとします。
1 2 3 4 |
# INPUTにルールを追加 iptables -A INPUT -s xxx.xxx.xxx.xxx -j drop iptables -A INPUT -s xxx.xxx.xxx.xxx -j drop iptables -A INPUT -s yyy.yyy.yyy.yyy -j drop |
この時点では、ふるまいに問題はありません。
しかし、この後、実は拒否したい2つのIPアドレスが、信頼できるIPアドレスだった(拒否するべきではなかった)場合、ルールを削除する必要があります。
1 2 3 |
# INPUTにルールを削除 iptables -D INPUT -s xxx.xxx.xxx.xxx -j drop iptables -D INPUT -s yyy.yyy.yyy.yyy -j drop |
一見これでデフォルト状態になったように思えます。
しかし、xxx.xxx.xxx.xxxを2回登録していたため、実はINPUTにxxx.xxx.xxx.xxxを拒否するルールが残置しています。
1 2 |
# INPUTルールを確認 iptables -nL INPUT |
1 2 3 4 |
Chain INPUT (policy ACCEPT) target prot opt source destination all -- 0.0.0.0/0 0.0.0.0/0 DROP all -- xxx.xxx.xxx.xxx 0.0.0.0/0 |
このように、ルールの状態を意識して操作しないと、意図した状態にならないためスクリプトでルールを操作する場合は注意が必要になります。
考慮すべきポイント
単純にiptablesにルールを追加するだけなら簡単ですが、攻撃者は時と場合に応じてIPアドレスを使い分けて攻撃を仕掛けてきますし、対策したところで別のIPアドレスから攻撃を受けることは容易に想像できます。
攻撃者のIPアドレスが網羅的に把握出来ないことを前提に、対処する仕組みを考える必要があります。
攻撃者をどうやって見つけるか?
そもそも、SSHのログインは攻撃者だけが行うものではありません。
当然、私も自宅サーバのメンテナンスのためにSSHでログインします。
ただ、私がSSHでログインする場合はLAN内からですし、外出先からSSHでログインする場合はVPNを使います。
例外として、VPNを使わずにアクセスすることもありますが、この場合は接続元のネットワーク(IPアドレス)が信頼できる場合に限られます。
つまり、私が把握していないIPアドレスからのSSHのログインアクセスは、すべからく攻撃者だとみなすことができます。
そして、SSHのログインしようとする攻撃者は、SSHに限らずすべてのサービスへのアクセスを遮断するのが望ましいです。
逆を言うと、攻撃者以外のSSHのログインアクセス元は、私が把握しているIPアドレスからのみ、ということになります。
どうやって攻撃者のIPアドレスを追従するか?
まず、攻撃者のIPアドレスを事前に把握して対策することは困難です。
しかし、アクセスログからSSHログインに失敗した情報を基に、攻撃者かどうかを判定して対策することはできそうです。
上記で書いたように、SSHのアクセスログに私が把握していないIPアドレスがあれば、それは攻撃者からのアクセスだとみなすことができ、対策することができます。
つまり、定期的にアクセスログをチェックし、未対策のIPアドレスを発見したら、ブロックするという仕組みで対策できます。
私が考えたセキュリティの仕組み
あくまでもIPアドレスベースのFWによる対策になりますが、上記を踏まえて以下のような構図でiptablesを更新する仕組みを考えました。

前回の記事で述べたように、SSLHを使っていると攻撃者のIPアドレスが見えなくなるので、アクセスログから攻撃者の身元を確認するためのに443番ポートに加えて22番ポートでSSHDにアクセスできる状態にしておきます。
そして、この仕組みを成立させるためのシェルスクリプトを作成します。
このスクリプトをクーロンで定期的に実行することで、うまくこの仕組みを回すという魂胆です。
スクリプトを書いてみた
書きました。
これについては次の記事で解説を含めて紹介したいと思います。
作っている途中に思ったこともあるので、それも含めて記事にしたいと思います。
まとめ
前回の記事に続いて、自宅サーバのセキュリティについて、SSHで侵入しようとする攻撃者から身を守る具体的な仕組みを考えてみました。
前回の記事で述べたようにiptablesでFWを設定することが基本方針ですが、攻撃者のIPアドレスを追従する仕組みを含めて検討しました。
方針と仕組みが決まったので、この仕組みを実現するための具体的なスクリプトを次回ご紹介したいと思います。
参考になれば幸いです。
コメント