セキュリティ対策 - ファイアウォール IP Firewall - テーブル国別で


クラウディア 


1. 概要
2. ダウンロード
3. 抽出スクリプト
4. 登録スクリプト
5. 参考サイト

1. 概要

 前ページで、特定のアドレスをテーブルにいれて、まとめて、接続許可/拒否を設定するテキストとスクリプトを作成しましたが。  これを少し、発展させます。  もうね、メールサーバでリレーしようとしてくるような相手は、ほぼ国ごとに決まっているので、失礼ながらそこの国別ドメインをまるごと拒否しようと思います。

2. ダウンロード

 国別ドメインを提供してくれているサイトがあります。  「ネットワークサービス - お役立ち・面白サイト」「国別 IP アドレス」のページで紹介しておりますので、そこから。

IP2LOCATION-LITE-DB1.CIDR.zip
 というファイルをダウンロードします。  展開すると、中に。

IP2LOCATION-LITE-DB1.CIDR.CSV
 というファイルがあります。  およそ。

"0.0.0.0/8","-","-"
"1.0.0.0/24","AU","Australia"
"1.0.1.0/24","CN","China"
"1.0.2.0/23","CN","China"
"1.0.4.0/22","AU","Australia"
"1.0.8.0/21","CN","China"
"1.0.16.0/20","JP","Japan"
"1.0.32.0/19","CN","China"
"1.0.64.0/18","JP","Japan"
"1.0.128.0/17","TH","Thailand"
 てな感じで、「CIDR」形式で、444,086 行の国別ドメインが記述されています。

3. 抽出スクリプト

 「python」で、国別の「IP」アドレスリストを抽出してファイルに出力するソースを作成します。  仮に、「ipfilter.py」というソース名として。

vi ipfilter.py
 下記を記述します。

import csv
import os
import argparse
import sys

def parse_args():
  parser = argparse.ArgumentParser(
    description="指定した国コードのCIDRリストをipfw形式のシェルスクリプトとして抽出します"
  )
  # 半角2文字の必須引数として設定
  parser.add_argument(
    "country",
    type=str,
    help="対象の国コード(例: cn, ru, us)"
  )
  args = parser.parse_args()

  # 簡易的なバリデーション(2文字チェック)
  if len(args.country) != 2:
    print(f"Error: 国コードは半角2文字で指定してください ({args.country})", file=sys.stderr)
    sys.exit(1)

  return args.country.lower()

def main():
  country = parse_args()

  # スクリプトの場所を基準にパスを設定
  base_dir = os.path.dirname(os.path.abspath(__file__))
  list_file = os.path.join(base_dir, 'IP2LOCATION-LITE-DB1.CIDR.CSV')

  # 出力先ディレクトリ(update_tables.shの階層に合わせた ../../../ipfw/country/)
  output_dir = os.path.abspath(os.path.join(base_dir, '../../../ipfw/country'))
  output_file = os.path.join(output_dir, f'{country}.sh')

  # 出力先ディレクトリが存在しない場合は作成
  if not os.path.exists(output_dir):
    os.makedirs(output_dir)

  my_list = []

  # CSVの読み込み
  try:
    with open(list_file, 'r', encoding='utf-8') as file:
      reader = csv.reader(file, quotechar='"')
      for row in reader:
        # row[0]: CIDR, row[1]: Country Code
        if len(row) >= 2 and row[1].lower() == country:
          my_list.append(row[0])
  except FileNotFoundError:
    print(f"Error: 入力ファイルが見つかりません: {list_file}", file=sys.stderr)
    sys.exit(1)

  # シェルスクリプトの書き出し(改行コードはLF固定)
  with open(output_file, 'w', newline='\n') as file:
    file.write('#!/bin/sh\n')
    for cidr in my_list:
      # exists/addedの出力を抑止したい場合はここに >/dev/null 2>&1 を追記可能
      line = f'ipfw table 12 add {cidr}\n'
      file.write(line)

  print(f"Successfully generated: {output_file} ({len(my_list)} records)")

if __name__ == "__main__":
  main()
 これで。

python ipfilter.py xx
 と「xx」の箇所に国別ドメインの2文字をいれると。  ソースファイルの3階層上に、下記のファイルが作成されます。

ipfw/country/xx.sh
 これを前ページのテーブル「12」にぶっこみます。

4. 登録スクリプト

 前ページで作成した。

update_tables.sh
 の最終行の前に、下記を追加します。

# countryディレクトリ配下のすべての.shファイルを実行する
if [ -d "${DIR}/country" ]; then
    echo "Updating country tables from ${DIR}/country..."
    for f in "${DIR}/country/"*.sh; do
        # ファイルが存在することを確認(ファイルがない場合のワイルドカード展開対策)
        if [ -f "$f" ]; then
            echo "  Executing $(basename "$f")..."
            sh "$f" >/dev/null 2>&1 || true
        fi
    done
fi
 これで、「update_tables.sh」のスクリプトを実行すると、前項で作成した国別ドメインの「IP」アドレスを拒否テーブルにいれるスクリプトを最後に実行することができます。

5. 参考サイト

 本ページは、「Gemini」伍長を参考にさせていただきました。

TikTok Shop 【リピート用プログラム】
AbemaTV 無料体験