-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathban4ipd_unban.php
158 lines (153 loc) · 9.65 KB
/
ban4ipd_unban.php
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
<?php
// ------------------------------------------------------------
//
// BAN for iptables/ip6tables
//
// T.Kabu/MyDNS.JP http://www.MyDNS.JP/
// Future Versatile Group http://www.fvg-on.net/
//
// ------------------------------------------------------------
?>
<?php
// ----------------------------------------------------------------------
// Sub Routine
// ----------------------------------------------------------------------
function ban4ip_unban($TARGET_CONF)
{
// 対象IPアドレスを/で分割して配列に設定
$TARGET_ADDRESS = explode("/", $TARGET_CONF['target_address']);
// 対象IPアドレスがIPv6なら(IPv6だったら文字列そのものが返ってくる)
if (filter_var($TARGET_ADDRESS[0], FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) !== FALSE)
{
$IPTABLES = $TARGET_CONF['ip6tables'];
}
// 対象IPアドレスがIPv4なら(IPv4だったら文字列そのものが返ってくる)
else if (filter_var($TARGET_ADDRESS[0], FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) !== FALSE)
{
$IPTABLES = $TARGET_CONF['iptables'];
}
// 対象IPアドレスがIPv4でもIPv6でもないなら
else
{
// 対象IPアドレスはBANの対象だけど、アドレスがおかしい旨のメッセージを設定
$TARGET_CONF['log_msg'] = date("Y-m-d H:i:s", local_time())." ban4ip[".getmypid()."]: NOTICE [".$TARGET_CONF['target_service']."] Ban ".$TARGET_CONF['target_address']." (over ".$TARGET_CONF['maxretry']." counts) ";
$TARGET_CONF['log_msg'] .= 'Illegal address!?'."\n";
// 2021.09.07 T.Kabu どうもSQLite3が、DELETEの時にだけ何かのタイミングでデータベースがロックしているという判断でエラーとなる。実際にはDELETE出来ているので再試行も発生しないので、try/catchでスルーするようにした
try {
// BANデータベースから対象IPアドレス(とポートとルールが合致するもの)を削除
$TARGET_CONF['ban_db']->exec("DELETE FROM ban_tbl WHERE address = '".$TARGET_CONF['target_address']."' AND protcol = '".$TARGET_CONF['target_protcol']."' AND port = '".$TARGET_CONF['target_port']."' AND rule = '".$TARGET_CONF['target_rule']."'");
}
catch (PDOException $PDO_E) {
// エラーの旨メッセージを設定
$TARGET_CONF['log_msg'] .= date("Y-m-d H:i:s", local_time())." ban4ip[".getmypid()."]: WARN PDOException:".$PDO_E->getMessage()." on ".__FILE__.":".__LINE__."\n";
}
// 戻る
return $TARGET_CONF;
}
// 対象サービスについてBANのルール設定があるなら
if (isset($TARGET_CONF['target_rule']))
{
// 対象サービスについてBANのプロトコルとポートがともに'all'なら
if ($TARGET_CONF['target_protcol'] == 'all' && $TARGET_CONF['target_port'] == 'all')
{
// -----------------------------
// BANルールを設定する
// -----------------------------
// UNBANする前のコマンド(exec_befor_unban)が設定されていたら実行(UNBANする場合、すでにUNBAN済みでも実行)
$TARGET_CONF = ban4ip_exec($TARGET_CONF, 'exec_befor_unban');
// ban4ipチェインの設定を取得する
$PROC_P = popen($IPTABLES." -L ban4ip -n", "r");
$TARGET_PATTERN = '/^'.$TARGET_CONF['target_rule'].' .* '.preg_replace('/\//', '\/', $TARGET_CONF['target_address']).'.*$/';
// ban4ipチェインに該当ルールがあるなら
if (psearch($PROC_P, $TARGET_PATTERN) == TRUE)
{
// ban4ipチェインから対象BANを削除する
system($IPTABLES.' -D ban4ip --source '.$TARGET_CONF['target_address'].' --jump '.$TARGET_CONF['target_rule']);
// 対象IPアドレスをUNBANした旨を出力
$TARGET_CONF['log_msg'] = date("Y-m-d H:i:s", local_time())." ban4ip[".getmypid()."]: NOTICE [".$TARGET_CONF['target_service']."] Unban ".$TARGET_CONF['target_address']."\n";
}
else
{
// 対象IPアドレスがUNBANされている旨を出力
$TARGET_CONF['log_msg'] = date("Y-m-d H:i:s", local_time())." ban4ip[".getmypid()."]: NOTICE [".$TARGET_CONF['target_service']."] Unbaned aleady ".$TARGET_CONF['target_address']."\n";
}
pclose($PROC_P);
// UNBANした後のコマンド(exec_afer_unban)が設定されていたら実行(UNBANする場合、すでにUNBAN済みでも実行)
$TARGET_CONF = ban4ip_exec($TARGET_CONF, 'exec_after_unban');
}
// 対象サービスについてBANのプロトコルとポートが個別に設定されているなら
else if (isset($TARGET_CONF['target_protcol']) && isset($TARGET_CONF['target_port']))
{
// -----------------------------
// BANルールを設定する
// -----------------------------
// UNBANする前のコマンド(exec_befor_unban)が設定されていたら実行(UNBANする場合、すでにUNBAN済みでも実行)
$TARGET_CONF = ban4ip_exec($TARGET_CONF, 'exec_befor_unban');
// ban4ipチェインの設定を取得する
$PROC_P = popen($IPTABLES." -L ban4ip -n", "r");
$TARGET_PATTERN = '/^'.$TARGET_CONF['target_rule'].' .* '.preg_replace('/\//', '\/', $TARGET_CONF['target_address']).'.* '.$TARGET_CONF['target_protcol'].' dpt:'.$TARGET_CONF['target_port'].'$/';
// ban4ipチェインに該当ルールがあるなら
if (psearch($PROC_P, $TARGET_PATTERN) == TRUE)
{
// ban4ipチェインから対象BANを削除する
system($IPTABLES.' -D ban4ip --source '.$TARGET_CONF['target_address'].' --proto '.$TARGET_CONF['target_protcol'].' --dport '.$TARGET_CONF['target_port'].' --jump '.$TARGET_CONF['target_rule']);
// 対象IPアドレスをUNBANした旨を出力
$TARGET_CONF['log_msg'] = date("Y-m-d H:i:s", local_time())." ban4ip[".getmypid()."]: NOTICE [".$TARGET_CONF['target_service']."] Unban ".$TARGET_CONF['target_address']."\n";
}
else
{
// 対象IPアドレスがUNBANされている旨を出力
$TARGET_CONF['log_msg'] = date("Y-m-d H:i:s", local_time())." ban4ip[".getmypid()."]: NOTICE [".$TARGET_CONF['target_service']."] Unbaned aleady ".$TARGET_CONF['target_address']."\n";
}
pclose($PROC_P);
// UNBANした後のコマンド(exec_afer_unban)が設定されていたら実行(UNBANする場合、すでにUNBAN済みでも実行)
$TARGET_CONF = ban4ip_exec($TARGET_CONF, 'exec_after_unban');
}
else
{
// 対象IPアドレスをUNBAN?した旨を出力
$TARGET_CONF['log_msg'] = date("Y-m-d H:i:s", local_time())." ban4ip[".getmypid()."]: NOTICE [".$TARGET_CONF['target_service']."] Unban? ".$TARGET_CONF['target_address']."\n";
}
}
// 2021.09.07 T.Kabu どうもSQLite3が、DELETEの時にだけ何かのタイミングでデータベースがロックしているという判断でエラーとなる。実際にはDELETE出来ているので再試行も発生しないので、try/catchでスルーするようにした
try {
// BANデータベースから対象IPアドレス(とポートとルールが合致するもの)を削除
$RESULT = $TARGET_CONF['ban_db']->exec("DELETE FROM ban_tbl WHERE address = '".$TARGET_CONF['target_address']."' AND protcol = '".$TARGET_CONF['target_protcol']."' AND port = '".$TARGET_CONF['target_port']."' AND rule = '".$TARGET_CONF['target_rule']."'");
}
catch (PDOException $PDO_E) {
// エラーの旨メッセージを設定
$TARGET_CONF['log_msg'] .= date("Y-m-d H:i:s", local_time())." ban4ip[".getmypid()."]: WARN PDOException:".$PDO_E->getMessage()." on ".__FILE__.":".__LINE__."\n";
// TRUEにしていたが、エラーだったらFALSEにしてDBのリセット判定をするように処理の流れを変更 2025.03.05 T.Kabu
$RESULT = FALSE;
}
// 削除できなかったら
if ($RESULT === FALSE)
{
// BANデータベースのデータソース名(DSN)の指定が「sqlite」なら
if (isset($TARGET_CONF['pdo_dsn_ban']) && preg_match('/^sqlite/', $TARGET_CONF['pdo_dsn_ban']))
{
// delete_err_countの宣言がなかったら
if (!isset($TARGET_CONF['delete_err_count']))
{
// 宣言をする
$TARGET_CONF['delete_err_count'] = 0;
}
$TARGET_CONF['delete_err_count'] += 1;
// もし検出回数以上になったら
if ($TARGET_CONF['delete_err_count'] >= $TARGET_CONF['maxretry'])
{
// エラーの旨メッセージを設定
$TARGET_CONF['log_msg'] .= date("Y-m-d H:i:s", local_time())." ban4ip[".getmypid()."]: WARN [".$TARGET_CONF['target_service']."] Cannot Query the DB, ".$TARGET_CONF['target_address']." ... DB File DELETE & REBOOT!(3)"."\n";
// 親プロセスに送信…はしなくていい、unbanは親プロセスだから
//ban4ip_sendmsg($TARGET_CONF);
// ログに出力する(親プロセスにログを送信する代わりに)
log_write($TARGET_CONF);
// SQLite3のデータベースファイルをリセット
ban4ip_dbreset_sqlite3();
}
}
}
// 戻る
return $TARGET_CONF;
}
?>