Subversion Repositories qbpwcf-lib(archive)

Rev

Rev 619 | Rev 906 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1 liveuser 1
#!/usr/bin/php
2
<?php
3
 
464 liveuser 4
/*
5
	QBPWCF, Quick Build PHP website Component base on Fedora Linux.
619 liveuser 6
    Copyright (C) 2015~2024 Min-Jhin,Chen
464 liveuser 7
 
8
    This file is part of QBPWCF.
9
 
10
    QBPWCF is free software: you can redistribute it and/or modify
11
    it under the terms of the GNU General Public License as published by
12
    the Free Software Foundation, either version 3 of the License, or
13
    (at your option) any later version.
14
 
15
    QBPWCF is distributed in the hope that it will be useful,
16
    but WITHOUT ANY WARRANTY; without even the implied warranty of
17
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18
    GNU General Public License for more details.
19
 
20
    You should have received a copy of the GNU General Public License
21
    along with QBPWCF.  If not, see <http://www.gnu.org/licenses/>.
22
 
23
*/
24
 
1 liveuser 25
#使用命名空間qbpwcf
26
namespace qbpwcf;
27
 
466 liveuser 28
#以該檔案的實際位置的 lib path 為 include path 首位
29
exec("cd ".pathinfo(__FILE__)["dirname"]."/../../;pwd;",$output,$status);
30
set_include_path($output[0].PATH_SEPARATOR.get_include_path());
31
 
464 liveuser 32
#匯入外部套件
466 liveuser 33
include("allInOne.php");
1 liveuser 34
 
35
#設定記憶體可以用1024MB
36
ini_set("memory_limit","1024M");
37
 
38
#取得可能有問題的ip
39
#涵式說明:
40
#呼叫shell執行系統命令,並取得回傳的內容.
41
#回傳的結果:
42
#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
43
#$result["error"],錯誤訊息陣列.
44
#$result["function"],當前執行的函數名稱.
45
#$result["argu"],使用的參數.
46
#$result["cmd"],執行的指令內容.
47
#$result["fullCmd"],如果參數 $conf["inBackGround"] 為 "true" 則會回傳該值.
48
#$result["output"],爲執行完二元碼後的輸出陣列,若 $conf["inBackGround"] 為 "true",則為當下的輸出.
49
#$result["tmpFileOutput"],儲存輸出的暫存檔案名稱,若 $conf["inBackGround"] 為 "true" 則會回傳該值.
50
#$result["running"],是否還在執行.
51
#$result["pid"],pid.
52
#$result["statusCode"],執行結束後的代碼.
53
#必填的參數
54
#$conf["command"],字串,要執行的指令與.
55
$conf["command"]="journalctl";
56
#$conf["fileArgu"],字串,變數__FILE__的內容.
57
$conf["fileArgu"]=__FILE__;		
58
#可省略參數:
59
#$conf["argu"],陣列字串,指令搭配的參數,預設為空陣列.
60
$conf["argu"]=array("-a","|","grep","ssh","|","grep","failed");
61
#$conf["arguIsAddr"],陣列字串,指令搭配的哪些參數為路徑,為路徑的參數會進行轉換以便符合呼叫當前函數的位置,預設不指定,若有3個參數,其中第3個參數為路徑,則表示為array("false","false","true").
62
#$conf["arguIsAddr"]=array();	
63
#$conf["pre"],陣列,要在本指令前執行的每個指令與參數.
64
#$conf["pre"][$i]["cmd"],字串,要在本指令前執行的第$i+1個指令.
65
#$conf["pre"][$i]["param"],陣列字串,要在本指令前執行的第$i+1個指令的參數.
66
#$conf["enablePrintDescription"],字串,是否要印出$conf["printDescription"]的內容,"true"代表要,"false"代表不要,預設為"false".
67
#$conf["enablePrintDescription"]="true";
68
#$conf["printDescription"],字串,執行該外部程式前要印出來的的文字,預設為$conf["command"]的內容加上使用的$conf["argu"]參數.
69
#$conf["printDescription"]="";
70
#$conf["escapeshellarg"],字串,是否要啟用過濾參數,用了比較安全,但可能會出錯,"true"為啟用,"false"為不啟用,預設為"false".
453 liveuser 71
$conf["escapeshellarg"]="true";
1 liveuser 72
#$conf["username"],字串,要用什麼使用者來執行,預設為執行php的使用者,該參數不適用於apache環境.
73
#$conf["username"]="";
74
#$conf["password"],字串,root的使用者密碼,預設不使用密碼,該參數不適用於apache環境.
75
#$conf["password"]="";
76
#$conf["useScript"],字串,是否要啟用Linux的script指令來記錄輸出,"true"代表要,Fedora的selinux會擋住該操作;"false"代表不要,預設為"false".
77
#$conf["useScript"]="";
78
#$conf["logFilePath"],字串,當 $conf["useScript"] 為 "true" 時,輸出的內容要暫存到哪裡,預設為 "/tmp/.qbpwcf_tmp/external/callShell/".
79
#$conf["logFilePath"]=".qbpwcf_tmp/external/callShell/";
80
#$conf["inBackGround"],字串,是否要在背景執行,且不會等待程式執行結束再執行下一個指令,"true"代表是,"false"代表不要,預設為"false",如果$conf["command"]有用「;」區隔的多個指令將會出錯.
81
#$conf["inBackGround"]="";
82
#$conf["getErr"],字串,"true"代表將錯誤輸出變成標準輸出,反之"false"為不變動.
83
#$conf["getErr"]="false";
84
#備註:
85
#不是所有指令都能用apache的身份執行,目前已知java,javac指令無法執行,使用root身份可能會被selinux阻擋.
86
#參考資料:
87
#exec=>http://php.net/manual/en/function.exec.php
88
#escapeshellcmd=>http://php.net/manual/en/function.escapeshellcmd.php
89
#escapeshellarg=>http://php.net/manual/en/function.escapeshellarg.php
90
$callShell=external::callShell($conf);
91
unset($conf);
92
 
93
#如果執行失敗
94
if($callShell["status"]==="false"){
95
 
96
	#印出結果
97
	var_dump($callShell);
98
 
99
	#結束執行
100
	exit;
101
 
102
	}#if end
103
 
104
#取得輸出的lines
105
$lines=$callShell["output"];
106
 
107
#分割用的關鍵字
108
$keyWord1="addr=";
109
 
110
#初始化儲存有多少ip有問題
111
$ipsInfo=array();
112
 
113
#針對每個line
114
foreach($lines as $line){
115
 
116
	#移除多餘的內容
117
	#函式說明:
118
	#將字串特定關鍵字與其前面的內容剔除
119
	#回傳結果:
120
	#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
121
	#$result["error"],錯誤訊息陣列.
122
	#$result["warning"],警告訊息鎮列.
123
	#$result["founded"],有無找到定字串"true"代表有,"false"代表沒有.
124
	#$result["function"],當前執行的函數名稱.
125
	#$result["oriStr"],要處理的原始字串內容.
126
	#$result["content"],處理好的的字串內容.	
127
	#必填的參數:
128
	#$conf["stringIn"],字串,要處理的字串.
129
	$conf["stringIn"]=$line;
130
	#$conf["keyWord"],字串,特定字串.
131
	$conf["keyWord"]=$keyWord1;
132
	$delStrBeforeKeyWord=stringProcess::delStrBeforeKeyWord($conf);
133
	unset($conf);
134
 
135
	#如果執行失敗
136
	if($delStrBeforeKeyWord["status"]==="false"){
137
 
138
		#印出結果
139
		var_dump($delStrBeforeKeyWord);
140
 
141
		#結束執行
142
		exit;
143
 
144
		}#if end
145
 
146
	#如果執行失敗
147
	if($delStrBeforeKeyWord["founded"]==="false"){
148
 
149
		#印出結果
150
		var_dump($delStrBeforeKeyWord);
151
 
152
		#跳過該行,繼續執行
153
		continue;
154
 
155
		}#if end
156
 
157
	#取得處理一半的字串
158
	$line=$delStrBeforeKeyWord["content"];
159
 
160
	#用空格分割內容
161
	#涵式說明:
162
	#將固定格式的字串分開,並回傳分開的結果。
163
	#回傳結果:
164
	#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
165
	#$result["error"],錯誤訊息陣列
166
	#$result["function"],當前執行的函數名稱.
167
	#$result["argu"],使用的參數.
168
	#$result["oriStr"],要分割的原始字串內容
169
	#$result["dataArray"],爲分割好字串的陣列內容,$result["dataArray"][$i]爲第($i+1)段的內容。
170
	#$result["dataCounts"],爲總共分成幾段
171
	#$result["found"],是否有在$conf["stringIn"]找到$conf["spiltSymbol"],"true"代表有找到,"false"代表沒有找到.
172
	#必填的參數:
173
	#$conf["stringIn"],字串,要處理的字串.
174
	$conf["stringIn"]=$line;
175
	#$conf["spiltSymbol"],字串,爲以哪個符號作爲分割.
176
	$conf["spiltSymbol"]=" ";
177
	#可省略參數:
178
	#$conf["allowEmptyStr"],是否允許分割出來空字串,預設為"false"不允許;"true"代表允許.
179
	$conf["allowEmptyStr"]="false";
180
	$spiltString=stringProcess::spiltString($conf);
181
	unset($conf);
182
 
183
	#如果執行失敗
184
	if($spiltString["status"]==="false"){
185
 
186
		#印出結果
187
		var_dump($delStrBeforeKeyWord);
188
 
189
		#結束執行
190
		exit;
191
 
192
		}#if end
193
 
194
	#如果執行失敗
195
	if($spiltString["found"]==="false"){
196
 
197
		#印出結果
198
		var_dump($delStrBeforeKeyWord);
199
 
200
		#跳過該行,繼續執行
201
		continue;
202
 
203
		}#if end
204
 
205
	#第一段為有問題的ip
206
	$ip=$spiltString["dataArray"][0];
207
 
208
	#如果是第一次發現的ip
209
	if(!isset($ipsInfo[$ip])){
210
 
211
		#計數該ip出現一次
212
		$ipsInfo[$ip]=1;
213
 
214
		}#if end
215
 
216
	#反之有出現過
217
	else{
218
 
219
		#計數該ip出現一次
220
		$ipsInfo[$ip]++;
221
 
222
		}#else end
223
 
224
	}#foreach end
225
 
226
#當還有ip未處理
227
while(count($ipsInfo)>0){
228
 
229
	#max count ip
230
	$maxCountIp=array();
231
 
232
	#排序有問題的ip,次數最多的優先.
233
	foreach($ipsInfo as $ip => $count){
234
 
235
		#如果沒有既有的最多次數ip
236
		if($maxCountIp===array()){
237
 
238
			#將該ip視為最多次數
239
			$maxCountIp["ip"]=$ip;
240
			$maxCountIp["count"]=$count;
241
 
242
			}#if end
243
 
244
		#反之
245
		else{
246
			#如果當前ip的次數更多
247
			if($maxCountIp["count"]<$count){
248
 
249
				#將該ip視為最多次數
250
				$maxCountIp["ip"]=$ip;
251
				$maxCountIp["count"]=$count;
252
 
253
				}#if end
254
 
255
			}#else end
256
 
257
		}#foreach end
258
 
259
	#儲存目前次數最多的ip
260
	$ip=$maxCountIp["ip"];
261
 
89 liveuser 262
	#確認該IP是否已經封鎖
263
	#取得防火牆的IP block清單
264
	#cmd:firewall-cmd --list-rich-rule
265
 
266
	#函式說明:
267
	#檢查指令的輸出是否含有關鍵字
268
	#回傳結果:
269
	#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
270
	#$result["error"],錯誤訊息.
271
	#$result["function"],當前執行的函式名稱.
272
	#$result["argu"],使用的參數.
273
	#$result["grepCmd"],截取關鍵字的指令.
274
	#$result["founded"],是否找到關鍵字,"true"代表有,"false"代表沒有.
275
	#$result["content"],關鍵字所在列的輸出.
276
	#必填參數:
277
	#$conf["cmd"],字串,要執行的指令.
278
	$conf["cmd::searchOutPut"]["cmd"]="firewall-cmd";
279
	#$conf["keyWord"],字串,要檢查是否有關鍵字.
280
	$conf["cmd::searchOutPut"]["keyWord"]="\"".$ip."\" reject";
281
	#$conf["fileArgu"],字串,變數__FILE__的內容.
90 liveuser 282
	$conf["cmd::searchOutPut"]["fileArgu"]=__FILE__;
89 liveuser 283
	#可省略參數:
284
	#$conf["binPath"],字串,應用程式的路徑,預設為"/usr/bin".
285
	#$conf["binPath"]="";
286
	#$conf["argu"],陣列字串,指令搭配的參數,預設不使用.
287
	$conf["cmd::searchOutPut"]["argu"]=array("--list-rich-rule");
288
	#$conf["excludeGrep"],字串,"true"代表排除含有 " | grep ".$conf["keyWord"] 字樣的輸出;預設為"false",不排除.
289
	#$conf["excludeGrep"]="false";
290
 
291
	#如果有設置 username
292
	if(isset($conf["username"])){
293
 
294
		#$conf["username"],字串,要用什麼使用者來執行,預設為執行php的使用者,該參數不適用於apache環境.
295
		$conf["cmd::searchOutPut"]["username"]=$conf["username"];
296
 
297
		}#if end
298
 
299
	#如果有設置 password
300
	if(isset($conf["password"])){
301
 
302
		#$conf["password"],字串,與$conf["username"]搭配的使用者密碼,預設不使用密碼,該參數不適用於apache環境.
303
		$conf["cmd::searchOutPut"]["password"]=$conf["password"];
304
 
305
		}#if end
306
 
307
	$searchOutPut=cmd::searchOutPut($conf["cmd::searchOutPut"]);
308
	unset($conf["cmd::searchOutPut"]);
309
 
310
	#如果執行失敗
311
	if($searchOutPut["status"]==="false"){
312
 
313
		#設置執行失敗
314
		$result["status"]="false";
315
 
316
		#設置錯誤訊息
317
		$result["error"]=$searchOutPut;
318
 
319
		#回傳結果
320
		return $result;
321
 
322
		}#if end
323
 
324
	#如果有找到關鍵字 " reject"
325
	if($searchOutPut["founded"]==="true"){
326
 
327
		#移除該ip
328
		unset($ipsInfo[$ip]);
329
 
330
		#跳過該ip
331
		continue;
332
 
333
		}#if end
334
 
1 liveuser 335
	#儲存目前次數最多的ip次數
336
	$count=$maxCountIp["count"];
337
 
338
	#提示有問題的 ip
339
	echo "IP:".$ip." 拜訪了 ".$count." 次都失敗".PHP_EOL;
340
	echo "是否要 block it?".PHP_EOL;
341
 
342
	#涵式說明:
343
	#讀取標準I/O的一行輸入.並提供提示說明.
344
	#回傳的結果:
345
	#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
346
	#$result["error"],錯誤訊息.
347
	#$result["function"],當前執行的函數名稱.
348
	#$result["content"],取得的輸入內容.
349
	#必填的參數:
350
	#$conf["commentsArray"],字串陣列,提示輸入的文字描述,$conf["commentsArray"][$i]代表第($+1)行的描述.
351
	$conf["commentsArray"]=array("請輸入(y/n)");
352
	#可省略的參數:
353
	#$conf["newLineBreak"],字串,是否$conf["commentsArray"]的每個元素後面都要斷行,"false"代表不要,預設為"true"要斷行.
354
	#$conf["newLineBreak"]="false";
355
	$readLine=cmd::readLine($conf);
356
	unset($conf);
357
 
358
	#如果讀取失敗
359
	if($readLine["status"]==="false"){
360
 
361
		#印出結果
362
		var_dump($readLine);
363
 
364
		#結束執行
365
		exit;
366
 
367
		}#if end
368
 
369
	#取得輸入的內容
370
	$input=$readLine["content"];
371
 
372
	#判斷輸入
373
	switch($input){
374
 
375
		#如果輸入 "y"
376
		case "y":
377
 
378
			#封鎖該ip
379
			#涵式說明:
380
			#呼叫shell依序執行系統命令,並取得回傳的內容.
381
			#回傳的結果:
382
			#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
383
			#$result["error"],錯誤訊息陣列.
384
			#$result["function"],當前執行的函數名稱.
385
			#$result["cmd"],執行的指令內容.
386
			#$result["output"],爲執行完每個指令後的輸出陣列.
387
			#必填的參數
388
			#$conf["command"],字串陣列,要執行的指令.
389
			$conf["external::callShellMulti"]["command"]=array("echo");
390
			#$conf["fileArgu"],字串,變數__FILE__的內容,預設為當前檔案的路徑與名稱.
391
			$conf["external::callShellMulti"]["fileArgu"]=__FILE__;		
392
			#可省略參數:
393
			#$conf["argu"],陣字串列,執行各個$conf["command"]時指令搭配的參數,預設為空陣列.
453 liveuser 394
			$conf["external::callShellMulti"]["argu"]=array(array($ip,"|","block_ip.sh"));
1 liveuser 395
			#$conf["enablePrintDescription"],字串陣列,執行各個$conf["command"]時是否要印出$conf["printDescription"]的內容,"true"代表要,"false"代表不要,其數量須與$conf["command"]的元素數量相同,若只有一個元素,則代表是每個$conf["command"]執行時都用此參數.
396
			#$conf["enablePrintDescription"]=array("false");
397
			#$conf["printDescription"],字串陣列,執行各個$conf["command"]前要印出來的的文字,預設為$conf["command"]的內容,其數量須與$conf["command"]的元素數量相同,若只有一個元素,則代表是每個$conf["command"]執行時都用此參數.
398
			#$conf["printDescription"]=array("");
399
			#$conf["escapeshellarg"],字串陣列,執行各個$conf["command"]時是否要啟用過濾參數,用了比較安全,但可能會出錯,"true"為啟用,"false"為不啟用,預設為"false",其數量須與$conf["command"]的元素數量相同,若只有一個元素,則代表是每個$conf["command"]執行時都用此參數.
453 liveuser 400
			$conf["external::callShellMulti"]["escapeshellarg"]=array("true");
1 liveuser 401
			#$conf["useScript"],字串,每個指令的執行是否要啟用Linux的script指令來記錄輸出,"true"代表要;"false"代表不要,預設為"false".
402
			#$conf["useScript"]="";
403
			#$conf["logFilePath"],字串,當 $conf["useScript"] 為 "true" 時,輸出的內容要暫存到哪裡,預設為 ".qbpwcf_tmp/external/callShell/".
404
			#$conf["logFilePath"]=".qbpwcf_tmp/external/callShell/";
405
			#$conf["inBackGround"],字串,每個指令的執行是否要在背景執行,且不會等待程式執行結束再執行下一個指令,"true"代表是,"false"代表不要,預設為"false",如果$conf["command"]有用";"區隔的多個指令將會出錯.
406
			#$conf["inBackGround"]="";
407
			#備註:
408
			#不是所有指令都能用apache的身份執行,目前已知java,javac指令無法執行.
409
			#參考資料:
410
			#exec=>http://php.net/manual/en/function.exec.php
411
			#escapeshellcmd=>http://php.net/manual/en/function.escapeshellcmd.php
412
			#escapeshellarg=>http://php.net/manual/en/function.escapeshellarg.php	
413
			$callShellMulti=external::callShellMulti($conf["external::callShellMulti"]);
414
			unset($conf["external::callShellMulti"]);
415
 
416
			#如果執行失敗
417
			if($callShellMulti["status"]==="false"){
418
 
419
				#設置執行失敗
420
				$result["status"]="false";
421
 
422
				#設置錯誤訊息
423
				$result["error"]=$callShellMulti;
424
 
425
				#回傳結果
426
				return $result;
427
 
428
				}#if end
429
 
430
			#移除該ip
431
			unset($ipsInfo[$ip]);
432
 
433
			#結束執行
434
			break;
435
 
436
		#如果輸入 "n"
437
		case "n":
438
 
439
			#移除該ip
440
			unset($ipsInfo[$ip]);
441
 
442
			#換下一個ip
443
			continue 2;
444
 
445
			#結束執行
446
			break;
447
 
448
		#其他輸入內容
449
		default:
450
 
451
			#重複詢問
452
			continue 2;
453
 
454
		}#switch end
455
 
456
	}#while end
457
 
458
?>