Subversion Repositories php-qbpwcf

Rev

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