Subversion Repositories php-qbpwcf

Rev

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

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