Subversion Repositories php-qbpwcf

Rev

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