Subversion Repositories php-qbpwcf

Rev

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