メールログから怪しい国外IPアドレスを取得しブロックする方法
このスクリプトは、メールログから取得したIPアドレスをファイアウォールでブロックします。
日本国内のIPアドレス範囲に該当するIPは除外し、それ以外のIPをブロックします。
1. Pythonスクリプト (/root/fw_script/deny_ip.py
)
"""
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
このセットアップにより、毎時間スクリプトが実行され、ログファイルに結果が記録されます。
必要に応じてスクリプトや設定ファイルを更新してください。