今までは下記のサイトから取得したデータからJPを抽出して/etc/hosts.allowに追加していたのですが、直ぐに面倒になって放置していました。
ftp://ftp.apnic.net/pub/apnic/stats/apnic/delegated-apnic-latest
自動更新にするスクリプトを作成するかと思いつつ、代わりになるような方法は無いかなと探していたらありました。GeoIPを使って簡単にできるとは。
Allow SSH access based on GeoIP country
https://www.claudiokuenzler.com/blog/676/ssh-access-filter-based-on-geoip-database-allow-deny
MaxMind
https://www.maxmind.com/en/home
GeoLite2 Free Downloadable Databases
https://dev.maxmind.com/geoip/geoip2/geolite2/
今回はCentOS 7に設定してみました。
上記サイトのスクリプトはgeoiplookup,geoiplookup6コマンドを利用しています。インストールされていない場合は下記のコマンドでインストールして下さい。
1 |
[root@centos7 ~]# yum install GeoIP |
geoiplookupコマンドを実行してみます。ここから国コードを抽出しているのですね。
1 2 |
[root@centos7 ~]# geoiplookup 121.178.60.41 GeoIP Country Edition: KR, Korea, Republic of |
- スクリプト/usr/local/bin/ipfilter.shの作成
- 実行権限の設定
- 全てのssh接続を拒否
- 許可するIP(国コードJP)を設定
許可する国をJPに修正しています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
#!/bin/bash # License: WTFPL # UPPERCASE space-separated country codes to ACCEPT ALLOW_COUNTRIES="JP" LOGDENY_FACILITY="authpriv.notice" if [ $# -ne 1 ]; then echo "Usage: `basename $0` " 1>&2 exit 0 # return true in case of config issue fi if [[ "`echo $1 | grep ':'`" != "" ]] ; then COUNTRY=`/usr/bin/geoiplookup6 "$1" | awk -F ": " '{ print $2 }' | awk -F "," '{ print $1 }' | head -n 1` else COUNTRY=`/usr/bin/geoiplookup "$1" | awk -F ": " '{ print $2 }' | awk -F "," '{ print $1 }' | head -n 1` fi [[ $COUNTRY = "IP Address not found" || $ALLOW_COUNTRIES =~ $COUNTRY ]] && RESPONSE="ALLOW" || RESPONSE="DENY" if [[ "$RESPONSE" == "ALLOW" ]] ; then logger -p $LOGDENY_FACILITY "$RESPONSE sshd connection from $1 ($COUNTRY)" exit 0 else logger -p $LOGDENY_FACILITY "$RESPONSE sshd connection from $1 ($COUNTRY)" exit 1 fi |
1 |
[root@centos7 ~]# chmod 755 /usr/local/bin/ipfilter.sh |
1 2 3 |
[root@centos7 ~]# vi /etc/hosts.deny [root@centos7 ~]# cat /etc/hosts.deny sshd: ALL |
1 2 3 4 5 6 7 |
[root@centos7 ~]# vi /etc/hosts.allow [root@centos7 ~]# cat /etc/hosts.allow # local address sshd: 192.168.1. # Japan IP sshd: ALL: spawn /usr/local/bin/ipfilter.sh %a |
暫くすると拒否されたIPがログに記録されました。
1 2 3 4 5 |
[root@centos7 ~]# grep "sshd connection from" /var/log/secure Oct 2 18:33:31 centos7 root: DENY sshd connection from 222.186.175.167 (CN) Oct 2 18:33:53 centos7 root: DENY sshd connection from 222.186.42.163 (CN) Oct 2 18:36:34 centos7 root: DENY sshd connection from 222.186.42.241 (CN) Oct 2 18:38:35 centos7 root: DENY sshd connection from 60.169.69.101 (CN) |
2019/10/5 追記
どうもCentOS 7のTCP wrapperでは終了コードでallow,denyが機能していないようです。いろいろ情報を探しているけど出来ないっているのを一つだけ見つけました。
https://www.linuxsecrets.com/3805-tcp-wrapper-block
ログにはDENYと記録されているのに、その後接続を受け付けているんですよね。
1 2 3 4 5 6 7 8 9 10 |
Oct 4 16:04:30 centos7 root: DENY sshd connection from 211.117.121.xxx (KR) Oct 4 16:04:32 centos7 sshd[7482]: pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=211.117.121.xxx user=root Oct 4 16:04:34 centos7 sshd[7482]: Failed password for root from 211.117.121.xxx port 51474 ssh2 Oct 4 16:04:36 centos7 sshd[7482]: Failed password for root from 211.117.121.xxx port 51474 ssh2 Oct 4 16:04:39 centos7 sshd[7482]: Failed password for root from 211.117.121.xxx port 51474 ssh2 Oct 4 16:04:40 centos7 sshd[7482]: Failed password for root from 211.117.121.xxx port 51474 ssh2 Oct 4 16:04:42 centos7 sshd[7482]: Failed password for root from 211.117.121.xxx port 51474 ssh2 Oct 4 16:04:44 centos7 sshd[7482]: Failed password for root from 211.117.121.xxx port 51474 ssh2 Oct 4 16:04:44 centos7 sshd[7482]: error: maximum authentication attempts exceeded for root from 211.117.121.xxx port 51474 ssh2 [preauth] Oct 4 16:04:44 centos7 sshd[7482]: PAM 5 more authentication failures; logname= uid=0 euid=0 tty=ssh ruser= rhost=211.117.121.xxx user=root |
ちなみに/etc/hosts.allowに許可IPを記述すると、それ以外からの接続は下記のようにログに記録されます。
1 |
Oct 5 08:57:57 centos7 sshd[32654]: refused connect from 222.186.52.xxx (222.186.52.xxx) |