メールログからFWにて怪しいIPをブロック

# メールログから怪しい国外IPアドレスを取得しブロックする方法

このスクリプトは、メールログから取得したIPアドレスをファイアウォールでブロックします。
日本国内のIPアドレス範囲に該当するIPは除外し、それ以外のIPをブロックします。

## 1. Pythonスクリプト (`/root/fw_script/deny_ip.py`)

```python
"""
deny_ip.py
このスクリプトは、メールログから取得したIPアドレスをファイアウォールでブロックします。
日本国内のIPアドレス範囲に該当するIPは除外し、それ以外のIPをブロックします。
"""
import ipaddress
import subprocess
import datetime

log_entries = []

def log(message):
    print(message)  # コンソールに出力
    log_entries.append(message)  # ログエントリに追加

# 日本のIPアドレス範囲を読み込み
with open('/root/fw_script/japan_ip_ranges.txt', 'r') as f:
    japan_ip_ranges = [line.strip() for line in f if line.strip()]  # 空の行をフィルタリング

log("Loaded Japan IP ranges.")

# 日本のIP範囲をIPネットワークオブジェクトに変換
try:
    japan_ip_networks = [ipaddress.ip_network(ip_range, strict=False) for ip_range in japan_ip_ranges]
except ValueError as e:
    log(f"Error processing IP ranges: {e}")
    japan_ip_networks = []

# 現在ブロックされているIPアドレスを取得
result = subprocess.run(
    ['firewall-cmd', '--zone=drop', '--list-all'],
    stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True
)
current_blocked_ips_output = result.stdout.splitlines()
current_blocked_ips = []
for line in current_blocked_ips_output:
    if line.startswith('  sources:'):
        current_blocked_ips = [ip.split('/')[0].strip() for ip in line.split()[1:]]
        break

log(f"Current blocked IPs: {current_blocked_ips}")

# メールログから不正なIPアドレスを取得
result = subprocess.run(
    "cat /var/log/maillog | grep 'SASL' | grep 'failed' | awk '{print $7}' | cut -d'[' -f2 | cut -d']' -f1 | sort | uniq -c | awk '$1 >= 5 {print $2}'",
    shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True
)
blocked_ips = result.stdout.splitlines()

log(f"Blocked IPs: {blocked_ips}")

# 日本のIP範囲に含まれないIPをフィルタリング
remaining_ips = []
for ip in blocked_ips:
    ip_obj = ipaddress.ip_address(ip)
    if any(ip_obj in network for network in japan_ip_networks):
        log(f"Skipping IP {ip}: belongs to Japan")
    elif ip in current_blocked_ips:
        log(f"Skipping IP {ip}: already blocked")
    else:
        remaining_ips.append(ip)

log(f"Remaining IPs: {remaining_ips}")

# フィルタリングされたIPでブロック実行
for ip in remaining_ips:
    result = subprocess.run(['firewall-cmd', '--zone=drop', '--permanent', '--add-source', f"{ip}/32"],
                            stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True)
    log_entry = f"Success: {ip} added" if "success" in result.stdout else f"Failed: {ip} - {result.stderr}"
    log(log_entry)

# ファイアウォールをリロード
subprocess.run(['firewall-cmd', '--reload'])

log("Firewall reloaded.")

# 残ったIPアドレスをファイルに保存
with open('/root/fw_script/remaining_ips.txt', 'w') as f:
    for ip in remaining_ips:
        f.write(f"{ip}\n")

log("Remaining IPs saved to file.")

# ログファイルに書き込み
log_file = '/var/log/deny_ip.log'
with open(log_file, 'a') as log_file:
    log_file.write(f"Execution at {datetime.datetime.now()}:\n")
    for entry in log_entries:
        log_file.write(f"{entry}\n")
    log_file.write("\n")

log("Log file updated.")
```

## 2. 日本のIPアドレス範囲 (`/root/fw_script/japan_ip_ranges.txt`)

```
1.0.16.0/20
1.1.0.0/24
1.72.0.0/14
14.128.0.0/10
27.96.0.0/12
27.112.0.0/12
36.0.0.0/9
39.96.0.0/11
42.96.0.0/12
43.240.0.0/12
49.128.0.0/10
58.0.0.0/8
59.128.0.0/10
60.32.0.0/11
61.192.0.0/10
101.0.0.0/8
103.0.0.0/8
106.128.0.0/9
110.0.0.0/8
111.64.0.0/11
113.32.0.0/11
114.144.0.0/12
115.0.0.0/8
116.64.0.0/11
118.0.0.0/8
119.0.0.0/8
120.0.0.0/8
121.0.0.0/8
122.0.0.0/8
123.0.0.0/8
124.0.0.0/8
125.0.0.0/8
126.0.0.0/8
128.0.0.0/8
133.0.0.0/8
140.0.0.0/8
143.0.0.0/8
150.0.0.0/8
153.0.0.0/8
160.0.0.0/8
175.0.0.0/8
180.0.0.0/8
183.0.0.0/8
202.0.0.0/7
210.0.0.0/7
211.0.0.0/8
218.0.0.0/8
219.0.0.0/8
220.0.0.0/7
221.0.0.0/8
222.0.0.0/7
223.0.0.0/8
```

## 3. cronジョブの設定 (`/etc/cron.d/deny_ip`)

```
0 * * * * root python3 /root/fw_script/deny_ip.py
```

## 4. ログファイルのパス

`/var/log/deny_ip.log`

このセットアップにより、毎時間スクリプトが実行され、ログファイルに結果が記録されます。
必要に応じてスクリプトや設定ファイルを更新してください。