[Work/TechInfo/other]

海外からのSSH接続を禁止したり時間制限をかけるiptablesと自動起動,sshguardの導入 / 2017-03-29 (水)

概要

ipsetを使うと複数のまとまりのIPアドレスをそのまま扱うことができる.

また,http://nami.jp/ipv4bycc/cidr.txt.gzにて,国内のIPアドレス範囲の一覧が公開されている.

これを利用して「ホワイトリスト」を作ることで,国内からのSSHのみ受けることができる.

またiptablesはリブートすると内容が消えてしまうので,最初にスクリプトを走らせてテーブルのruleファイルを生成,さらにsystemdのサービスに登録するための設定ファイルを書いて,systemdに登録しておくと,再起動時も自動的に適用される.

さらにsshguardを導入すると長めの設定時間内に認証開始の接続回数を超えると,かなり長めにブロックし,最終的には永久にブロックすることが可能になる.Ubuntuだとiptablesが入ってればsshguardもインストールするだけで自動的に設定されるので,とりあえず入れておけばかなり安全度が上がる.

以下はUbuntu 16.04LTS用.

iptablesの設定

#!/bin/bash
 
# 国別コードリストをダウンロード
cd /tmp
if [ -s cidr.txt ]; then
    mv cidr.txt cidr.txt.old
fi
 
wget http://nami.jp/ipv4bycc/cidr.txt.gz
gunzip cidr.txt.gz
 
# ホワイトリストを作成
ipset create -exist WHITELIST hash:net
 
# ホワイトリストに日本のIPアドレスを登録
sed -n 's/^JP\t//p' cidr.txt | while read ADDRESS; do
    ipset add WHITELIST $ADDRESS
done

# IPテーブルのセッティング
# ——————
# default setting
# ——————
iptables -P INPUT DROP
iptables -P OUTPUT ACCEPT
iptables -P FORWARD DROP
iptables -F
iptables -X

iptables -A INPUT -s 127.0.0.1 -d 127.0.0.1 -j ACCEPT
iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT

# ——————

# ブラックリストは今回使わないので,コメントアウト
# iptables -A INPUT -m set –match-set BLACKLIST src -j DROP
# HTTP
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
# HTTPS
iptables -A INPUT -p tcp --dport 443 -j ACCEPT
# DNS
iptables -A INPUT -p udp --dport 53 -j ACCEPT
# SSH, SFTPなどを国内からの接続に制限する
iptables -A INPUT -p tcp -m tcp --dport 22 -m set --match-set WHITELIST src -j ACCEPT
# SSH, SFTPの接続開始(認証)を300秒に5回までに制限する
iptables -A INPUT -p tcp --syn --dport 22 -m recent --name sshattack --set
iptables -A INPUT -p tcp --syn --dport 22 -m recent --name sshattack --update --seconds 300 --hitcount 5 -j DROP
# そのサーバの機能に必要な必要な範囲を開けて,国内からの接続に制限する
iptables -A INPUT -p tcp -m tcp --dport 60100:60200 -m set --match-set WHITELIST src -j ACCEPT

# 再起動時にiptableのルールを読み込めるように,ファイルに書き出しておく
iptables-save > /etc/iptables.rules

このシェルスクリプトを最初にsudoで実行しておく.すると,/etc/iptables.rulesに設定が吐き出される.

起動時に実行するスクリプトは以下.

#/bin/sh
cd /tmp
wget http://nami.jp/ipv4bycc/cidr.txt.gz -P /tmp
gunzip /tmp/cidr.txt.gz

ipset create -exist WHITELIST hash:net

sed -n 's/^JP\t//p' /tmp/cidr.txt | while read ADDRESS; do
    ipset add WHITELIST $ADDRESS
done

/sbin/iptables-restore < /etc/iptables.rules

最初に実行したスクリプトから,リストをダウンロードしipset WHITELISTを指定する処理を抜き出した部分と,事前に書き出したルールファイルからiptablesを読み込む処理の部分からなる,このシェルスクリプトを/opt/iptables_ssh_jpn_only.shとして作っておき755を与えておく.

[Unit]
Description = SSH allowd only JPN IP

[Service]
ExecStart = /opt/iptables_ssh_jpn_only.sh
Restart = always
Type = simple

[Install]
WantedBy = multi-user.target

これがsystemdの設定ファイルなので/etc/systemd/system/iptables_ssh_jpn_only.serviceとして作っておく.

$ sudo systemctl list-unit-files --type=service

の出力の中に含まれていれば,systemdに認識されている.あとは自動起動の設定をして起動する.

$ sudo systemctl enable iptables_ssh_jpn_only
$ sudo systemctl start iptables_ssh_jpn_only

とすれば,再起動されても自動的にiptablesが読み込まれるようになる.

sshguardのインストール

$ sudo apt install sshguard
$ sudo systemctl enable sshguard
$ sudo systemctl restart sshguard

Ubuntuはiptablesがインストールされていれば,これだけで,

SSHGuardのデフォルトの挙動では、20分間に4回攻撃を検出すると、そのIPアドレスからの接続をブロックします。接続ブロックは一定時間経過すると解除します。但し、接続ブロックから20分以内に再度攻撃を検出すると、ブロック時間を長くしていきます。ブロック回数とブロック時間は以下のようになります。

1回目:420~630秒間の範囲内でブロック
2回目:840~1260秒間の範囲内でブロック
3回目:永久にブロック

SSH総当たり攻撃(辞書攻撃/ブルートフォースアタック)の対策とその効果 - パソコン鳥のブログ

の設定がされる.