sslhdへのログイン試行ログを見つけてから、セキュリティ対策について検討してきました。
攻撃者はターゲットを絞るとサーバに対してブルートフォース(総当たり)攻撃でセキュリティを突破しようとしてきます。
もちろん、サーバへの侵入は許さないのですが、ログイン試行を許してしまうとCPU負荷が高くなるという悪影響があります。
そこでFW(iptables)によるアクセス拒否を考えたのですが、攻撃者のIPアドレスは固定ではなく、対策したところでIPアドレスを変えて攻撃してきます。
そのため、外部からのアクセスに対するセキュリティを少しでも高める為に、以下のようにFWを更新する仕組みを考えました。
今回、sshログイン失敗履歴から攻撃者のIPアドレスを特定し、FW(iptables)に自動でアクセス拒否ルールを設定するシェルスクリプトを作成してみましたので、記事にしたいと思います。
Contents
やりたいこと
復習になりますが、以下のような自律的にFW(iptables)を更新する仕組みを作りたいと考えています。
この仕組みを実現するためのシェルスクリプトについて検討しました。
スクリプトの概要
今回は、攻撃者と思われるIPアドレスを拒否(ブロック)するスクリプトを作成しました。
以下のようなことを実現するスクリプトです。
1はsshのログイン失敗履歴(/var/log/auth.log)から、ログインに失敗したIPアドレスを攻撃者とみなし、アクセスを拒否(プロック)します。
攻撃者のIPアドレスはログの“Failed”あるいは“Invalid”を含む行のIPアドレスとします。
1 2 |
# 本スクリプトが攻撃者とみなすIPアドレス一覧 cat /var/log/auth.log* | grep -E "Failed|Invalid" | grep -Eo '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | sort | uniq |
2は、あらかじめ指定した拒否したいIPアドレスを対象に、アクセス拒否します。
1と2の違いは、1はsshのログイン失敗履歴から抽出するIPアドレスが対象なのに対し、2はログに関わらず静的なIPアドレスを対象にする点です。
「ログにはないけど、このIPアドレスからのアクセスは拒否したい」、という場合を想定しています。
3は、間違って自身の信頼されたネットワークからのアクセスを拒否しないようにするためです。
自分が自宅サーバにsshログインする際に、うっかりパスワード入力を間違ってしまうとログイン失敗履歴に残ってしまうので、その場合でもアクセス拒否しないよう指定したIPアドレスからのアクセスは拒否しないようにします。
4は、FWの設定の仕方です。
今回は、アクセス拒否するIPアドレスを対象にFWを設定します。
INPUTポリシへの追加のためFWは「デフォルト許可」を前提として、拒否するIPアドレスのみを明にiptalbesにルール追加します。
ベン図
一旦、整理するとやりたいことを以下のIPアドレスの集合で表してみます。
「拒否したいIPアドレス」は、スクリプトで実現することの1,2に相当します(A,D,F,G)。
また、「拒否したIPアドレス」は、 拒否したいIPアドレスとは似て非なるもので既にiptablesにルール(拒否)が設定されているIPアドレスの集合です(B,D,E,G)。
拒否したいIPアドレスの中には、これからルールに登録しなければならないIPアドレス(A,F)と既にiptablesに登録されているもの(D,G)があります。
iptablesへの二重登録を避けるために、後者についてはルールを追加してはいけないのでこのように分類して考えます。
最終的なFW(iptables)の設定内容は、拒否するIPアドレスの追加ルール設定(A)と、許可するIPアドレスの既存ルール削除設定(E,G)となります。
拒否したいIPアドレスと許可したいIPアドレスが重複する場合、そのIPアドレスは許可することとします。
また、拒否したIPアドレス(iptables設定済み)と許可したいIPアドレスが重複する場合も同様に、そのiPアドレスは許可(iptablesから削除)することとします。
上記の、A,G,Eのiptablesルールを作成するシェルスクリプトを作成しました。
※図中の「許可したいIPアドレス」、「許可するIPアドレス」は、正確には「拒否したくないIPアドレス」、「拒否しないIPアドレス」と書くのが正しいです。
作成したシェルスクリプト
シェルスクリプト(bash)を書いてみました。
このシェルスクリプトによって書き換えたルールは後で元に戻すことができるので、興味があればお試しで実行してみてください。
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 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 |
#! /bin/bash ################################################################## # <概要> 作成日:2020/11/1 # /var/log/auth.logの認証失敗履歴から接続元IPアドレスを抽出し, # iptablesのINPUTチェインに接続拒否ルールを追加するスクリプト. # ・固定的に拒否するIPアドレスは,DENY_IP_LIST_FILE に記載する. # ・固定的に許可するIPアドレスは,ALLOW_IP_LIST_FILE に記載する. # ・ローカルIPアドレスは接続許可する(ALLOW_IP_REGEXで指定). # iptablesのコマンドはIPTABLES_SCRIPT_FILEに残る. # crontabに設定済み. # #<実行コマンド> # command: bash deny-ip update|remove|status|dump" # option: # update iptablesのルールを更新 # remove iptablesのルールをを削除 # status iptables追加ルールの内容をターミナルに出力 # dump 拒否対象のIPアドレスをDENY_IP_LIST_FILEに出力 ################################################################## ######## 変数定義 ############ # 引数 MODE=$1 # iptablesのチェイン名 CHAIN_NAME=DENY-IP # このスクリプトのディレクトリ CURRENT=$(cd $(dirname $0);pwd) # 作業ファイルを配置するディレクトリ TMP_DIR=${CURRENT}/deny-ip.d # ssh接続を許可するIPアドレス接頭辞(正規表現) ALLOW_IP_REGEX="^10\.|^172\.|^192\.168\." # ssh接続を拒否するIPアドレスファイル(リスト形式)のパス DENY_IP_LIST_FILE=${TMP_DIR}/deny_ip_list # ssh接続を許可するIPアドレスファイル(リスト形式)のパス ALLOW_IP_LIST_FILE=${TMP_DIR}/allow_ip_list # iptablesルール追加スクリプト IPTABLES_SCRIPT_FILE=${TMP_DIR}/iptables-sh ######## mainスクリプト ######## if [ $# -lt 1 ]; then echo "command: bash $0 update|remove|status|dump" # 引数がdumpの時 elif [ $MODE = "dump" ]; then echo "iptables dump script." echo "# iptables -nL ${CHAIN_NAME} | awk '{print \$4}'| grep -Eo '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | sort | uniq > ${DENY_IP_LIST_FILE}" iptables -nL ${CHAIN_NAME} | awk '{print $4}'| grep -Eo '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | sort | uniq > ${DENY_IP_LIST_FILE} # 引数がstatusの時 elif [ $MODE = "status" ]; then echo "iptables show script." echo "# iptables -nvL ${CHAIN_NAME}" iptables -nvL ${CHAIN_NAME} # 引数がremoveの時 elif [ $MODE = "remove" ]; then echo "iptables restore script." # INPUTチェインからルールを削除 echo "# iptables -D INPUT -j ${CHAIN_NAME}" iptables -D INPUT -j ${CHAIN_NAME} # チェインを削除 echo "# iptables -F ${CHAIN_NAME}" iptables -F ${CHAIN_NAME} echo "# iptables -X ${CHAIN_NAME}" iptables -X ${CHAIN_NAME} # 引数がupdateの時 elif [ $MODE = "update" ]; then echo "iptables set script." # 作業ファイルを配置するディレクトリを作成 mkdir -p ${TMP_DIR} touch ${DENY_IP_LIST_FILE} touch ${ALLOW_IP_LIST_FILE} touch ${IPTABLES_SCRIPT_FILE} # 接続を拒否するIPアドレスリストを作成(grep Failed|Invalid) cat /var/log/auth.log* | grep -E "Failed|Invalid" | grep -Eo '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | sort | uniq | grep -v -E $ALLOW_IP_REGEX > ${IPTABLES_SCRIPT_FILE}.buf cat ${DENY_IP_LIST_FILE} ${IPTABLES_SCRIPT_FILE}.buf | sort | uniq > ${DENY_IP_LIST_FILE}.tmp # iptables(チェイン)の既設定IPアドレスを抽出 iptables -nL ${CHAIN_NAME} | awk '{print $4}' | grep -Eo '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' > ${DENY_IP_LIST_FILE}.def # 接続を拒否するIPアドレスを設定するスクリプトを作成 comm --nocheck-order -23 ${DENY_IP_LIST_FILE}.tmp ${DENY_IP_LIST_FILE}.def > ${IPTABLES_SCRIPT_FILE}.buf comm --nocheck-order -23 ${IPTABLES_SCRIPT_FILE}.buf ${ALLOW_IP_LIST_FILE} | sed "s/^\(.*\)/iptables -A ${CHAIN_NAME} -s \1 -j DROP/g" | sort | uniq > ${IPTABLES_SCRIPT_FILE} # 接続を許可するIPアドレスの設定を消すスクリプトを作成 comm --nocheck-order -13 ${DENY_IP_LIST_FILE}.tmp ${DENY_IP_LIST_FILE}.def > ${IPTABLES_SCRIPT_FILE}.buf comm --nocheck-order -12 ${IPTABLES_SCRIPT_FILE}.buf ${ALLOW_IP_LIST_FILE} | sed "s/^\(.*\)/iptables -D ${CHAIN_NAME} -s \1 -j DROP/g" | sort | uniq >> ${IPTABLES_SCRIPT_FILE} comm --nocheck-order -12 ${DENY_IP_LIST_FILE}.tmp ${DENY_IP_LIST_FILE}.def > ${IPTABLES_SCRIPT_FILE}.buf comm --nocheck-order -12 ${IPTABLES_SCRIPT_FILE}.buf ${ALLOW_IP_LIST_FILE} | sed "s/^\(.*\)/iptables -D ${CHAIN_NAME} -s \1 -j DROP/g" | sort | uniq >> ${IPTABLES_SCRIPT_FILE} rm ${IPTABLES_SCRIPT_FILE}.buf ${DENY_IP_LIST_FILE}.def ${DENY_IP_LIST_FILE}.tmp # チェインを作成 echo "# iptables -N ${CHAIN_NAME}" iptables -N ${CHAIN_NAME} # ルールを作成 echo "# bash ${IPTABLES_SCRIPT_FILE}" cat ${IPTABLES_SCRIPT_FILE} | sed "s/\(.*\)/\+\1/g" bash ${IPTABLES_SCRIPT_FILE} # INPUTチェインに追加 echo "# iptables -C INPUT -j ${CHAIN_NAME} || iptables -A INPUT -j ${CHAIN_NAME}" iptables -C INPUT -j ${CHAIN_NAME} || iptables -A INPUT -j ${CHAIN_NAME} else bash $0 fi |
コメントと空行を除けば、53行のスクリプトです。
Debian系のLinux(Ubuntu、Raspbian)を想定していますので、RedHat系のLinux(CentOS)で実行する場合はログの場所(91行目)のパスを/var/log/secureに修正してください。
スクリプトの処理について、以下の記事で解説します。
使い方
事前準備
上記のシェルスクリプトを適当な場所(/path/to/script/)において、実行権限を付与してください(必須)。
事前に拒否したいIPアドレスリストと許可したいIPアドレスリストを作成しておきます(任意)。
(IPアドレスと許可したいIPアドレスが無ければ、シェルスクリプト単体で動作します。)
ここでは、シェルスクリプトと同ディレクトリ配下にdeny-ip.dディレクトリを作成し、ファイルを配置します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
# ディレクトリを作成 mkdir -p /path/to/script/deny-ip.d # ディレクトリに移動 cd /path/to/script/deny-ip.d # 拒否したいIPアドレスリストを作成(任意) emacs deny_ip_list # リストを作成 cat deny_ip_list 101.132.227.124 101.200.177.198 101.200.55.9 : # 許可したいIPアドレスリストを作成(任意) emacs allow_ip_list |
1 |
emacs deny_ip_list |
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 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 |
101.132.227.124 101.200.177.198 101.200.55.9 101.201.237.252 101.87.101.87 103.108.187.4 103.130.209.251 103.210.73.67 103.21.148.54 103.239.252.178 104.236.246.16 104.236.81.204 104.248.144.147 104.248.181.156 106.13.20.31 106.14.135.136 106.14.163.216 106.15.250.167 106.252.253.10 106.255.236.106 106.3.129.209 106.3.40.140 106.45.0.217 106.45.0.9 106.75.239.79 107.170.172.23 109.110.52.77 109.111.164.63 110.45.145.178 110.55.109.59 110.83.32.64 111.121.71.113 111.12.52.238 111.230.105.142 112.132.89.81 112.222.255.100 112.74.203.41 113.105.94.66 113.116.246.129 113.128.104.208 113.128.104.254 113.160.98.121 113.200.78.222 113.208.113.35 113.52.135.201 113.57.95.215 114.116.103.75 114.118.97.195 114.7.206.227 115.143.217.157 115.233.227.46 115.236.53.226 115.29.143.215 115.29.7.45 115.68.184.88 116.112.0.60 116.197.132.33 116.31.102.81 116.31.102.82 117.186.220.86 117.50.36.250 117.78.42.106 118.136.85.166 118.140.104.238 118.25.62.164 118.27.18.232 118.45.190.167 1.190.192.178 119.23.33.89 119.28.1.253 119.3.201.34 119.39.46.202 119.73.125.51 120.133.17.168 120.133.22.121 120.133.226.22 120.202.57.157 120.220.15.5 120.230.82.40 120.78.11.170 120.78.160.213 120.79.0.86 121.128.236.62 121.135.237.32 121.140.142.231 121.159.95.49 121.196.23.247 121.196.57.160 121.43.189.248 121.48.164.130 122.116.40.230 122.15.82.86 122.189.56.78 122.224.94.188 122.96.92.246 123.142.108.122 123.157.134.238 123.206.21.48 1.235.143.134 123.57.213.165 123.59.72.15 123.59.94.122 124.127.102.1 124.160.236.161 124.193.149.90 124.194.49.19 124.227.31.8 124.43.161.249 124.43.177.160 124.65.186.186 124.95.128.163 125.131.73.90 125.212.202.179 125.227.130.2 1.254.154.42 125.75.40.119 125.88.254.178 128.199.127.217 128.199.80.18 128.199.81.8 129.28.147.159 131.100.11.232 138.118.143.206 13.81.50.85 138.197.105.79 138.68.20.158 139.129.90.203 139.129.97.42 139.196.124.205 139.198.123.233 139.199.200.182 139.59.131.37 139.59.14.210 139.59.25.238 139.59.59.187 139.59.61.186 139.59.79.56 139.59.99.142 139.9.165.138 139.99.98.192 14.136.204.41 14.225.3.47 142.93.112.49 142.93.127.16 142.93.178.254 142.93.215.82 142.93.42.177 142.93.82.229 14.36.197.119 147.135.231.210 147.139.34.137 149.202.102.36 149.202.208.104 149.202.3.113 150.255.9.205 152.231.89.122 154.198.2.4 157.230.163.6 157.230.39.120 157.230.54.248 157.245.149.151 157.245.246.132 157.245.60.215 159.192.148.4 159.203.161.124 159.65.136.194 159.65.144.233 159.65.159.1 159.65.245.203 159.65.54.221 159.65.65.54 159.89.165.127 163.179.126.62 164.132.101.10 165.22.110.2 165.22.127.136 165.22.242.174 165.22.250.226 165.22.60.7 165.227.5.140 165.227.53.241 167.71.115.245 167.71.217.92 167.71.239.181 167.99.167.105 167.99.170.160 167.99.75.174 168.195.113.11 168.228.220.252 169.55.91.115 170.151.0.4 171.34.177.61 175.121.153.50 175.184.164.160 175.184.165.200 176.166.1.64 177.152.144.58 178.128.10.117 178.128.148.98 178.128.156.174 178.128.173.238 178.128.39.0 178.62.220.70 178.62.99.41 180.250.18.20 180.250.80.88 180.76.56.128 181.10.18.188 181.143.228.170 181.191.98.227 181.27.127.132 181.65.157.134 183.134.198.30 183.195.37.143 183.195.40.85 185.117.57.86 185.228.138.227 185.50.37.152 185.51.63.242 187.115.80.122 188.10.184.201 188.165.245.53 188.166.253.195 188.166.34.234 188.166.72.240 188.226.250.187 188.242.70.154 188.44.52.11 188.6.165.216 188.93.245.172 189.126.202.121 189.254.33.157 190.103.200.2 190.112.226.197 190.121.130.37 190.145.38.91 190.85.18.130 193.112.187.205 193.112.248.85 193.151.128.73 193.27.228.17 195.158.29.222 195.161.72.70 195.239.237.94 195.91.186.78 198.100.45.126 198.199.66.10 199.19.225.67 201.140.123.130 201.182.66.18 201.216.217.25 201.6.247.90 202.107.251.28 202.114.100.250 202.88.241.107 203.143.119.196 203.251.139.218 206.189.132.204 206.189.136.160 206.189.172.90 206.189.188.223 206.189.28.79 207.154.198.74 209.124.69.227 210.117.210.226 210.4.118.157 211.210.154.32 211.99.229.3 212.102.39.1 212.64.40.200 213.187.77.253 216.150.147.66 216.8.167.175 218.201.114.34 218.28.30.125 218.29.67.194 218.66.59.169 218.75.61.254 218.92.40.162 219.147.90.16 219.153.97.127 219.93.106.38 220.76.205.178 221.11.104.118 221.207.122.234 221.218.247.38 221.234.237.140 221.238.32.130 222.106.160.180 222.122.179.208 222.77.98.78 222.79.49.199 222.87.147.62 223.171.50.236 223.197.175.171 223.70.246.131 24.64.157.148 27.128.201.88 27.17.28.132 27.224.137.14 3.1.255.152 3.249.33.21 36.133.62.154 36.32.3.60 36.37.201.133 37.139.9.23 37.187.96.130 37.252.70.69 37.59.43.216 39.105.200.55 39.106.118.147 39.106.50.251 39.129.55.85 39.96.19.171 39.96.82.174 39.99.203.251 40.117.253.222 41.141.248.196 42.112.20.32 45.238.33.147 45.238.33.150 45.33.88.237 46.101.24.197 46.101.93.149 46.105.163.8 46.146.136.8 47.100.88.65 47.101.187.9 47.104.176.209 47.105.164.105 47.105.220.149 47.106.210.207 47.107.140.220 47.107.141.34 47.107.62.218 47.110.225.78 47.114.96.237 47.244.175.167 47.244.213.73 47.244.45.12 47.88.17.25 47.92.152.148 47.92.98.123 47.94.175.175 47.94.215.35 47.96.144.102 47.96.4.84 49.4.69.192 49.69.78.132 50.250.224.225 5.146.80.53 51.77.246.155 51.79.147.177 5.188.210.227 5.196.110.170 52.130.75.15 5.39.74.233 54.38.190.187 54.39.149.152 58.132.203.179 58.132.214.152 58.16.48.190 58.214.246.34 58.69.176.224 5.88.155.130 60.12.26.9 60.13.6.208 60.165.50.150 60.170.152.153 60.250.67.47 60.29.123.202 61.245.153.139 61.250.206.110 61.81.0.121 61.82.100.143 62.197.86.15 62.234.188.157 66.70.157.67 68.183.190.43 68.183.218.50 70.50.213.95 76.14.151.130 76.161.57.154 77.56.63.223 77.94.137.91 79.137.84.210 79.8.152.248 80.241.44.238 80.28.151.210 80.66.77.110 80.92.232.39 81.169.241.30 81.183.220.42 82.145.31.212 82.207.87.24 82.223.69.17 85.172.174.46 85.214.224.252 85.243.161.243 87.106.30.24 88.204.164.234 89.179.125.71 89.189.154.66 89.252.228.135 91.192.197.172 91.205.217.22 91.224.205.62 91.227.12.20 91.234.99.173 91.238.244.37 92.246.16.39 92.45.61.93 92.63.199.27 93.100.138.129 93.180.157.61 94.102.50.155 95.213.214.13 95.217.18.33 95.68.243.7 95.79.41.188 96.239.37.123 |
ローカルIPアドレスは拒否されないようにしていますので、ローカルIPアドレスはallow_ip_listに記載は不要です。
事前に必要なファイルの構成は以下となります。
1 2 3 4 5 |
/path/to/script/ |--deny-ip # シェルスクリプト |--deny-ip.d/ # 設定ファイル置き場(任意) |--deny_ip_list # 拒否したいIPアドレスリスト(任意) |--allow_ip_list # 許可したいIPアドレスリスト(任意) |
FWの更新(update)
firewall(iptables)を更新するときは、以下のコマンドを実行します。
1 |
sudo bash /usr/tool/deny-ip update |
初回起動時は、以下のような出力となります。
1 2 3 4 5 6 7 8 |
iptables set script. # iptables -N DENY-IP # bash /usr/tool/deny-ip.d/iptables-sh >iptables -A DENY-IP -s 101.132.227.124 -j DROP >iptables -A DENY-IP -s 101.200.177.198 -j DROP : : # iptables -C INPUT -j DENY-IP || iptables -A INPUT -j DENY-IP |
deny-ip.dが無い場合は、シェルスクリプトと同ディレクトリ配下に、deny-ip.dディレクトリとファイルが作成されます。
1 2 3 4 5 6 |
/path/to/script/ |--deny-ip # シェルスクリプト |--deny-ip.d/ # 設定ファイル置き場(任意) |--deny_ip_list # 拒否したいIPアドレスリスト |--allow_ip_list # 許可したいIPアドレスリスト |--iptables-sh # iptablesに追加したルール ★作成される |
iptablesに追加したルールを見たい場合は、iptables-shを参照してください。
FWを元に戻す(remove)
このシェルスクリプトによって追加されたルールを消します。
1 |
sudo bash /usr/tool/deny-ip remove |
iptablesが元通りになります。
1 2 |
# iptables -F DENY-IP # iptables -X DENY-IP |
iptablesルール確認(status)
このシェルスクリプトによって追加されたルールを参照します。
1 |
sudo bash deny-ip status |
iptables(DENY-IP)のルールが表示されます。
1 2 3 4 5 6 7 8 |
iptables show script. # iptables -nvL DENY-IP Chain DENY-IP (1 references) pkts bytes target prot opt in out source destination 0 0 DROP all -- * * 101.132.227.124 0.0.0.0/0 0 0 DROP all -- * * 101.200.177.198 0.0.0.0/0 0 0 DROP all -- * * 101.200.55.9 0.0.0.0/0 : |
拒否したIPアドレスリストを書き出す(dump)
iptablesにルール追加されたIPアドレスリストをdeny_ip_listに書き出し、静的な拒否IPアドレスリストを作成します。
dumpすることによって、ログ(/var/log/auth.log)に記録されていなくても、アクセス拒否ルールを追加することができます。
1 |
sudo bash deny-ip dump |
iptables(DENY-IP)のルールからIPアドレスを抽出してdeny_ip_listに出力します。
1 2 |
iptables dump script. # iptables -nL DENY-IP | awk '{print $4}'| grep -Eo '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | sort | uniq > /path/to/script/deny-ip.d/deny_ip_list |
定期実行
一通り動作確認をしてみて、問題なかったのでこれをcrontabに設定して自動的に起動させてみます。
1 |
emacs /etc/crontab |
以下の内容を追記します。
1 2 3 4 5 |
: # 以下をcrontabに追記する @reboot root /path/to/script/deny-ip update 55 4 * * * root /path/to/script/deny-ip update 00 0 * * 0 root /path/to/script/deny-ip status && /path/to/script/deny-ip dump |
追記の意味は、
- システムブート時にdeny-ip updateを実行する
- 毎日朝4:55にdeny-ip updateを実行する
- 毎週月曜日0:00にdeny-ip stausを実行して、deny-ip dumpを実行する
毎週deny-ip stausを実行するのは、実行結果をログに残すためです。
これで、毎日自動的にFWを更新する仕組みができました!
1週間運用してみて
1週間運用してみて、効果があったのか確認してます。
1 |
cat /var/log/auth.log | grep -E "Failed|Invalid" | grep -Eo '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | sort | uniq |
結果は0件、良好です。
ただ、たまたまアクセスが無かっただけかもしれないのでフィルタしたパケット数を確認してみます。
1 |
sudo iptables -nvL INPUT |
1 2 3 4 |
Chain INPUT (policy ACCEPT 9355K packets, 908M bytes) pkts bytes target prot opt in out source destination 48M 3689M all -- * * 0.0.0.0/0 0.0.0.0/0 42M 3323M DENY-IP all -- * * 0.0.0.0/0 0.0.0.0/0 |
DENY-IPが42M(3323MB)のパケットをブロックしているようです。
ちゃんと機能しています!
まとめ
sshログイン失敗履歴から攻撃者のIPアドレスを特定し、FW(iptables)に自動でアクセス拒否ルールを設定するシェルスクリプトを作成してみました。
これをcrontabで自動起動させてやれば、攻撃者から身を守れます。
そして、私の自宅サーバでも絶賛稼働中です。
そのため、間違っても私のサーバ(komone-life.com)にsshでログインしようとしないでください。
sshログインに失敗すると、攻撃者とみなして翌日にはそのIPアドレスからのアクセスが拒否されてこのブログが読めなくなってしまいます。
ブログにアクセスできなくなった方は、フィルタを解除しますのでどうにかして私に連絡してください。
ふつうの人が私の自宅サーバにsshでログインしてくることは無いので、このスキーム(sshログイン失敗したIPアドレスをブロックする)に問題はないはず。
そして、このプログラムを作りながら思ったことがあります。
それは、、
結局22番ポート空けるならFail2Banでよくね?
うん、、だけど、良い頭の体操になったからいいんです。
参考になれば幸いです。
コメント