Subversion Repositories php-qbpwcf

Rev

Rev 344 | Rev 368 | 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
333 liveuser 1079
 
1080
	#反之如果不存在 http 從 log 查出的存取時間
1081
	else if(!isset($httpTimeFloat)){
1082
 
1083
		#初始化為0
1084
		$httpTimeFloat=0;
1085
 
1086
		}#else end
3 liveuser 1087
 
1088
	#函式說明:
1089
	#檢查多個檔案與資料夾是否存在.
1090
	#回傳的結果:
1091
	#$result["status"],執行正常與否,"true"代表正常,"false"代表不正常.
1092
	#$result["error"],錯誤訊息陣列.
1093
	#$resutl["function"],當前執行的涵式名稱.
1094
	#$result["argu"],使用的參數.
1095
	#$result["allExist"],所有檔案皆存在的識別,"true"代表皆存在,"false"代表沒有全部都存在.
1096
	#$result["varName"][$i],爲第$i個資料夾或檔案的路徑與名稱。
1097
	#$result["varNameFullPath"][$i],爲第$i個資料夾或檔案的完整檔案系統路徑與名稱,如果不存在則代表路徑是網址.
1098
	#$result["varNameWebPath"][$i],為第$i個資料夾或檔案的網址,若"web"參數為"true",才會有該內容.
1099
	#$result["varExist"][$i],爲第$i個資料夾或檔案是否存在,"true"代表存在,"false"代表不存在。
1100
	#必填參數:
1101
	#$conf["fileArray"],陣列字串,要檢查是否存在的檔案有哪些,須爲一維陣列數值。
168 liveuser 1102
	$conf["fileAccess::checkMultiFileExist"]["fileArray"]=array("/var/log/httpd/ssl_access_log");
3 liveuser 1103
	#$conf["fileArgu"],字串,php變數__FILE__的內容,亦即該檔案在檔案系統的絕對路徑
168 liveuser 1104
	$conf["fileAccess::checkMultiFileExist"]["fileArgu"]=__FILE__;
3 liveuser 1105
	#可省略參數:
1106
	#$conf["disableWebSearch"],"字串",是否取消「當檔案找不到時,改用catchWebContent類別的wget函數來檢查檔案是否存在於網路上」的功能,"false"不取消,若要取消該功能請設為"true",若抓到的內容為空字串則會視為檔案不存在,預設為"true".
1107
	#$conf["disableWebSearch"]="false";
1108
	#$conf["userDir"],字串,網頁是否置放於家目錄底下,"true"為是,"false"為不是,預設為"true".
168 liveuser 1109
	$conf["fileAccess::checkMultiFileExist"]["userDir"]="false";
3 liveuser 1110
	#$conf["web"],字串,檔案是放在web就是"true",反之為檔案系統"false",預設為"true".
168 liveuser 1111
	$conf["fileAccess::checkMultiFileExist"]["web"]="false";
3 liveuser 1112
	#參考資料:
1113
	#http://php.net/manual/en/function.file-exists.php
1114
	#http://php.net/manual/en/control-structures.foreach.php
1115
	#備註:
1116
	#函數file_exists檢查的路徑為檔案系統的路徑
1117
	#$result["varName"][$i]結果未實作
168 liveuser 1118
	$checkMultiFileExist=fileAccess::checkMultiFileExist($conf["fileAccess::checkMultiFileExist"]);
1119
	unset($conf["fileAccess::checkMultiFileExist"]);
3 liveuser 1120
 
1121
	#如果運行失敗
1122
	if($checkMultiFileExist["status"]==="false"){
226 liveuser 1123
 
3 liveuser 1124
		#設置執行失敗
1125
		$result["status"]="false";
1126
 
1127
		#設置錯誤訊息
1128
		$result["error"]=$checkMultiFileExist;
1129
 
1130
		#印出結果
1131
		var_dump($checkMultiFileExist);
226 liveuser 1132
 
3 liveuser 1133
		#結束執行
1134
		exit(1);
226 liveuser 1135
 
3 liveuser 1136
		}#if end
226 liveuser 1137
 
3 liveuser 1138
	#如果存在 https log
1139
	if($checkMultiFileExist["allExist"]==="true"){
226 liveuser 1140
 
168 liveuser 1141
		#函式說明:
1142
		#呼叫shell執行系統命令,並取得回傳的內容.
3 liveuser 1143
		#回傳結果:
168 liveuser 1144
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
3 liveuser 1145
		#$result["error"],錯誤訊息陣列.
168 liveuser 1146
		#$result["function"],當前執行的函數名稱.
1147
		#$result["argu"],使用的參數.
1148
		#$result["cmd"],執行的指令內容.
1149
		#$result["fullCmd"],如果參數 $conf["inBackGround"] 為 "true" 則會回傳該值.
1150
		#$result["output"],爲執行完後的輸出陣列,若 $conf["inBackGround"] 為 "true",則為當下的輸出.
1151
		#$result["content"],為執行完後的輸出字串.
1152
		#$result["tmpFileOutput"],儲存輸出的暫存檔案名稱,若 $conf["inBackGround"] 為 "true" 則會回傳該值.
1153
		#$result["running"],是否還在執行.
1154
		#$result["pid"],pid.
1155
		#$result["statusCode"],執行結束後的代碼.
1156
		#$result["escape"],陣列,儲存重新排序過且已經escape過的指令(key為"cmd")與參數(key為"argu")與兩者組合的一維陣列(key為"array").
1157
		#$result["noEcaped"],陣列,儲存重新排序過未經過escape過的指令(key為"cmd")與參數(key為"argu")與兩者組合的一維陣列(key為"array").
3 liveuser 1158
		#必填參數:
168 liveuser 1159
		#$conf["command"],字串,要執行的指令.
1160
		$conf["external::callShell"]["command"]="tail";
1161
		#$conf["fileArgu"],字串,變數__FILE__的內容.
1162
		$conf["external::callShell"]["fileArgu"]=__FILE__;
1163
		#可省略參數:
1164
		#$conf["argu"],陣列字串,指令搭配的參數,預設為空陣列.
1165
		$conf["external::callShell"]["argu"]=array("-n","1","/var/log/httpd/ssl_access_log");
1166
		#$conf["arguIsAddr"],陣列字串,指令搭配的哪些參數為路徑,為路徑的參數會進行轉換以便符合呼叫當前函數的位置,預設不指定,若有3個參數,其中第3個參數為路徑,則表示為array("false","false","true").
1167
		#$conf["arguIsAddr"]=array();
1168
		#$conf["pre"],陣列,要在本指令前執行的每個指令與參數.
1169
		#$conf["pre"][$i]["cmd"],字串,要在本指令前執行的第$i+1個指令.
1170
		#$conf["pre"][$i]["param"],陣列字串,要在本指令前執行的第$i+1個指令的參數.
1171
		#$conf["enablePrintDescription"],字串,是否要印出$conf["printDescription"]的內容,"true"代表要,"false"代表不要,預設為"false".
1172
		#$conf["enablePrintDescription"]="true";
1173
		#$conf["printDescription"],字串,執行該外部程式前要印出來的的文字,預設為$conf["command"]的內容加上使用的$conf["argu"]參數.
1174
		#$conf["printDescription"]="";
1175
		#$conf["escapeshellarg"],字串,是否要啟用過濾參數,用了比較安全,但可能會出錯,"true"為啟用,"false"為不啟用,預設為"false".如果參數為"< 、<< 、> 、>> 、| 、2>&1"之一則不會過濾.
1176
		$conf["external::callShell"]["escapeshellarg"]="true";
1177
		#$conf["thereIsShellVar"],陣列字串,指令搭配的參數"argu",若含有「\'」,則取代為「"」.每個argu參數都要有對應的元素."true"代表要置換.
1178
		#$conf["thereIsShellVar"]=array();
1179
		#$conf["username"],字串,要用什麼使用者來執行,預設為執行php的使用者,該參數不適用於apache環境.
1180
		#$conf["username"]="";
1181
		#$conf["password"],字串,root的使用者密碼,預設不使用密碼,該參數不適用於apache環境.
226 liveuser 1182
		#$conf["password"]="";
168 liveuser 1183
		#$conf["useScript"],字串,是否要啟用Linux的script指令來記錄輸出,"true"代表要,Fedora的selinux會擋住該操作;"false"代表不要,預設為"false".
1184
		#$conf["useScript"]="";
1185
		#$conf["logFilePath"],字串,當 $conf["useScript"] 為 "true" 時,輸出的內容要暫存到哪裡,預設為 "/tmp/.qbpwcf_tmp/external/callShell/".
1186
		#$conf["logFilePath"]=".qbpwcf_tmp/external/callShell/";
1187
		#$conf["inBackGround"],字串,是否要在背景執行,且不會等待程式執行結束再執行下一個指令,"true"代表是,"false"代表不要,預設為"false",如果$conf["command"]有用「;」區隔的多個指令將會出錯.
1188
		#$conf["inBackGround"]="";
1189
		#$conf["getErr"],字串,"true"代表將錯誤輸出變成標準輸出,反之"false"為不變動.
1190
		#$conf["getErr"]="false";
1191
		#$conf["doNotRun"],字串,"true"代表不執行指令,預設為"false"會執行指令.
1192
		#$conf["doNotRun"]="false";
1193
		#參考資料:
1194
		#exec=>http://php.net/manual/en/function.exec.php
1195
		#escapeshellcmd=>http://php.net/manual/en/function.escapeshellcmd.php
1196
		#escapeshellarg=>http://php.net/manual/en/function.escapeshellarg.php
1197
		#備註:
1198
		#不是所有指令都能用apache的身份執行,目前已知java,javac指令無法執行,使用root身份可能會被selinux阻擋.
1199
		#若使用的 command、argu 參數,含有 ~ 則會被視為字串,若有需要其於 shell 中代表的家目錄位置,可用 fileAccess::tildeToPath 來進行轉換.
1200
		$callShell=external::callShell($conf["external::callShell"]);
1201
		unset($conf["external::callShell"]);
226 liveuser 1202
 
168 liveuser 1203
		#如果執行異常
1204
		if($callShell["status"]==="false"){
226 liveuser 1205
 
168 liveuser 1206
			#debug
1207
			var_dump($callShell);
226 liveuser 1208
 
168 liveuser 1209
			#結束並回傳代表1,表示異常
3 liveuser 1210
			exit(1);
226 liveuser 1211
 
3 liveuser 1212
			}#if end
226 liveuser 1213
 
168 liveuser 1214
		#如果輸出有一行
1215
		if(count($callShell["output"])===1){
226 liveuser 1216
 
168 liveuser 1217
			#debug
1218
			if($debug){
226 liveuser 1219
 
168 liveuser 1220
				#標題提示
1221
				echo "最新一筆log".PHP_EOL;
226 liveuser 1222
 
168 liveuser 1223
				#印出log
1224
				echo $callShell["output"][0].PHP_EOL;
226 liveuser 1225
 
168 liveuser 1226
				}#if end
226 liveuser 1227
 
168 liveuser 1228
			#範例log
1229
			#193.42.43.36 - - [30/Sep/2025:13:15:04 +0800] "GET / HTTP/2.0" 200 138772
1230
			#${ip} ${doNotNeed} [${day}/${month}/${year}:${hour}:${min}:${sec} ${timezone}] ${method} ${path} ${protocol} ${responseCode} ${bytesSend}
226 liveuser 1231
 
168 liveuser 1232
			#解析時間
1233
			#函式說明:
1234
			#尋找字串中是否含有符合格式的內容,且回傳解析好的變數數值.
1235
			#回傳結果:
1236
			#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
1237
			#$reuslt["error"],執行不正常結束的錯訊息陣列.
1238
			#$result["function"],當前執行的函式名稱.
1239
			#$result["argu"],所使用的參數.
1240
			#$result["found"],是否有找到符合格式的字串內容,"true"代表有找到,"false"代表沒有找到.
1241
			#$result["content"],陣列,若為n個${*},則當found為"true"時,就會回傳n個元素.
1242
			#$result["parsedVar"][varName],陣列,解析好的變數陣列,varName為${}中的內容.
1243
			#必填參數:
1244
			#$conf["input"],字串,要檢查的字串.
1245
			$conf["input"]=$callShell["output"][0];
1246
			#$conf["format"],格式字串,要尋找的格式字串.格式為固定的字串("fixedStr format")與變數("${keyWordVarName}")組成.
1247
			$conf["format"]="\${ip} \${doNotNeed} [\${day}/\${month}/\${year}:\${hour}:\${min}:\${sec} \${timezone}] \${method} \${path} \${protocol} \${responseCode} \${bytesSend}";
1248
			#可省略參數:
1249
			#$conf["varEqual"],陣列,變數對應的數值,null代表不指定,其他內容代表該變數解析出來必須要為該內容.
1250
			#$conf["varEqual"]=array(null,"found");
1251
			#$conf["varCon"],陣列,每個varEqual為null者,其是否有其他條件,預設為null代表無其他條件,條件的表示是用陣列的key與value來表達,例如:array("no_tail"=>" not"),就代表變數的結尾不能為" not",可以用的key有"head",代表開頭要有什麼;"no_head",代表不能為什麼開頭;"tail",代表要什麼結尾;"no_tail",代表不能什麼結尾.
1252
			#$conf["varCon"]=array("no_tail"=>" not");
1253
			#參考資料:
1254
			#無.
1255
			#備註:
1256
			#無.
1257
			$findSpecifyStrFormat=search::findSpecifyStrFormat($conf);
1258
			unset($conf);
226 liveuser 1259
 
168 liveuser 1260
			#如果執行異常
1261
			if($findSpecifyStrFormat["status"]==="false"){
226 liveuser 1262
 
168 liveuser 1263
				#debug
1264
				var_dump($findSpecifyStrFormat);
226 liveuser 1265
 
168 liveuser 1266
				#結束並回傳代表1,表示異常
1267
				exit(1);
226 liveuser 1268
 
168 liveuser 1269
				}#if end
226 liveuser 1270
 
168 liveuser 1271
			#如果格式有符合
1272
			if($findSpecifyStrFormat["found"]==="true"){
226 liveuser 1273
 
168 liveuser 1274
				#記錄 http log 的最後變更時間
1275
				$httpsTimeFloat=strtotime($findSpecifyStrFormat["parsedVar"]["month"][0]." ".$findSpecifyStrFormat["parsedVar"]["day"][0]." ".$findSpecifyStrFormat["parsedVar"]["hour"][0].":".$findSpecifyStrFormat["parsedVar"]["min"][0].":".$findSpecifyStrFormat["parsedVar"]["sec"][0]);
226 liveuser 1276
 
168 liveuser 1277
				}#if end
226 liveuser 1278
 
168 liveuser 1279
			}#if end
3 liveuser 1280
 
168 liveuser 1281
		#反之沒變動
1282
		else{
226 liveuser 1283
 
168 liveuser 1284
			#沿用上次時間
1285
			$httpsTimeFloat=$params["info"]["preTimeFloat"]["https"];
226 liveuser 1286
 
168 liveuser 1287
			}#else ebd
1288
 
3 liveuser 1289
		#debug
1290
		if($debug){
226 liveuser 1291
 
3 liveuser 1292
			#comment
1293
			echo "accessed file /var/log/httpd/ssl_access_log".PHP_EOL;
226 liveuser 1294
 
3 liveuser 1295
			}#if end
226 liveuser 1296
 
3 liveuser 1297
		}#if end
333 liveuser 1298
 
1299
	#反之如果不存在 https 從 log 查出的存取時間
1300
	else if(!isset($httpsTimeFloat)){
1301
 
1302
		#初始化為0
1303
		$httpsTimeFloat=0;
1304
 
1305
		}#else end
226 liveuser 1306
 
3 liveuser 1307
	#透過運行以下指令取得最後變更時間
168 liveuser 1308
	#journalctl -a -e --unit=postfix.service | tail -n 1;
3 liveuser 1309
	#涵式說明:
1310
	#呼叫shell執行系統命令,並取得回傳的內容.
1311
	#回傳的結果:
1312
	#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
1313
	#$result["error"],錯誤訊息陣列.
1314
	#$result["function"],當前執行的函數名稱.
1315
	#$result["argu"],使用的參數.
1316
	#$result["cmd"],執行的指令內容.
1317
	#$result["fullCmd"],如果參數 $conf["inBackGround"] 為 "true" 則會回傳該值.
1318
	#$result["output"],爲執行完二元碼後的輸出陣列,若 $conf["inBackGround"] 為 "true",則為當下的輸出.
1319
	#$result["tmpFileOutput"],儲存輸出的暫存檔案名稱,若 $conf["inBackGround"] 為 "true" 則會回傳該值.
1320
	#$result["running"],是否還在執行.
1321
	#$result["pid"],pid.
1322
	#$result["statusCode"],執行結束後的代碼.
1323
	#必填的參數
1324
	#$conf["command"],字串,要執行的指令與.
1325
	$conf["external::callShell"]["command"]="journalctl";
1326
	#$conf["fileArgu"],字串,變數__FILE__的內容.
168 liveuser 1327
	$conf["external::callShell"]["fileArgu"]=__FILE__;
3 liveuser 1328
	#可省略參數:
1329
	#$conf["argu"],陣列字串,指令搭配的參數,預設為空陣列.
168 liveuser 1330
	$conf["external::callShell"]["argu"]=array("-a","-e","--unit=postfix.service","|","tail","-n","1");
3 liveuser 1331
	#$conf["arguIsAddr"],陣列字串,指令搭配的哪些參數為路徑,為路徑的參數會進行轉換以便符合呼叫當前函數的位置,預設不指定,若有3個參數,其中第3個參數為路徑,則表示為array("false","false","true").
226 liveuser 1332
	#$conf["arguIsAddr"]=array();
3 liveuser 1333
	#$conf["pre"],陣列,要在本指令前執行的每個指令與參數.
1334
	#$conf["pre"][$i]["cmd"],字串,要在本指令前執行的第$i+1個指令.
1335
	#$conf["pre"][$i]["param"],陣列字串,要在本指令前執行的第$i+1個指令的參數.
1336
	#$conf["enablePrintDescription"],字串,是否要印出$conf["printDescription"]的內容,"true"代表要,"false"代表不要,預設為"false".
1337
	#$conf["enablePrintDescription"]="true";
1338
	#$conf["printDescription"],字串,執行該外部程式前要印出來的的文字,預設為$conf["command"]的內容加上使用的$conf["argu"]參數.
1339
	#$conf["printDescription"]="";
1340
	#$conf["escapeshellarg"],字串,是否要啟用過濾參數,用了比較安全,但可能會出錯,"true"為啟用,"false"為不啟用,預設為"false".
1341
	$conf["external::callShell"]["escapeshellarg"]="true";
1342
	#$conf["username"],字串,要用什麼使用者來執行,預設為執行php的使用者,該參數不適用於apache環境.
1343
	#$conf["username"]="";
1344
	#$conf["password"],字串,root的使用者密碼,預設不使用密碼,該參數不適用於apache環境.
1345
	#$conf["password"]="";
1346
	#$conf["useScript"],字串,是否要啟用Linux的script指令來記錄輸出,"true"代表要,Fedora的selinux會擋住該操作;"false"代表不要,預設為"false".
1347
	#$conf["useScript"]="";
1348
	#$conf["logFilePath"],字串,當 $conf["useScript"] 為 "true" 時,輸出的內容要暫存到哪裡,預設為 "/tmp/.qbpwcf_tmp/external/callShell/".
1349
	#$conf["logFilePath"]=".qbpwcf_tmp/external/callShell/";
1350
	#$conf["inBackGround"],字串,是否要在背景執行,且不會等待程式執行結束再執行下一個指令,"true"代表是,"false"代表不要,預設為"false",如果$conf["command"]有用「;」區隔的多個指令將會出錯.
1351
	#$conf["inBackGround"]="";
1352
	#$conf["getErr"],字串,"true"代表將錯誤輸出變成標準輸出,反之"false"為不變動.
1353
	#$conf["getErr"]="false";
1354
	#備註:
1355
	#不是所有指令都能用apache的身份執行,目前已知java,javac指令無法執行,使用root身份可能會被selinux阻擋.
1356
	#參考資料:
1357
	#exec=>http://php.net/manual/en/function.exec.php
1358
	#escapeshellcmd=>http://php.net/manual/en/function.escapeshellcmd.php
1359
	#escapeshellarg=>http://php.net/manual/en/function.escapeshellarg.php
1360
	$callShell=external::callShell($conf["external::callShell"]);
1361
	unset($conf["external::callShell"]);
226 liveuser 1362
 
3 liveuser 1363
	#如果執行失敗
1364
	if($callShell["status"]==="false"){
226 liveuser 1365
 
3 liveuser 1366
		#設置執行失敗
1367
		$result["status"]="false";
1368
 
1369
		#設置錯誤訊息
1370
		$result["error"]=$callShell;
1371
 
1372
		#回傳結果
1373
		var_dump($result);
226 liveuser 1374
 
3 liveuser 1375
		#結束執行
1376
		exit(1);
226 liveuser 1377
 
3 liveuser 1378
		}#if end
226 liveuser 1379
 
3 liveuser 1380
	#debug
1381
	if($debug){
226 liveuser 1382
 
3 liveuser 1383
		#comment
1384
		echo "accessed file postfix/smtp log".PHP_EOL;
226 liveuser 1385
 
3 liveuser 1386
		}#if end
226 liveuser 1387
 
3 liveuser 1388
	#取得行數
1389
	$lineCount=count($callShell["output"]);
226 liveuser 1390
 
168 liveuser 1391
	#函式說明:
1392
	#多層if判斷.
1393
	#回傳結果:
1394
	#$result["status"],字串,"true"代表執行正常;"false"代表執行異常.
1395
	#$result["function"],當前函式的名稱.
1396
	#$result["pass"],字串,"true"代表通過多層if判斷;反之為"false".
1397
	#必填參數:
1398
	#$conf["get_defined_vars"],陣列,所有已經定義的變數.
1399
	$conf["controlStructures::nestedIf"]["get_defined_vars"]=get_defined_vars();
1400
	#$conf["varToControlLeft"],變數陣列,依照順序每層要做判斷的變數.
196 liveuser 1401
	$conf["controlStructures::nestedIf"]["varToControlLeft"]=array("lineCount",array("callShell","output",0));
168 liveuser 1402
	#$conf["conditions"],字串陣列,依照順序每層變數判斷的條件,例如">","<",">=","<=","!=","==","<==","!==","===".
1403
	$conf["controlStructures::nestedIf"]["conditions"]=array("===","!==");
1404
	#$conf["varToControlRight"],變數陣列,依照順序每層變數判斷期望的結果.
1405
	$conf["controlStructures::nestedIf"]["varToControlRight"]=array(1,"-- No entries --");
1406
	#可省略參數:
1407
	#無.
1408
	#參考資料:
1409
	#無.
1410
	#備註:
1411
	#無.
1412
	$nestedIf=controlStructures::nestedIf($conf["controlStructures::nestedIf"]);
1413
	unset($conf["controlStructures::nestedIf"]);
226 liveuser 1414
 
168 liveuser 1415
	#如果執行異常
1416
	if($nestedIf["status"]==="false"){
226 liveuser 1417
 
168 liveuser 1418
		#設置執行異常
1419
		$result["status"]="false";
226 liveuser 1420
 
168 liveuser 1421
		#設置執行錯誤
1422
		$result["error"]=$nestedIf;
226 liveuser 1423
 
168 liveuser 1424
		#回傳結果
1425
		return $result;
226 liveuser 1426
 
168 liveuser 1427
		}#if end
226 liveuser 1428
 
168 liveuser 1429
	#如果不通過判斷
1430
	if($nestedIf["pass"]==="false"){
226 liveuser 1431
 
168 liveuser 1432
		#沿用上次時間
1433
		$smtpTimeFloat=$params["info"]["preTimeFloat"]["smtp"];
226 liveuser 1434
 
168 liveuser 1435
		}#if end
226 liveuser 1436
 
168 liveuser 1437
	#反之
1438
	else{
1439
 
3 liveuser 1440
		#debug
1441
		if($debug){
226 liveuser 1442
 
168 liveuser 1443
			#標題提示
1444
			echo "最新一筆log".PHP_EOL;
226 liveuser 1445
 
168 liveuser 1446
			#印出log
1447
			echo $callShell["output"][0].PHP_EOL;
226 liveuser 1448
 
3 liveuser 1449
			}#if end
226 liveuser 1450
 
3 liveuser 1451
		#Aug 09 07:12:09 www.qbpwcf.org postfix/smtpd[20829]: connect from unknown[185.234.219.62]
1452
		#Apr 04 15:11:16 mail.qbpwcf.org postfix/smtps/smtpd[10145]: connect from unknown[212.70.149.72]
207 liveuser 1453
		#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 1454
		#${month} ${day} ${hour}:${min}:${sec} ${doNotNeed}"
226 liveuser 1455
 
168 liveuser 1456
		#解析時間點
1457
		#函式說明:
1458
		#尋找字串中是否含有符合格式的內容,且回傳解析好的變數數值.
1459
		#回傳結果:
1460
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
1461
		#$reuslt["error"],執行不正常結束的錯訊息陣列.
1462
		#$result["function"],當前執行的函式名稱.
1463
		#$result["argu"],所使用的參數.
1464
		#$result["found"],是否有找到符合格式的字串內容,"true"代表有找到,"false"代表沒有找到.
1465
		#$result["content"],陣列,若為n個${*},則當found為"true"時,就會回傳n個元素.
1466
		#$result["parsedVar"][varName],陣列,解析好的變數陣列,varName為${}中的內容.
1467
		#必填參數:
1468
		#$conf["input"],字串,要檢查的字串.
1469
		$conf["search::findSpecifyStrFormat"]["input"]=$callShell["output"][0];
1470
		#$conf["format"],格式字串,要尋找的格式字串.格式為固定的字串("fixedStr format")與變數("${keyWordVarName}")組成.
1471
		$conf["search::findSpecifyStrFormat"]["format"]="\${month} \${day} \${hour}:\${min}:\${sec} \${doNotNeed}";
1472
		#可省略參數:
1473
		#$conf["varEqual"],陣列,變數對應的數值,null代表不指定,其他內容代表該變數解析出來必須要為該內容.
1474
		#$conf["varEqual"]=array(null,"found");
1475
		#$conf["varCon"],陣列,每個varEqual為null者,其是否有其他條件,預設為null代表無其他條件,條件的表示是用陣列的key與value來表達,例如:array("no_tail"=>" not"),就代表變數的結尾不能為" not",可以用的key有"head",代表開頭要有什麼;"no_head",代表不能為什麼開頭;"tail",代表要什麼結尾;"no_tail",代表不能什麼結尾.
1476
		#$conf["varCon"]=array("no_tail"=>" not");
1477
		#參考資料:
1478
		#無.
1479
		#備註:
1480
		#無.
1481
		$findSpecifyStrFormat=search::findSpecifyStrFormat($conf["search::findSpecifyStrFormat"]);
1482
		unset($conf["search::findSpecifyStrFormat"]);
226 liveuser 1483
 
168 liveuser 1484
		#如果執行失敗
1485
		if($findSpecifyStrFormat["status"]==="false"){
226 liveuser 1486
 
3 liveuser 1487
			#設置執行失敗
1488
			$result["status"]="false";
1489
 
1490
			#設置錯誤訊息
168 liveuser 1491
			$result["error"]=$findSpecifyStrFormat;
3 liveuser 1492
 
168 liveuser 1493
			#回傳結果
3 liveuser 1494
			var_dump($result);
226 liveuser 1495
 
168 liveuser 1496
			#結束執行
3 liveuser 1497
			exit(1);
226 liveuser 1498
 
3 liveuser 1499
			}#if end
226 liveuser 1500
 
168 liveuser 1501
		#如果log沒有時間戳記
1502
		if($findSpecifyStrFormat["found"]==="false"){
226 liveuser 1503
 
168 liveuser 1504
			#設置執行失敗
1505
			$result["status"]="false";
1506
 
1507
			#設置錯誤訊息
1508
			$result["error"]=$findSpecifyStrFormat;
1509
 
1510
			#回傳結果
1511
			var_dump($result);
226 liveuser 1512
 
168 liveuser 1513
			#結束執行
1514
			exit(1);
226 liveuser 1515
 
168 liveuser 1516
			}#if end
226 liveuser 1517
 
3 liveuser 1518
		#記錄 smtpd log 最後變更的時間
168 liveuser 1519
		$smtpTimeFloat=strtotime($findSpecifyStrFormat["parsedVar"]["month"][0]." ".$findSpecifyStrFormat["parsedVar"]["day"][0]." ".$findSpecifyStrFormat["parsedVar"]["hour"][0].":".$findSpecifyStrFormat["parsedVar"]["min"][0].":".$findSpecifyStrFormat["parsedVar"]["sec"][0]);
226 liveuser 1520
 
344 liveuser 1521
		}#else end
333 liveuser 1522
 
344 liveuser 1523
	#如果不存在 smtp 從 log 查出的存取時間
1524
	if(!isset($smtpTimeFloat)){
333 liveuser 1525
 
1526
		#初始化為0
1527
		$smtpTimeFloat=0;
1528
 
1529
		}#else end
226 liveuser 1530
 
3 liveuser 1531
	#透過運行以下指令取得最後變更時間
168 liveuser 1532
	#journalctl -a -e --unit=dovecot.service | tail -n 1
3 liveuser 1533
	#涵式說明:
1534
	#呼叫shell執行系統命令,並取得回傳的內容.
1535
	#回傳的結果:
1536
	#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
1537
	#$result["error"],錯誤訊息陣列.
1538
	#$result["function"],當前執行的函數名稱.
1539
	#$result["argu"],使用的參數.
1540
	#$result["cmd"],執行的指令內容.
1541
	#$result["fullCmd"],如果參數 $conf["inBackGround"] 為 "true" 則會回傳該值.
1542
	#$result["output"],爲執行完二元碼後的輸出陣列,若 $conf["inBackGround"] 為 "true",則為當下的輸出.
1543
	#$result["tmpFileOutput"],儲存輸出的暫存檔案名稱,若 $conf["inBackGround"] 為 "true" 則會回傳該值.
1544
	#$result["running"],是否還在執行.
1545
	#$result["pid"],pid.
1546
	#$result["statusCode"],執行結束後的代碼.
1547
	#必填的參數
1548
	#$conf["command"],字串,要執行的指令與.
1549
	$conf["external::callShell"]["command"]="journalctl";
1550
	#$conf["fileArgu"],字串,變數__FILE__的內容.
168 liveuser 1551
	$conf["external::callShell"]["fileArgu"]=__FILE__;
3 liveuser 1552
	#可省略參數:
1553
	#$conf["argu"],陣列字串,指令搭配的參數,預設為空陣列.
168 liveuser 1554
	$conf["external::callShell"]["argu"]=array("-a","-e","--unit=dovecot.service","|","tail","-n","1");
3 liveuser 1555
	#$conf["arguIsAddr"],陣列字串,指令搭配的哪些參數為路徑,為路徑的參數會進行轉換以便符合呼叫當前函數的位置,預設不指定,若有3個參數,其中第3個參數為路徑,則表示為array("false","false","true").
226 liveuser 1556
	#$conf["arguIsAddr"]=array();
3 liveuser 1557
	#$conf["pre"],陣列,要在本指令前執行的每個指令與參數.
1558
	#$conf["pre"][$i]["cmd"],字串,要在本指令前執行的第$i+1個指令.
1559
	#$conf["pre"][$i]["param"],陣列字串,要在本指令前執行的第$i+1個指令的參數.
1560
	#$conf["enablePrintDescription"],字串,是否要印出$conf["printDescription"]的內容,"true"代表要,"false"代表不要,預設為"false".
1561
	#$conf["enablePrintDescription"]="true";
1562
	#$conf["printDescription"],字串,執行該外部程式前要印出來的的文字,預設為$conf["command"]的內容加上使用的$conf["argu"]參數.
1563
	#$conf["printDescription"]="";
1564
	#$conf["escapeshellarg"],字串,是否要啟用過濾參數,用了比較安全,但可能會出錯,"true"為啟用,"false"為不啟用,預設為"false".
1565
	$conf["external::callShell"]["escapeshellarg"]="true";
1566
	#$conf["username"],字串,要用什麼使用者來執行,預設為執行php的使用者,該參數不適用於apache環境.
1567
	#$conf["username"]="";
1568
	#$conf["password"],字串,root的使用者密碼,預設不使用密碼,該參數不適用於apache環境.
1569
	#$conf["password"]="";
1570
	#$conf["useScript"],字串,是否要啟用Linux的script指令來記錄輸出,"true"代表要,Fedora的selinux會擋住該操作;"false"代表不要,預設為"false".
1571
	#$conf["useScript"]="";
1572
	#$conf["logFilePath"],字串,當 $conf["useScript"] 為 "true" 時,輸出的內容要暫存到哪裡,預設為 "/tmp/.qbpwcf_tmp/external/callShell/".
1573
	#$conf["logFilePath"]=".qbpwcf_tmp/external/callShell/";
1574
	#$conf["inBackGround"],字串,是否要在背景執行,且不會等待程式執行結束再執行下一個指令,"true"代表是,"false"代表不要,預設為"false",如果$conf["command"]有用「;」區隔的多個指令將會出錯.
1575
	#$conf["inBackGround"]="";
1576
	#$conf["getErr"],字串,"true"代表將錯誤輸出變成標準輸出,反之"false"為不變動.
1577
	#$conf["getErr"]="false";
1578
	#備註:
1579
	#不是所有指令都能用apache的身份執行,目前已知java,javac指令無法執行,使用root身份可能會被selinux阻擋.
1580
	#參考資料:
1581
	#exec=>http://php.net/manual/en/function.exec.php
1582
	#escapeshellcmd=>http://php.net/manual/en/function.escapeshellcmd.php
1583
	#escapeshellarg=>http://php.net/manual/en/function.escapeshellarg.php
1584
	$callShell=external::callShell($conf["external::callShell"]);
1585
	unset($conf["external::callShell"]);
226 liveuser 1586
 
3 liveuser 1587
	#如果執行失敗
1588
	if($callShell["status"]==="false"){
226 liveuser 1589
 
3 liveuser 1590
		#設置執行失敗
1591
		$result["status"]="false";
1592
 
1593
		#設置錯誤訊息
1594
		$result["error"]=$callShell;
1595
 
1596
		#回傳結果
1597
		var_dump($result);
226 liveuser 1598
 
3 liveuser 1599
		#結束執行
1600
		exit(1);
226 liveuser 1601
 
3 liveuser 1602
		}#if end
226 liveuser 1603
 
3 liveuser 1604
	#debug
1605
	if($debug){
226 liveuser 1606
 
3 liveuser 1607
		#comment
1608
		echo "accessed file dovecot/imap log".PHP_EOL;
226 liveuser 1609
 
3 liveuser 1610
		}#if end
226 liveuser 1611
 
3 liveuser 1612
	#取得行數
1613
	$lineCount=count($callShell["output"]);
226 liveuser 1614
 
168 liveuser 1615
	#函式說明:
1616
	#多層if判斷.
1617
	#回傳結果:
1618
	#$result["status"],字串,"true"代表執行正常;"false"代表執行異常.
1619
	#$result["function"],當前函式的名稱.
1620
	#$result["pass"],字串,"true"代表通過多層if判斷;反之為"false".
1621
	#必填參數:
1622
	#$conf["get_defined_vars"],陣列,所有已經定義的變數.
1623
	$conf["controlStructures::nestedIf"]["get_defined_vars"]=get_defined_vars();
1624
	#$conf["varToControlLeft"],變數陣列,依照順序每層要做判斷的變數.
196 liveuser 1625
	$conf["controlStructures::nestedIf"]["varToControlLeft"]=array("lineCount",array("callShell","output",0));
168 liveuser 1626
	#$conf["conditions"],字串陣列,依照順序每層變數判斷的條件,例如">","<",">=","<=","!=","==","<==","!==","===".
1627
	$conf["controlStructures::nestedIf"]["conditions"]=array("===","!==");
1628
	#$conf["varToControlRight"],變數陣列,依照順序每層變數判斷期望的結果.
1629
	$conf["controlStructures::nestedIf"]["varToControlRight"]=array(1,"-- No entries --");
1630
	#可省略參數:
1631
	#無.
1632
	#參考資料:
1633
	#無.
1634
	#備註:
1635
	#無.
1636
	$nestedIf=controlStructures::nestedIf($conf["controlStructures::nestedIf"]);
1637
	unset($conf["controlStructures::nestedIf"]);
226 liveuser 1638
 
168 liveuser 1639
	#如果執行異常
1640
	if($nestedIf["status"]==="false"){
226 liveuser 1641
 
168 liveuser 1642
		#設置執行異常
1643
		$result["status"]="false";
226 liveuser 1644
 
168 liveuser 1645
		#設置執行錯誤
1646
		$result["error"]=$nestedIf;
226 liveuser 1647
 
168 liveuser 1648
		#回傳結果
1649
		return $result;
226 liveuser 1650
 
168 liveuser 1651
		}#if end
226 liveuser 1652
 
168 liveuser 1653
	#如果不通過判斷
1654
	if($nestedIf["pass"]==="false"){
226 liveuser 1655
 
168 liveuser 1656
		#沿用上次時間
1657
		$imapTimeFloat=$params["info"]["preTimeFloat"]["imap"];
226 liveuser 1658
 
168 liveuser 1659
		}#if end
226 liveuser 1660
 
168 liveuser 1661
	#反之
1662
	else{
226 liveuser 1663
 
3 liveuser 1664
		#debug
1665
		if($debug){
226 liveuser 1666
 
168 liveuser 1667
			#標題提示
1668
			echo "最新一筆log".PHP_EOL;
226 liveuser 1669
 
168 liveuser 1670
			#印出log
1671
			echo $callShell["output"][0].PHP_EOL;
226 liveuser 1672
 
3 liveuser 1673
			}#if end
226 liveuser 1674
 
3 liveuser 1675
		#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 1676
		#${month} ${day} ${hour}:${min}:${sec} ${doNotNeed}"
226 liveuser 1677
 
168 liveuser 1678
		#解析時間點
1679
		#函式說明:
1680
		#尋找字串中是否含有符合格式的內容,且回傳解析好的變數數值.
1681
		#回傳結果:
1682
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
1683
		#$reuslt["error"],執行不正常結束的錯訊息陣列.
1684
		#$result["function"],當前執行的函式名稱.
1685
		#$result["argu"],所使用的參數.
1686
		#$result["found"],是否有找到符合格式的字串內容,"true"代表有找到,"false"代表沒有找到.
1687
		#$result["content"],陣列,若為n個${*},則當found為"true"時,就會回傳n個元素.
1688
		#$result["parsedVar"][varName],陣列,解析好的變數陣列,varName為${}中的內容.
1689
		#必填參數:
1690
		#$conf["input"],字串,要檢查的字串.
1691
		$conf["search::findSpecifyStrFormat"]["input"]=$callShell["output"][0];
1692
		#$conf["format"],格式字串,要尋找的格式字串.格式為固定的字串("fixedStr format")與變數("${keyWordVarName}")組成.
1693
		$conf["search::findSpecifyStrFormat"]["format"]="\${month} \${day} \${hour}:\${min}:\${sec} \${doNotNeed}";
1694
		#可省略參數:
1695
		#$conf["varEqual"],陣列,變數對應的數值,null代表不指定,其他內容代表該變數解析出來必須要為該內容.
1696
		#$conf["varEqual"]=array(null,"found");
1697
		#$conf["varCon"],陣列,每個varEqual為null者,其是否有其他條件,預設為null代表無其他條件,條件的表示是用陣列的key與value來表達,例如:array("no_tail"=>" not"),就代表變數的結尾不能為" not",可以用的key有"head",代表開頭要有什麼;"no_head",代表不能為什麼開頭;"tail",代表要什麼結尾;"no_tail",代表不能什麼結尾.
1698
		#$conf["varCon"]=array("no_tail"=>" not");
1699
		#參考資料:
1700
		#無.
1701
		#備註:
1702
		#無.
1703
		$findSpecifyStrFormat=search::findSpecifyStrFormat($conf["search::findSpecifyStrFormat"]);
1704
		unset($conf["search::findSpecifyStrFormat"]);
226 liveuser 1705
 
168 liveuser 1706
		#如果執行失敗
1707
		if($findSpecifyStrFormat["status"]==="false"){
226 liveuser 1708
 
3 liveuser 1709
			#設置執行失敗
1710
			$result["status"]="false";
1711
 
1712
			#設置錯誤訊息
168 liveuser 1713
			$result["error"]=$findSpecifyStrFormat;
3 liveuser 1714
 
168 liveuser 1715
			#回傳結果
3 liveuser 1716
			var_dump($result);
226 liveuser 1717
 
168 liveuser 1718
			#結束執行
3 liveuser 1719
			exit(1);
226 liveuser 1720
 
3 liveuser 1721
			}#if end
226 liveuser 1722
 
168 liveuser 1723
		#如果log沒有時間戳記
1724
		if($findSpecifyStrFormat["found"]==="false"){
226 liveuser 1725
 
168 liveuser 1726
			#設置執行失敗
1727
			$result["status"]="false";
1728
 
1729
			#設置錯誤訊息
1730
			$result["error"]=$findSpecifyStrFormat;
1731
 
1732
			#回傳結果
1733
			var_dump($result);
226 liveuser 1734
 
168 liveuser 1735
			#結束執行
1736
			exit(1);
226 liveuser 1737
 
168 liveuser 1738
			}#if end
226 liveuser 1739
 
168 liveuser 1740
		#記錄 dovecot log 最後變更的時間
1741
		$imapTimeFloat=strtotime($findSpecifyStrFormat["parsedVar"]["month"][0]." ".$findSpecifyStrFormat["parsedVar"]["day"][0]." ".$findSpecifyStrFormat["parsedVar"]["hour"][0].":".$findSpecifyStrFormat["parsedVar"]["min"][0].":".$findSpecifyStrFormat["parsedVar"]["sec"][0]);
226 liveuser 1742
 
168 liveuser 1743
		}#if end
226 liveuser 1744
 
168 liveuser 1745
	#透過 journalctl -a -e --unit=named.service | tail -n 1 來取得最後一筆 dns 查詢記錄
3 liveuser 1746
	#涵式說明:
1747
	#呼叫shell執行系統命令,並取得回傳的內容.
1748
	#回傳的結果:
1749
	#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
1750
	#$result["error"],錯誤訊息陣列.
1751
	#$result["function"],當前執行的函數名稱.
1752
	#$result["argu"],使用的參數.
1753
	#$result["cmd"],執行的指令內容.
1754
	#$result["fullCmd"],如果參數 $conf["inBackGround"] 為 "true" 則會回傳該值.
1755
	#$result["output"],爲執行完二元碼後的輸出陣列,若 $conf["inBackGround"] 為 "true",則為當下的輸出.
1756
	#$result["tmpFileOutput"],儲存輸出的暫存檔案名稱,若 $conf["inBackGround"] 為 "true" 則會回傳該值.
1757
	#$result["running"],是否還在執行.
1758
	#$result["pid"],pid.
1759
	#$result["statusCode"],執行結束後的代碼.
1760
	#必填的參數
1761
	#$conf["command"],字串,要執行的指令與.
1762
	$conf["external::callShell"]["command"]="journalctl";
1763
	#$conf["fileArgu"],字串,變數__FILE__的內容.
168 liveuser 1764
	$conf["external::callShell"]["fileArgu"]=__FILE__;
3 liveuser 1765
	#可省略參數:
1766
	#$conf["argu"],陣列字串,指令搭配的參數,預設為空陣列.
168 liveuser 1767
	$conf["external::callShell"]["argu"]=array("-a","-e","--unit=named.service","|","tail","-n","1");
3 liveuser 1768
	#$conf["arguIsAddr"],陣列字串,指令搭配的哪些參數為路徑,為路徑的參數會進行轉換以便符合呼叫當前函數的位置,預設不指定,若有3個參數,其中第3個參數為路徑,則表示為array("false","false","true").
226 liveuser 1769
	#$conf["arguIsAddr"]=array();
3 liveuser 1770
	#$conf["pre"],陣列,要在本指令前執行的每個指令與參數.
1771
	#$conf["pre"][$i]["cmd"],字串,要在本指令前執行的第$i+1個指令.
1772
	#$conf["pre"][$i]["param"],陣列字串,要在本指令前執行的第$i+1個指令的參數.
1773
	#$conf["enablePrintDescription"],字串,是否要印出$conf["printDescription"]的內容,"true"代表要,"false"代表不要,預設為"false".
1774
	#$conf["enablePrintDescription"]="true";
1775
	#$conf["printDescription"],字串,執行該外部程式前要印出來的的文字,預設為$conf["command"]的內容加上使用的$conf["argu"]參數.
1776
	#$conf["printDescription"]="";
1777
	#$conf["escapeshellarg"],字串,是否要啟用過濾參數,用了比較安全,但可能會出錯,"true"為啟用,"false"為不啟用,預設為"false".
1778
	$conf["external::callShell"]["escapeshellarg"]="true";
1779
	#$conf["username"],字串,要用什麼使用者來執行,預設為執行php的使用者,該參數不適用於apache環境.
1780
	#$conf["username"]="";
1781
	#$conf["password"],字串,root的使用者密碼,預設不使用密碼,該參數不適用於apache環境.
1782
	#$conf["password"]="";
1783
	#$conf["useScript"],字串,是否要啟用Linux的script指令來記錄輸出,"true"代表要,Fedora的selinux會擋住該操作;"false"代表不要,預設為"false".
1784
	#$conf["useScript"]="";
1785
	#$conf["logFilePath"],字串,當 $conf["useScript"] 為 "true" 時,輸出的內容要暫存到哪裡,預設為 "/tmp/.qbpwcf_tmp/external/callShell/".
1786
	#$conf["logFilePath"]=".qbpwcf_tmp/external/callShell/";
1787
	#$conf["inBackGround"],字串,是否要在背景執行,且不會等待程式執行結束再執行下一個指令,"true"代表是,"false"代表不要,預設為"false",如果$conf["command"]有用「;」區隔的多個指令將會出錯.
1788
	#$conf["inBackGround"]="";
1789
	#$conf["getErr"],字串,"true"代表將錯誤輸出變成標準輸出,反之"false"為不變動.
1790
	#$conf["getErr"]="false";
1791
	#備註:
1792
	#不是所有指令都能用apache的身份執行,目前已知java,javac指令無法執行,使用root身份可能會被selinux阻擋.
1793
	#參考資料:
1794
	#exec=>http://php.net/manual/en/function.exec.php
1795
	#escapeshellcmd=>http://php.net/manual/en/function.escapeshellcmd.php
1796
	#escapeshellarg=>http://php.net/manual/en/function.escapeshellarg.php
1797
	$callShell=external::callShell($conf["external::callShell"]);
1798
	unset($conf["external::callShell"]);
226 liveuser 1799
 
3 liveuser 1800
	#如果執行失敗
1801
	if($callShell["status"]==="false"){
226 liveuser 1802
 
3 liveuser 1803
		#設置執行失敗
1804
		$result["status"]="false";
1805
 
1806
		#設置錯誤訊息
1807
		$result["error"]=$callShell;
1808
 
1809
		#回傳結果
1810
		var_dump($result);
226 liveuser 1811
 
3 liveuser 1812
		#結束執行
1813
		exit(1);
226 liveuser 1814
 
3 liveuser 1815
		}#if end
226 liveuser 1816
 
3 liveuser 1817
	#debug
1818
	if($debug){
226 liveuser 1819
 
3 liveuser 1820
		#comment
1821
		echo "accessed file named log".PHP_EOL;
226 liveuser 1822
 
3 liveuser 1823
		}#if end
226 liveuser 1824
 
3 liveuser 1825
	#取得行數
1826
	$lineCount=count($callShell["output"]);
226 liveuser 1827
 
168 liveuser 1828
	#函式說明:
1829
	#多層if判斷.
1830
	#回傳結果:
1831
	#$result["status"],字串,"true"代表執行正常;"false"代表執行異常.
1832
	#$result["function"],當前函式的名稱.
1833
	#$result["pass"],字串,"true"代表通過多層if判斷;反之為"false".
1834
	#必填參數:
1835
	#$conf["get_defined_vars"],陣列,所有已經定義的變數.
1836
	$conf["controlStructures::nestedIf"]["get_defined_vars"]=get_defined_vars();
1837
	#$conf["varToControlLeft"],變數陣列,依照順序每層要做判斷的變數.
196 liveuser 1838
	$conf["controlStructures::nestedIf"]["varToControlLeft"]=array("lineCount",array("callShell","output",0));
168 liveuser 1839
	#$conf["conditions"],字串陣列,依照順序每層變數判斷的條件,例如">","<",">=","<=","!=","==","<==","!==","===".
1840
	$conf["controlStructures::nestedIf"]["conditions"]=array("===","!==");
1841
	#$conf["varToControlRight"],變數陣列,依照順序每層變數判斷期望的結果.
1842
	$conf["controlStructures::nestedIf"]["varToControlRight"]=array(1,"-- No entries --");
1843
	#可省略參數:
1844
	#無.
1845
	#參考資料:
1846
	#無.
1847
	#備註:
1848
	#無.
1849
	$nestedIf=controlStructures::nestedIf($conf["controlStructures::nestedIf"]);
1850
	unset($conf["controlStructures::nestedIf"]);
226 liveuser 1851
 
168 liveuser 1852
	#如果執行異常
1853
	if($nestedIf["status"]==="false"){
226 liveuser 1854
 
168 liveuser 1855
		#設置執行異常
1856
		$result["status"]="false";
226 liveuser 1857
 
168 liveuser 1858
		#設置執行錯誤
1859
		$result["error"]=$nestedIf;
226 liveuser 1860
 
168 liveuser 1861
		#回傳結果
1862
		return $result;
226 liveuser 1863
 
168 liveuser 1864
		}#if end
226 liveuser 1865
 
168 liveuser 1866
	#如果不通過判斷
1867
	if($nestedIf["pass"]==="false"){
226 liveuser 1868
 
168 liveuser 1869
		#沿用上次的時間
1870
		$namedTimeFloat=$params["info"]["preTimeFloat"]["named"];
226 liveuser 1871
 
168 liveuser 1872
		}#if end
226 liveuser 1873
 
168 liveuser 1874
	#反之
1875
	else{
226 liveuser 1876
 
3 liveuser 1877
		#debug
1878
		if($debug){
226 liveuser 1879
 
168 liveuser 1880
			#標題提示
1881
			echo "最新一筆log".PHP_EOL;
226 liveuser 1882
 
168 liveuser 1883
			#印出log
1884
			echo $callShell["output"][0].PHP_EOL;
226 liveuser 1885
 
3 liveuser 1886
			}#if end
226 liveuser 1887
 
168 liveuser 1888
		#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
1889
		#${month} ${day} ${hour}:${min}:${sec} ${doNotNeed}
226 liveuser 1890
 
168 liveuser 1891
		#解析時間點
1892
		#函式說明:
1893
		#尋找字串中是否含有符合格式的內容,且回傳解析好的變數數值.
1894
		#回傳結果:
1895
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
1896
		#$reuslt["error"],執行不正常結束的錯訊息陣列.
1897
		#$result["function"],當前執行的函式名稱.
1898
		#$result["argu"],所使用的參數.
1899
		#$result["found"],是否有找到符合格式的字串內容,"true"代表有找到,"false"代表沒有找到.
1900
		#$result["content"],陣列,若為n個${*},則當found為"true"時,就會回傳n個元素.
1901
		#$result["parsedVar"][varName],陣列,解析好的變數陣列,varName為${}中的內容.
1902
		#必填參數:
1903
		#$conf["input"],字串,要檢查的字串.
1904
		$conf["search::findSpecifyStrFormat"]["input"]=$callShell["output"][0];
1905
		#$conf["format"],格式字串,要尋找的格式字串.格式為固定的字串("fixedStr format")與變數("${keyWordVarName}")組成.
1906
		$conf["search::findSpecifyStrFormat"]["format"]="\${month} \${day} \${hour}:\${min}:\${sec} \${doNotNeed}";
1907
		#可省略參數:
1908
		#$conf["varEqual"],陣列,變數對應的數值,null代表不指定,其他內容代表該變數解析出來必須要為該內容.
1909
		#$conf["varEqual"]=array(null,"found");
1910
		#$conf["varCon"],陣列,每個varEqual為null者,其是否有其他條件,預設為null代表無其他條件,條件的表示是用陣列的key與value來表達,例如:array("no_tail"=>" not"),就代表變數的結尾不能為" not",可以用的key有"head",代表開頭要有什麼;"no_head",代表不能為什麼開頭;"tail",代表要什麼結尾;"no_tail",代表不能什麼結尾.
1911
		#$conf["varCon"]=array("no_tail"=>" not");
1912
		#參考資料:
1913
		#無.
1914
		#備註:
1915
		#無.
1916
		$findSpecifyStrFormat=search::findSpecifyStrFormat($conf["search::findSpecifyStrFormat"]);
1917
		unset($conf["search::findSpecifyStrFormat"]);
226 liveuser 1918
 
168 liveuser 1919
		#如果執行失敗
1920
		if($findSpecifyStrFormat["status"]==="false"){
226 liveuser 1921
 
168 liveuser 1922
			#設置執行失敗
1923
			$result["status"]="false";
1924
 
1925
			#設置錯誤訊息
1926
			$result["error"]=$findSpecifyStrFormat;
1927
 
1928
			#回傳結果
1929
			var_dump($result);
226 liveuser 1930
 
168 liveuser 1931
			#結束執行
1932
			exit(1);
226 liveuser 1933
 
168 liveuser 1934
			}#if end
226 liveuser 1935
 
168 liveuser 1936
		#如果log沒有時間戳記
1937
		if($findSpecifyStrFormat["found"]==="false"){
226 liveuser 1938
 
3 liveuser 1939
			#設置執行失敗
1940
			$result["status"]="false";
1941
 
1942
			#設置錯誤訊息
168 liveuser 1943
			$result["error"]=$findSpecifyStrFormat;
3 liveuser 1944
 
168 liveuser 1945
			#回傳結果
3 liveuser 1946
			var_dump($result);
226 liveuser 1947
 
168 liveuser 1948
			#結束執行
3 liveuser 1949
			exit(1);
226 liveuser 1950
 
3 liveuser 1951
			}#if end
226 liveuser 1952
 
3 liveuser 1953
		#記錄 named log 最後變更的時間
168 liveuser 1954
		$namedTimeFloat=strtotime($findSpecifyStrFormat["parsedVar"]["month"][0]." ".$findSpecifyStrFormat["parsedVar"]["day"][0]." ".$findSpecifyStrFormat["parsedVar"]["hour"][0].":".$findSpecifyStrFormat["parsedVar"]["min"][0].":".$findSpecifyStrFormat["parsedVar"]["sec"][0]);
226 liveuser 1955
 
168 liveuser 1956
		}#else end
226 liveuser 1957
 
168 liveuser 1958
	#透過 journalctl -a -e --unit=sshd.service | tail -n 1 來取得最後一筆 dns 查詢記錄
1959
	#涵式說明:
1960
	#呼叫shell執行系統命令,並取得回傳的內容.
1961
	#回傳的結果:
1962
	#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
1963
	#$result["error"],錯誤訊息陣列.
1964
	#$result["function"],當前執行的函數名稱.
1965
	#$result["argu"],使用的參數.
1966
	#$result["cmd"],執行的指令內容.
1967
	#$result["fullCmd"],如果參數 $conf["inBackGround"] 為 "true" 則會回傳該值.
1968
	#$result["output"],爲執行完二元碼後的輸出陣列,若 $conf["inBackGround"] 為 "true",則為當下的輸出.
1969
	#$result["tmpFileOutput"],儲存輸出的暫存檔案名稱,若 $conf["inBackGround"] 為 "true" 則會回傳該值.
1970
	#$result["running"],是否還在執行.
1971
	#$result["pid"],pid.
1972
	#$result["statusCode"],執行結束後的代碼.
1973
	#必填的參數
1974
	#$conf["command"],字串,要執行的指令與.
1975
	$conf["external::callShell"]["command"]="journalctl";
1976
	#$conf["fileArgu"],字串,變數__FILE__的內容.
1977
	$conf["external::callShell"]["fileArgu"]=__FILE__;
1978
	#可省略參數:
1979
	#$conf["argu"],陣列字串,指令搭配的參數,預設為空陣列.
1980
	$conf["external::callShell"]["argu"]=array("-a","-e","--unit=sshd.service","|","tail","-n","1");
1981
	#$conf["arguIsAddr"],陣列字串,指令搭配的哪些參數為路徑,為路徑的參數會進行轉換以便符合呼叫當前函數的位置,預設不指定,若有3個參數,其中第3個參數為路徑,則表示為array("false","false","true").
226 liveuser 1982
	#$conf["arguIsAddr"]=array();
168 liveuser 1983
	#$conf["pre"],陣列,要在本指令前執行的每個指令與參數.
1984
	#$conf["pre"][$i]["cmd"],字串,要在本指令前執行的第$i+1個指令.
1985
	#$conf["pre"][$i]["param"],陣列字串,要在本指令前執行的第$i+1個指令的參數.
1986
	#$conf["enablePrintDescription"],字串,是否要印出$conf["printDescription"]的內容,"true"代表要,"false"代表不要,預設為"false".
1987
	#$conf["enablePrintDescription"]="true";
1988
	#$conf["printDescription"],字串,執行該外部程式前要印出來的的文字,預設為$conf["command"]的內容加上使用的$conf["argu"]參數.
1989
	#$conf["printDescription"]="";
1990
	#$conf["escapeshellarg"],字串,是否要啟用過濾參數,用了比較安全,但可能會出錯,"true"為啟用,"false"為不啟用,預設為"false".
1991
	$conf["external::callShell"]["escapeshellarg"]="true";
1992
	#$conf["username"],字串,要用什麼使用者來執行,預設為執行php的使用者,該參數不適用於apache環境.
1993
	#$conf["username"]="";
1994
	#$conf["password"],字串,root的使用者密碼,預設不使用密碼,該參數不適用於apache環境.
1995
	#$conf["password"]="";
1996
	#$conf["useScript"],字串,是否要啟用Linux的script指令來記錄輸出,"true"代表要,Fedora的selinux會擋住該操作;"false"代表不要,預設為"false".
1997
	#$conf["useScript"]="";
1998
	#$conf["logFilePath"],字串,當 $conf["useScript"] 為 "true" 時,輸出的內容要暫存到哪裡,預設為 "/tmp/.qbpwcf_tmp/external/callShell/".
1999
	#$conf["logFilePath"]=".qbpwcf_tmp/external/callShell/";
2000
	#$conf["inBackGround"],字串,是否要在背景執行,且不會等待程式執行結束再執行下一個指令,"true"代表是,"false"代表不要,預設為"false",如果$conf["command"]有用「;」區隔的多個指令將會出錯.
2001
	#$conf["inBackGround"]="";
2002
	#$conf["getErr"],字串,"true"代表將錯誤輸出變成標準輸出,反之"false"為不變動.
2003
	#$conf["getErr"]="false";
2004
	#備註:
2005
	#不是所有指令都能用apache的身份執行,目前已知java,javac指令無法執行,使用root身份可能會被selinux阻擋.
2006
	#參考資料:
2007
	#exec=>http://php.net/manual/en/function.exec.php
2008
	#escapeshellcmd=>http://php.net/manual/en/function.escapeshellcmd.php
2009
	#escapeshellarg=>http://php.net/manual/en/function.escapeshellarg.php
2010
	$callShell=external::callShell($conf["external::callShell"]);
2011
	unset($conf["external::callShell"]);
226 liveuser 2012
 
168 liveuser 2013
	#如果執行失敗
2014
	if($callShell["status"]==="false"){
226 liveuser 2015
 
168 liveuser 2016
		#設置執行失敗
2017
		$result["status"]="false";
2018
 
2019
		#設置錯誤訊息
2020
		$result["error"]=$callShell;
2021
 
2022
		#回傳結果
2023
		var_dump($result);
226 liveuser 2024
 
168 liveuser 2025
		#結束執行
2026
		exit(1);
226 liveuser 2027
 
3 liveuser 2028
		}#if end
226 liveuser 2029
 
168 liveuser 2030
	#debug
2031
	if($debug){
226 liveuser 2032
 
168 liveuser 2033
		#comment
2034
		echo "accessed sshd log".PHP_EOL;
226 liveuser 2035
 
168 liveuser 2036
		}#if end
226 liveuser 2037
 
168 liveuser 2038
	#取得行數
2039
	$lineCount=count($callShell["output"]);
226 liveuser 2040
 
190 liveuser 2041
	#debug
2042
	#var_dump(__LINE__,get_defined_vars()["lineCount"],get_defined_vars()["callShell"]["output"]);
226 liveuser 2043
 
168 liveuser 2044
	#函式說明:
2045
	#多層if判斷.
2046
	#回傳結果:
2047
	#$result["status"],字串,"true"代表執行正常;"false"代表執行異常.
2048
	#$result["function"],當前函式的名稱.
2049
	#$result["pass"],字串,"true"代表通過多層if判斷;反之為"false".
2050
	#必填參數:
2051
	#$conf["get_defined_vars"],陣列,所有已經定義的變數.
2052
	$conf["controlStructures::nestedIf"]["get_defined_vars"]=get_defined_vars();
2053
	#$conf["varToControlLeft"],變數陣列,依照順序每層要做判斷的變數.
196 liveuser 2054
	$conf["controlStructures::nestedIf"]["varToControlLeft"]=array("lineCount",array("callShell","output",0));
168 liveuser 2055
	#$conf["conditions"],字串陣列,依照順序每層變數判斷的條件,例如">","<",">=","<=","!=","==","<==","!==","===".
2056
	$conf["controlStructures::nestedIf"]["conditions"]=array("===","!==");
2057
	#$conf["varToControlRight"],變數陣列,依照順序每層變數判斷期望的結果.
2058
	$conf["controlStructures::nestedIf"]["varToControlRight"]=array(1,"-- No entries --");
2059
	#可省略參數:
2060
	#無.
2061
	#參考資料:
2062
	#無.
2063
	#備註:
2064
	#無.
2065
	$nestedIf=controlStructures::nestedIf($conf["controlStructures::nestedIf"]);
2066
	unset($conf["controlStructures::nestedIf"]);
226 liveuser 2067
 
168 liveuser 2068
	#如果執行異常
2069
	if($nestedIf["status"]==="false"){
226 liveuser 2070
 
168 liveuser 2071
		#設置執行異常
2072
		$result["status"]="false";
226 liveuser 2073
 
168 liveuser 2074
		#設置執行錯誤
2075
		$result["error"]=$nestedIf;
226 liveuser 2076
 
168 liveuser 2077
		#回傳結果
2078
		return $result;
226 liveuser 2079
 
168 liveuser 2080
		}#if end
190 liveuser 2081
 
2082
	#debug
2083
	#var_dump(__LINE__,$nestedIf["pass"]);
226 liveuser 2084
 
168 liveuser 2085
	#如果不通過判斷
2086
	if($nestedIf["pass"]==="false"){
226 liveuser 2087
 
190 liveuser 2088
		#debug
2089
		var_dump(__LINE__,$nestedIf["reason"]);
226 liveuser 2090
 
168 liveuser 2091
		#沿用上次的時間
2092
		$sshdTimeFloat=$params["info"]["preTimeFloat"]["sshd"];
226 liveuser 2093
 
168 liveuser 2094
		}#if end
226 liveuser 2095
 
168 liveuser 2096
	#反之
3 liveuser 2097
	else{
226 liveuser 2098
 
168 liveuser 2099
		#debug
2100
		if($debug){
226 liveuser 2101
 
168 liveuser 2102
			#標題提示
2103
			echo "最新一筆log".PHP_EOL;
226 liveuser 2104
 
168 liveuser 2105
			#印出log
2106
			echo $callShell["output"][0].PHP_EOL;
226 liveuser 2107
 
168 liveuser 2108
			}#if end
226 liveuser 2109
 
168 liveuser 2110
		#Sep 30 00:36:36 silverblue-guest.qbpwcf.org sshd-session[1607010]: Invalid user lizepeng from 60.213.10.69 port 39156
2111
		#${month} ${day} ${hour}:${min}:${sec} ${doNotNeed}
226 liveuser 2112
 
168 liveuser 2113
		#解析時間點
2114
		#函式說明:
2115
		#尋找字串中是否含有符合格式的內容,且回傳解析好的變數數值.
2116
		#回傳結果:
2117
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
2118
		#$reuslt["error"],執行不正常結束的錯訊息陣列.
2119
		#$result["function"],當前執行的函式名稱.
2120
		#$result["argu"],所使用的參數.
2121
		#$result["found"],是否有找到符合格式的字串內容,"true"代表有找到,"false"代表沒有找到.
2122
		#$result["content"],陣列,若為n個${*},則當found為"true"時,就會回傳n個元素.
2123
		#$result["parsedVar"][varName],陣列,解析好的變數陣列,varName為${}中的內容.
2124
		#必填參數:
2125
		#$conf["input"],字串,要檢查的字串.
2126
		$conf["search::findSpecifyStrFormat"]["input"]=$callShell["output"][0];
2127
		#$conf["format"],格式字串,要尋找的格式字串.格式為固定的字串("fixedStr format")與變數("${keyWordVarName}")組成.
2128
		$conf["search::findSpecifyStrFormat"]["format"]="\${month} \${day} \${hour}:\${min}:\${sec} \${doNotNeed}";
2129
		#可省略參數:
2130
		#$conf["varEqual"],陣列,變數對應的數值,null代表不指定,其他內容代表該變數解析出來必須要為該內容.
2131
		#$conf["varEqual"]=array(null,"found");
2132
		#$conf["varCon"],陣列,每個varEqual為null者,其是否有其他條件,預設為null代表無其他條件,條件的表示是用陣列的key與value來表達,例如:array("no_tail"=>" not"),就代表變數的結尾不能為" not",可以用的key有"head",代表開頭要有什麼;"no_head",代表不能為什麼開頭;"tail",代表要什麼結尾;"no_tail",代表不能什麼結尾.
2133
		#$conf["varCon"]=array("no_tail"=>" not");
2134
		#參考資料:
2135
		#無.
2136
		#備註:
2137
		#無.
2138
		$findSpecifyStrFormat=search::findSpecifyStrFormat($conf["search::findSpecifyStrFormat"]);
2139
		unset($conf["search::findSpecifyStrFormat"]);
226 liveuser 2140
 
168 liveuser 2141
		#如果執行失敗
2142
		if($findSpecifyStrFormat["status"]==="false"){
226 liveuser 2143
 
168 liveuser 2144
			#設置執行失敗
2145
			$result["status"]="false";
3 liveuser 2146
 
168 liveuser 2147
			#設置錯誤訊息
2148
			$result["error"]=$findSpecifyStrFormat;
2149
 
2150
			#回傳結果
2151
			var_dump($result);
226 liveuser 2152
 
168 liveuser 2153
			#結束執行
2154
			exit(1);
226 liveuser 2155
 
168 liveuser 2156
			}#if end
226 liveuser 2157
 
168 liveuser 2158
		#如果log沒有時間戳記
2159
		if($findSpecifyStrFormat["found"]==="false"){
226 liveuser 2160
 
168 liveuser 2161
			#設置執行失敗
2162
			$result["status"]="false";
2163
 
2164
			#設置錯誤訊息
2165
			$result["error"]=$findSpecifyStrFormat;
2166
 
2167
			#回傳結果
2168
			var_dump($result);
226 liveuser 2169
 
168 liveuser 2170
			#結束執行
2171
			exit(1);
226 liveuser 2172
 
168 liveuser 2173
			}#if end
226 liveuser 2174
 
168 liveuser 2175
		#記錄 sshd log 最後變更的時間
2176
		$sshdTimeFloat=strtotime($findSpecifyStrFormat["parsedVar"]["month"][0]." ".$findSpecifyStrFormat["parsedVar"]["day"][0]." ".$findSpecifyStrFormat["parsedVar"]["hour"][0].":".$findSpecifyStrFormat["parsedVar"]["min"][0].":".$findSpecifyStrFormat["parsedVar"]["sec"][0]);
226 liveuser 2177
 
168 liveuser 2178
		}#else end
226 liveuser 2179
 
3 liveuser 2180
	#debug mode
2181
	if($debug){
2182
 
2183
		#comment
2184
		echo "\$httpTimeFloat:".$httpTimeFloat.PHP_EOL;
2185
		echo "\$httpsTimeFloat:".$httpsTimeFloat.PHP_EOL;
2186
		echo "\$smtpTimeFloat:".$smtpTimeFloat.PHP_EOL;
2187
		echo "\$imapTimeFloat:".$imapTimeFloat.PHP_EOL;
2188
		echo "\$namedTimeFloat:".$namedTimeFloat.PHP_EOL;
168 liveuser 2189
		echo "\$sshdTimeFloat:".$sshdTimeFloat.PHP_EOL;
3 liveuser 2190
 
2191
		}#if end
2192
 
2193
	#第一次運行,不做事.
345 liveuser 2194
	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 2195
 
2196
		#將本次http記錄覆寫到上次的記錄
2197
		$params["info"]["preTimeFloat"]["http"]=$httpTimeFloat;
226 liveuser 2198
 
3 liveuser 2199
		#將本次https記錄覆寫到上次的記錄
2200
		$params["info"]["preTimeFloat"]["https"]=$httpsTimeFloat;
226 liveuser 2201
 
3 liveuser 2202
		#將本次smtps記錄覆寫到上次的記錄
2203
		$params["info"]["preTimeFloat"]["smtp"]=$smtpTimeFloat;
226 liveuser 2204
 
3 liveuser 2205
		#將本次imaps記錄覆寫到上次的記錄
2206
		$params["info"]["preTimeFloat"]["imap"]=$imapTimeFloat;
226 liveuser 2207
 
3 liveuser 2208
		#將本次nmaed記錄覆寫到上次的記錄
2209
		$params["info"]["preTimeFloat"]["named"]=$namedTimeFloat;
226 liveuser 2210
 
168 liveuser 2211
		#將本次sshd記錄覆寫到上次的記錄
2212
		$params["info"]["preTimeFloat"]["sshd"]=$sshdTimeFloat;
226 liveuser 2213
 
3 liveuser 2214
		#睡一秒
2215
		sleep(1);
2216
 
2217
		#debug mode
2218
		if($debug){
2219
 
2220
			#comment
2221
			echo "第一次運行,不做事".PHP_EOL;
2222
 
2223
			}#if end
2224
 
2225
		#結束執行
2226
		return;
226 liveuser 2227
 
3 liveuser 2228
		}#if end
226 liveuser 2229
 
3 liveuser 2230
	#非第一次運行,且 http 與 https 與 imap 與 smtp 與 named log 都沒變動過.
168 liveuser 2231
	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 2232
 
3 liveuser 2233
		#睡一秒
2234
		sleep(1);
226 liveuser 2235
 
3 liveuser 2236
		#debug mode
2237
		if($debug){
2238
 
2239
			#comment
2240
			echo "Log檔無變動,不做事".PHP_EOL;
2241
 
2242
			}#if end
226 liveuser 2243
 
3 liveuser 2244
		#結束執行
2245
		return;
226 liveuser 2246
 
3 liveuser 2247
		}#else end
2248
 
2249
	#debug mode
2250
	if($debug){
2251
 
333 liveuser 2252
 
2253
 
3 liveuser 2254
		#comment
2255
		echo "Log檔有變動,要做事".PHP_EOL;
2256
		echo "\$preHttpTimeFloat:".$params["info"]["preTimeFloat"]["http"].PHP_EOL;
2257
		echo "\$preHttpsTimeFloat:".$params["info"]["preTimeFloat"]["https"].PHP_EOL;
2258
		echo "\$preSmtpTimeFloat:".$params["info"]["preTimeFloat"]["smtp"].PHP_EOL;
2259
		echo "\$preImapTimeFloat:".$params["info"]["preTimeFloat"]["imap"].PHP_EOL;
2260
		echo "\$preNamedTimeFloat:".$params["info"]["preTimeFloat"]["named"].PHP_EOL;
168 liveuser 2261
		echo "\$preSshdTimeFloat:".$params["info"]["preTimeFloat"]["sshd"].PHP_EOL;
333 liveuser 2262
 
2263
 
2264
 
3 liveuser 2265
		echo "\$httpTimeFloat:".$httpTimeFloat.PHP_EOL;
2266
		echo "\$httpsTimeFloat:".$httpsTimeFloat.PHP_EOL;
2267
		echo "\$smtpTimeFloat:".$smtpTimeFloat.PHP_EOL;
2268
		echo "\$imapTimeFloat:".$imapTimeFloat.PHP_EOL;
2269
		echo "\$namedTimeFloat:".$namedTimeFloat.PHP_EOL;
168 liveuser 2270
		echo "\$sshdTimeFloat:".$sshdTimeFloat.PHP_EOL;
3 liveuser 2271
 
2272
		}#if end
2273
 
2274
	#將本次http記錄覆寫到上次的記錄
2275
	$params["info"]["preTimeFloat"]["http"]=$httpTimeFloat;
226 liveuser 2276
 
3 liveuser 2277
	#將本次https記錄覆寫到上次的記錄
2278
	$params["info"]["preTimeFloat"]["https"]=$httpsTimeFloat;
226 liveuser 2279
 
168 liveuser 2280
	#將本次smtp記錄覆寫到上次的記錄
2281
	$params["info"]["preTimeFloat"]["smtp"]=$smtpTimeFloat;
226 liveuser 2282
 
168 liveuser 2283
	#將本次imap記錄覆寫到上次的記錄
2284
	$params["info"]["preTimeFloat"]["imap"]=$imapTimeFloat;
226 liveuser 2285
 
168 liveuser 2286
	#將本次named記錄覆寫到上次的記錄
2287
	$params["info"]["preTimeFloat"]["named"]=$namedTimeFloat;
226 liveuser 2288
 
168 liveuser 2289
	#將本次sshd記錄覆寫到上次的記錄
2290
	$params["info"]["preTimeFloat"]["sshd"]=$sshdTimeFloat;
226 liveuser 2291
 
3 liveuser 2292
	#初始化儲存暫時ip白名單的陣列
2293
	$excludeIpsTmp=array();
226 liveuser 2294
 
3 liveuser 2295
	#針對每個暫時白名單ip
2296
	foreach($params["info"]["excludeIpsTmp"] as $index=>$tmpIpInfo){
226 liveuser 2297
 
3 liveuser 2298
		#若暫存白名單已經過期
2299
		if($tmpIpInfo["unixtime"]<time()-$params["info"]["tmp-white-ip-valid-time"]*3600){
226 liveuser 2300
 
3 liveuser 2301
			#卸除之
2302
			unset($params["info"]["excludeIpsTmp"][$index]);
226 liveuser 2303
 
3 liveuser 2304
			}#if end
226 liveuser 2305
 
3 liveuser 2306
		#反之
2307
		else{
226 liveuser 2308
 
168 liveuser 2309
			#變成 $excludeIpsTmp 的內容
3 liveuser 2310
			$excludeIpsTmp[]=$params["info"]["excludeIpsTmp"][$index]["ip"];
226 liveuser 2311
 
3 liveuser 2312
			}#else end
226 liveuser 2313
 
3 liveuser 2314
		}#foreach end
226 liveuser 2315
 
3 liveuser 2316
	#函式說明:
2317
	#將多個多維陣列串聯起來,key從0開始排序.
2318
	#回傳的結果:
2319
	#$result["status"],"true"表執行正常,"false"代表執行不正常.
2320
	#$result["error"],錯誤訊息陣列.
2321
	#$result["function"],當前執行的函數.
2322
	#$result["content"],合併好的一維陣列.
2323
	#必填參數
2324
	#$conf["inputArray"],陣列,要合併的一維陣列變數,例如:=array($array1,$array2);
168 liveuser 2325
	$conf["arrays::mergeMultiDimensionArray"]["inputArray"]=array($params["info"]["excludeIp"],$excludeIpsTmp);
3 liveuser 2326
	#可省略參數:
2327
	#$conf["allowRepeat"],字串,預設為"false",不允許重複的結果;反之為"true".
2328
	#$conf["allowRepeat"]="true";
2329
	#$conf["equalKeyStruc"],字串陣列,若 allowRepeat 參數為 "false", 這該參數生效.該參數為用來判斷每個陣列的哪個鍵值路徑底下的數值相同時要進行取代,後者會取代前者.
2330
	#$conf["equalKeyStruc"]=array();
2331
	#參考資料:
2332
	#無.
2333
	#備註:
2334
	#無.
168 liveuser 2335
	$mergeMultiDimensionArray=arrays::mergeMultiDimensionArray($conf["arrays::mergeMultiDimensionArray"]);
2336
	unset($conf["arrays::mergeMultiDimensionArray"]);
226 liveuser 2337
 
3 liveuser 2338
	#如果執行失敗
2339
	if($mergeMultiDimensionArray["status"]==="false"){
226 liveuser 2340
 
3 liveuser 2341
		#設置執行失敗
2342
		$result["status"]="false";
2343
 
2344
		#設置錯誤訊息
2345
		$result["error"]=$mergeMultiDimensionArray;
2346
 
2347
		#回傳結果
2348
		var_dump($result);
226 liveuser 2349
 
3 liveuser 2350
		#結束執行
2351
		exit(1);
226 liveuser 2352
 
3 liveuser 2353
		}#if end
226 liveuser 2354
 
3 liveuser 2355
	#debug
2356
	#var_dump(__LINE__,$mergeMultiDimensionArray);
226 liveuser 2357
 
3 liveuser 2358
	#涵式說明:
168 liveuser 2359
	#檢查 httpd 與 postfix/smtpd 的 log 與 named 的 log 與 sshd 的 log 把惡意連線的 IP 用防火牆阻擋
3 liveuser 2360
	#回傳結果:
2361
	#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
2362
	#$result["error"],錯誤訊息.
2363
	#$result["function"],當前執行的函數名稱.
2364
	#$result["argu"],所使用的參數.
2365
	#$result["found"],是否有找到符合的檔案,"true"代表有;"false"代表沒有.
280 liveuser 2366
	#$result["content"],阻擋IP的結果或有問題的IP資訊清單.
2367
	#$result["reason"][$ip],特定ip被阻擋的資訊.
3 liveuser 2368
	#必填參數:
2369
	#$conf["fileArgu"],字串,php變數__FILE__的內容,亦即該檔案在檔案系統的絕對路徑
168 liveuser 2370
	$conf["cmd::blockAcctackIp"]["fileArgu"]=__FILE__;
3 liveuser 2371
	#可省略參數:
2372
	#$conf["excludeIp"],字串陣列,白名單ip陣列.
168 liveuser 2373
	$conf["cmd::blockAcctackIp"]["excludeIp"]=$mergeMultiDimensionArray["content"];
3 liveuser 2374
	#$conf["logPath"],字串,httpd的log位置,預設為 "/var/log/httpd"
2375
	#$conf["logPath"]="";
2376
	#$conf["username"],字串,要用什麼使用者來執行,預設為root使用者
2377
	#$conf["username"]="";
2378
	#$conf["password"],字串,root使用者的密碼,
2379
	#$conf["password"]="";
2380
	#$conf["getIplistOnly"],字串,是否不阻擋IP只取得有問題的IP,預設為"false",要阻擋IP;"true"代表只取得有問題的IP.
2381
	#$conf["getIplistOnly"]="true";
168 liveuser 2382
	$blockAcctackIp=cmd::blockAcctackIp($conf["cmd::blockAcctackIp"]);
2383
	unset($conf["cmd::blockAcctackIp"]);
3 liveuser 2384
 
2385
	#如果執行失敗
2386
	if($blockAcctackIp["status"]==="false"){
2387
 
2388
		#設置執行失敗
2389
		$result["status"]="false";
2390
 
2391
		#設置錯誤訊息
2392
		$result["error"]=$blockAcctackIp;
2393
 
2394
		#印出結果
2395
		var_dump($result);
226 liveuser 2396
 
3 liveuser 2397
		#結束執行
2398
		exit(1);
2399
 
2400
		}#if end
226 liveuser 2401
 
3 liveuser 2402
	#如果有執行封鎖IP的情形
280 liveuser 2403
	if(isset($blockAcctackIp["reason"])){
3 liveuser 2404
 
2405
		#comment
2406
		echo "本次封鎖IP的結果如下:".PHP_EOL;
2407
		var_dump($blockAcctackIp["reason"]);
2408
 
2409
		}#if end
226 liveuser 2410
 
3 liveuser 2411
	#睡一秒
2412
	sleep(1);
226 liveuser 2413
 
3 liveuser 2414
	#結束執行
2415
	return;
226 liveuser 2416
 
3 liveuser 2417
	}//function funcToRunWhenIdle end
2418
 
226 liveuser 2419
?>