Subversion Repositories php-qbpwcf

Rev

Rev 226 | Details | Compare with Previous | Last modification | View Log | RSS feed

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