sshguardでsshを守る

こんにちワン!grasysの長谷gaワン!です。
わんわん言ってますが、最近ニャンちゅうって言われ始めてますw

sshguard
sshd用のブルートフォースアタック対策ツールです。

grasysではsshguardを要件次第で活用しています。
こちらではsshguardをgcloudコマンドを交えて自動設定してみようかなと!

1番安全なのはIP制限をGoogle Cloud Compute Engine Firewallでかけて閉じることなんですが
お客様の環境やワークスタイル次第では
sshは開けて欲しいけどセキュリティがががが・・・
みたいな要望もあったので取り急ぎアタックを制御することで 以下の形で選んで貰うようにしています。

前提条件: opsというインスタンスを必ず作るようにしてますがopsのみssh許可

  1. sshguard + Firewall公開
  2. FirewallでIP制限

移動が多いお客さんもいるしね

実際アタックがどれくらい多いか

以下ちょっと1週間放置したsshのlogin失敗のlog

grep "input_userauth_request: invalid user" /var/log/secure* | awk '{print $9}' | sort | uniq -c

      1 1
      2 1234
      1 ~1EaseUs@AcsT
      1 500
      3 a
      1 aaron
      3 adam
      1 adempiere
      3 adilson
    675 admin
      1 ADMIN
      1 Administrateur
      3 administrator
      5 Administrator
      3 aktainfo
      1 alan
~~~~~~~~中略~~~~~~~~
      1 www
      1 wwwroot
      1 xbian
      1 xbmc
      1 z
      2 zabbix
      1 zhangchuanzhuo
      2 zzadmin
  • 1ってユーザなんなんだよ
  • 1234ってユーザなんなんだよ
  • zabbixは許す、、、zってユーザが許せん!
  • 全体的に1文字ユーザ許せん!ふざけんな!w

wcしてみる

grep "input_userauth_request: invalid user" /var/log/secure* | wc -l

1521

おおい・・・w

Compute EngineのFirewall Rule default設定

これで確認できます。

gcloud compute firewall-rules describe default-allow-ssh

allowed:
- IPProtocol: tcp
  ports:
  - '22'
creationTimestamp: '2014-11-10T20:58:42.327-08:00'
description: Allow SSH from anywhere
id: 'xxxxxxxxxxxxxxxxxxx'
kind: compute#firewall
name: default-allow-ssh
network: https://www.googleapis.com/compute/v1/projects/xxxxx-xxxxxxx-xxx/global/networks/default
selfLink: https://www.googleapis.com/compute/v1/projects/xxxxx-xxxxxxx-xxx/global/firewalls/default-allow-ssh
sourceRanges:
- 0.0.0.0/0

Project作ってCompute Engineを有効化した直後はデフォルトだと基本sourceRangesで0.0.0.0/0が設定されていて公開になってます。

これを設定変更して所定のIPのみにしたりして制御します。

Project作った時期によっても多少違うかも

Install sshguard

まずgcc入れましょう
入ってたら飛ばして!

CentOS6向けです(CentOS7でもやれてるから多分動くと思うけど・・・)

yum -y install gcc

build sshguard

最新版でいきたい!オレは常に最新版がいい!w
たぶん動く!動かなかったら手でゴニョゴニョしてください!

  1. ゴニョゴニョ変数準備
  2. sshguardのtarballをダウンロード
  3. tarball 展開
  4. configure
  5. make && make install
  6. symlink

/opt/配下にInstallします。

version=1.7.0
module=sshguard
name=${module}-${version}

build_base=/tmp/src/
build_dir=/tmp/src/${name}
deploy_to=/opt/${name}
symlink_to=/opt/${module}

download_url=http://downloads.sourceforge.net/project/${module}/${module}/${version}/${name}.tar.gz
download_to=/tmp/src/${name}.tar.gz

curl --create-dirs -o ${download_to} -L ${download_url}
tar -xvzf ${download_to} -C ${build_base}
cd ${build_dir}
./configure \
  --prefix=${deploy_to} \
  --with-firewall=iptables
make
make install

ln -sf ${deploy_to} ${symlink_to}

これやったら多分入ったと思うんで
おもむろに以下を叩くとヘルプが見れます!

/opt/sshguard/sbin/sshguard -h
usage: sshguard [-v] [-a thresh] [-b thresh:file] [-e script]
       		[-f service:pid-file] [-i pidfile] [-l source] [-p interval]
       		[-s interval] [-w address | file]

whitelistを作る!

sshguardにはwhitelist機能があるので一応活用します。

せっかくなんでGoogle Cloud Platform Compute EngineのInternalをwhitelistに登録します。

  1. metadataに自分のインスタンスのネットワークを聞きに行く
  2. network名でnetworkのx_gcloud_modeを調べる
  3. Network Rangeを取得
  4. /tmp/sshguard_whitelistに出力(/tmp配下なのに意味はとくにありません!)
network=`curl -s -H "Metadata-Flavor: Google" metadata/computeMetadata/v1/instance/network-interfaces/0/network | xargs basename`
x_gcloud_mode=`gcloud compute networks describe ${network} | grep x_gcloud_mode | awk '{print $2}'`
if [ ${x_gcloud_mode} = "legacy" ]; then
  IPv4Range=`gcloud compute networks describe ${network} | grep IPv4Range | awk '{print $2}'`
elif [ ${x_gcloud_mode} = "auto" -o ${x_gcloud_mode} = "custom" ]; then
  IPv4Range=()
  for t in `gcloud compute networks subnets list | grep -v NAME | grep ${network} | awk '{print $4}'`
  do
    IPv4Range+=("${t}")
  done
else
  echo "gcloud components updateしましょう!"
  exit 1
fi

test -f /tmp/sshguard_whitelist && rm -rf /tmp/sshguard_whitelist
for r in ${IPv4Range[@]}
do
  echo ${r} >> /tmp/sshguard_whitelist
done

できあがったwhitelistは以下で確認できます。

cat /tmp/sshguard_whitelist

sshguard WHITELISTING


x_gcloud_modeはUsing Subnetworksここをみるとわかるんだけど
2016年08月30日現在のところ3種類

  • legacy
  • auto
  • custom

いつのまにかに・・・w

iptables

sshguardはiptablesを利用します。
以下のコマンドでchainを作成して下さい。

iptables -N sshguard
iptables -A INPUT -m multiport -p tcp --destination-ports 22 -j sshguard

sshguard SETUP NETFILTER/IPTABLES

Init sshguard

option description
-a 閾値
-p 閾値を超えたIPをここで設定した秒数 iptablesでフィルタリングする
-s 閾値を超えたIPを開放する秒数
thresh=50
p_interval=420
s_interval=1200
/opt/sshguard/sbin/sshguard \
  -a ${thresh} \
  -p ${p_interval} \
  -s ${s_interval} \
  -l /var/log/secure \
  -i /var/run/sshguard.pid \
  -w /tmp/sshguard_whitelist

threshを30にすると3回でsshguardがiptablesにフィルターしちゃうので
gcloud compute sshするときに困りますw

5回の50くらいがいいかも・・・

sshguardのフィルター確認

以下とある環境の出力

iptables -L -n
iptables -L -n

なんで気を使ってIPにモザイクかけてるかわからんけど・・・

iptablesのお掃除

sshguardは登録する機能しか持っていないので
iptablesにchainは残ります。

邪魔なら以下で消えるのでどうぞ

for sshguard_num in `iptables -L INPUT --line-numbers | grep sshguard | awk '{print $1}'`
do
  iptables -D INPUT ${sshguard_num}
done
iptables -X sshguard

grasysでは

こんなのつどつどでもやってられないので
bashのCommand Line Framework rerunを利用して 1 commandで諸々設定できるようになってます。

こんな感じ

rerun security: sshguard