Subversion Repositories php-qbpwcf

Rev

Rev 190 | Rev 207 | Go to most recent revision | 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.
6
    Copyright (C) 2015~2024 Min-Jhin,Chen
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
 
25
/*
26
封鎖來自http、https、smtp、named的惡意ip. 
27
*/
28
 
29
/*
30
 
31
bug log:
32
 
33
journalctl -a -e -f
34
Mar 09 13:40:20 qbpwcf.org postfix/smtpd[1058247]: connect from unknown[194.48.251.15]
35
Mar 09 13:40:21 qbpwcf.org postfix/smtpd[1058247]: disconnect from unknown[194.48.251.15] ehlo=1 auth=0/1 quit=1 commands=2/3
36
Mar 09 13:40:45 qbpwcf.org postfix/smtpd[1050779]: connect from unknown[194.48.251.15]
37
Mar 09 13:40:46 qbpwcf.org postfix/smtpd[1050779]: disconnect from unknown[194.48.251.15] ehlo=1 auth=0/1 quit=1 commands=2/3
38
Mar 09 13:41:07 qbpwcf.org postfix/smtpd[1058247]: connect from unknown[194.48.251.15]
39
Mar 09 13:41:08 qbpwcf.org postfix/smtpd[1058247]: disconnect from unknown[194.48.251.15] ehlo=1 auth=0/1 quit=1 commands=2/3
40
 
41
*/
42
 
43
#指派命名空間
44
namespace qbpwcf;
45
 
46
#取得 lib path
47
exec("php -f ".escapeshellarg(pathinfo(__FILE__)["dirname"]."/libexec/folderOfUsrLib.php"),$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
 
60
#儲存lib path
61
$folderOfUsrLib=$output[0];
62
 
63
#以該檔案的實際位置的 lib path 為 include path 首位
64
$output=array();
65
exec("cd ".escapeshellarg(pathinfo(__FILE__)["dirname"]."/../".$folderOfUsrLib."/qbpwcf").";pwd;",$output,$status);
66
 
67
#如果執行失敗
68
if($status!==0){
69
 
70
	#debug
71
	var_dump(__LINE__,$output);
72
 
73
	#結束執行,回傳shell 1.
74
	exit(1);
75
 
76
	}#if end
77
 
78
#設置 include path 
79
set_include_path($output[0].PATH_SEPARATOR.get_include_path());
80
 
81
#匯入外部套件
82
include("allInOne.php");
83
 
84
#當前lib路徑
85
$pwd=$output[0];
86
 
87
#unix socket 的位置
88
$unixSocket=$pwd."/../../../var/qbpwcf/".basename(__FILE__).".sock";
89
 
90
#提示unix domain socket位置
91
echo "unix domain socket used at ".$unixSocket;
92
 
93
#初始化儲存上次各log的時間
94
$preTimeFloat=array();
95
 
96
#初始化記錄 http log 最後變更的時間
97
$preTimeFloat["http"]=0;
98
 
99
#初始化記錄 https log 最後變更的時間
100
$preTimeFloat["https"]=0;
101
 
102
#初始化記錄 smtpd log 最後變更的時間
103
$preTimeFloat["smtp"]=0;
104
 
105
#初始化記錄 dovecot/imap log 最後變更的時間
106
$preTimeFloat["imap"]=0;
107
 
108
#初始化記錄 named log 最後變更的時間
109
$preTimeFloat["named"]=0;
110
 
168 liveuser 111
#初始化記錄 sshd log 最後變更的時間
112
$preTimeFloat["sshd"]=0;
113
 
3 liveuser 114
#初始化不啟用debug模式
115
$debug=false;
116
 
117
#預設暫存的白名單ip有效時間為1小時
118
$tmp_white_ip_valid_time=1;
119
 
120
#說明函式
121
function help(){
122
 
123
	#印出指令說明
124
	echo "Usage of ".basename(__FILE__).":".PHP_EOL; 
125
	echo "--debug [true/false] 代表是否要啟動 debug 模式".PHP_EOL;
126
	echo "--exclude [white list ip] 代表白名單IP,一次只能放一個IP.".PHP_EOL;
127
	echo "--tmp-white-ip-valid-time [white ip value time] 指定暫時白名單的有效小時".PHP_EOL;
128
	echo "--client [true/false] 代表是否為 client 端,而非 server 端".PHP_EOL;
129
	echo "--client-add-tmp-white-ip [while ip for while] client端指令,代表要增加的暫時白名單IP".PHP_EOL;
130
	echo "--client-update-tmp-white-ip-valid-time [white ip value time] client端指令,代表要更新暫時白名單的有效時間,單位為小時".PHP_EOL;
131
 
132
	#結束執行
133
	exit;
134
 
135
	}#function help end
136
 
137
#函式說明:
138
#解析參數.
139
#回傳結果:
140
#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
141
#$reuslt["error"],執行不正常結束的錯訊息陣列.
142
#$result["function"],當前執行的函式名稱.
143
#$result["content"],解析好的參數陣列.
144
#$result["content"][$key][$i],參數 $key 的 $i+1 個參數數值內容.
145
#$result["program"],字串,執行的程式名稱.
146
#必填參數:
147
#無.
148
#可省略參數:
149
#$conf["helpFunc"],如果解析的參數不成對,則要執行的函式名稱.
150
$conf["helpFunc"]="help";
151
#參考資料:
152
#無.
153
#備註:
154
#僅能在命令列底下執行.
155
#以後可將參數 --a--b 的名稱與後面的數值 $value 存成 $result["a"]["b"][$i]=$value .
156
$parseArgu=cmd::parseArgu($conf);
157
unset($conf);
158
 
159
#如果執行失敗
160
if($parseArgu["status"]==="false"){
161
 
162
	#設置執行失敗
163
	$result["status"]="false";
164
 
165
	#設置錯誤訊息
166
	$result["error"]=$parseArgu;
167
 
168
	#印出結果
169
	var_dump($result);
170
 
171
	#結束執行
172
	exit(1);
173
 
174
	}#if end
175
 
176
#檢查參數
177
#函式說明:
178
#檢查必填與可省略的參數,可省略參數可指定預設要給與什麼數值內容.
179
#回傳結果:
180
#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
181
#$result["error"],執行不正常結束的錯訊息陣列.
182
#$result["simpleError"],簡單表示的錯誤訊息.
183
#$result["function"],當前執行的函式名稱.
184
#$result["argu"],設置給予的參數.
185
#$result["passed"],識別要檢查的全體變數是否存在以及型態是否正確的變數,"true"代表檢查全部通過;"false"代表檢查不通過
186
#$result[$shouldBeCheckedVarName]["varExist"],所檢查的變數是否存在,"false"代表不存在;"true"代表存在
187
#$result[$shouldBeCheckedVarName]["varType"],所檢查的變數型態是否正確,"false"代表錯誤;"true"代表正確
188
#$result[$shouldBeCheckedVarName]["error"],每個參數設定的錯誤訊息
189
#$result["shouldNotBeEmpty"],不應該為空字串或控陣列的變數.
190
#$result["argu"],字串陣列,目前輸入的參數名稱陣列.
191
#$result["legalVarName"],字串陣列,合法可用的參數名稱陣列.
192
#$result["notNeedVar"],字串陣列,多餘的參數名稱.
193
#必填參數:
194
#$conf["varInput"],陣列變數,要檢查的陣列變數,請在要檢查的參數前面加上&,這樣變動的結果才能被套用。
195
$conf["varInput"]=&$parseArgu["content"];
196
#$conf["referenceVarKey"],字串,$conf參數後面的key值,用於移除不要的參考陣列.
197
$conf["referenceVarKey"]="variableCheck::checkArguments";
198
#可省略參數:
199
#$conf["mustBeFilledVariableName"],爲必填參數的變數名稱陣列,形態爲陣列變數,元素數量需要跟"mustBeFilledVariableType"參數的元素數量一致,例如: $conf["mustBeFilledVariableName"] = array("id","account","password");
200
#$conf["mustBeFilledVariableName"]=array();
201
#$conf["mustBeFilledVariableType"],爲必填參數的變數陣列應該爲何種變數形態,形態爲陣列,元素數量需要跟"mustBeFilledVariableName"參數的元素數量一致,例如: $conf["mustBeFilledVariableType"] = array("string",integer,"double","resource","object"); , null代表不指定變數形態.
202
#$conf["mustBeFilledVariableType"]=array();
203
#$conf["canBeEmptyString"],字串,必填變數內容如果是空字串就不能算是有設置的話,請設為"false",預設爲"true",可以為空字串.
204
#$conf["canBeEmptyString"]="false";
205
#$conf["canNotBeEmpty"],字串陣列,哪些必填參數的內容不得為空字串或空陣列,僅當$conf["canBeEmptyString"]為"true"時會生效.
206
#$conf["canNotBeEmpty"]=array();
207
#$conf["canBeEmpty"],字串陣列,哪些必填參數的內容可為空字串或空陣列,僅當$conf["canBeEmptyString"]為"false"時會生效.
208
#$conf["canBeEmpty"]=array();
209
#$conf["skipableVariableCanNotBeEmpty"],字串陣列,哪些可省略參數不可以為空字串或空陣列.
210
$conf["skipableVariableCanNotBeEmpty"]=array("debug","exclude","tmp-white-ip-valid-time","client","tmp-white-ip-valid-time","client-add-tmp-white-ip","client-update-tmp-white-ip-valid-time");
211
#$conf["skipableVariableName"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableName"] = array("id","account","password");
212
$conf["skipableVariableName"]=array("debug","exclude","tmp-white-ip-valid-time","client","tmp-white-ip-valid-time","client-add-tmp-white-ip","client-update-tmp-white-ip-valid-time");
213
#$conf["skipableVariableType"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableType"] = array("string",integer,"double");
214
$conf["skipableVariableType"]=array("array","array","array","array","array","array","array");
215
#$conf["skipableVarDefaultValue"],字串陣列,每個不存在的可省略變數要初始化為什麼,null與代表不指定,若預設值是參數之一,請將$conf["mustBeFilledVar"]改成"\$conf["\mustBeFilledVar\"]".
216
$conf["skipableVarDefaultValue"]=array(array("false"),null,array("1"),null,null,null,null);
217
#$conf["disallowAllSkipableVarIsEmpty"],字串,是否允許每個可省略參數都為空字串,預設為"true"允許,反之為"false".
218
$conf["disallowAllSkipableVarIsEmpty"]="false";
219
#$conf["disallowAllSkipableVarIsEmptyArray"],字串,是否允許每個可省略參數都為空陣列,預設為"true"允許,反之為"false".
220
$conf["disallowAllSkipableVarIsEmptyArray"]="false";
221
#$conf["arrayCountEqualCheck"],字串陣列,為檢查哪些陣列參數的元素數量要一樣,$conf["arrayCountEqualCheck"][$i]=array()為第$i組key為哪些的變數其元素數量要相等.
222
#$conf["arrayCountEqualCheck"][]=array();
223
#參考資料:
224
#array_keys=>http://php.net/manual/en/function.array-keys.php
225
#備註:
226
#無.
227
$checkArguments=variableCheck::checkArguments($conf);
228
unset($conf);
229
 
230
#如果檢查參數失敗
231
if($checkArguments["status"]==="false"){
232
 
233
	#設置執行失敗
234
	$result["status"]="false";
235
 
236
	#設置錯誤訊息
237
	$result["error"]=$checkArguments;
238
 
239
	#印出結果
240
	var_dump($result);
241
 
242
	#結束執行,跟回傳錯誤代碼.
243
	exit(1);
244
 
245
	}#if end
246
 
247
#如果檢查參數不通過
248
if($checkArguments["passed"]==="false"){
249
 
250
	#設置執行失敗
251
	$result["status"]="false";
252
 
253
	#設置錯誤訊息
254
	$result["error"]=$checkArguments;
255
 
256
	#印出結果
257
	var_dump($result);
258
 
259
	#結束執行,跟回傳錯誤代碼.
260
	exit(1);
261
 
262
	}#if end
263
 
264
#如果有debug參數
265
if(isset($parseArgu["content"]["debug"])){
266
 
267
	#如果第一個參數為 "--debug true"
268
	if($parseArgu["content"]["debug"][0]==="true"){
269
 
270
		#設置debug模式
271
		$debug=true;
272
 
273
		#comment
274
		echo "debug mode".PHP_EOL;
275
 
168 liveuser 276
		}#if end
3 liveuser 277
 
278
	}#if end
279
 
280
#如果有client參數
281
if(isset($parseArgu["content"]["client"])){
282
 
283
	#預設沒有id
284
	$clientId="";
285
 
286
	#如果第一個參數為 "--client true"
287
	if($parseArgu["content"]["client"][0]==="true"){
288
 
289
		#函式說明:
290
		#連線到 unixDomainSockServer 提供的 unix domain socket.
291
		#回傳結果:
292
		#$result["status"],"true"代表執行正常;"false"代表執行不正常.
293
		#$result["error"],錯誤訊息陣列.
294
		#$result["function"],當前執行的函式名稱.
295
		#$result["content"],取得的回應.
296
		#必填參數:
297
		#$conf["sock"],字串,要連線的unix domain socket.
298
		$conf["sock"]=$unixSocket;
299
		#可省略參數:
300
		#$conf["id"],字串,取得的id,若無此值,則會得到新的數值.
301
		#$conf["id"]="";
302
		#$conf["cmd"],字串,要執行的指令,當$conf["id"]參數合法時,才會執行.
303
		#$conf["cmd"]="";
304
		#$conf["param"],參數陣列.
305
		#$conf["param"]=array();
306
		#$conf["escaped"],字串,param參數是否已經escaped了,預設為"false",反之為"true".
307
		#$conf["escaped"]="true";
308
		#$conf["custom"],陣列,要客制化傳輸的內容,會覆蓋以上除了$conf["id"]以外的可省略參數.
309
		#$conf["custom"]=array();
310
		#參考資料:
311
		#http://php.net/manual/en/function.stream-socket-client.php
312
		#http://php.net/manual/en/function.stream-get-contents.php
313
		#備註:
314
		#無.
315
		$unixDomainSockClient=sock::unixDomainSockClient($conf);
316
		unset($conf);
317
 
318
		#如果執行失敗
319
		if($unixDomainSockClient["status"]==="false"){
320
 
321
			#設置執行失敗
322
			$result["status"]="false";
323
 
324
			#設置錯誤訊息
325
			$result["error"]=$unixDomainSockClient;
326
 
327
			#印出結果
328
			var_dump($result);
329
 
330
			#結束執行,跟回傳錯誤代碼.
331
			exit(1);
332
 
333
			}#if end
334
 
335
		#取得會應
336
		$res=$unixDomainSockClient["content"];
337
 
338
		#解析回應
339
		$res=(array)json_decode(trim($res));
340
 
341
		#debug
342
		#var_dump($res);
343
 
344
		#如果沒有給予 id
345
		if(!isset($res["id"])){
346
 
347
			#設置執行失敗
348
			$result["status"]="false";
349
 
350
			#設置錯誤訊息
351
			$result["error"][]="id not found";
352
 
353
			#設置錯誤訊息
354
			$result["error"][]=$res;
355
 
356
			#印出結果
357
			var_dump($result);
358
 
359
			#結束執行,跟回傳錯誤代碼.
360
			exit(1);
361
 
362
			}#if end
363
 
364
		#取得用戶端的id	
190 liveuser 365
		$clientId=$res["id"];
3 liveuser 366
 
367
		}#if end
368
 
369
	#如果有要增加暫時的白名單
370
	if(isset($parseArgu["content"]["client-add-tmp-white-ip"])){
371
 
372
		#針對每個要增加暫時的白名單
373
		foreach($parseArgu["content"]["client-add-tmp-white-ip"] as $tmpWhilteIp){
374
 
375
			#要求 server 端增加暫時白名單 - start
376
 
377
			#產生要傳遞的陣列
378
			$request=array();
379
 
380
			#設置要新增暫時白名單的ip
381
			$request["add-tmp-white-ip"]=$tmpWhilteIp;
382
 
383
			#函式說明:
384
			#連線到 unixDomainSockServer 提供的 unix domain socket.
385
			#回傳結果:
386
			#$result["status"],"true"代表執行正常;"false"代表執行不正常.
387
			#$result["error"],錯誤訊息陣列.
388
			#$result["function"],當前執行的函式名稱.
389
			#$result["content"],取得的回應.
390
			#必填參數:
391
			#$conf["sock"],字串,要連線的unix domain socket.
392
			$conf["sock"]=$unixSocket;
393
			#可省略參數:
394
			#$conf["id"],字串,取得的id,若無此值,則會得到新的數值.
395
			$conf["id"]=$clientId;
396
			#$conf["cmd"],字串,要執行的指令,當$conf["id"]參數合法時,才會執行.
397
			#$conf["cmd"]="";
398
			#$conf["param"],參數陣列.
399
			#$conf["param"]=array();
400
			#$conf["escaped"],字串,param參數是否已經escaped了,預設為"false",反之為"true".
401
			#$conf["escaped"]="true";
402
			#$conf["custom"],陣列,要客制化傳輸的內容,會覆蓋以上除了$conf["id"]以外的可省略參數.
403
			$conf["custom"]=$request;
404
			#參考資料:
405
			#http://php.net/manual/en/function.stream-socket-client.php
406
			#http://php.net/manual/en/function.stream-get-contents.php
407
			#備註:
408
			#無.
409
			$unixDomainSockClient=sock::unixDomainSockClient($conf);
410
			unset($conf);
411
 
412
			#debug
413
			#var_dump($unixDomainSockClient);
414
 
415
			#如果執行失敗
416
			if($unixDomainSockClient["status"]==="false"){
417
 
418
				#設置執行失敗
419
				$result["status"]="false";
420
 
421
				#設置錯誤訊息
422
				$result["error"]=$unixDomainSockClient;
423
 
424
				#印出結果
425
				var_dump($result);
426
 
427
				#結束執行,跟回傳錯誤代碼.
428
				exit(1);
429
 
430
				}#if end
431
 
432
			#取得回應
433
			$res=$unixDomainSockClient["content"];
434
 
435
			#解析回應
436
			$res=(array)json_decode(trim($res));
437
 
168 liveuser 438
			#要求 server 端增加暫時白名單 - end
3 liveuser 439
 
440
			}#foreach end
441
 
442
		}#if end
443
 
444
	#如果有要更新暫存白名單的有效時間
445
	if(isset($parseArgu["content"]["client-update-tmp-white-ip-valid-time"])){
446
 
447
		#要求 server 端更新暫時白名單的期限 - start
448
 
449
		#產生要傳遞的陣列
450
		$request=array();
451
 
452
		#設置要更新暫時白名單ip的有效時間
453
		$request["update-tmp-white-ip-valid-time"]=$parseArgu["content"]["client-update-tmp-white-ip-valid-time"][0];
454
 
455
		#函式說明:
456
		#連線到 unixDomainSockServer 提供的 unix domain socket.
457
		#回傳結果:
458
		#$result["status"],"true"代表執行正常;"false"代表執行不正常.
459
		#$result["error"],錯誤訊息陣列.
460
		#$result["function"],當前執行的函式名稱.
461
		#$result["content"],取得的回應.
462
		#必填參數:
463
		#$conf["sock"],字串,要連線的unix domain socket.
464
		$conf["sock"]=$unixSocket;
465
		#可省略參數:
466
		#$conf["id"],字串,取得的id,若無此值,則會得到新的數值.
467
		$conf["id"]=$clientId;
468
		#$conf["cmd"],字串,要執行的指令,當$conf["id"]參數合法時,才會執行.
469
		#$conf["cmd"]="";
470
		#$conf["param"],參數陣列.
471
		#$conf["param"]=array();
472
		#$conf["escaped"],字串,param參數是否已經escaped了,預設為"false",反之為"true".
473
		#$conf["escaped"]="true";
474
		#$conf["custom"],陣列,要客制化傳輸的內容,會覆蓋以上除了$conf["id"]以外的可省略參數.
475
		$conf["custom"]=$request;
476
		#參考資料:
477
		#http://php.net/manual/en/function.stream-socket-client.php
478
		#http://php.net/manual/en/function.stream-get-contents.php
479
		#備註:
480
		#無.
481
		$unixDomainSockClient=sock::unixDomainSockClient($conf);
482
		unset($conf);
483
 
484
		#如果執行失敗
485
		if($unixDomainSockClient["status"]==="false"){
486
 
487
			#設置執行失敗
488
			$result["status"]="false";
489
 
490
			#設置錯誤訊息
491
			$result["error"]=$unixDomainSockClient;
492
 
493
			#印出結果
494
			var_dump($result);
495
 
496
			#結束執行,跟回傳錯誤代碼.
497
			exit(1);
498
 
499
			}#if end
500
 
501
		#取得回應
502
		$res=$unixDomainSockClient["content"];
503
 
504
		#解析回應
505
		$res=(array)json_decode(trim($res));
506
 
507
		#要求 server 端更新暫時白名單的期限 - end
508
 
509
		}#if end
510
 
511
	#client端程式結束,結束執行
512
	exit;
513
 
514
	}#if end
515
 
516
#取得自己對外的ip
517
#函式說明:
518
#依據提供查詢IP服務的網站取得伺服器對外的IP.
519
#回傳結果:
520
#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
521
#$result["function"],當前執行的函數名稱.
522
#$result["error"],錯誤訊息陣列.
523
#$result["content"],伺服端對外的IP.
524
#必填參數:
525
#$conf["fileArgu"],字串,php變數__FILE__的內容,亦即該檔案在檔案系統的絕對路徑
526
$conf["fileArgu"]=__FILE__;
527
#可省略參數:
528
#無.
529
#備註:
530
#需要有網站支援此服務.
531
$getServerRealIP=csInformation::getServerRealIP($conf);
532
unset($conf);	
533
 
534
#如果執行失敗
535
if($getServerRealIP["status"]==="false"){
536
 
537
	#設置執行失敗
538
	$result["status"]="false";
539
 
540
	#設置錯誤訊息
541
	$result["error"]=$getServerRealIP;
542
 
543
	#印出結果
544
	var_dump($result);
545
 
546
	#結束執行,跟回傳錯誤代碼.
547
	exit(1);
548
 
549
	}#if end
550
 
551
#預設的白名單為自己對外的IP
168 liveuser 552
$excludeIp=array($getServerRealIP["content"]);
3 liveuser 553
 
554
#提示內建白名單
555
echo "內建白名單:".$excludeIp[0].PHP_EOL;
556
 
557
#如果有 exclude 參數
558
if(isset($parseArgu["content"]["exclude"])){
559
 
560
	#針對每個白名單 IP
561
	foreach($parseArgu["content"]["exclude"] as $whiteIp){
562
 
563
		#提示內建白名單
564
		echo "附加白名單:".$whiteIp.PHP_EOL;
565
 
566
		#取得每個指定要排除的ip
567
		$excludeIp[]=$whiteIp;
568
 
569
		}#foreach end
570
 
571
	}#if end
572
 
573
#暫時的白名單
574
$excludeIpsTmp=array();
575
 
576
#函式說明:
577
#建立 unix domain socket server, 僅提供具備檔案存取權限的用戶使用,預設提供可以下達任何指令的功能.
578
#回傳結果:
579
#$result["status"],"true"代表執行正常;"false"代表執行不正常.
580
#$result["error"],錯誤訊息陣列.
581
#$result["function"],當前執行的函式名稱.
582
#必填參數:
583
#$conf["sock"],字串,socket檔案要放在哪邊,名稱為何.
584
$conf["sock"]=$unixSocket;
585
#$conf["fileArgu"],字串,變數__FILE__的內容.
586
$conf["fileArgu"]=__FILE__;
587
#可省略參數:
588
#$conf["changeOwner"],字串,要將socket檔案的擁有着權限進行修改."user.group"代表擁有者帳號為user,群組為group.
589
#$conf["changeOwner"]="";
590
#$conf["changePermission"],字串,要將socket檔案的權限設為多少.ex: 0666(所有帳戶都有存取的權限) 或 0660(僅有擁有者與群組帳戶有存取的權限) 或 0600(只有擁有者有權限執行).
591
$conf["changePermission"]="0666";
592
#$conf["sessionTimeout"],字串,當連線結束後於下一次連線間隔多久就算session timeout,server端會將記錄移除,client端需要重新拿取id,預設為300秒.
593
#$conf["sessionTimeout"]="300";
594
#$conf["addOnProcessFunc"],字串陣列,增加用於處理 json request 的函式名稱,給予的參數為array("request"=>收到的json訊息,"sock"=>用戶的socket).
595
$conf["addOnProcessFunc"]=array("\qbpwcf\addOnProcessFunc");
596
#$conf["funcToRunWhenIdle"],字串陣列,當沒有事件產生時,要執行的函式名稱,給予參數為array("client"=>所有用戶).
597
$conf["funcToRunWhenIdle"]=array("\qbpwcf\\funcToRunWhenIdle");
598
#$conf["infoToFunction"],陣列,需要增加給addOnProcessFunc跟funcToRunWhenIdle函式的資訊,在函式中其參數的info鍵值.
599
$conf["infoToFunction"]=array("debug"=>&$debug,"preTimeFloat"=>&$preTimeFloat,"excludeIpsTmp"=>&$excludeIpsTmp,"excludeIp"=>&$excludeIp,"tmp-white-ip-valid-time"=>&$tmp_white_ip_valid_time);
600
#參考資料:
601
#http://php.net/manual/en/function.stream-socket-server.php
602
#備註:
603
#無.
604
$unixDomainSockServer=sock::unixDomainSockServer($conf);
605
unset($conf);
606
 
607
#當執行失敗
608
if($unixDomainSockServer["status"]==="false"){
609
 
610
	#設置執行失敗
611
	$result["status"]="false";
612
 
613
	#設置錯誤訊息
614
	$result["error"]=$unixDomainSockServer;
615
 
616
	#印出結果
617
	var_dump($result);
618
 
619
	#結束執行,跟回傳錯誤代碼.
620
	exit(1);
621
 
622
	}#if end
623
 
624
#收到訊息要怎麼處理的函式
625
function addOnProcessFunc($params){
626
 
627
	#debug
628
	#var_dump(__LINE__,$params["request"]);
629
 
630
	#取得收到的訊息
631
	$receivedArray=$params["request"];
632
 
633
	#取得用戶的 socket
634
	$clientSock=$params["socket"];
635
 
636
	#預設不 debug
637
	$debug=false;
638
 
639
	#如果有debug鍵數值.
640
	if(isset($params["info"]["debug"])){
641
 
642
		#設置之
643
		$debug=$params["info"]["debug"];
644
 
645
		}#if end
646
 
647
	#debug mode
648
	if($debug){
649
 
650
		#debug
651
		var_dump(__LINE__,$params);
652
 
653
		}#if end
654
 
655
	#如果解析 json 失敗
656
	if(json_last_error()!==JSON_ERROR_NONE){
657
 
658
		#初始化結果
659
		$result=array();
660
 
661
		#設置執行失敗
662
		$result["status"]="false";
663
 
664
		#記錄錯誤訊息
665
		$result["error"]=json_last_error_msg();
666
 
667
		#回覆錯誤訊息
668
		fwrite($clientSock,json_encode($result).PHP_EOL);
669
 
670
		#初始化要回傳的訊息
671
		$result=array();
672
 
673
		#設置不繼續執行
674
		$result["continue"]="false";
675
 
676
		#回傳結果
677
		return $result;
678
 
679
		}#if end
680
 
681
	#debug mode
682
	if($debug){
683
 
684
		#debug
685
		var_dump(__LINE__,$receivedArray);
686
 
687
		}#if end
688
 
689
	#如果要新增暫時的ip白名單
690
	if(isset($receivedArray["add-tmp-white-ip"])){
691
 
692
		#函式說明:
693
		#將多個多維陣列串聯起來,key從0開始排序.
694
		#回傳的結果:
695
		#$result["status"],"true"表執行正常,"false"代表執行不正常.
696
		#$result["error"],錯誤訊息陣列.
697
		#$result["function"],當前執行的函數.
698
		#$result["content"],合併好的一維陣列.
699
		#必填參數
700
		#$conf["inputArray"],陣列,要合併的一維陣列變數,例如:=array($array1,$array2);
701
		$conf["inputArray"]=array($params["info"]["excludeIpsTmp"],array(array("ip"=>$receivedArray["add-tmp-white-ip"],"unixtime"=>time())));
702
		#可省略參數:
703
		#$conf["allowRepeat"],字串,預設為"false",不允許重複的結果;反之為"true".
704
		#$conf["allowRepeat"]="true";
705
		#$conf["equalKeyStruc"],字串陣列,若 allowRepeat 參數為 "false", 這該參數生效.該參數為用來判斷每個陣列的哪個鍵值路徑底下的數值相同時要進行取代,後者會取代前者.
706
		$conf["equalKeyStruc"]=array("ip");
707
		#參考資料:
708
		#無.
709
		#備註:
710
		#無.
711
		$mergeMultiDimensionArray=arrays::mergeMultiDimensionArray($conf);
712
		unset($conf);
713
 
714
		#debug mode
715
		if($debug){
716
 
717
			#debug
718
			var_dump(__LINE__,$mergeMultiDimensionArray);
719
 
720
			}#if end
721
 
722
		#如果運行失敗
723
		if($mergeMultiDimensionArray["status"]==="false"){
724
 
725
			#設置執行失敗
726
			$result["status"]="false";
727
 
728
			#設置錯誤訊息
729
			$result["error"]=$mergeMultiDimensionArray;
730
 
731
			#印出結果
732
			var_dump($result);
733
 
734
			#結束執行
735
			exit(1);
736
 
737
			}#if end
738
 
739
		#更新白名單
740
		$params["info"]["excludeIpsTmp"]=$mergeMultiDimensionArray["content"];
741
 
742
		#debug mode
743
		if($debug){
744
 
745
			#debug
746
			var_dump(__LINE__,$params["info"]["excludeIpsTmp"]);
747
 
748
			}#if end
749
 
750
		}#if end
751
 
752
	#反之收到 update-tmp-white-ip-valid-time
753
	if(isset($receivedArray["update-tmp-white-ip-valid-time"])){
754
 
755
		#更新白名單有效時間
756
		$params["info"]["tmp-white-ip-valid-time"]=$receivedArray["update-tmp-white-ip-valid-time"];
168 liveuser 757
 
3 liveuser 758
		#debug mode
759
		if($debug){
760
 
761
			#debug
762
			var_dump(__LINE__,$params["info"]["tmp-white-ip-valid-time"]);
168 liveuser 763
 
3 liveuser 764
			}#if end
765
 
766
		}#if end
168 liveuser 767
 
3 liveuser 768
	#初始化要回傳的結果
168 liveuser 769
	$result=array();
3 liveuser 770
 
771
	#設置執行正常
168 liveuser 772
	$result["status"]="true";
773
 
3 liveuser 774
	#設置可以繼續執行後面的函式
775
	$result["continue"]="true";
776
 
777
	#回傳結果
778
	return $result;
779
 
780
	}#function addOnProcessFunc end
781
 
168 liveuser 782
/*
783
#說明:
3 liveuser 784
#沒事時要重複執行的函式
168 liveuser 785
#參數:
786
#$params["info"]["preTimeFloat"]["http"],http log的最新時間.
787
#$params["info"]["preTimeFloat"]["https"],https log的最新時間.
788
#$params["info"]["preTimeFloat"]["smtp"],postfix.service log的最新時間.
789
#$params["info"]["preTimeFloat"]["imap"],dovecot.service log的最新時間.
790
#$params["info"]["preTimeFloat"]["named"],named.service log的最新時間.
791
#$params["info"]["preTimeFloat"]["sshd"],sshd.service log的最新時間.
792
*/
793
function funcToRunWhenIdle(&$params){
3 liveuser 794
 
795
	#預設不 debug
796
	$debug=false;
797
 
798
	#如果有debug鍵數值.
799
	if(isset($params["info"]["debug"])){
800
 
801
		#設置之
802
		$debug=$params["info"]["debug"];
803
 
804
		}#if end
805
 
806
	#debug mode
807
	if($debug){
808
 
809
		#comment
810
		echo "new round".PHP_EOL;
811
 
812
		}#if end
813
 
814
	#debug mode
815
	if($debug){
816
 
817
		#comment
818
		echo "\$preHttpTimeFloat:".$params["info"]["preTimeFloat"]["http"].PHP_EOL;
819
		echo "\$preHttpsTimeFloat:".$params["info"]["preTimeFloat"]["https"].PHP_EOL;
820
		echo "\$preSmtpTimeFloat:".$params["info"]["preTimeFloat"]["smtp"].PHP_EOL;
821
		echo "\$preImapTimeFloat:".$params["info"]["preTimeFloat"]["imap"].PHP_EOL;
822
		echo "\$preNamedTimeFloat:".$params["info"]["preTimeFloat"]["named"].PHP_EOL;
168 liveuser 823
		echo "\$preSshddTimeFloat:".$params["info"]["preTimeFloat"]["sshd"].PHP_EOL;
3 liveuser 824
 
825
		}#if end
826
 
827
	#函式說明:
828
	#檢查多個檔案與資料夾是否存在.
829
	#回傳的結果:
830
	#$result["status"],執行正常與否,"true"代表正常,"false"代表不正常.
831
	#$result["error"],錯誤訊息陣列.
832
	#$resutl["function"],當前執行的涵式名稱.
833
	#$result["argu"],使用的參數.
834
	#$result["allExist"],所有檔案皆存在的識別,"true"代表皆存在,"false"代表沒有全部都存在.
835
	#$result["varName"][$i],爲第$i個資料夾或檔案的路徑與名稱。
836
	#$result["varNameFullPath"][$i],爲第$i個資料夾或檔案的完整檔案系統路徑與名稱,如果不存在則代表路徑是網址.
837
	#$result["varNameWebPath"][$i],為第$i個資料夾或檔案的網址,若"web"參數為"true",才會有該內容.
838
	#$result["varExist"][$i],爲第$i個資料夾或檔案是否存在,"true"代表存在,"false"代表不存在。
839
	#必填參數:
840
	#$conf["fileArray"],陣列字串,要檢查是否存在的檔案有哪些,須爲一維陣列數值。
168 liveuser 841
	$conf["fileAccess::checkMultiFileExist"]["fileArray"]=array("/var/log/httpd/access_log");
3 liveuser 842
	#$conf["fileArgu"],字串,php變數__FILE__的內容,亦即該檔案在檔案系統的絕對路徑
168 liveuser 843
	$conf["fileAccess::checkMultiFileExist"]["fileArgu"]=__FILE__;
3 liveuser 844
	#可省略參數:
845
	#$conf["disableWebSearch"],"字串",是否取消「當檔案找不到時,改用catchWebContent類別的wget函數來檢查檔案是否存在於網路上」的功能,"false"不取消,若要取消該功能請設為"true",若抓到的內容為空字串則會視為檔案不存在,預設為"true".
846
	#$conf["disableWebSearch"]="false";
847
	#$conf["userDir"],字串,網頁是否置放於家目錄底下,"true"為是,"false"為不是,預設為"true".
168 liveuser 848
	$conf["fileAccess::checkMultiFileExist"]["userDir"]="false";
3 liveuser 849
	#$conf["web"],字串,檔案是放在web就是"true",反之為檔案系統"false",預設為"true".
168 liveuser 850
	$conf["fileAccess::checkMultiFileExist"]["web"]="false";
3 liveuser 851
	#參考資料:
852
	#http://php.net/manual/en/function.file-exists.php
853
	#http://php.net/manual/en/control-structures.foreach.php
854
	#備註:
855
	#函數file_exists檢查的路徑為檔案系統的路徑
856
	#$result["varName"][$i]結果未實作
168 liveuser 857
	$checkMultiFileExist=fileAccess::checkMultiFileExist($conf["fileAccess::checkMultiFileExist"]);
858
	unset($conf["fileAccess::checkMultiFileExist"]);
3 liveuser 859
 
860
	#如果運行失敗
861
	if($checkMultiFileExist["status"]==="false"){
862
 
863
		#設置執行失敗
864
		$result["status"]="false";
865
 
866
		#設置錯誤訊息
867
		$result["error"]=$checkMultiFileExist;
868
 
869
		#印出結果
870
		var_dump($checkMultiFileExist);
871
 
872
		#結束執行
873
		exit(1);
874
 
875
		}#if end
876
 
877
	#如果存在 http log
878
	if($checkMultiFileExist["allExist"]==="true"){
168 liveuser 879
 
880
		#函式說明:
881
		#呼叫shell執行系統命令,並取得回傳的內容.
3 liveuser 882
		#回傳結果:
168 liveuser 883
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
3 liveuser 884
		#$result["error"],錯誤訊息陣列.
168 liveuser 885
		#$result["function"],當前執行的函數名稱.
886
		#$result["argu"],使用的參數.
887
		#$result["cmd"],執行的指令內容.
888
		#$result["fullCmd"],如果參數 $conf["inBackGround"] 為 "true" 則會回傳該值.
889
		#$result["output"],爲執行完後的輸出陣列,若 $conf["inBackGround"] 為 "true",則為當下的輸出.
890
		#$result["content"],為執行完後的輸出字串.
891
		#$result["tmpFileOutput"],儲存輸出的暫存檔案名稱,若 $conf["inBackGround"] 為 "true" 則會回傳該值.
892
		#$result["running"],是否還在執行.
893
		#$result["pid"],pid.
894
		#$result["statusCode"],執行結束後的代碼.
895
		#$result["escape"],陣列,儲存重新排序過且已經escape過的指令(key為"cmd")與參數(key為"argu")與兩者組合的一維陣列(key為"array").
896
		#$result["noEcaped"],陣列,儲存重新排序過未經過escape過的指令(key為"cmd")與參數(key為"argu")與兩者組合的一維陣列(key為"array").
3 liveuser 897
		#必填參數:
168 liveuser 898
		#$conf["command"],字串,要執行的指令.
899
		$conf["external::callShell"]["command"]="tail";
900
		#$conf["fileArgu"],字串,變數__FILE__的內容.
901
		$conf["external::callShell"]["fileArgu"]=__FILE__;
902
		#可省略參數:
903
		#$conf["argu"],陣列字串,指令搭配的參數,預設為空陣列.
904
		$conf["external::callShell"]["argu"]=array("-n","1","/var/log/httpd/access_log");
905
		#$conf["arguIsAddr"],陣列字串,指令搭配的哪些參數為路徑,為路徑的參數會進行轉換以便符合呼叫當前函數的位置,預設不指定,若有3個參數,其中第3個參數為路徑,則表示為array("false","false","true").
906
		#$conf["arguIsAddr"]=array();
907
		#$conf["pre"],陣列,要在本指令前執行的每個指令與參數.
908
		#$conf["pre"][$i]["cmd"],字串,要在本指令前執行的第$i+1個指令.
909
		#$conf["pre"][$i]["param"],陣列字串,要在本指令前執行的第$i+1個指令的參數.
910
		#$conf["enablePrintDescription"],字串,是否要印出$conf["printDescription"]的內容,"true"代表要,"false"代表不要,預設為"false".
911
		#$conf["enablePrintDescription"]="true";
912
		#$conf["printDescription"],字串,執行該外部程式前要印出來的的文字,預設為$conf["command"]的內容加上使用的$conf["argu"]參數.
913
		#$conf["printDescription"]="";
914
		#$conf["escapeshellarg"],字串,是否要啟用過濾參數,用了比較安全,但可能會出錯,"true"為啟用,"false"為不啟用,預設為"false".如果參數為"< 、<< 、> 、>> 、| 、2>&1"之一則不會過濾.
915
		$conf["external::callShell"]["escapeshellarg"]="true";
916
		#$conf["thereIsShellVar"],陣列字串,指令搭配的參數"argu",若含有「\'」,則取代為「"」.每個argu參數都要有對應的元素."true"代表要置換.
917
		#$conf["thereIsShellVar"]=array();
918
		#$conf["username"],字串,要用什麼使用者來執行,預設為執行php的使用者,該參數不適用於apache環境.
919
		#$conf["username"]="";
920
		#$conf["password"],字串,root的使用者密碼,預設不使用密碼,該參數不適用於apache環境.
921
		#$conf["password"]="";	
922
		#$conf["useScript"],字串,是否要啟用Linux的script指令來記錄輸出,"true"代表要,Fedora的selinux會擋住該操作;"false"代表不要,預設為"false".
923
		#$conf["useScript"]="";
924
		#$conf["logFilePath"],字串,當 $conf["useScript"] 為 "true" 時,輸出的內容要暫存到哪裡,預設為 "/tmp/.qbpwcf_tmp/external/callShell/".
925
		#$conf["logFilePath"]=".qbpwcf_tmp/external/callShell/";
926
		#$conf["inBackGround"],字串,是否要在背景執行,且不會等待程式執行結束再執行下一個指令,"true"代表是,"false"代表不要,預設為"false",如果$conf["command"]有用「;」區隔的多個指令將會出錯.
927
		#$conf["inBackGround"]="";
928
		#$conf["getErr"],字串,"true"代表將錯誤輸出變成標準輸出,反之"false"為不變動.
929
		#$conf["getErr"]="false";
930
		#$conf["doNotRun"],字串,"true"代表不執行指令,預設為"false"會執行指令.
931
		#$conf["doNotRun"]="false";
932
		#參考資料:
933
		#exec=>http://php.net/manual/en/function.exec.php
934
		#escapeshellcmd=>http://php.net/manual/en/function.escapeshellcmd.php
935
		#escapeshellarg=>http://php.net/manual/en/function.escapeshellarg.php
936
		#備註:
937
		#不是所有指令都能用apache的身份執行,目前已知java,javac指令無法執行,使用root身份可能會被selinux阻擋.
938
		#若使用的 command、argu 參數,含有 ~ 則會被視為字串,若有需要其於 shell 中代表的家目錄位置,可用 fileAccess::tildeToPath 來進行轉換.
939
		$callShell=external::callShell($conf["external::callShell"]);
940
		unset($conf["external::callShell"]);
3 liveuser 941
 
168 liveuser 942
		#如果執行異常
943
		if($callShell["status"]==="false"){
3 liveuser 944
 
168 liveuser 945
			#debug
946
			var_dump($callShell);
947
 
948
			#結束並回傳代表1,表示異常
3 liveuser 949
			exit(1);
950
 
951
			}#if end
952
 
168 liveuser 953
		#如果輸出有一行
954
		if(count($callShell["output"])===1){
955
 
956
			#debug
957
			if($debug){
958
 
959
				#標題提示
960
				echo "最新一筆log".PHP_EOL;
961
 
962
				#印出log
963
				echo $callShell["output"][0].PHP_EOL;
964
 
965
				}#if end
966
 
967
			#範例log
968
			#193.42.43.36 - - [30/Sep/2025:13:15:04 +0800] "GET / HTTP/2.0" 200 138772
969
			#${ip} ${doNotNeed} [${day}/${month}/${year}:${hour}:${min}:${sec} ${timezone}] ${method} ${path} ${protocol} ${responseCode} ${bytesSend}
970
 
971
			#解析時間
972
			#函式說明:
973
			#尋找字串中是否含有符合格式的內容,且回傳解析好的變數數值.
974
			#回傳結果:
975
			#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
976
			#$reuslt["error"],執行不正常結束的錯訊息陣列.
977
			#$result["function"],當前執行的函式名稱.
978
			#$result["argu"],所使用的參數.
979
			#$result["found"],是否有找到符合格式的字串內容,"true"代表有找到,"false"代表沒有找到.
980
			#$result["content"],陣列,若為n個${*},則當found為"true"時,就會回傳n個元素.
981
			#$result["parsedVar"][varName],陣列,解析好的變數陣列,varName為${}中的內容.
982
			#必填參數:
983
			#$conf["input"],字串,要檢查的字串.
984
			$conf["search::findSpecifyStrFormat"]["input"]=$callShell["output"][0];
985
			#$conf["format"],格式字串,要尋找的格式字串.格式為固定的字串("fixedStr format")與變數("${keyWordVarName}")組成.
986
			$conf["search::findSpecifyStrFormat"]["format"]="\${ip} \${doNotNeed} [\${day}/\${month}/\${year}:\${hour}:\${min}:\${sec} \${timezone}] \${method} \${path} \${protocol} \${responseCode} \${bytesSend}";
987
			#可省略參數:
988
			#$conf["varEqual"],陣列,變數對應的數值,null代表不指定,其他內容代表該變數解析出來必須要為該內容.
989
			#$conf["varEqual"]=array(null,"found");
990
			#$conf["varCon"],陣列,每個varEqual為null者,其是否有其他條件,預設為null代表無其他條件,條件的表示是用陣列的key與value來表達,例如:array("no_tail"=>" not"),就代表變數的結尾不能為" not",可以用的key有"head",代表開頭要有什麼;"no_head",代表不能為什麼開頭;"tail",代表要什麼結尾;"no_tail",代表不能什麼結尾.
991
			#$conf["varCon"]=array("no_tail"=>" not");
992
			#參考資料:
993
			#無.
994
			#備註:
995
			#無.
996
			$findSpecifyStrFormat=search::findSpecifyStrFormat($conf["search::findSpecifyStrFormat"]);
997
			unset($conf["search::findSpecifyStrFormat"]);
998
 
999
			#如果執行異常
1000
			if($findSpecifyStrFormat["status"]==="false"){
1001
 
1002
				#debug
1003
				var_dump($findSpecifyStrFormat);
1004
 
1005
				#結束並回傳代表1,表示異常
1006
				exit(1);
1007
 
1008
				}#if end
1009
 
1010
			#如果格式有符合
1011
			if($findSpecifyStrFormat["found"]==="true"){
1012
 
1013
				#記錄 http log 的最後變更時間
1014
				$httpTimeFloat=strtotime($findSpecifyStrFormat["parsedVar"]["month"][0]." ".$findSpecifyStrFormat["parsedVar"]["day"][0]." ".$findSpecifyStrFormat["parsedVar"]["hour"][0].":".$findSpecifyStrFormat["parsedVar"]["min"][0].":".$findSpecifyStrFormat["parsedVar"]["sec"][0]);
1015
 
1016
				}#if end
1017
 
1018
			}#if end
1019
 
1020
			#反之沒變動
1021
			else{
1022
 
1023
				#沿用上次時間
1024
				$httpTimeFloat=$params["info"]["preTimeFloat"]["http"];
1025
 
1026
				}#else ebd
1027
 
3 liveuser 1028
		#debug
1029
		if($debug){
1030
 
1031
			#comment
1032
			echo "accessed file /var/log/httpd/access_log".PHP_EOL;
1033
 
1034
			}#if end
1035
 
1036
		}#if end
1037
 
1038
	#函式說明:
1039
	#檢查多個檔案與資料夾是否存在.
1040
	#回傳的結果:
1041
	#$result["status"],執行正常與否,"true"代表正常,"false"代表不正常.
1042
	#$result["error"],錯誤訊息陣列.
1043
	#$resutl["function"],當前執行的涵式名稱.
1044
	#$result["argu"],使用的參數.
1045
	#$result["allExist"],所有檔案皆存在的識別,"true"代表皆存在,"false"代表沒有全部都存在.
1046
	#$result["varName"][$i],爲第$i個資料夾或檔案的路徑與名稱。
1047
	#$result["varNameFullPath"][$i],爲第$i個資料夾或檔案的完整檔案系統路徑與名稱,如果不存在則代表路徑是網址.
1048
	#$result["varNameWebPath"][$i],為第$i個資料夾或檔案的網址,若"web"參數為"true",才會有該內容.
1049
	#$result["varExist"][$i],爲第$i個資料夾或檔案是否存在,"true"代表存在,"false"代表不存在。
1050
	#必填參數:
1051
	#$conf["fileArray"],陣列字串,要檢查是否存在的檔案有哪些,須爲一維陣列數值。
168 liveuser 1052
	$conf["fileAccess::checkMultiFileExist"]["fileArray"]=array("/var/log/httpd/ssl_access_log");
3 liveuser 1053
	#$conf["fileArgu"],字串,php變數__FILE__的內容,亦即該檔案在檔案系統的絕對路徑
168 liveuser 1054
	$conf["fileAccess::checkMultiFileExist"]["fileArgu"]=__FILE__;
3 liveuser 1055
	#可省略參數:
1056
	#$conf["disableWebSearch"],"字串",是否取消「當檔案找不到時,改用catchWebContent類別的wget函數來檢查檔案是否存在於網路上」的功能,"false"不取消,若要取消該功能請設為"true",若抓到的內容為空字串則會視為檔案不存在,預設為"true".
1057
	#$conf["disableWebSearch"]="false";
1058
	#$conf["userDir"],字串,網頁是否置放於家目錄底下,"true"為是,"false"為不是,預設為"true".
168 liveuser 1059
	$conf["fileAccess::checkMultiFileExist"]["userDir"]="false";
3 liveuser 1060
	#$conf["web"],字串,檔案是放在web就是"true",反之為檔案系統"false",預設為"true".
168 liveuser 1061
	$conf["fileAccess::checkMultiFileExist"]["web"]="false";
3 liveuser 1062
	#參考資料:
1063
	#http://php.net/manual/en/function.file-exists.php
1064
	#http://php.net/manual/en/control-structures.foreach.php
1065
	#備註:
1066
	#函數file_exists檢查的路徑為檔案系統的路徑
1067
	#$result["varName"][$i]結果未實作
168 liveuser 1068
	$checkMultiFileExist=fileAccess::checkMultiFileExist($conf["fileAccess::checkMultiFileExist"]);
1069
	unset($conf["fileAccess::checkMultiFileExist"]);
3 liveuser 1070
 
1071
	#如果運行失敗
1072
	if($checkMultiFileExist["status"]==="false"){
1073
 
1074
		#設置執行失敗
1075
		$result["status"]="false";
1076
 
1077
		#設置錯誤訊息
1078
		$result["error"]=$checkMultiFileExist;
1079
 
1080
		#印出結果
1081
		var_dump($checkMultiFileExist);
1082
 
1083
		#結束執行
1084
		exit(1);
1085
 
1086
		}#if end
168 liveuser 1087
 
3 liveuser 1088
	#如果存在 https log
1089
	if($checkMultiFileExist["allExist"]==="true"){
1090
 
168 liveuser 1091
		#函式說明:
1092
		#呼叫shell執行系統命令,並取得回傳的內容.
3 liveuser 1093
		#回傳結果:
168 liveuser 1094
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
3 liveuser 1095
		#$result["error"],錯誤訊息陣列.
168 liveuser 1096
		#$result["function"],當前執行的函數名稱.
1097
		#$result["argu"],使用的參數.
1098
		#$result["cmd"],執行的指令內容.
1099
		#$result["fullCmd"],如果參數 $conf["inBackGround"] 為 "true" 則會回傳該值.
1100
		#$result["output"],爲執行完後的輸出陣列,若 $conf["inBackGround"] 為 "true",則為當下的輸出.
1101
		#$result["content"],為執行完後的輸出字串.
1102
		#$result["tmpFileOutput"],儲存輸出的暫存檔案名稱,若 $conf["inBackGround"] 為 "true" 則會回傳該值.
1103
		#$result["running"],是否還在執行.
1104
		#$result["pid"],pid.
1105
		#$result["statusCode"],執行結束後的代碼.
1106
		#$result["escape"],陣列,儲存重新排序過且已經escape過的指令(key為"cmd")與參數(key為"argu")與兩者組合的一維陣列(key為"array").
1107
		#$result["noEcaped"],陣列,儲存重新排序過未經過escape過的指令(key為"cmd")與參數(key為"argu")與兩者組合的一維陣列(key為"array").
3 liveuser 1108
		#必填參數:
168 liveuser 1109
		#$conf["command"],字串,要執行的指令.
1110
		$conf["external::callShell"]["command"]="tail";
1111
		#$conf["fileArgu"],字串,變數__FILE__的內容.
1112
		$conf["external::callShell"]["fileArgu"]=__FILE__;
1113
		#可省略參數:
1114
		#$conf["argu"],陣列字串,指令搭配的參數,預設為空陣列.
1115
		$conf["external::callShell"]["argu"]=array("-n","1","/var/log/httpd/ssl_access_log");
1116
		#$conf["arguIsAddr"],陣列字串,指令搭配的哪些參數為路徑,為路徑的參數會進行轉換以便符合呼叫當前函數的位置,預設不指定,若有3個參數,其中第3個參數為路徑,則表示為array("false","false","true").
1117
		#$conf["arguIsAddr"]=array();
1118
		#$conf["pre"],陣列,要在本指令前執行的每個指令與參數.
1119
		#$conf["pre"][$i]["cmd"],字串,要在本指令前執行的第$i+1個指令.
1120
		#$conf["pre"][$i]["param"],陣列字串,要在本指令前執行的第$i+1個指令的參數.
1121
		#$conf["enablePrintDescription"],字串,是否要印出$conf["printDescription"]的內容,"true"代表要,"false"代表不要,預設為"false".
1122
		#$conf["enablePrintDescription"]="true";
1123
		#$conf["printDescription"],字串,執行該外部程式前要印出來的的文字,預設為$conf["command"]的內容加上使用的$conf["argu"]參數.
1124
		#$conf["printDescription"]="";
1125
		#$conf["escapeshellarg"],字串,是否要啟用過濾參數,用了比較安全,但可能會出錯,"true"為啟用,"false"為不啟用,預設為"false".如果參數為"< 、<< 、> 、>> 、| 、2>&1"之一則不會過濾.
1126
		$conf["external::callShell"]["escapeshellarg"]="true";
1127
		#$conf["thereIsShellVar"],陣列字串,指令搭配的參數"argu",若含有「\'」,則取代為「"」.每個argu參數都要有對應的元素."true"代表要置換.
1128
		#$conf["thereIsShellVar"]=array();
1129
		#$conf["username"],字串,要用什麼使用者來執行,預設為執行php的使用者,該參數不適用於apache環境.
1130
		#$conf["username"]="";
1131
		#$conf["password"],字串,root的使用者密碼,預設不使用密碼,該參數不適用於apache環境.
1132
		#$conf["password"]="";	
1133
		#$conf["useScript"],字串,是否要啟用Linux的script指令來記錄輸出,"true"代表要,Fedora的selinux會擋住該操作;"false"代表不要,預設為"false".
1134
		#$conf["useScript"]="";
1135
		#$conf["logFilePath"],字串,當 $conf["useScript"] 為 "true" 時,輸出的內容要暫存到哪裡,預設為 "/tmp/.qbpwcf_tmp/external/callShell/".
1136
		#$conf["logFilePath"]=".qbpwcf_tmp/external/callShell/";
1137
		#$conf["inBackGround"],字串,是否要在背景執行,且不會等待程式執行結束再執行下一個指令,"true"代表是,"false"代表不要,預設為"false",如果$conf["command"]有用「;」區隔的多個指令將會出錯.
1138
		#$conf["inBackGround"]="";
1139
		#$conf["getErr"],字串,"true"代表將錯誤輸出變成標準輸出,反之"false"為不變動.
1140
		#$conf["getErr"]="false";
1141
		#$conf["doNotRun"],字串,"true"代表不執行指令,預設為"false"會執行指令.
1142
		#$conf["doNotRun"]="false";
1143
		#參考資料:
1144
		#exec=>http://php.net/manual/en/function.exec.php
1145
		#escapeshellcmd=>http://php.net/manual/en/function.escapeshellcmd.php
1146
		#escapeshellarg=>http://php.net/manual/en/function.escapeshellarg.php
1147
		#備註:
1148
		#不是所有指令都能用apache的身份執行,目前已知java,javac指令無法執行,使用root身份可能會被selinux阻擋.
1149
		#若使用的 command、argu 參數,含有 ~ 則會被視為字串,若有需要其於 shell 中代表的家目錄位置,可用 fileAccess::tildeToPath 來進行轉換.
1150
		$callShell=external::callShell($conf["external::callShell"]);
1151
		unset($conf["external::callShell"]);
3 liveuser 1152
 
168 liveuser 1153
		#如果執行異常
1154
		if($callShell["status"]==="false"){
1155
 
1156
			#debug
1157
			var_dump($callShell);
1158
 
1159
			#結束並回傳代表1,表示異常
3 liveuser 1160
			exit(1);
1161
 
1162
			}#if end
168 liveuser 1163
 
1164
		#如果輸出有一行
1165
		if(count($callShell["output"])===1){
1166
 
1167
			#debug
1168
			if($debug){
1169
 
1170
				#標題提示
1171
				echo "最新一筆log".PHP_EOL;
1172
 
1173
				#印出log
1174
				echo $callShell["output"][0].PHP_EOL;
1175
 
1176
				}#if end
1177
 
1178
			#範例log
1179
			#193.42.43.36 - - [30/Sep/2025:13:15:04 +0800] "GET / HTTP/2.0" 200 138772
1180
			#${ip} ${doNotNeed} [${day}/${month}/${year}:${hour}:${min}:${sec} ${timezone}] ${method} ${path} ${protocol} ${responseCode} ${bytesSend}
1181
 
1182
			#解析時間
1183
			#函式說明:
1184
			#尋找字串中是否含有符合格式的內容,且回傳解析好的變數數值.
1185
			#回傳結果:
1186
			#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
1187
			#$reuslt["error"],執行不正常結束的錯訊息陣列.
1188
			#$result["function"],當前執行的函式名稱.
1189
			#$result["argu"],所使用的參數.
1190
			#$result["found"],是否有找到符合格式的字串內容,"true"代表有找到,"false"代表沒有找到.
1191
			#$result["content"],陣列,若為n個${*},則當found為"true"時,就會回傳n個元素.
1192
			#$result["parsedVar"][varName],陣列,解析好的變數陣列,varName為${}中的內容.
1193
			#必填參數:
1194
			#$conf["input"],字串,要檢查的字串.
1195
			$conf["input"]=$callShell["output"][0];
1196
			#$conf["format"],格式字串,要尋找的格式字串.格式為固定的字串("fixedStr format")與變數("${keyWordVarName}")組成.
1197
			$conf["format"]="\${ip} \${doNotNeed} [\${day}/\${month}/\${year}:\${hour}:\${min}:\${sec} \${timezone}] \${method} \${path} \${protocol} \${responseCode} \${bytesSend}";
1198
			#可省略參數:
1199
			#$conf["varEqual"],陣列,變數對應的數值,null代表不指定,其他內容代表該變數解析出來必須要為該內容.
1200
			#$conf["varEqual"]=array(null,"found");
1201
			#$conf["varCon"],陣列,每個varEqual為null者,其是否有其他條件,預設為null代表無其他條件,條件的表示是用陣列的key與value來表達,例如:array("no_tail"=>" not"),就代表變數的結尾不能為" not",可以用的key有"head",代表開頭要有什麼;"no_head",代表不能為什麼開頭;"tail",代表要什麼結尾;"no_tail",代表不能什麼結尾.
1202
			#$conf["varCon"]=array("no_tail"=>" not");
1203
			#參考資料:
1204
			#無.
1205
			#備註:
1206
			#無.
1207
			$findSpecifyStrFormat=search::findSpecifyStrFormat($conf);
1208
			unset($conf);
1209
 
1210
			#如果執行異常
1211
			if($findSpecifyStrFormat["status"]==="false"){
1212
 
1213
				#debug
1214
				var_dump($findSpecifyStrFormat);
1215
 
1216
				#結束並回傳代表1,表示異常
1217
				exit(1);
1218
 
1219
				}#if end
1220
 
1221
			#如果格式有符合
1222
			if($findSpecifyStrFormat["found"]==="true"){
1223
 
1224
				#記錄 http log 的最後變更時間
1225
				$httpsTimeFloat=strtotime($findSpecifyStrFormat["parsedVar"]["month"][0]." ".$findSpecifyStrFormat["parsedVar"]["day"][0]." ".$findSpecifyStrFormat["parsedVar"]["hour"][0].":".$findSpecifyStrFormat["parsedVar"]["min"][0].":".$findSpecifyStrFormat["parsedVar"]["sec"][0]);
1226
 
1227
				}#if end
1228
 
1229
			}#if end
3 liveuser 1230
 
168 liveuser 1231
		#反之沒變動
1232
		else{
1233
 
1234
			#沿用上次時間
1235
			$httpsTimeFloat=$params["info"]["preTimeFloat"]["https"];
1236
 
1237
			}#else ebd
1238
 
3 liveuser 1239
		#debug
1240
		if($debug){
1241
 
1242
			#comment
1243
			echo "accessed file /var/log/httpd/ssl_access_log".PHP_EOL;
1244
 
1245
			}#if end
168 liveuser 1246
 
3 liveuser 1247
		}#if end
1248
 
1249
	#透過運行以下指令取得最後變更時間
168 liveuser 1250
	#journalctl -a -e --unit=postfix.service | tail -n 1;
3 liveuser 1251
	#涵式說明:
1252
	#呼叫shell執行系統命令,並取得回傳的內容.
1253
	#回傳的結果:
1254
	#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
1255
	#$result["error"],錯誤訊息陣列.
1256
	#$result["function"],當前執行的函數名稱.
1257
	#$result["argu"],使用的參數.
1258
	#$result["cmd"],執行的指令內容.
1259
	#$result["fullCmd"],如果參數 $conf["inBackGround"] 為 "true" 則會回傳該值.
1260
	#$result["output"],爲執行完二元碼後的輸出陣列,若 $conf["inBackGround"] 為 "true",則為當下的輸出.
1261
	#$result["tmpFileOutput"],儲存輸出的暫存檔案名稱,若 $conf["inBackGround"] 為 "true" 則會回傳該值.
1262
	#$result["running"],是否還在執行.
1263
	#$result["pid"],pid.
1264
	#$result["statusCode"],執行結束後的代碼.
1265
	#必填的參數
1266
	#$conf["command"],字串,要執行的指令與.
1267
	$conf["external::callShell"]["command"]="journalctl";
1268
	#$conf["fileArgu"],字串,變數__FILE__的內容.
168 liveuser 1269
	$conf["external::callShell"]["fileArgu"]=__FILE__;
3 liveuser 1270
	#可省略參數:
1271
	#$conf["argu"],陣列字串,指令搭配的參數,預設為空陣列.
168 liveuser 1272
	$conf["external::callShell"]["argu"]=array("-a","-e","--unit=postfix.service","|","tail","-n","1");
3 liveuser 1273
	#$conf["arguIsAddr"],陣列字串,指令搭配的哪些參數為路徑,為路徑的參數會進行轉換以便符合呼叫當前函數的位置,預設不指定,若有3個參數,其中第3個參數為路徑,則表示為array("false","false","true").
1274
	#$conf["arguIsAddr"]=array();	
1275
	#$conf["pre"],陣列,要在本指令前執行的每個指令與參數.
1276
	#$conf["pre"][$i]["cmd"],字串,要在本指令前執行的第$i+1個指令.
1277
	#$conf["pre"][$i]["param"],陣列字串,要在本指令前執行的第$i+1個指令的參數.
1278
	#$conf["enablePrintDescription"],字串,是否要印出$conf["printDescription"]的內容,"true"代表要,"false"代表不要,預設為"false".
1279
	#$conf["enablePrintDescription"]="true";
1280
	#$conf["printDescription"],字串,執行該外部程式前要印出來的的文字,預設為$conf["command"]的內容加上使用的$conf["argu"]參數.
1281
	#$conf["printDescription"]="";
1282
	#$conf["escapeshellarg"],字串,是否要啟用過濾參數,用了比較安全,但可能會出錯,"true"為啟用,"false"為不啟用,預設為"false".
1283
	$conf["external::callShell"]["escapeshellarg"]="true";
1284
	#$conf["username"],字串,要用什麼使用者來執行,預設為執行php的使用者,該參數不適用於apache環境.
1285
	#$conf["username"]="";
1286
	#$conf["password"],字串,root的使用者密碼,預設不使用密碼,該參數不適用於apache環境.
1287
	#$conf["password"]="";
1288
	#$conf["useScript"],字串,是否要啟用Linux的script指令來記錄輸出,"true"代表要,Fedora的selinux會擋住該操作;"false"代表不要,預設為"false".
1289
	#$conf["useScript"]="";
1290
	#$conf["logFilePath"],字串,當 $conf["useScript"] 為 "true" 時,輸出的內容要暫存到哪裡,預設為 "/tmp/.qbpwcf_tmp/external/callShell/".
1291
	#$conf["logFilePath"]=".qbpwcf_tmp/external/callShell/";
1292
	#$conf["inBackGround"],字串,是否要在背景執行,且不會等待程式執行結束再執行下一個指令,"true"代表是,"false"代表不要,預設為"false",如果$conf["command"]有用「;」區隔的多個指令將會出錯.
1293
	#$conf["inBackGround"]="";
1294
	#$conf["getErr"],字串,"true"代表將錯誤輸出變成標準輸出,反之"false"為不變動.
1295
	#$conf["getErr"]="false";
1296
	#備註:
1297
	#不是所有指令都能用apache的身份執行,目前已知java,javac指令無法執行,使用root身份可能會被selinux阻擋.
1298
	#參考資料:
1299
	#exec=>http://php.net/manual/en/function.exec.php
1300
	#escapeshellcmd=>http://php.net/manual/en/function.escapeshellcmd.php
1301
	#escapeshellarg=>http://php.net/manual/en/function.escapeshellarg.php
1302
	$callShell=external::callShell($conf["external::callShell"]);
1303
	unset($conf["external::callShell"]);
1304
 
1305
	#如果執行失敗
1306
	if($callShell["status"]==="false"){
1307
 
1308
		#設置執行失敗
1309
		$result["status"]="false";
1310
 
1311
		#設置錯誤訊息
1312
		$result["error"]=$callShell;
1313
 
1314
		#回傳結果
1315
		var_dump($result);
1316
 
1317
		#結束執行
1318
		exit(1);
1319
 
1320
		}#if end
1321
 
1322
	#debug
1323
	if($debug){
1324
 
1325
		#comment
1326
		echo "accessed file postfix/smtp log".PHP_EOL;
1327
 
1328
		}#if end
1329
 
1330
	#取得行數
1331
	$lineCount=count($callShell["output"]);
1332
 
168 liveuser 1333
	#函式說明:
1334
	#多層if判斷.
1335
	#回傳結果:
1336
	#$result["status"],字串,"true"代表執行正常;"false"代表執行異常.
1337
	#$result["function"],當前函式的名稱.
1338
	#$result["pass"],字串,"true"代表通過多層if判斷;反之為"false".
1339
	#必填參數:
1340
	#$conf["get_defined_vars"],陣列,所有已經定義的變數.
1341
	$conf["controlStructures::nestedIf"]["get_defined_vars"]=get_defined_vars();
1342
	#$conf["varToControlLeft"],變數陣列,依照順序每層要做判斷的變數.
196 liveuser 1343
	$conf["controlStructures::nestedIf"]["varToControlLeft"]=array("lineCount",array("callShell","output",0));
168 liveuser 1344
	#$conf["conditions"],字串陣列,依照順序每層變數判斷的條件,例如">","<",">=","<=","!=","==","<==","!==","===".
1345
	$conf["controlStructures::nestedIf"]["conditions"]=array("===","!==");
1346
	#$conf["varToControlRight"],變數陣列,依照順序每層變數判斷期望的結果.
1347
	$conf["controlStructures::nestedIf"]["varToControlRight"]=array(1,"-- No entries --");
1348
	#可省略參數:
1349
	#無.
1350
	#參考資料:
1351
	#無.
1352
	#備註:
1353
	#無.
1354
	$nestedIf=controlStructures::nestedIf($conf["controlStructures::nestedIf"]);
1355
	unset($conf["controlStructures::nestedIf"]);
1356
 
1357
	#如果執行異常
1358
	if($nestedIf["status"]==="false"){
3 liveuser 1359
 
168 liveuser 1360
		#設置執行異常
1361
		$result["status"]="false";
1362
 
1363
		#設置執行錯誤
1364
		$result["error"]=$nestedIf;
1365
 
1366
		#回傳結果
1367
		return $result;
1368
 
1369
		}#if end
1370
 
1371
	#如果不通過判斷
1372
	if($nestedIf["pass"]==="false"){
1373
 
1374
		#沿用上次時間
1375
		$smtpTimeFloat=$params["info"]["preTimeFloat"]["smtp"];
1376
 
1377
		}#if end
1378
 
1379
	#反之
1380
	else{
1381
 
3 liveuser 1382
		#debug
1383
		if($debug){
1384
 
168 liveuser 1385
			#標題提示
1386
			echo "最新一筆log".PHP_EOL;
3 liveuser 1387
 
168 liveuser 1388
			#印出log
1389
			echo $callShell["output"][0].PHP_EOL;
1390
 
3 liveuser 1391
			}#if end
1392
 
1393
		#Aug 09 07:12:09 www.qbpwcf.org postfix/smtpd[20829]: connect from unknown[185.234.219.62]
1394
		#Apr 04 15:11:16 mail.qbpwcf.org postfix/smtps/smtpd[10145]: connect from unknown[212.70.149.72]
168 liveuser 1395
		#${month} ${day} ${hour}:${min}:${sec} ${doNotNeed}"
3 liveuser 1396
 
168 liveuser 1397
		#解析時間點
1398
		#函式說明:
1399
		#尋找字串中是否含有符合格式的內容,且回傳解析好的變數數值.
1400
		#回傳結果:
1401
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
1402
		#$reuslt["error"],執行不正常結束的錯訊息陣列.
1403
		#$result["function"],當前執行的函式名稱.
1404
		#$result["argu"],所使用的參數.
1405
		#$result["found"],是否有找到符合格式的字串內容,"true"代表有找到,"false"代表沒有找到.
1406
		#$result["content"],陣列,若為n個${*},則當found為"true"時,就會回傳n個元素.
1407
		#$result["parsedVar"][varName],陣列,解析好的變數陣列,varName為${}中的內容.
1408
		#必填參數:
1409
		#$conf["input"],字串,要檢查的字串.
1410
		$conf["search::findSpecifyStrFormat"]["input"]=$callShell["output"][0];
1411
		#$conf["format"],格式字串,要尋找的格式字串.格式為固定的字串("fixedStr format")與變數("${keyWordVarName}")組成.
1412
		$conf["search::findSpecifyStrFormat"]["format"]="\${month} \${day} \${hour}:\${min}:\${sec} \${doNotNeed}";
1413
		#可省略參數:
1414
		#$conf["varEqual"],陣列,變數對應的數值,null代表不指定,其他內容代表該變數解析出來必須要為該內容.
1415
		#$conf["varEqual"]=array(null,"found");
1416
		#$conf["varCon"],陣列,每個varEqual為null者,其是否有其他條件,預設為null代表無其他條件,條件的表示是用陣列的key與value來表達,例如:array("no_tail"=>" not"),就代表變數的結尾不能為" not",可以用的key有"head",代表開頭要有什麼;"no_head",代表不能為什麼開頭;"tail",代表要什麼結尾;"no_tail",代表不能什麼結尾.
1417
		#$conf["varCon"]=array("no_tail"=>" not");
1418
		#參考資料:
1419
		#無.
1420
		#備註:
1421
		#無.
1422
		$findSpecifyStrFormat=search::findSpecifyStrFormat($conf["search::findSpecifyStrFormat"]);
1423
		unset($conf["search::findSpecifyStrFormat"]);
3 liveuser 1424
 
168 liveuser 1425
		#如果執行失敗
1426
		if($findSpecifyStrFormat["status"]==="false"){
3 liveuser 1427
 
1428
			#設置執行失敗
1429
			$result["status"]="false";
1430
 
1431
			#設置錯誤訊息
168 liveuser 1432
			$result["error"]=$findSpecifyStrFormat;
3 liveuser 1433
 
168 liveuser 1434
			#回傳結果
3 liveuser 1435
			var_dump($result);
1436
 
168 liveuser 1437
			#結束執行
3 liveuser 1438
			exit(1);
1439
 
1440
			}#if end
168 liveuser 1441
 
1442
		#如果log沒有時間戳記
1443
		if($findSpecifyStrFormat["found"]==="false"){
3 liveuser 1444
 
168 liveuser 1445
			#設置執行失敗
1446
			$result["status"]="false";
1447
 
1448
			#設置錯誤訊息
1449
			$result["error"]=$findSpecifyStrFormat;
1450
 
1451
			#回傳結果
1452
			var_dump($result);
1453
 
1454
			#結束執行
1455
			exit(1);
1456
 
1457
			}#if end
1458
 
3 liveuser 1459
		#記錄 smtpd log 最後變更的時間
168 liveuser 1460
		$smtpTimeFloat=strtotime($findSpecifyStrFormat["parsedVar"]["month"][0]." ".$findSpecifyStrFormat["parsedVar"]["day"][0]." ".$findSpecifyStrFormat["parsedVar"]["hour"][0].":".$findSpecifyStrFormat["parsedVar"]["min"][0].":".$findSpecifyStrFormat["parsedVar"]["sec"][0]);
3 liveuser 1461
 
168 liveuser 1462
		}#if end
3 liveuser 1463
 
1464
	#透過運行以下指令取得最後變更時間
168 liveuser 1465
	#journalctl -a -e --unit=dovecot.service | tail -n 1
3 liveuser 1466
	#涵式說明:
1467
	#呼叫shell執行系統命令,並取得回傳的內容.
1468
	#回傳的結果:
1469
	#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
1470
	#$result["error"],錯誤訊息陣列.
1471
	#$result["function"],當前執行的函數名稱.
1472
	#$result["argu"],使用的參數.
1473
	#$result["cmd"],執行的指令內容.
1474
	#$result["fullCmd"],如果參數 $conf["inBackGround"] 為 "true" 則會回傳該值.
1475
	#$result["output"],爲執行完二元碼後的輸出陣列,若 $conf["inBackGround"] 為 "true",則為當下的輸出.
1476
	#$result["tmpFileOutput"],儲存輸出的暫存檔案名稱,若 $conf["inBackGround"] 為 "true" 則會回傳該值.
1477
	#$result["running"],是否還在執行.
1478
	#$result["pid"],pid.
1479
	#$result["statusCode"],執行結束後的代碼.
1480
	#必填的參數
1481
	#$conf["command"],字串,要執行的指令與.
1482
	$conf["external::callShell"]["command"]="journalctl";
1483
	#$conf["fileArgu"],字串,變數__FILE__的內容.
168 liveuser 1484
	$conf["external::callShell"]["fileArgu"]=__FILE__;
3 liveuser 1485
	#可省略參數:
1486
	#$conf["argu"],陣列字串,指令搭配的參數,預設為空陣列.
168 liveuser 1487
	$conf["external::callShell"]["argu"]=array("-a","-e","--unit=dovecot.service","|","tail","-n","1");
3 liveuser 1488
	#$conf["arguIsAddr"],陣列字串,指令搭配的哪些參數為路徑,為路徑的參數會進行轉換以便符合呼叫當前函數的位置,預設不指定,若有3個參數,其中第3個參數為路徑,則表示為array("false","false","true").
1489
	#$conf["arguIsAddr"]=array();	
1490
	#$conf["pre"],陣列,要在本指令前執行的每個指令與參數.
1491
	#$conf["pre"][$i]["cmd"],字串,要在本指令前執行的第$i+1個指令.
1492
	#$conf["pre"][$i]["param"],陣列字串,要在本指令前執行的第$i+1個指令的參數.
1493
	#$conf["enablePrintDescription"],字串,是否要印出$conf["printDescription"]的內容,"true"代表要,"false"代表不要,預設為"false".
1494
	#$conf["enablePrintDescription"]="true";
1495
	#$conf["printDescription"],字串,執行該外部程式前要印出來的的文字,預設為$conf["command"]的內容加上使用的$conf["argu"]參數.
1496
	#$conf["printDescription"]="";
1497
	#$conf["escapeshellarg"],字串,是否要啟用過濾參數,用了比較安全,但可能會出錯,"true"為啟用,"false"為不啟用,預設為"false".
1498
	$conf["external::callShell"]["escapeshellarg"]="true";
1499
	#$conf["username"],字串,要用什麼使用者來執行,預設為執行php的使用者,該參數不適用於apache環境.
1500
	#$conf["username"]="";
1501
	#$conf["password"],字串,root的使用者密碼,預設不使用密碼,該參數不適用於apache環境.
1502
	#$conf["password"]="";
1503
	#$conf["useScript"],字串,是否要啟用Linux的script指令來記錄輸出,"true"代表要,Fedora的selinux會擋住該操作;"false"代表不要,預設為"false".
1504
	#$conf["useScript"]="";
1505
	#$conf["logFilePath"],字串,當 $conf["useScript"] 為 "true" 時,輸出的內容要暫存到哪裡,預設為 "/tmp/.qbpwcf_tmp/external/callShell/".
1506
	#$conf["logFilePath"]=".qbpwcf_tmp/external/callShell/";
1507
	#$conf["inBackGround"],字串,是否要在背景執行,且不會等待程式執行結束再執行下一個指令,"true"代表是,"false"代表不要,預設為"false",如果$conf["command"]有用「;」區隔的多個指令將會出錯.
1508
	#$conf["inBackGround"]="";
1509
	#$conf["getErr"],字串,"true"代表將錯誤輸出變成標準輸出,反之"false"為不變動.
1510
	#$conf["getErr"]="false";
1511
	#備註:
1512
	#不是所有指令都能用apache的身份執行,目前已知java,javac指令無法執行,使用root身份可能會被selinux阻擋.
1513
	#參考資料:
1514
	#exec=>http://php.net/manual/en/function.exec.php
1515
	#escapeshellcmd=>http://php.net/manual/en/function.escapeshellcmd.php
1516
	#escapeshellarg=>http://php.net/manual/en/function.escapeshellarg.php
1517
	$callShell=external::callShell($conf["external::callShell"]);
1518
	unset($conf["external::callShell"]);
1519
 
1520
	#如果執行失敗
1521
	if($callShell["status"]==="false"){
1522
 
1523
		#設置執行失敗
1524
		$result["status"]="false";
1525
 
1526
		#設置錯誤訊息
1527
		$result["error"]=$callShell;
1528
 
1529
		#回傳結果
1530
		var_dump($result);
1531
 
1532
		#結束執行
1533
		exit(1);
1534
 
1535
		}#if end
1536
 
1537
	#debug
1538
	if($debug){
1539
 
1540
		#comment
1541
		echo "accessed file dovecot/imap log".PHP_EOL;
1542
 
1543
		}#if end
1544
 
1545
	#取得行數
1546
	$lineCount=count($callShell["output"]);
1547
 
168 liveuser 1548
	#函式說明:
1549
	#多層if判斷.
1550
	#回傳結果:
1551
	#$result["status"],字串,"true"代表執行正常;"false"代表執行異常.
1552
	#$result["function"],當前函式的名稱.
1553
	#$result["pass"],字串,"true"代表通過多層if判斷;反之為"false".
1554
	#必填參數:
1555
	#$conf["get_defined_vars"],陣列,所有已經定義的變數.
1556
	$conf["controlStructures::nestedIf"]["get_defined_vars"]=get_defined_vars();
1557
	#$conf["varToControlLeft"],變數陣列,依照順序每層要做判斷的變數.
196 liveuser 1558
	$conf["controlStructures::nestedIf"]["varToControlLeft"]=array("lineCount",array("callShell","output",0));
168 liveuser 1559
	#$conf["conditions"],字串陣列,依照順序每層變數判斷的條件,例如">","<",">=","<=","!=","==","<==","!==","===".
1560
	$conf["controlStructures::nestedIf"]["conditions"]=array("===","!==");
1561
	#$conf["varToControlRight"],變數陣列,依照順序每層變數判斷期望的結果.
1562
	$conf["controlStructures::nestedIf"]["varToControlRight"]=array(1,"-- No entries --");
1563
	#可省略參數:
1564
	#無.
1565
	#參考資料:
1566
	#無.
1567
	#備註:
1568
	#無.
1569
	$nestedIf=controlStructures::nestedIf($conf["controlStructures::nestedIf"]);
1570
	unset($conf["controlStructures::nestedIf"]);
1571
 
1572
	#如果執行異常
1573
	if($nestedIf["status"]==="false"){
3 liveuser 1574
 
168 liveuser 1575
		#設置執行異常
1576
		$result["status"]="false";
1577
 
1578
		#設置執行錯誤
1579
		$result["error"]=$nestedIf;
1580
 
1581
		#回傳結果
1582
		return $result;
1583
 
1584
		}#if end
1585
 
1586
	#如果不通過判斷
1587
	if($nestedIf["pass"]==="false"){
1588
 
1589
		#沿用上次時間
1590
		$imapTimeFloat=$params["info"]["preTimeFloat"]["imap"];
1591
 
1592
		}#if end
1593
 
1594
	#反之
1595
	else{
1596
 
3 liveuser 1597
		#debug
1598
		if($debug){
1599
 
168 liveuser 1600
			#標題提示
1601
			echo "最新一筆log".PHP_EOL;
3 liveuser 1602
 
168 liveuser 1603
			#印出log
1604
			echo $callShell["output"][0].PHP_EOL;
1605
 
3 liveuser 1606
			}#if end
1607
 
1608
		#Feb 23 07:44:29 localhost.localdomain dovecot[1427]: imap-login: Disconnected (no auth attempts in 0 secs): user=<>, rip=101.136.215.61, lip=169.254.1.1, TLS handshaking: SSL_accept() failed: error:14094416:SSL routines:ssl3_read_bytes:sslv3 alert certificate unknown: SSL alert number 46, session=<9oMMYvW7ihhliNc9>
168 liveuser 1609
		#${month} ${day} ${hour}:${min}:${sec} ${doNotNeed}"
3 liveuser 1610
 
168 liveuser 1611
		#解析時間點
1612
		#函式說明:
1613
		#尋找字串中是否含有符合格式的內容,且回傳解析好的變數數值.
1614
		#回傳結果:
1615
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
1616
		#$reuslt["error"],執行不正常結束的錯訊息陣列.
1617
		#$result["function"],當前執行的函式名稱.
1618
		#$result["argu"],所使用的參數.
1619
		#$result["found"],是否有找到符合格式的字串內容,"true"代表有找到,"false"代表沒有找到.
1620
		#$result["content"],陣列,若為n個${*},則當found為"true"時,就會回傳n個元素.
1621
		#$result["parsedVar"][varName],陣列,解析好的變數陣列,varName為${}中的內容.
1622
		#必填參數:
1623
		#$conf["input"],字串,要檢查的字串.
1624
		$conf["search::findSpecifyStrFormat"]["input"]=$callShell["output"][0];
1625
		#$conf["format"],格式字串,要尋找的格式字串.格式為固定的字串("fixedStr format")與變數("${keyWordVarName}")組成.
1626
		$conf["search::findSpecifyStrFormat"]["format"]="\${month} \${day} \${hour}:\${min}:\${sec} \${doNotNeed}";
1627
		#可省略參數:
1628
		#$conf["varEqual"],陣列,變數對應的數值,null代表不指定,其他內容代表該變數解析出來必須要為該內容.
1629
		#$conf["varEqual"]=array(null,"found");
1630
		#$conf["varCon"],陣列,每個varEqual為null者,其是否有其他條件,預設為null代表無其他條件,條件的表示是用陣列的key與value來表達,例如:array("no_tail"=>" not"),就代表變數的結尾不能為" not",可以用的key有"head",代表開頭要有什麼;"no_head",代表不能為什麼開頭;"tail",代表要什麼結尾;"no_tail",代表不能什麼結尾.
1631
		#$conf["varCon"]=array("no_tail"=>" not");
1632
		#參考資料:
1633
		#無.
1634
		#備註:
1635
		#無.
1636
		$findSpecifyStrFormat=search::findSpecifyStrFormat($conf["search::findSpecifyStrFormat"]);
1637
		unset($conf["search::findSpecifyStrFormat"]);
3 liveuser 1638
 
168 liveuser 1639
		#如果執行失敗
1640
		if($findSpecifyStrFormat["status"]==="false"){
3 liveuser 1641
 
1642
			#設置執行失敗
1643
			$result["status"]="false";
1644
 
1645
			#設置錯誤訊息
168 liveuser 1646
			$result["error"]=$findSpecifyStrFormat;
3 liveuser 1647
 
168 liveuser 1648
			#回傳結果
3 liveuser 1649
			var_dump($result);
1650
 
168 liveuser 1651
			#結束執行
3 liveuser 1652
			exit(1);
1653
 
1654
			}#if end
1655
 
168 liveuser 1656
		#如果log沒有時間戳記
1657
		if($findSpecifyStrFormat["found"]==="false"){
3 liveuser 1658
 
168 liveuser 1659
			#設置執行失敗
1660
			$result["status"]="false";
1661
 
1662
			#設置錯誤訊息
1663
			$result["error"]=$findSpecifyStrFormat;
1664
 
1665
			#回傳結果
1666
			var_dump($result);
1667
 
1668
			#結束執行
1669
			exit(1);
1670
 
1671
			}#if end
3 liveuser 1672
 
168 liveuser 1673
		#記錄 dovecot log 最後變更的時間
1674
		$imapTimeFloat=strtotime($findSpecifyStrFormat["parsedVar"]["month"][0]." ".$findSpecifyStrFormat["parsedVar"]["day"][0]." ".$findSpecifyStrFormat["parsedVar"]["hour"][0].":".$findSpecifyStrFormat["parsedVar"]["min"][0].":".$findSpecifyStrFormat["parsedVar"]["sec"][0]);
3 liveuser 1675
 
168 liveuser 1676
		}#if end
3 liveuser 1677
 
168 liveuser 1678
	#透過 journalctl -a -e --unit=named.service | tail -n 1 來取得最後一筆 dns 查詢記錄
3 liveuser 1679
	#涵式說明:
1680
	#呼叫shell執行系統命令,並取得回傳的內容.
1681
	#回傳的結果:
1682
	#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
1683
	#$result["error"],錯誤訊息陣列.
1684
	#$result["function"],當前執行的函數名稱.
1685
	#$result["argu"],使用的參數.
1686
	#$result["cmd"],執行的指令內容.
1687
	#$result["fullCmd"],如果參數 $conf["inBackGround"] 為 "true" 則會回傳該值.
1688
	#$result["output"],爲執行完二元碼後的輸出陣列,若 $conf["inBackGround"] 為 "true",則為當下的輸出.
1689
	#$result["tmpFileOutput"],儲存輸出的暫存檔案名稱,若 $conf["inBackGround"] 為 "true" 則會回傳該值.
1690
	#$result["running"],是否還在執行.
1691
	#$result["pid"],pid.
1692
	#$result["statusCode"],執行結束後的代碼.
1693
	#必填的參數
1694
	#$conf["command"],字串,要執行的指令與.
1695
	$conf["external::callShell"]["command"]="journalctl";
1696
	#$conf["fileArgu"],字串,變數__FILE__的內容.
168 liveuser 1697
	$conf["external::callShell"]["fileArgu"]=__FILE__;
3 liveuser 1698
	#可省略參數:
1699
	#$conf["argu"],陣列字串,指令搭配的參數,預設為空陣列.
168 liveuser 1700
	$conf["external::callShell"]["argu"]=array("-a","-e","--unit=named.service","|","tail","-n","1");
3 liveuser 1701
	#$conf["arguIsAddr"],陣列字串,指令搭配的哪些參數為路徑,為路徑的參數會進行轉換以便符合呼叫當前函數的位置,預設不指定,若有3個參數,其中第3個參數為路徑,則表示為array("false","false","true").
1702
	#$conf["arguIsAddr"]=array();	
1703
	#$conf["pre"],陣列,要在本指令前執行的每個指令與參數.
1704
	#$conf["pre"][$i]["cmd"],字串,要在本指令前執行的第$i+1個指令.
1705
	#$conf["pre"][$i]["param"],陣列字串,要在本指令前執行的第$i+1個指令的參數.
1706
	#$conf["enablePrintDescription"],字串,是否要印出$conf["printDescription"]的內容,"true"代表要,"false"代表不要,預設為"false".
1707
	#$conf["enablePrintDescription"]="true";
1708
	#$conf["printDescription"],字串,執行該外部程式前要印出來的的文字,預設為$conf["command"]的內容加上使用的$conf["argu"]參數.
1709
	#$conf["printDescription"]="";
1710
	#$conf["escapeshellarg"],字串,是否要啟用過濾參數,用了比較安全,但可能會出錯,"true"為啟用,"false"為不啟用,預設為"false".
1711
	$conf["external::callShell"]["escapeshellarg"]="true";
1712
	#$conf["username"],字串,要用什麼使用者來執行,預設為執行php的使用者,該參數不適用於apache環境.
1713
	#$conf["username"]="";
1714
	#$conf["password"],字串,root的使用者密碼,預設不使用密碼,該參數不適用於apache環境.
1715
	#$conf["password"]="";
1716
	#$conf["useScript"],字串,是否要啟用Linux的script指令來記錄輸出,"true"代表要,Fedora的selinux會擋住該操作;"false"代表不要,預設為"false".
1717
	#$conf["useScript"]="";
1718
	#$conf["logFilePath"],字串,當 $conf["useScript"] 為 "true" 時,輸出的內容要暫存到哪裡,預設為 "/tmp/.qbpwcf_tmp/external/callShell/".
1719
	#$conf["logFilePath"]=".qbpwcf_tmp/external/callShell/";
1720
	#$conf["inBackGround"],字串,是否要在背景執行,且不會等待程式執行結束再執行下一個指令,"true"代表是,"false"代表不要,預設為"false",如果$conf["command"]有用「;」區隔的多個指令將會出錯.
1721
	#$conf["inBackGround"]="";
1722
	#$conf["getErr"],字串,"true"代表將錯誤輸出變成標準輸出,反之"false"為不變動.
1723
	#$conf["getErr"]="false";
1724
	#備註:
1725
	#不是所有指令都能用apache的身份執行,目前已知java,javac指令無法執行,使用root身份可能會被selinux阻擋.
1726
	#參考資料:
1727
	#exec=>http://php.net/manual/en/function.exec.php
1728
	#escapeshellcmd=>http://php.net/manual/en/function.escapeshellcmd.php
1729
	#escapeshellarg=>http://php.net/manual/en/function.escapeshellarg.php
1730
	$callShell=external::callShell($conf["external::callShell"]);
1731
	unset($conf["external::callShell"]);
1732
 
1733
	#如果執行失敗
1734
	if($callShell["status"]==="false"){
1735
 
1736
		#設置執行失敗
1737
		$result["status"]="false";
1738
 
1739
		#設置錯誤訊息
1740
		$result["error"]=$callShell;
1741
 
1742
		#回傳結果
1743
		var_dump($result);
1744
 
1745
		#結束執行
1746
		exit(1);
1747
 
1748
		}#if end
1749
 
1750
	#debug
1751
	if($debug){
1752
 
1753
		#comment
1754
		echo "accessed file named log".PHP_EOL;
1755
 
1756
		}#if end
1757
 
1758
	#取得行數
1759
	$lineCount=count($callShell["output"]);
1760
 
168 liveuser 1761
	#函式說明:
1762
	#多層if判斷.
1763
	#回傳結果:
1764
	#$result["status"],字串,"true"代表執行正常;"false"代表執行異常.
1765
	#$result["function"],當前函式的名稱.
1766
	#$result["pass"],字串,"true"代表通過多層if判斷;反之為"false".
1767
	#必填參數:
1768
	#$conf["get_defined_vars"],陣列,所有已經定義的變數.
1769
	$conf["controlStructures::nestedIf"]["get_defined_vars"]=get_defined_vars();
1770
	#$conf["varToControlLeft"],變數陣列,依照順序每層要做判斷的變數.
196 liveuser 1771
	$conf["controlStructures::nestedIf"]["varToControlLeft"]=array("lineCount",array("callShell","output",0));
168 liveuser 1772
	#$conf["conditions"],字串陣列,依照順序每層變數判斷的條件,例如">","<",">=","<=","!=","==","<==","!==","===".
1773
	$conf["controlStructures::nestedIf"]["conditions"]=array("===","!==");
1774
	#$conf["varToControlRight"],變數陣列,依照順序每層變數判斷期望的結果.
1775
	$conf["controlStructures::nestedIf"]["varToControlRight"]=array(1,"-- No entries --");
1776
	#可省略參數:
1777
	#無.
1778
	#參考資料:
1779
	#無.
1780
	#備註:
1781
	#無.
1782
	$nestedIf=controlStructures::nestedIf($conf["controlStructures::nestedIf"]);
1783
	unset($conf["controlStructures::nestedIf"]);
1784
 
1785
	#如果執行異常
1786
	if($nestedIf["status"]==="false"){
3 liveuser 1787
 
168 liveuser 1788
		#設置執行異常
1789
		$result["status"]="false";
1790
 
1791
		#設置執行錯誤
1792
		$result["error"]=$nestedIf;
1793
 
1794
		#回傳結果
1795
		return $result;
1796
 
1797
		}#if end
1798
 
1799
	#如果不通過判斷
1800
	if($nestedIf["pass"]==="false"){
1801
 
1802
		#沿用上次的時間
1803
		$namedTimeFloat=$params["info"]["preTimeFloat"]["named"];
1804
 
1805
		}#if end
1806
 
1807
	#反之
1808
	else{
1809
 
3 liveuser 1810
		#debug
1811
		if($debug){
1812
 
168 liveuser 1813
			#標題提示
1814
			echo "最新一筆log".PHP_EOL;
3 liveuser 1815
 
168 liveuser 1816
			#印出log
1817
			echo $callShell["output"][0].PHP_EOL;
1818
 
3 liveuser 1819
			}#if end
168 liveuser 1820
 
1821
		#Nov 24 20:55:15 localhost.localdomain named[99512]: client @0x7f7714041d10 191.7.219.100#6238 (PEACECORPS.GOV): query (cache) 'PEACECORPS.GOV/ANY/IN' denied
1822
		#${month} ${day} ${hour}:${min}:${sec} ${doNotNeed}
3 liveuser 1823
 
168 liveuser 1824
		#解析時間點
1825
		#函式說明:
1826
		#尋找字串中是否含有符合格式的內容,且回傳解析好的變數數值.
1827
		#回傳結果:
1828
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
1829
		#$reuslt["error"],執行不正常結束的錯訊息陣列.
1830
		#$result["function"],當前執行的函式名稱.
1831
		#$result["argu"],所使用的參數.
1832
		#$result["found"],是否有找到符合格式的字串內容,"true"代表有找到,"false"代表沒有找到.
1833
		#$result["content"],陣列,若為n個${*},則當found為"true"時,就會回傳n個元素.
1834
		#$result["parsedVar"][varName],陣列,解析好的變數陣列,varName為${}中的內容.
1835
		#必填參數:
1836
		#$conf["input"],字串,要檢查的字串.
1837
		$conf["search::findSpecifyStrFormat"]["input"]=$callShell["output"][0];
1838
		#$conf["format"],格式字串,要尋找的格式字串.格式為固定的字串("fixedStr format")與變數("${keyWordVarName}")組成.
1839
		$conf["search::findSpecifyStrFormat"]["format"]="\${month} \${day} \${hour}:\${min}:\${sec} \${doNotNeed}";
1840
		#可省略參數:
1841
		#$conf["varEqual"],陣列,變數對應的數值,null代表不指定,其他內容代表該變數解析出來必須要為該內容.
1842
		#$conf["varEqual"]=array(null,"found");
1843
		#$conf["varCon"],陣列,每個varEqual為null者,其是否有其他條件,預設為null代表無其他條件,條件的表示是用陣列的key與value來表達,例如:array("no_tail"=>" not"),就代表變數的結尾不能為" not",可以用的key有"head",代表開頭要有什麼;"no_head",代表不能為什麼開頭;"tail",代表要什麼結尾;"no_tail",代表不能什麼結尾.
1844
		#$conf["varCon"]=array("no_tail"=>" not");
1845
		#參考資料:
1846
		#無.
1847
		#備註:
1848
		#無.
1849
		$findSpecifyStrFormat=search::findSpecifyStrFormat($conf["search::findSpecifyStrFormat"]);
1850
		unset($conf["search::findSpecifyStrFormat"]);
3 liveuser 1851
 
168 liveuser 1852
		#如果執行失敗
1853
		if($findSpecifyStrFormat["status"]==="false"){
3 liveuser 1854
 
168 liveuser 1855
			#設置執行失敗
1856
			$result["status"]="false";
1857
 
1858
			#設置錯誤訊息
1859
			$result["error"]=$findSpecifyStrFormat;
1860
 
1861
			#回傳結果
1862
			var_dump($result);
1863
 
1864
			#結束執行
1865
			exit(1);
1866
 
1867
			}#if end
1868
 
1869
		#如果log沒有時間戳記
1870
		if($findSpecifyStrFormat["found"]==="false"){
3 liveuser 1871
 
1872
			#設置執行失敗
1873
			$result["status"]="false";
1874
 
1875
			#設置錯誤訊息
168 liveuser 1876
			$result["error"]=$findSpecifyStrFormat;
3 liveuser 1877
 
168 liveuser 1878
			#回傳結果
3 liveuser 1879
			var_dump($result);
1880
 
168 liveuser 1881
			#結束執行
3 liveuser 1882
			exit(1);
1883
 
1884
			}#if end
168 liveuser 1885
 
3 liveuser 1886
		#記錄 named log 最後變更的時間
168 liveuser 1887
		$namedTimeFloat=strtotime($findSpecifyStrFormat["parsedVar"]["month"][0]." ".$findSpecifyStrFormat["parsedVar"]["day"][0]." ".$findSpecifyStrFormat["parsedVar"]["hour"][0].":".$findSpecifyStrFormat["parsedVar"]["min"][0].":".$findSpecifyStrFormat["parsedVar"]["sec"][0]);
3 liveuser 1888
 
168 liveuser 1889
		}#else end
1890
 
1891
	#透過 journalctl -a -e --unit=sshd.service | tail -n 1 來取得最後一筆 dns 查詢記錄
1892
	#涵式說明:
1893
	#呼叫shell執行系統命令,並取得回傳的內容.
1894
	#回傳的結果:
1895
	#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
1896
	#$result["error"],錯誤訊息陣列.
1897
	#$result["function"],當前執行的函數名稱.
1898
	#$result["argu"],使用的參數.
1899
	#$result["cmd"],執行的指令內容.
1900
	#$result["fullCmd"],如果參數 $conf["inBackGround"] 為 "true" 則會回傳該值.
1901
	#$result["output"],爲執行完二元碼後的輸出陣列,若 $conf["inBackGround"] 為 "true",則為當下的輸出.
1902
	#$result["tmpFileOutput"],儲存輸出的暫存檔案名稱,若 $conf["inBackGround"] 為 "true" 則會回傳該值.
1903
	#$result["running"],是否還在執行.
1904
	#$result["pid"],pid.
1905
	#$result["statusCode"],執行結束後的代碼.
1906
	#必填的參數
1907
	#$conf["command"],字串,要執行的指令與.
1908
	$conf["external::callShell"]["command"]="journalctl";
1909
	#$conf["fileArgu"],字串,變數__FILE__的內容.
1910
	$conf["external::callShell"]["fileArgu"]=__FILE__;
1911
	#可省略參數:
1912
	#$conf["argu"],陣列字串,指令搭配的參數,預設為空陣列.
1913
	$conf["external::callShell"]["argu"]=array("-a","-e","--unit=sshd.service","|","tail","-n","1");
1914
	#$conf["arguIsAddr"],陣列字串,指令搭配的哪些參數為路徑,為路徑的參數會進行轉換以便符合呼叫當前函數的位置,預設不指定,若有3個參數,其中第3個參數為路徑,則表示為array("false","false","true").
1915
	#$conf["arguIsAddr"]=array();	
1916
	#$conf["pre"],陣列,要在本指令前執行的每個指令與參數.
1917
	#$conf["pre"][$i]["cmd"],字串,要在本指令前執行的第$i+1個指令.
1918
	#$conf["pre"][$i]["param"],陣列字串,要在本指令前執行的第$i+1個指令的參數.
1919
	#$conf["enablePrintDescription"],字串,是否要印出$conf["printDescription"]的內容,"true"代表要,"false"代表不要,預設為"false".
1920
	#$conf["enablePrintDescription"]="true";
1921
	#$conf["printDescription"],字串,執行該外部程式前要印出來的的文字,預設為$conf["command"]的內容加上使用的$conf["argu"]參數.
1922
	#$conf["printDescription"]="";
1923
	#$conf["escapeshellarg"],字串,是否要啟用過濾參數,用了比較安全,但可能會出錯,"true"為啟用,"false"為不啟用,預設為"false".
1924
	$conf["external::callShell"]["escapeshellarg"]="true";
1925
	#$conf["username"],字串,要用什麼使用者來執行,預設為執行php的使用者,該參數不適用於apache環境.
1926
	#$conf["username"]="";
1927
	#$conf["password"],字串,root的使用者密碼,預設不使用密碼,該參數不適用於apache環境.
1928
	#$conf["password"]="";
1929
	#$conf["useScript"],字串,是否要啟用Linux的script指令來記錄輸出,"true"代表要,Fedora的selinux會擋住該操作;"false"代表不要,預設為"false".
1930
	#$conf["useScript"]="";
1931
	#$conf["logFilePath"],字串,當 $conf["useScript"] 為 "true" 時,輸出的內容要暫存到哪裡,預設為 "/tmp/.qbpwcf_tmp/external/callShell/".
1932
	#$conf["logFilePath"]=".qbpwcf_tmp/external/callShell/";
1933
	#$conf["inBackGround"],字串,是否要在背景執行,且不會等待程式執行結束再執行下一個指令,"true"代表是,"false"代表不要,預設為"false",如果$conf["command"]有用「;」區隔的多個指令將會出錯.
1934
	#$conf["inBackGround"]="";
1935
	#$conf["getErr"],字串,"true"代表將錯誤輸出變成標準輸出,反之"false"為不變動.
1936
	#$conf["getErr"]="false";
1937
	#備註:
1938
	#不是所有指令都能用apache的身份執行,目前已知java,javac指令無法執行,使用root身份可能會被selinux阻擋.
1939
	#參考資料:
1940
	#exec=>http://php.net/manual/en/function.exec.php
1941
	#escapeshellcmd=>http://php.net/manual/en/function.escapeshellcmd.php
1942
	#escapeshellarg=>http://php.net/manual/en/function.escapeshellarg.php
1943
	$callShell=external::callShell($conf["external::callShell"]);
1944
	unset($conf["external::callShell"]);
1945
 
1946
	#如果執行失敗
1947
	if($callShell["status"]==="false"){
1948
 
1949
		#設置執行失敗
1950
		$result["status"]="false";
1951
 
1952
		#設置錯誤訊息
1953
		$result["error"]=$callShell;
1954
 
1955
		#回傳結果
1956
		var_dump($result);
1957
 
1958
		#結束執行
1959
		exit(1);
1960
 
3 liveuser 1961
		}#if end
168 liveuser 1962
 
1963
	#debug
1964
	if($debug){
3 liveuser 1965
 
168 liveuser 1966
		#comment
1967
		echo "accessed sshd log".PHP_EOL;
1968
 
1969
		}#if end
1970
 
1971
	#取得行數
1972
	$lineCount=count($callShell["output"]);
1973
 
190 liveuser 1974
	#debug
1975
	#var_dump(__LINE__,get_defined_vars()["lineCount"],get_defined_vars()["callShell"]["output"]);
1976
 
168 liveuser 1977
	#函式說明:
1978
	#多層if判斷.
1979
	#回傳結果:
1980
	#$result["status"],字串,"true"代表執行正常;"false"代表執行異常.
1981
	#$result["function"],當前函式的名稱.
1982
	#$result["pass"],字串,"true"代表通過多層if判斷;反之為"false".
1983
	#必填參數:
1984
	#$conf["get_defined_vars"],陣列,所有已經定義的變數.
1985
	$conf["controlStructures::nestedIf"]["get_defined_vars"]=get_defined_vars();
1986
	#$conf["varToControlLeft"],變數陣列,依照順序每層要做判斷的變數.
196 liveuser 1987
	$conf["controlStructures::nestedIf"]["varToControlLeft"]=array("lineCount",array("callShell","output",0));
168 liveuser 1988
	#$conf["conditions"],字串陣列,依照順序每層變數判斷的條件,例如">","<",">=","<=","!=","==","<==","!==","===".
1989
	$conf["controlStructures::nestedIf"]["conditions"]=array("===","!==");
1990
	#$conf["varToControlRight"],變數陣列,依照順序每層變數判斷期望的結果.
1991
	$conf["controlStructures::nestedIf"]["varToControlRight"]=array(1,"-- No entries --");
1992
	#可省略參數:
1993
	#無.
1994
	#參考資料:
1995
	#無.
1996
	#備註:
1997
	#無.
1998
	$nestedIf=controlStructures::nestedIf($conf["controlStructures::nestedIf"]);
1999
	unset($conf["controlStructures::nestedIf"]);
190 liveuser 2000
 
168 liveuser 2001
	#如果執行異常
2002
	if($nestedIf["status"]==="false"){
2003
 
2004
		#設置執行異常
2005
		$result["status"]="false";
2006
 
2007
		#設置執行錯誤
2008
		$result["error"]=$nestedIf;
2009
 
2010
		#回傳結果
2011
		return $result;
2012
 
2013
		}#if end
190 liveuser 2014
 
2015
	#debug
2016
	#var_dump(__LINE__,$nestedIf["pass"]);
168 liveuser 2017
 
2018
	#如果不通過判斷
2019
	if($nestedIf["pass"]==="false"){
2020
 
190 liveuser 2021
		#debug
2022
		var_dump(__LINE__,$nestedIf["reason"]);
2023
 
168 liveuser 2024
		#沿用上次的時間
2025
		$sshdTimeFloat=$params["info"]["preTimeFloat"]["sshd"];
2026
 
2027
		}#if end
2028
 
2029
	#反之
3 liveuser 2030
	else{
168 liveuser 2031
 
2032
		#debug
2033
		if($debug){
2034
 
2035
			#標題提示
2036
			echo "最新一筆log".PHP_EOL;
2037
 
2038
			#印出log
2039
			echo $callShell["output"][0].PHP_EOL;
2040
 
2041
			}#if end
2042
 
2043
		#Sep 30 00:36:36 silverblue-guest.qbpwcf.org sshd-session[1607010]: Invalid user lizepeng from 60.213.10.69 port 39156
2044
		#${month} ${day} ${hour}:${min}:${sec} ${doNotNeed}
2045
 
2046
		#解析時間點
2047
		#函式說明:
2048
		#尋找字串中是否含有符合格式的內容,且回傳解析好的變數數值.
2049
		#回傳結果:
2050
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
2051
		#$reuslt["error"],執行不正常結束的錯訊息陣列.
2052
		#$result["function"],當前執行的函式名稱.
2053
		#$result["argu"],所使用的參數.
2054
		#$result["found"],是否有找到符合格式的字串內容,"true"代表有找到,"false"代表沒有找到.
2055
		#$result["content"],陣列,若為n個${*},則當found為"true"時,就會回傳n個元素.
2056
		#$result["parsedVar"][varName],陣列,解析好的變數陣列,varName為${}中的內容.
2057
		#必填參數:
2058
		#$conf["input"],字串,要檢查的字串.
2059
		$conf["search::findSpecifyStrFormat"]["input"]=$callShell["output"][0];
2060
		#$conf["format"],格式字串,要尋找的格式字串.格式為固定的字串("fixedStr format")與變數("${keyWordVarName}")組成.
2061
		$conf["search::findSpecifyStrFormat"]["format"]="\${month} \${day} \${hour}:\${min}:\${sec} \${doNotNeed}";
2062
		#可省略參數:
2063
		#$conf["varEqual"],陣列,變數對應的數值,null代表不指定,其他內容代表該變數解析出來必須要為該內容.
2064
		#$conf["varEqual"]=array(null,"found");
2065
		#$conf["varCon"],陣列,每個varEqual為null者,其是否有其他條件,預設為null代表無其他條件,條件的表示是用陣列的key與value來表達,例如:array("no_tail"=>" not"),就代表變數的結尾不能為" not",可以用的key有"head",代表開頭要有什麼;"no_head",代表不能為什麼開頭;"tail",代表要什麼結尾;"no_tail",代表不能什麼結尾.
2066
		#$conf["varCon"]=array("no_tail"=>" not");
2067
		#參考資料:
2068
		#無.
2069
		#備註:
2070
		#無.
2071
		$findSpecifyStrFormat=search::findSpecifyStrFormat($conf["search::findSpecifyStrFormat"]);
2072
		unset($conf["search::findSpecifyStrFormat"]);
2073
 
2074
		#如果執行失敗
2075
		if($findSpecifyStrFormat["status"]==="false"){
2076
 
2077
			#設置執行失敗
2078
			$result["status"]="false";
3 liveuser 2079
 
168 liveuser 2080
			#設置錯誤訊息
2081
			$result["error"]=$findSpecifyStrFormat;
2082
 
2083
			#回傳結果
2084
			var_dump($result);
2085
 
2086
			#結束執行
2087
			exit(1);
2088
 
2089
			}#if end
2090
 
2091
		#如果log沒有時間戳記
2092
		if($findSpecifyStrFormat["found"]==="false"){
2093
 
2094
			#設置執行失敗
2095
			$result["status"]="false";
2096
 
2097
			#設置錯誤訊息
2098
			$result["error"]=$findSpecifyStrFormat;
2099
 
2100
			#回傳結果
2101
			var_dump($result);
2102
 
2103
			#結束執行
2104
			exit(1);
2105
 
2106
			}#if end
2107
 
2108
		#記錄 sshd log 最後變更的時間
2109
		$sshdTimeFloat=strtotime($findSpecifyStrFormat["parsedVar"]["month"][0]." ".$findSpecifyStrFormat["parsedVar"]["day"][0]." ".$findSpecifyStrFormat["parsedVar"]["hour"][0].":".$findSpecifyStrFormat["parsedVar"]["min"][0].":".$findSpecifyStrFormat["parsedVar"]["sec"][0]);
2110
 
2111
		}#else end
3 liveuser 2112
 
2113
	#debug mode
2114
	if($debug){
2115
 
2116
		#comment
2117
		echo "\$httpTimeFloat:".$httpTimeFloat.PHP_EOL;
2118
		echo "\$httpsTimeFloat:".$httpsTimeFloat.PHP_EOL;
2119
		echo "\$smtpTimeFloat:".$smtpTimeFloat.PHP_EOL;
2120
		echo "\$imapTimeFloat:".$imapTimeFloat.PHP_EOL;
2121
		echo "\$namedTimeFloat:".$namedTimeFloat.PHP_EOL;
168 liveuser 2122
		echo "\$sshdTimeFloat:".$sshdTimeFloat.PHP_EOL;
3 liveuser 2123
 
2124
		}#if end
2125
 
2126
	#第一次運行,不做事.
2127
	if($params["info"]["preTimeFloat"]["http"]===0 && $params["info"]["preTimeFloat"]["https"]===0 && $params["info"]["preTimeFloat"]["smtp"]===0 && $params["info"]["preTimeFloat"]["imap"]===0 && $params["info"]["preTimeFloat"]["named"]===0){
2128
 
2129
		#將本次http記錄覆寫到上次的記錄
2130
		$params["info"]["preTimeFloat"]["http"]=$httpTimeFloat;
2131
 
2132
		#將本次https記錄覆寫到上次的記錄
2133
		$params["info"]["preTimeFloat"]["https"]=$httpsTimeFloat;
2134
 
2135
		#將本次smtps記錄覆寫到上次的記錄
2136
		$params["info"]["preTimeFloat"]["smtp"]=$smtpTimeFloat;
2137
 
2138
		#將本次imaps記錄覆寫到上次的記錄
2139
		$params["info"]["preTimeFloat"]["imap"]=$imapTimeFloat;
2140
 
2141
		#將本次nmaed記錄覆寫到上次的記錄
2142
		$params["info"]["preTimeFloat"]["named"]=$namedTimeFloat;
2143
 
168 liveuser 2144
		#將本次sshd記錄覆寫到上次的記錄
2145
		$params["info"]["preTimeFloat"]["sshd"]=$sshdTimeFloat;
2146
 
3 liveuser 2147
		#睡一秒
2148
		sleep(1);
2149
 
2150
		#debug mode
2151
		if($debug){
2152
 
2153
			#comment
2154
			echo "第一次運行,不做事".PHP_EOL;
2155
 
2156
			}#if end
2157
 
2158
		#結束執行
2159
		return;
2160
 
2161
		}#if end
2162
 
2163
	#非第一次運行,且 http 與 https 與 imap 與 smtp 與 named log 都沒變動過.
168 liveuser 2164
	else if($params["info"]["preTimeFloat"]["http"]===$httpTimeFloat && $params["info"]["preTimeFloat"]["https"]===$httpsTimeFloat && $params["info"]["preTimeFloat"]["smtp"]===$smtpTimeFloat && $params["info"]["preTimeFloat"]["imap"]===$imapTimeFloat && $params["info"]["preTimeFloat"]["named"]===$namedTimeFloat && $params["info"]["preTimeFloat"]["sshd"]===$sshdTimeFloat){
3 liveuser 2165
 
2166
		#睡一秒
2167
		sleep(1);
2168
 
2169
		#debug mode
2170
		if($debug){
2171
 
2172
			#comment
2173
			echo "Log檔無變動,不做事".PHP_EOL;
2174
 
2175
			}#if end
2176
 
2177
		#結束執行
2178
		return;
2179
 
2180
		}#else end
2181
 
2182
	#debug mode
2183
	if($debug){
2184
 
2185
		#comment
2186
		echo "Log檔有變動,要做事".PHP_EOL;
2187
		echo "\$preHttpTimeFloat:".$params["info"]["preTimeFloat"]["http"].PHP_EOL;
2188
		echo "\$preHttpsTimeFloat:".$params["info"]["preTimeFloat"]["https"].PHP_EOL;
2189
		echo "\$preSmtpTimeFloat:".$params["info"]["preTimeFloat"]["smtp"].PHP_EOL;
2190
		echo "\$preImapTimeFloat:".$params["info"]["preTimeFloat"]["imap"].PHP_EOL;
2191
		echo "\$preNamedTimeFloat:".$params["info"]["preTimeFloat"]["named"].PHP_EOL;
168 liveuser 2192
		echo "\$preSshdTimeFloat:".$params["info"]["preTimeFloat"]["sshd"].PHP_EOL;
3 liveuser 2193
		echo "\$httpTimeFloat:".$httpTimeFloat.PHP_EOL;
2194
		echo "\$httpsTimeFloat:".$httpsTimeFloat.PHP_EOL;
2195
		echo "\$smtpTimeFloat:".$smtpTimeFloat.PHP_EOL;
2196
		echo "\$imapTimeFloat:".$imapTimeFloat.PHP_EOL;
2197
		echo "\$namedTimeFloat:".$namedTimeFloat.PHP_EOL;
168 liveuser 2198
		echo "\$sshdTimeFloat:".$sshdTimeFloat.PHP_EOL;
3 liveuser 2199
 
2200
		}#if end
2201
 
2202
	#將本次http記錄覆寫到上次的記錄
2203
	$params["info"]["preTimeFloat"]["http"]=$httpTimeFloat;
2204
 
2205
	#將本次https記錄覆寫到上次的記錄
2206
	$params["info"]["preTimeFloat"]["https"]=$httpsTimeFloat;
2207
 
168 liveuser 2208
	#將本次smtp記錄覆寫到上次的記錄
2209
	$params["info"]["preTimeFloat"]["smtp"]=$smtpTimeFloat;
2210
 
2211
	#將本次imap記錄覆寫到上次的記錄
2212
	$params["info"]["preTimeFloat"]["imap"]=$imapTimeFloat;
2213
 
2214
	#將本次named記錄覆寫到上次的記錄
2215
	$params["info"]["preTimeFloat"]["named"]=$namedTimeFloat;
2216
 
2217
	#將本次sshd記錄覆寫到上次的記錄
2218
	$params["info"]["preTimeFloat"]["sshd"]=$sshdTimeFloat;
2219
 
3 liveuser 2220
	#初始化儲存暫時ip白名單的陣列
2221
	$excludeIpsTmp=array();
2222
 
2223
	#針對每個暫時白名單ip
2224
	foreach($params["info"]["excludeIpsTmp"] as $index=>$tmpIpInfo){
2225
 
2226
		#若暫存白名單已經過期
2227
		if($tmpIpInfo["unixtime"]<time()-$params["info"]["tmp-white-ip-valid-time"]*3600){
2228
 
2229
			#卸除之
2230
			unset($params["info"]["excludeIpsTmp"][$index]);
2231
 
2232
			}#if end
2233
 
2234
		#反之
2235
		else{
2236
 
168 liveuser 2237
			#變成 $excludeIpsTmp 的內容
3 liveuser 2238
			$excludeIpsTmp[]=$params["info"]["excludeIpsTmp"][$index]["ip"];
2239
 
2240
			}#else end
2241
 
2242
		}#foreach end
2243
 
2244
	#函式說明:
2245
	#將多個多維陣列串聯起來,key從0開始排序.
2246
	#回傳的結果:
2247
	#$result["status"],"true"表執行正常,"false"代表執行不正常.
2248
	#$result["error"],錯誤訊息陣列.
2249
	#$result["function"],當前執行的函數.
2250
	#$result["content"],合併好的一維陣列.
2251
	#必填參數
2252
	#$conf["inputArray"],陣列,要合併的一維陣列變數,例如:=array($array1,$array2);
168 liveuser 2253
	$conf["arrays::mergeMultiDimensionArray"]["inputArray"]=array($params["info"]["excludeIp"],$excludeIpsTmp);
3 liveuser 2254
	#可省略參數:
2255
	#$conf["allowRepeat"],字串,預設為"false",不允許重複的結果;反之為"true".
2256
	#$conf["allowRepeat"]="true";
2257
	#$conf["equalKeyStruc"],字串陣列,若 allowRepeat 參數為 "false", 這該參數生效.該參數為用來判斷每個陣列的哪個鍵值路徑底下的數值相同時要進行取代,後者會取代前者.
2258
	#$conf["equalKeyStruc"]=array();
2259
	#參考資料:
2260
	#無.
2261
	#備註:
2262
	#無.
168 liveuser 2263
	$mergeMultiDimensionArray=arrays::mergeMultiDimensionArray($conf["arrays::mergeMultiDimensionArray"]);
2264
	unset($conf["arrays::mergeMultiDimensionArray"]);
3 liveuser 2265
 
2266
	#如果執行失敗
2267
	if($mergeMultiDimensionArray["status"]==="false"){
2268
 
2269
		#設置執行失敗
2270
		$result["status"]="false";
2271
 
2272
		#設置錯誤訊息
2273
		$result["error"]=$mergeMultiDimensionArray;
2274
 
2275
		#回傳結果
2276
		var_dump($result);
2277
 
2278
		#結束執行
2279
		exit(1);
2280
 
2281
		}#if end
2282
 
2283
	#debug
2284
	#var_dump(__LINE__,$mergeMultiDimensionArray);
168 liveuser 2285
 
3 liveuser 2286
	#涵式說明:
168 liveuser 2287
	#檢查 httpd 與 postfix/smtpd 的 log 與 named 的 log 與 sshd 的 log 把惡意連線的 IP 用防火牆阻擋
3 liveuser 2288
	#回傳結果:
2289
	#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
2290
	#$result["error"],錯誤訊息.
2291
	#$result["function"],當前執行的函數名稱.
2292
	#$result["argu"],所使用的參數.
2293
	#$result["found"],是否有找到符合的檔案,"true"代表有;"false"代表沒有.
2294
	#$result["content"],找到的檔案陣列.
2295
	#必填參數:
2296
	#$conf["fileArgu"],字串,php變數__FILE__的內容,亦即該檔案在檔案系統的絕對路徑
168 liveuser 2297
	$conf["cmd::blockAcctackIp"]["fileArgu"]=__FILE__;
3 liveuser 2298
	#可省略參數:
2299
	#$conf["excludeIp"],字串陣列,白名單ip陣列.
168 liveuser 2300
	$conf["cmd::blockAcctackIp"]["excludeIp"]=$mergeMultiDimensionArray["content"];
3 liveuser 2301
	#$conf["logPath"],字串,httpd的log位置,預設為 "/var/log/httpd"
2302
	#$conf["logPath"]="";
2303
	#$conf["username"],字串,要用什麼使用者來執行,預設為root使用者
2304
	#$conf["username"]="";
2305
	#$conf["password"],字串,root使用者的密碼,
2306
	#$conf["password"]="";
2307
	#$conf["getIplistOnly"],字串,是否不阻擋IP只取得有問題的IP,預設為"false",要阻擋IP;"true"代表只取得有問題的IP.
2308
	#$conf["getIplistOnly"]="true";
168 liveuser 2309
	$blockAcctackIp=cmd::blockAcctackIp($conf["cmd::blockAcctackIp"]);
2310
	unset($conf["cmd::blockAcctackIp"]);
3 liveuser 2311
 
2312
	#如果執行失敗
2313
	if($blockAcctackIp["status"]==="false"){
2314
 
2315
		#設置執行失敗
2316
		$result["status"]="false";
2317
 
2318
		#設置錯誤訊息
2319
		$result["error"]=$blockAcctackIp;
2320
 
2321
		#印出結果
2322
		var_dump($result);
2323
 
2324
		#結束執行
2325
		exit(1);
2326
 
2327
		}#if end
2328
 
2329
	#如果有執行封鎖IP的情形
2330
	if(isset($blockAcctackIp["content"])){
2331
 
2332
		#comment
2333
		echo "本次封鎖IP的結果如下:".PHP_EOL;
2334
		var_dump($blockAcctackIp["content"]);
2335
		var_dump($blockAcctackIp["reason"]);
2336
 
2337
		}#if end
2338
 
2339
	#睡一秒
2340
	sleep(1);
2341
 
2342
	#結束執行
2343
	return;
2344
 
2345
	}//function funcToRunWhenIdle end
2346
 
2347
?>