グローバルIPでssh を有効にしたらスキャンがいっぱい来る
別に、実害は無いんだけど、ちょっと気持ち悪いよね。 1時間で1000近いログが溜まるんですね。
ポート22のsshはすげぇアクセス来るんだよね。
ISP側である程度のフィルタをされているはずなんだけど。それでもコレくらい来る。
Dec 21 15:02:13 raspi3 sshd[3524]: Received disconnect from 115.238.245.2 port 33445:11: [preauth] Dec 21 15:02:13 raspi3 sshd[3524]: Disconnected from 115.238.245.2 port 33445 [preauth] Dec 21 15:03:49 raspi3 sshd[3532]: Received disconnect from 115.238.245.6 port 34296:11: [preauth] Dec 21 15:03:49 raspi3 sshd[3532]: Disconnected from 115.238.245.6 port 34296 [preauth] Dec 21 15:04:34 raspi3 sshd[3537]: Received disconnect from 221.194.47.245 port 57877:11: [preauth] Dec 21 15:04:34 raspi3 sshd[3537]: Disconnected from 221.194.47.245 port 57877 [preauth] Dec 21 15:05:40 raspi3 sshd[3542]: Received disconnect from 221.194.47.243 port 52506:11: [preauth] Dec 21 15:05:40 raspi3 sshd[3542]: Disconnected from 221.194.47.243 port 52506 [preauth]
大学の研究用のガチのグローバルIPだと秒間で10とか来てたから、ソレを考えたら少ない方だわ
公開鍵認証のみなので実害はない。
preauth で止まってるし、password をブルートフォース攻撃されるわけでもないので、別にいいんですが、ログをみてるときにちょっと気持ち悪いよね。 家のドアチャイムを定期的にピンポンダッシュされて空き家か調べられるのはっちょっとだけ良い気がしない。
日本国内のIPアドレスに限定してみよう。
ssh のポートについては日本国内のIPアドレスに限定してみようと思い立った。
日本国内のIPアドレスは何処で取れるのか?
ぐぐったらいくつか在るんだけど、今回は、 https://ipv4.fetus.jp/ を使うことにした。
日本国内のIPアドレスは→ https://ipv4.fetus.jp/jp.txt
iptableにコレ全部登録するの?
流石に約3000件を登録するのはちょっと現実的じゃないよね。
iptables で第三国のIPアドレスを制限して、日本国内に限定したいとか思ったんですが。IPアドレスの範囲を指定するのって思った以上に不便。
iptablesの件数がどこまでも伸びていってしまうよね。
ipsetを使います。
ipsetを使えばかんたんに設定できるようです。
調べてみたら カーネルにnetfilter に ipset という、IPアドレスをグルーピングしてフィルタを記述できるセットが用意されていた。
ipset のインストール
sudo apt search ipset ipset/stable 6.30-2 armhf administration tool for kernel IP sets
sudo apt install ipset
ipset の使い方
ipset は、名前を付けてリスト(フォルダ的なもの)にIPアドレスか、ネットワーク・アドレスをガンガン放り込んでグルーピングしていくもの
ipset でリストを作る・潰す
リストの作り方と削除
sudo ipset create my_list hash:ip sudo ipset destory my_list
hash:ip
は ip アドレスで、hash:net
はネットワークで、それぞれ指定する。件数が多いものはまよわず net
を使う。
sudo ipset create my_list hash:net sudo ipset destory my_list
ipset のリストにIPを登録する・確認する・削除する
ip set のリストにIP・ネットワークを登録し確認し、削除する。
sudo ipset add my_list 1.0.16.0/20 sudo ipset list my_list sudo ipset del my_list 1.0.23.58
ただし、hash:ip で定義したリストに、サブネット切ったネットワークで、ガッツリIPを放り込むと大量にエントリが発生するので注意が必要
hash:net の方がいいと思う。
実際に入れてみた例
$ sudo ipset create my_list hash:net $ sudo ipset add my_list 1.0.16.0/20 $ sudo ipset list my_list Name: my_list Type: hash:net Revision: 6 Header: family inet hashsize 1024 maxelem 65536 Size in memory: 396 References: 0 Members: 1.0.16.0/20
国内限定にするフィルタを作る
ipset の使い方がわかったところで、iptables と連携するための ipset を作ります。
日本国内のIPをざっくり取得する
日本に割当てられたIPv4アドレスを取得する
curl https://ipv4.fetus.jp/jp.txt | \grep -v '^#'
何度も取得に行くと負荷かけちゃうので、適当にキャッシュした方がいいです。
日本国内IPをざっくり登録する
取得した結果のすべてを ipset で自分の許可リストに放り込んで行きます。
$ curl https://ipv4.fetus.jp/jp.txt | \grep -v '^#' |xargs -I@ -P 0 sudo ipset add my_list @
登録したら、確認する
登録ができたら確認してみます。
$ sudo ipset list my_list
登録結果を保存する
登録した結果を保存して
sudo ipset save my_list > my_list.txt
iptablesでフィルタを作る準備をします。
万が一失敗しても死なないように、別ポートでもsshd を起動しておきます。
/etc/ssh/sshd_config
Port 22 Port 2222
port 2222 でもssh を起動しておきます。
ssh -p 2222 で接続ができることを確認
失敗した時でも安心できるように別ポートが使えることを確認
ssh localhost -p 2222
ローカルIPの追加。
今回は、国内限定にする=ホワイトリスト方式。なので、許可リストにローカルIPを入れておきます。
sudo ipset add my_list 192.168.0.0/16 sudo ipset add my_list 10.0.0.0/8 sudo ipset add my_list 172.16.0.0/12
最後に、ipset の登録値を使ってiptablesを構成する
sudo iptables -I INPUT -m state --state NEW -p tcp --dport 22 -m set --match-set my_list src -j ACCEPT
iptables の設定が出来たことを確認
takuya@raspi3:~$ sudo iptables -L Chain INPUT (policy ACCEPT) target prot opt source destination ACCEPT tcp -- anywhere anywhere state NEW tcp dpt:ssh match-set my_list src Chain FORWARD (policy ACCEPT) target prot opt source destination Chain OUTPUT (policy ACCEPT) target prot opt source destination
設定を保存( permanently/persist)して再起動後も有効な設定 にする
systemd をつかって ipset の取得を定期実行にしたりしておく。
起動時にipset を再度有効にするようにしておく
sudo sh -c 'ipset save > /etc/ipset.conf'
iptablesの設定の保存。これは定番 iptables が再起動後に ipset のリストを使うようにしておく
sudo sh -c 'iptables-save > /etc/iptables.up.rules'
再起動後に実行されるようにする。
再起動に有効にする。
sudo vim /etc/network/if-pre-up.d/iptables-with-ipset sudo chmod ug+x /etc/network/if-pre-up.d/iptables-with-ipset
/etc/network/if-pre-up.d/iptables
#!/bin/sh ## ## 2017/12/23 記述 ## /etc/network/if-pre-up.d/iptables-with-ipset ## # ipset からリストを読み込む ipset restore < /etc/ipset.conf # ipset を使ってiptablesを構成する iptables-restore < /etc/iptables.up.rules
これで、再起動に有効になる。
メモなど
本当は iptables じゃなくて、openssh側の設定でやりたいんだけどなぁ。
openssh-server の拒否リスト(もしくは MatchAddress )的なところで、ホワイトリストを使えれば良いんだけどなぁ。
iptablesはいろいろな設定をドンドン書いていくので、ゴチャゴチャしすぎて整理できないから辛い。
もしかしてv4の方が使いやすい??
v4 の在庫は枯渇してて、どの国にドレだけ割当てられてるかすでに決まっていて今後大幅に増減はないと考えるなら、v4のフィルタって更新やメンテをあまりしなくても動くんじゃないですかね。
参考資料
https://inaba-serverdesign.jp/blog/20150209/ipset_iptables_country_centos6.html