Subversion Repositories php-qbpwcf

Rev

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

Rev Author Line No. Line
3 liveuser 1
<?php
2
 
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/>.
22
 
23
*/
24
namespace qbpwcf;
25
 
26
/*
27
類別說明:
368 liveuser 28
跟網頁、資訊安全性有關的類別.
3 liveuser 29
備註:
30
無.
31
*/
32
class security{
33
 
34
	/*
35
	#函式說明:
36
	#當前類別被呼叫的靜態方法不存在時,將會執行該函數,回報該方法不存在.
37
	#回傳結果:
38
	#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
39
	#$reuslt["error"],執行不正常結束的錯訊息陣列.
40
	#$result["function"],當前執行的函式名稱.
41
	#必填參數:
42
	#$method,物件,為物件實體或類別名稱,會自動置入該參數.
43
	#$arguments,陣列,為呼叫方法時所用的參數.
44
	#可省略參數:
45
	#無.
46
	#參考資料:
47
	#__call=>http://php.net/manual/en/language.oop5.overloading.php#object.callstatic
48
	#備註:
49
	#無.
50
	*/
51
	public function __call($method,$arguments){
226 liveuser 52
 
3 liveuser 53
		#取得當前執行的函式
54
		$result["function"]=__FUNCTION__;
226 liveuser 55
 
3 liveuser 56
		#設置執行不正常
57
		$result["status"]="false";
226 liveuser 58
 
3 liveuser 59
		#設置執行錯誤
60
		$result["error"][]=__NAMESPACE__ ."/".$method."() 不存在!";
226 liveuser 61
 
3 liveuser 62
		#設置所丟入的參數
63
		$result["error"][]=$arguments;
226 liveuser 64
 
3 liveuser 65
		#回傳結果
66
		return $result;
226 liveuser 67
 
3 liveuser 68
		}#function __call end
226 liveuser 69
 
3 liveuser 70
	/*
71
	#函式說明:
72
	#當前類別被呼叫的靜態方法不存在時,將會執行該函數,回報該方法不存在.
73
	#回傳結果:
74
	#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
75
	#$reuslt["error"],執行不正常結束的錯訊息陣列.
76
	#$result["function"],當前執行的函式名稱.
77
	#必填參數:
78
	#$method,物件,為物件實體或類別名稱,會自動置入該參數.
79
	#$arguments,陣列,為呼叫方法時所用的參數.
80
	#可省略參數:
81
	#無.
82
	#參考資料:
83
	#__callStatic=>http://php.net/manual/en/language.oop5.overloading.php#object.callstatic
84
	#備註:
85
	#無.
86
	*/
87
	public static function __callStatic($method,$arguments){
226 liveuser 88
 
3 liveuser 89
		#取得當前執行的函式
90
		$result["function"]=__FUNCTION__;
226 liveuser 91
 
3 liveuser 92
		#設置執行不正常
93
		$result["status"]="false";
226 liveuser 94
 
3 liveuser 95
		#設置執行錯誤
96
		$result["error"][]="欲呼叫的". __NAMESPACE__ ."/".$method."() 不存在!";
226 liveuser 97
 
3 liveuser 98
		#設置所丟入的參數
99
		$result["error"][]=$arguments;
226 liveuser 100
 
3 liveuser 101
		#回傳結果
102
		return $result;
226 liveuser 103
 
3 liveuser 104
		}#function __callStatic end
226 liveuser 105
 
3 liveuser 106
	/*
226 liveuser 107
	#函式說明:
3 liveuser 108
	#禁止特定的angent訪問我們的網站,例如google與百度的搜尋引擎。
109
	#回傳結果:
110
	#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
111
	#$result["error"],錯誤訊息.
112
	#$result["function"],當前執行的函數名稱.
113
	#必填參數:
114
	#$conf["disableAngentName"],字串,要禁止拜訪的用戶端資訊,代表要禁止哪些瀏覽器/搜尋引擎瀏覽,格式爲 /(含有哪些關鍵字,若有多個請用「|」隔開。)/i.
115
	$conf["disableAngentName"]="/(Chrome|Mozilla|Internet)/i";
116
	#可省略參數:
117
	#$conf["transferLocation"],字串,如果是要禁止搜尋引擎,要轉址到那個地方?,若沒設定,則預設爲資安素養網的臉書(https://zh-tw.facebook.com/isafemoe).
118
	#$conf["transferLocation"]="";
119
	#參考資料:
120
	#http://php.net/manual/en/function.preg-match.php
121
	#備註:
122
	#無.
123
	*/
124
	public static function preventSerchEngine(&$conf){
125
 
126
		#初始化要回傳的內容
127
		$result=array();
226 liveuser 128
 
3 liveuser 129
		#取得當前執行的函式
130
		$result["function"]=__FUNCTION__;
226 liveuser 131
 
3 liveuser 132
		#如果 $conf 不為陣列
133
		if(gettype($conf)!="array"){
226 liveuser 134
 
3 liveuser 135
			#設置執行失敗
136
			$result["status"]="false";
226 liveuser 137
 
3 liveuser 138
			#設置執行錯誤訊息
139
			$result["error"][]="\$conf變數須為陣列形態";
140
 
141
			#如果傳入的參數為 null
142
			if($conf==null){
226 liveuser 143
 
3 liveuser 144
				#設置執行錯誤訊息
145
				$result["error"][]="\$conf變數不得為null,請檢查函數「".$result["function"]."」的參數設置有無正確!";
226 liveuser 146
 
3 liveuser 147
				}#if end
148
 
149
			#回傳結果
150
			return $result;
226 liveuser 151
 
3 liveuser 152
			}#if end
153
 
154
		#debug,檢查 $_SERVER["HTTP_USER_AGENT"] 的內容
155
		#var_dump($_SERVER['HTTP_USER_AGENT']);
226 liveuser 156
 
3 liveuser 157
		#檢查參數
158
		#函式說明:
159
		#檢查必填與可省略的參數,可省略參數可指定預設要給與什麼數值內容。
160
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
161
		#$reuslt["error"],執行不正常結束的錯訊息陣列.
162
		#$result["function"],當前執行的函式名稱.
163
		#$result["passed"],識別要檢查的全體變數是否存在以及型態是否正確的變數,"true"代表檢查全部通過;"false"代表檢查不通過
164
		#$result[$shouldBtCheckedVarName]["varExist"],所檢查的變數是否存在,"false"代表不存在;"true"代表存在
165
		#$result[$shouldBtCheckedVarName]["varType"],所檢查的變數型態是否正確,"false"代表錯誤;"true"代表正確
166
		#$result[$shouldBtCheckedVarName]["error"],每個參數設定的錯誤訊息
167
		#$result["argu"],字串陣列,目前輸入的參數名稱陣列.
168
		#$result["legalVarName"],字串陣列,合法可用的參數名稱陣列.
169
		#$result["notNeedVar"],字串陣列,多餘的參數名稱.
170
		#必填寫的參數:
171
		#$conf["variableCheck::checkArguments"]["varInput"],陣列變數,要檢查的陣列變數,請在要檢查的參數前面加上&,這樣變動的結果才能被套用。
172
		$conf["variableCheck::checkArguments"]["varInput"]=&$conf;
173
		#$conf["variableCheck::checkArguments"]["mustBeFilledVariableName"],爲必填參數的變數名稱陣列,形態爲陣列變數,元素數量需要跟"mustBeFilledVariableType"參數的元素數量一致,例如: $conf["mustBeFilledVariableName"] = array("id","account","password");
174
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableName"]=array("disableAngentName");
226 liveuser 175
		#$conf["variableCheck::checkArguments"]["mustBeFilledVariableType"],爲必填參數的變數陣列應該爲何種變數形態,形態爲陣列,元素數量需要跟"mustBeFilledVariableName"參數的元素數量一致,例如: $conf["mustBeFilledVariableType"] = array("string",integer,"double","resource","object");
3 liveuser 176
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableType"]=array("string");
177
		#$conf["variableCheck::checkArguments"]["referenceVarKey"],字串,$conf參數後面的key值,用於移除不要的參考陣列.
178
		$conf["variableCheck::checkArguments"]["referenceVarKey"]="variableCheck::checkArguments";
179
		#可以省略的參數:
180
		#$conf["canBeEmptyString"],必填變數內容如果是空字串就不能算是有設置的話,請設為"false",預設爲"true"。
181
		#$conf["canBeEmptyString"]="false";
182
		#$conf["variableCheck::checkArguments"]["skipableVariableName"],爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableName"] = array("id","account","password");
183
		$conf["variableCheck::checkArguments"]["skipableVariableName"]=array("transferLocation");
226 liveuser 184
		#$conf["variableCheck::checkArguments"]["skipableVariableType"],爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableType"] = array("string",integer,"double");
3 liveuser 185
		$conf["variableCheck::checkArguments"]["skipableVariableType"]=array("string");
186
		#$conf["variableCheck::checkArguments"]["skipableVarDefaultValue"],字串陣列,每個不存在的可省略變數要初始化為什麼,null與代表不指定,若預設值是參數之一,請將$conf["mustBeFilledVar"]改成"\$conf["\mustBeFilledVar\"]".
187
		$conf["variableCheck::checkArguments"]["skipableVarDefaultValue"]=array("https://zh-tw.facebook.com/isafemoe");
188
		#$conf["arrayCountEqualCheck"],字串陣列,為檢查哪些陣列參數的元素數量要一樣,$conf["arrayCountEqualCheck"][$i]=array()為第$i組key為哪些的變數其元素數量要相等.
189
		#$conf["arrayCountEqualCheck"][]=array();
190
		#參考資料來源:
191
		#array_keys=>http://php.net/manual/en/function.array-keys.php
192
		$checkArguments=variableCheck::checkArguments($conf["variableCheck::checkArguments"]);
193
		unset($conf["variableCheck::checkArguments"]);
226 liveuser 194
 
3 liveuser 195
		#如果檢查失敗
196
		if($checkArguments["status"]=="false"){
226 liveuser 197
 
3 liveuser 198
			#設置執行失敗
199
			$result["status"]="false";
226 liveuser 200
 
3 liveuser 201
			#設置執行錯誤訊息
202
			$result["error"]=$checkArguments;
203
 
204
			#回傳結果
205
			return $result;
226 liveuser 206
 
207
			}#if end
208
 
3 liveuser 209
		#如果檢查不通過
210
		if($checkArguments["passed"]=="false"){
226 liveuser 211
 
3 liveuser 212
			#設置執行失敗
213
			$result["status"]="false";
226 liveuser 214
 
3 liveuser 215
			#設置執行錯誤訊息
216
			$result["error"]=$checkArguments;
217
 
218
			#回傳結果
219
			return $result;
226 liveuser 220
 
221
			}#if end
222
 
3 liveuser 223
		#如果使用者的瀏覽器出現變數 $conf["disableAngentName"] 裡面的關鍵字
224
		if(preg_match($conf["disableAngentName"],$_SERVER["HTTP_USER_AGENT"])){
225
 
226
			#則轉址特定頁面
227
			#函式說明:
228
			#設定session變數後,立即轉址.
229
			#回傳結果:
230
			#$result["status"],執行是否成功,"true"代表成功,"false"代表不成功.
231
			#$result["function"],當前執行的函數名稱.
232
			#$result["error"],錯誤訊息陣列.
233
			#必填的參數:
234
			#$conf["header::redirectionNow"]["headerLocation"],為要轉址到的地方,若爲 $_SERVER["PHP_SELF"],則爲回到目前頁面,全民資安素養網爲 https://isafe.moe.edu.tw/.
235
			$conf["header::redirectionNow"]["headerLocation"]=$conf["transferLocation"];
236
			#可省略的參數:
237
			#$conf["sessionName"],字串陣列,可以指派session變數的名稱.
238
			#$conf["sessionName"]=array("");
239
			#$conf["sessionValue"]字串陣列,可以指派session變數的內容.
240
			#$conf["sessionValue"]=array("");
241
			#參靠資料來源:
242
			#http://php.net/manual/en/reserved.variables.server.php
243
			$redirectionNow=header::redirectionNow($conf["header::redirectionNow"]);
226 liveuser 244
			unset($conf["header::redirectionNow"]);
245
 
3 liveuser 246
			#如果轉址失敗
247
			if($redirectionNow["status"]=="false"){
226 liveuser 248
 
3 liveuser 249
				#設置執行失敗
250
				$result["status"]="false";
226 liveuser 251
 
3 liveuser 252
				#設置執行錯誤訊息
253
				$result["error"]=$redirectionNow;
254
 
255
				#回傳結果
256
				return $result;
226 liveuser 257
 
3 liveuser 258
				}#if end
226 liveuser 259
 
260
			}#if end
261
 
3 liveuser 262
		#執行到這邊代表是可以拜訪的網頁瀏覽器
263
		$result["status"]="true";
226 liveuser 264
 
3 liveuser 265
		#回傳結果
266
		return $result;
267
 
268
		}#function preventSerchEngine end
269
 
270
	/*
271
	#函式說明:
272
	#禁止做任違反版權的事情,禁止在網頁按下滑鼠右鍵,禁止複製圖片,禁止開新分頁(失敗), 版權所有、Power by訊息.
273
	#回傳的內容:
274
	#保護版權的語法
275
	#必填參數:
276
	#無
277
	#可省略參數:
278
	#$conf["name"],字串,公司、組織、單位的名稱,預設不指定.
279
	#$conf["name"]="";
280
	#$conf["powerBy"],字串,由誰提供,預設爲QBPWCF.
281
	#$conf["powerBy"]="";
282
	#$conf["powerByLink"],字串,power by字串的連結目標,預設爲"https://www.qbpwcf.org".
283
	#$conf["powerByLink"]="";
284
	#$conf["bgColor"],字串,背景顏色,預設爲淡藍色.
285
	#$conf["bgColor"]="";
286
	#參考資料:
287
	#http://www.w3schools.com/jsref/dom_obj_event.asp
288
	#備註:
289
	#無.
290
	*/
291
	public static function copyRight(&$conf){
226 liveuser 292
 
3 liveuser 293
		#初始化要回傳的結果
294
		$result=array();
295
 
296
		#取得當前執行的函數名稱
297
		$result["function"]=__FUNCTION__;
298
 
299
		#取得參數
300
		$result["argu"]=$conf;
301
 
302
		#如果 $conf 不為陣列
303
		if(gettype($conf)!="array"){
304
 
305
			#設置執行失敗
306
			$result["status"]="false";
307
 
308
			#設置執行錯誤訊息
309
			$result["error"][]="\$conf變數須為陣列形態";
310
 
311
			#如果傳入的參數為 null
312
			if(is_null($conf)){
313
 
314
				#設置執行錯誤訊息
315
				$result["error"][]="\$conf變數不得為null,請檢查函數「".$result["function"]."」的參數設置有無正確!";
316
 
317
				}#if end
318
 
319
			#回傳結果
320
			return $result;
321
 
322
			}#if end
226 liveuser 323
 
3 liveuser 324
		#初始化 content
226 liveuser 325
		$result["content"]="";
326
 
3 liveuser 327
		#函式說明:
328
		#檢查必填與可省略的參數,可省略參數可指定預設要給與什麼數值內容。
329
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
330
		#$reuslt["error"],執行不正常結束的錯訊息陣列.
331
		#$result["function"],當前執行的函式名稱.
332
		#$result["argu"],設置給予的參數.
333
		#$result["passed"],識別要檢查的全體變數是否存在以及型態是否正確的變數,"true"代表檢查全部通過;"false"代表檢查不通過
334
		#$result[$shouldBeCheckedVarName]["varExist"],所檢查的變數是否存在,"false"代表不存在;"true"代表存在
335
		#$result[$shouldBeCheckedVarName]["varType"],所檢查的變數型態是否正確,"false"代表錯誤;"true"代表正確
336
		#$result[$shouldBeCheckedVarName]["error"],每個參數設定的錯誤訊息
337
		#$result["shouldNotBeEmpty"],不應該為空字串或控陣列的變數.
338
		#$result["argu"],字串陣列,目前輸入的參數名稱陣列.
339
		#$result["legalVarName"],字串陣列,合法可用的參數名稱陣列.
340
		#$result["notNeedVar"],字串陣列,多餘的參數名稱.
341
		#必填寫的參數:
342
		#$conf["varInput"],陣列變數,要檢查的陣列變數,請在要檢查的參數前面加上&,這樣變動的結果才能被套用。
343
		$conf["variableCheck::checkArguments"]["varInput"]=&$conf;
344
		#$conf["referenceVarKey"],字串,$conf參數後面的key值,用於移除不要的參考陣列.
345
		$conf["variableCheck::checkArguments"]["referenceVarKey"]="variableCheck::checkArguments";
346
		#可以省略的參數:
347
		#$conf["mustBeFilledVariableName"],爲必填參數的變數名稱陣列,形態爲陣列變數,元素數量需要跟"mustBeFilledVariableType"參數的元素數量一致,例如: $conf["mustBeFilledVariableName"] = array("id","account","password");
348
		#$conf["mustBeFilledVariableName"]=array();
349
		#$conf["mustBeFilledVariableType"],爲必填參數的變數陣列應該爲何種變數形態,形態爲陣列,元素數量需要跟"mustBeFilledVariableName"參數的元素數量一致,例如: $conf["mustBeFilledVariableType"] = array("string",integer,"double","resource","object"); , null代表不指定變數形態.
350
		#$conf["mustBeFilledVariableType"]=array();
351
		#$conf["canBeEmptyString"],字串,必填變數內容如果是空字串就不能算是有設置的話,請設為"false",預設爲"true",可以為空字串.
352
		#$conf["canBeEmptyString"]="false";
353
		#$conf["canNotBeEmpty"],字串陣列,哪些必填參數的內容不得為空字串或空陣列,僅當$conf["canBeEmptyString"]為"true"時會生效.
354
		#$conf["canNotBeEmpty"]=array();
355
		#$conf["canBeEmpty"],字串陣列,哪些必填參數的內容可為空字串或空陣列,僅當$conf["canBeEmptyString"]為"false"時會生效.
356
		#$conf["canBeEmpty"]=array();
357
		#$conf["skipableVariableCanNotBeEmpty"],字串陣列,哪些可省略參數不可以為空字串或空陣列.
358
		$conf["variableCheck::checkArguments"]["skipableVariableCanNotBeEmpty"]=array("powerBy","powerByLink","bgColor");
359
		#$conf["skipableVariableName"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableName"] = array("id","account","password");
360
		$conf["variableCheck::checkArguments"]["skipableVariableName"]=array("name","powerBy","powerByLink","bgColor");
361
		#$conf["skipableVariableType"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableType"] = array("string",integer,"double");
362
		$conf["variableCheck::checkArguments"]["skipableVariableType"]=array("string","string","string","string");
363
		#$conf["skipableVarDefaultValue"],字串陣列,每個不存在的可省略變數要初始化為什麼,null與代表不指定,若預設值是參數之一,請將$conf["mustBeFilledVar"]改成"\$conf["\mustBeFilledVar\"]".
364
		$conf["variableCheck::checkArguments"]["skipableVarDefaultValue"]=array("","QBPWCF","https://www.qbpwcf.org","#DDDDFF");
365
		#$conf["disallowAllSkipableVarIsEmpty"],字串,是否允許每個可省略參數都為空字串,預設為"true"允許,反之為"false".
366
		#$conf["disallowAllSkipableVarIsEmpty"]="";
367
		#$conf["disallowAllSkipableVarIsEmptyArray"],字串,是否允許每個可省略參數都為空陣列,預設為"true"允許,反之為"false".
368
		#$conf["disallowAllSkipableVarIsEmptyArray"]="";
369
		#$conf["arrayCountEqualCheck"],字串陣列,為檢查哪些陣列參數的元素數量要一樣,$conf["arrayCountEqualCheck"][$i]=array()為第$i組key為哪些的變數其元素數量要相等.
370
		#$conf["arrayCountEqualCheck"][]=array();
371
		#參考資料來源:
372
		#array_keys=>http://php.net/manual/en/function.array-keys.php
373
		$checkArguments=variableCheck::checkArguments($conf["variableCheck::checkArguments"]);
374
		unset($conf["variableCheck::checkArguments"]);
226 liveuser 375
 
3 liveuser 376
		#如果檢查失敗
377
		if($checkArguments["status"]=="false"){
378
 
379
			#設置錯誤狀態
380
			$result["status"]="false";
381
 
382
			#設置錯誤提示
383
			$result["error"]=$checkArguments;
384
 
385
			#回傳結果
386
			return $result;
387
 
388
			}#if end
389
 
390
		#如果檢查不通過
391
		if($checkArguments["passed"]=="false"){
392
 
393
			#設置錯誤狀態
394
			$result["status"]="false";
395
 
396
			#設置錯誤提示
397
			$result["error"]=$checkArguments;
398
 
399
			#回傳結果
400
			return $result;
401
 
402
			}#if end
226 liveuser 403
 
3 liveuser 404
		#函式說明:
405
		#將要執行的script語法透過該函式執行(會在程式外層用<script></script>包起來).
406
		#回傳結果:
407
		#$result["status"],執行是否正常,"true"為正常,"false"為不正常.
408
		#$result["error"],錯誤訊息陣列
409
		#$result["function"],當前執行的函數名稱
410
		#$result["content"],要執行的javaScript語法
411
		#必填參數:
412
		#$conf["script"],字串,要執行的javaScript語法.
413
		$conf["javaScript::toScript"]["script"]="
226 liveuser 414
 
415
 
416
 
3 liveuser 417
		var copyRightSpan=document.createElement('span');
418
		var copyRightText=document.createTextNode('".$conf["name"]."');
419
		copyRightSpan.appendChild(copyRightText);
226 liveuser 420
 
207 liveuser 421
		//建立power by span
3 liveuser 422
		var powerBySpan=document.createElement('span');
423
		var powerByA=document.createElement('a');
424
		powerByA.href='".$conf["powerByLink"]."';
425
		powerByA.target='_blank';
426
		var powerByText=document.createTextNode('Powered by '+'".$conf["powerBy"]."');
427
		powerByA.appendChild(powerByText);
428
		powerBySpan.appendChild(powerByA);
226 liveuser 429
 
207 liveuser 430
		//建立 copy right div
431
		var copyRightDiv=document.createElement('div');
3 liveuser 432
		copyRightDiv.appendChild(copyRightSpan);
433
		copyRightDiv.appendChild(powerBySpan);
434
		copyRightDiv.style.backgroundColor='".$conf["bgColor"]."';
435
		copyRightDiv.style.textAlign='center';
226 liveuser 436
 
207 liveuser 437
		//顯現 copy right
3 liveuser 438
		document.body.appendChild(copyRightDiv);
226 liveuser 439
 
3 liveuser 440
		";
441
		#可省略參數:
442
		#$conf["onReady"],字串,是否要在網頁完全載入後再執行,"false"為不等載入完就先執行,預設為"true"要等載入完再執行.
443
		#$conf["onReady"]="true";
444
		#$conf["globalJs"],字串陣列,為要放入<script>標籤的js全域變數.
445
		#$conf["globalJs"]=array();
446
		#$conf["jsFunciton"],字串陣列,為要放入<script>標籤的js函數.
447
		#$conf["jsFunciton"]=array();
448
		#參考資料:
449
		#http://stackoverflow.com/questions/9899372/pure-javascript-equivalent-to-jquerys-ready-how-to-call-a-function-when-the
450
		$toScript=javaScript::toScript($conf["javaScript::toScript"]);
451
		unset($conf["javaScript::toScript"]);
226 liveuser 452
 
3 liveuser 453
		#如果建立 javascript 語法失敗
226 liveuser 454
		if($toScript["status"]==="false"){
455
 
3 liveuser 456
			#設置執行失敗
457
			$result["status"]="false";
226 liveuser 458
 
3 liveuser 459
			#設置執行錯誤訊息
460
			$result["error"]=$toScript;
461
 
462
			#回傳結果
226 liveuser 463
			return $result;
464
 
3 liveuser 465
			}#if end
226 liveuser 466
 
467
		#傳接 content
3 liveuser 468
		$result["content"]=$result["content"].$toScript["content"];
226 liveuser 469
 
3 liveuser 470
		#保護版權的語法
471
		#oncontextmenu,按下滑鼠右鍵
472
		#onContextMenu,按下滑鼠右鍵
473
		#ondragstart,開始拖曳
474
		#onselsect,選取區塊時
475
		#onselectstart,開始選取區塊
476
		#onkeydown='if(event.tKey && event.ctrlKey),按下ctrl+t開分頁時
477
		$result["content"]=$result["content"]."
478
			<html
226 liveuser 479
			oncontextmenu=\"return false\"
3 liveuser 480
			onContextMenu=\"window.event.returnValue=false\"
481
			onselect=\"return false\"
226 liveuser 482
			onselectstart=\"return false\"
483
			ondragstart=\"return false\"
3 liveuser 484
			oncopy=\"return false\"
485
			onbeforeprint=\"return false\"
486
			>\r\n";
226 liveuser 487
 
3 liveuser 488
		#設置執行正常
489
		$result["status"]="true";
226 liveuser 490
 
3 liveuser 491
		#回傳語法
492
		return $result;
226 liveuser 493
 
3 liveuser 494
		}#函式結束
495
 
496
	/*
226 liveuser 497
	#函式說明:
3 liveuser 498
	#放置用空白圖片擋住要呈現的圖片
499
	#回傳結果:
500
	#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
501
	#$result["error"],錯誤訊息.
502
	#$result["function"],當前執行的函數名稱.
503
	#$result["content"],語法.
504
	#必填參數:
505
	$conf["imgAddress"],字串,要放的圖片位置和名稱.
506
	$conf["imgAddress"]="";
507
	$conf["imgWidth"],字串,爲圖片的寬.
508
	$conf["imgWidth"]="";
509
	$conf["imgHeight"],字串,爲圖片的高.
510
	$conf["imgHeight"]="";
511
	$conf["imgLeft"]=,字串,爲圖片放置的位置距離網頁左邊多少.
512
	$conf["imgLeft"]="";
513
	$conf["imgTop"]=,字串,爲圖片放置的位置距離網頁頂端多少.
514
	$conf["imgTop"]="";
515
	#可省略參數:
516
	#$conf["useBase64"],字串,是否要用base64的方式呈現圖片,預設為"true"代表要用base64的方式呈現,反之可用"false".
517
	#$conf["useBase64"]="true";
518
	#參考資料:
519
	#無.
520
	#備註:
521
	#無.
226 liveuser 522
	*/
3 liveuser 523
	public static function imgProtect(&$conf){
524
 
525
		#初始化要回傳的內容
526
		$result=array();
226 liveuser 527
 
3 liveuser 528
		#取得當前執行的函式
529
		$result["function"]=__FUNCTION__;
226 liveuser 530
 
3 liveuser 531
		#如果 $conf 不為陣列
532
		if(gettype($conf)!="array"){
226 liveuser 533
 
3 liveuser 534
			#設置執行失敗
535
			$result["status"]="false";
226 liveuser 536
 
3 liveuser 537
			#設置執行錯誤訊息
538
			$result["error"][]="\$conf變數須為陣列形態";
539
 
540
			#如果傳入的參數為 null
541
			if($conf==null){
226 liveuser 542
 
3 liveuser 543
				#設置執行錯誤訊息
544
				$result["error"][]="\$conf變數不得為null,請檢查函數「".$result["function"]."」的參數設置有無正確!";
226 liveuser 545
 
3 liveuser 546
				}#if end
547
 
548
			#回傳結果
549
			return $result;
226 liveuser 550
 
3 liveuser 551
			}#if end
552
 
553
		#初始化程式碼
554
		$result["content"]="";
226 liveuser 555
 
3 liveuser 556
		#檢查參數
557
		#函式說明:
558
		#檢查必填與可省略的參數,可省略參數可指定預設要給與什麼數值內容。
559
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
560
		#$reuslt["error"],執行不正常結束的錯訊息陣列.
561
		#$result["function"],當前執行的函式名稱.
562
		#$result["passed"],識別要檢查的全體變數是否存在以及型態是否正確的變數,"true"代表檢查全部通過;"false"代表檢查不通過
563
		#$result[$shouldBtCheckedVarName]["varExist"],所檢查的變數是否存在,"false"代表不存在;"true"代表存在
564
		#$result[$shouldBtCheckedVarName]["varType"],所檢查的變數型態是否正確,"false"代表錯誤;"true"代表正確
565
		#$result[$shouldBtCheckedVarName]["error"],每個參數設定的錯誤訊息
566
		#$result["argu"],字串陣列,目前輸入的參數名稱陣列.
567
		#$result["legalVarName"],字串陣列,合法可用的參數名稱陣列.
568
		#$result["notNeedVar"],字串陣列,多餘的參數名稱.
569
		#必填寫的參數:
570
		#$conf["variableCheck::checkArguments"]["varInput"],陣列變數,要檢查的陣列變數,請在要檢查的參數前面加上&,這樣變動的結果才能被套用。
571
		$conf["variableCheck::checkArguments"]["varInput"]=&$conf;
572
		#$conf["variableCheck::checkArguments"]["mustBeFilledVariableName"],爲必填參數的變數名稱陣列,形態爲陣列變數,元素數量需要跟"mustBeFilledVariableType"參數的元素數量一致,例如: $conf["mustBeFilledVariableName"] = array("id","account","password");
573
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableName"]=array("imgAddress","imgWidth","imgHeight","imgLeft","imgTop");
226 liveuser 574
		#$conf["variableCheck::checkArguments"]["mustBeFilledVariableType"],爲必填參數的變數陣列應該爲何種變數形態,形態爲陣列,元素數量需要跟"mustBeFilledVariableName"參數的元素數量一致,例如: $conf["mustBeFilledVariableType"] = array("string",integer,"double","resource","object");
3 liveuser 575
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableType"]=array("string","string","string","string","string");
576
		#$conf["variableCheck::checkArguments"]["referenceVarKey"],字串,$conf參數後面的key值,用於移除不要的參考陣列.
577
		$conf["variableCheck::checkArguments"]["referenceVarKey"]="variableCheck::checkArguments";
578
		#可以省略的參數:
579
		#$conf["canBeEmptyString"],必填變數內容如果是空字串就不能算是有設置的話,請設為"false",預設爲"true"。
580
		#$conf["canBeEmptyString"]="false";
581
		#$conf["variableCheck::checkArguments"]["skipableVariableName"],爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableName"] = array("id","account","password");
582
		$conf["variableCheck::checkArguments"]["skipableVariableName"]=array("useBase64");
226 liveuser 583
		#$conf["variableCheck::checkArguments"]["skipableVariableType"],爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableType"] = array("string",integer,"double");
3 liveuser 584
		$conf["variableCheck::checkArguments"]["skipableVariableType"]=array("string");
585
		#$conf["variableCheck::checkArguments"]["skipableVarDefaultValue"],字串陣列,每個不存在的可省略變數要初始化為什麼,null與代表不指定,若預設值是參數之一,請將$conf["mustBeFilledVar"]改成"\$conf["\mustBeFilledVar\"]".
586
		$conf["variableCheck::checkArguments"]["skipableVarDefaultValue"]=array("true");
587
		#$conf["arrayCountEqualCheck"],字串陣列,為檢查哪些陣列參數的元素數量要一樣,$conf["arrayCountEqualCheck"][$i]=array()為第$i組key為哪些的變數其元素數量要相等.
588
		#$conf["arrayCountEqualCheck"][]=array();
589
		#參考資料來源:
590
		#array_keys=>http://php.net/manual/en/function.array-keys.php
591
		$checkArguments=variableCheck::checkArguments($conf["variableCheck::checkArguments"]);
592
		unset($conf["variableCheck::checkArguments"]);
226 liveuser 593
 
3 liveuser 594
		#如果檢查失敗
595
		if($checkArguments["status"]=="false"){
226 liveuser 596
 
3 liveuser 597
			#設置執行失敗
598
			$result["status"]="false";
226 liveuser 599
 
3 liveuser 600
			#設置執行錯誤訊息
601
			$result["error"]=$checkArguments;
602
 
603
			#回傳結果
604
			return $result;
226 liveuser 605
 
606
			}#if end
607
 
3 liveuser 608
		#如果檢查不通過
609
		if($checkArguments["passed"]=="false"){
226 liveuser 610
 
3 liveuser 611
			#設置執行失敗
612
			$result["status"]="false";
226 liveuser 613
 
3 liveuser 614
			#設置執行錯誤訊息
615
			$result["error"]=$checkArguments;
616
 
617
			#回傳結果
618
			return $result;
226 liveuser 619
 
3 liveuser 620
			}#if end
621
 
622
		#建立要放置的圖片樣式
226 liveuser 623
		#函式說明:
3 liveuser 624
		#創建 css 樣式
625
		#回傳結果:
626
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
627
		#$result["css"],css設定內容
628
		#$result["function"],當前執行的函數
226 liveuser 629
		#$result["error"],涵式錯誤訊息,若爲""則表示沒有錯誤
3 liveuser 630
		$conf["css"]["createCssStyle"]["cssStyleName"]="imgStyle-".$conf["imgLeft"].$conf["imgTop"];
631
		$conf["css"]["createCssStyle"]["attributes"]=array("width","height","position","top","left");
632
		$conf["css"]["createCssStyle"]["content"]=array($conf["imgWidth"],$conf["imgHeight"],"absolute",$conf["imgTop"],$conf["imgLeft"]);
633
		$css=css::createCssStyle($conf["css"]["createCssStyle"]);
634
		unset($conf["css"]["createCssStyle"]);#清空變數避免出錯
226 liveuser 635
 
3 liveuser 636
		#如果建立css樣式失敗
637
		if($css["status"]=="false"){
226 liveuser 638
 
3 liveuser 639
			#設置執行失敗
640
			$result["status"]="false";
226 liveuser 641
 
3 liveuser 642
			#設置執行錯誤訊息
643
			$result["error"]=$css;
644
 
645
			#回傳結果
646
			return $result;
226 liveuser 647
 
3 liveuser 648
			}#if end
226 liveuser 649
 
3 liveuser 650
		#串接css語法
651
		$result["content"]=$result["content"].$css["css"];
652
 
653
		#如果要用base64顯示圖片
654
		if($conf["useBase64"]=="true"){
226 liveuser 655
 
3 liveuser 656
			#將圖片用base64加密呈現
657
			#函數說明:
658
			#用data:mimeType;base64,imgVar的形式來提供圖片的連結,亦即圖片儲存在變數裡面,本函式包含顯示圖片的語法.
659
			#回傳結果:
660
			#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
661
			#$result["error"],錯誤訊息
662
			#$result["content"],圖片的連結資訊
226 liveuser 663
			#$result["function"],當前執行的函數名稱
3 liveuser 664
			#必填參數:
665
			#$conf["img::data"]["imgPosition"],要轉存成2元碼的圖片檔案位置與名稱
666
			$conf["img::data"]["imgPosition"]=$conf["imgAddress"];
667
			#可省略參數:
668
			#$conf["img::data"]["alt"],若沒有圖片要用什麼文字顯示。
669
			$conf["img::data"]["alt"]="not found";
670
			#$conf["img::data"]["class"],圖片要套用的css樣式名稱.
671
			$conf["img::data"]["class"]="imgStyle-".$conf["imgLeft"].$conf["imgTop"];
672
			#$conf["mimeType"],2元碼的內容是什麼,預設為"image/*".
673
			#$conf["mimeType"]="image/*";
674
			#$conf["compressType"],2元碼壓縮的方式,預設為"base64".
675
			#$conf["compressType"]="base64";
676
			#$conf["delImg"],讀取完圖片檔案後,要移除圖片嗎?"true"代表要移除,"false"代表不要移除,預設為"false".
677
			#$conf["delImg"]="false";
678
			#參考資料:
679
			#將檔案用字串變數儲存起來=>http://php.net/manual/en/function.file-get-contents.php
680
			#壓縮2元碼=>http://php.net/manual/en/function.base64-encode.php
681
			$data=img::data($conf["img::data"]);
682
			unset($conf["img::data"]);
683
 
684
			#將圖片用base64加密呈現失敗
685
			if($data["status"]=="false"){
226 liveuser 686
 
3 liveuser 687
				#設置執行失敗
688
				$result["status"]="false";
226 liveuser 689
 
3 liveuser 690
				#設置執行錯誤訊息
691
				$result["error"]=$data;
692
 
693
				#回傳結果
694
				return $result;
226 liveuser 695
 
3 liveuser 696
				}#if end
226 liveuser 697
 
3 liveuser 698
			#取得用base64放置圖片的語法
699
			$result["content"]=$result["content"].$data["content"];
226 liveuser 700
 
3 liveuser 701
			}#if end
702
 
703
		#反之為一般放置圖片的方式
704
		else{
226 liveuser 705
 
3 liveuser 706
			#放置要放的圖片
707
			#函式說明:
708
			#放置可以套用css樣式的圖片
709
			#回傳結果:
710
			#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
711
			#$result["error"],錯誤訊息陣列
712
			#$result["function"],當前函數執行的名稱
226 liveuser 713
			#$result["content"],印出圖片的語法。
3 liveuser 714
			$conf["img"]["show"]["position"]=$conf["imgAddress"];
715
			$conf["img"]["show"]["alt"]="not found";
716
			$conf["img"]["show"]["class"]="imgStyle-".$conf["imgLeft"].$conf["imgTop"];
717
			$show=img::show($conf["img"]["show"]);
718
			unset($conf["img"]["show"]);#清空變數避免出錯
719
 
720
			#如果放置圖片的語法建立失敗
721
			if($show["status"]=="false"){
226 liveuser 722
 
3 liveuser 723
				#設置執行失敗
724
				$result["status"]="false";
226 liveuser 725
 
3 liveuser 726
				#設置執行錯誤訊息
727
				$result["error"]=$show;
728
 
729
				#回傳結果
730
				return $result;
226 liveuser 731
 
3 liveuser 732
				}#if end
226 liveuser 733
 
3 liveuser 734
			#串接顯示圖片的語法
735
			$result["content"]=$result["content"].$show["content"];
226 liveuser 736
 
3 liveuser 737
			}#else end
738
 
739
		#建立圖片隔離層樣式
740
		$conf["css"]["createCssStyle"]["cssStyleName"]="imgIsolationLayerStyle".$conf["imgLeft"].$conf["imgTop"];
741
		$conf["css"]["createCssStyle"]["attributes"]=array("width","height","opacity","position","top","left");
742
		$conf["css"]["createCssStyle"]["content"]=array($conf["imgWidth"],$conf["imgHeight"],".0","absolute",$conf["imgTop"],$conf["imgLeft"]);
743
		$css=css::createCssStyle($conf["css"]["createCssStyle"]);
744
		unset($conf["css"]["createCssStyle"]);#清空變數避免出錯
226 liveuser 745
 
3 liveuser 746
		#如果建立css樣式失敗
747
		if($css["status"]=="false"){
226 liveuser 748
 
3 liveuser 749
			#設置執行失敗
750
			$result["status"]="false";
226 liveuser 751
 
3 liveuser 752
			#設置執行錯誤訊息
753
			$result["error"]=$css;
754
 
755
			#回傳結果
756
			return $result;
226 liveuser 757
 
3 liveuser 758
			}#if end
226 liveuser 759
 
3 liveuser 760
		#取得圖片隔離層樣式程式碼
761
		$result["content"]=$result["content"].$css["css"];
762
 
763
		#放置隔離層
764
		#函式說明:
765
		#放置可以套用css樣式的圖片
766
		#回傳結果:
767
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
768
		#$result["error"],錯誤訊息陣列
769
		#$result["function"],當前函數執行的名稱
226 liveuser 770
		#$result["content"],印出圖片的語法。
3 liveuser 771
		#必填參數:
772
		$conf["img"]["show"]["position"]="copyRight.png";#圖片位置
773
		#可省略參數:
774
		#$conf["img"]["show"]["alt"]="not found";#若沒有圖片要用什麼文字顯示。
775
		$conf["img"]["show"]["class"]="imgIsolationLayerStyle".$conf["imgLeft"].$conf["imgTop"];#要套用的css樣式類別名稱。
776
		$show=img::show($conf["img"]["show"]);
777
		unset($conf["img"]["show"]);
226 liveuser 778
 
3 liveuser 779
		#如果放置圖片的語法建立失敗
780
		if($show["status"]=="false"){
226 liveuser 781
 
3 liveuser 782
			#設置執行失敗
783
			$result["status"]="false";
226 liveuser 784
 
3 liveuser 785
			#設置執行錯誤訊息
786
			$result["error"]=$show;
787
 
788
			#回傳結果
789
			return $result;
226 liveuser 790
 
3 liveuser 791
			}#if end
226 liveuser 792
 
3 liveuser 793
		#串接顯示隔離層圖片的語法
794
		$result["content"]=$result["content"].$show["content"];
795
 
796
		#執行到這邊代表執行成功
797
		$result["status"]="true";
226 liveuser 798
 
3 liveuser 799
		#回傳語法
800
		return $result;
801
 
802
		}#function imgProtect end
803
 
804
	/*
805
	#函式說明:
806
	#加密php檔案的內容將結果輸出.
807
	#回傳結果:
808
	#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
809
	#$result["error"],錯誤訊息陣列.
810
	#$result["function"],當前執行的函式名稱.
811
	#$result["content"],加密好的php內容字串.
812
	#必填參數:
813
	#$conf["phpFile"],字串,要加密的php檔案位置與名稱.
814
	$conf["phpFile"]="";
815
	#$conf["fileArgu"],字串,php變數__FILE__的內容,亦即該檔案在檔案系統的絕對路徑
816
	$conf["fileArgu"]=__FILE__;
817
	#可省略參數:
818
	#無.
819
	#參考資料:
820
	#無.
821
	#備註:
822
	#僅支援單行只出現<?php、?>、其他內容的PHP檔案格式內容.
823
	*/
824
	public static function encodePHP(&$conf){
226 liveuser 825
 
3 liveuser 826
		#初始化要回傳的內容
827
		$result=array();
226 liveuser 828
 
3 liveuser 829
		#取得當前執行的函式
830
		$result["function"]=__FUNCTION__;
226 liveuser 831
 
3 liveuser 832
		#如果 $conf 不為陣列
833
		if(gettype($conf)!="array"){
226 liveuser 834
 
3 liveuser 835
			#設置執行失敗
836
			$result["status"]="false";
226 liveuser 837
 
3 liveuser 838
			#設置執行錯誤訊息
839
			$result["error"][]="\$conf變數須為陣列形態";
840
 
841
			#如果傳入的參數為 null
842
			if($conf==null){
226 liveuser 843
 
3 liveuser 844
				#設置執行錯誤訊息
845
				$result["error"][]="\$conf變數不得為null,請檢查函數「".$result["function"]."」的參數設置有無正確!";
226 liveuser 846
 
3 liveuser 847
				}#if end
848
 
849
			#回傳結果
850
			return $result;
226 liveuser 851
 
3 liveuser 852
			}#if end
853
 
854
		#初始加密好的php程式內容
855
		$result["content"]="";
226 liveuser 856
 
3 liveuser 857
		#檢查參數
858
		#函式說明:
859
		#檢查必填與可省略的參數,可省略參數可指定預設要給與什麼數值內容。
860
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
861
		#$reuslt["error"],執行不正常結束的錯訊息陣列.
862
		#$result["function"],當前執行的函式名稱.
863
		#$result["passed"],識別要檢查的全體變數是否存在以及型態是否正確的變數,"true"代表檢查全部通過;"false"代表檢查不通過
864
		#$result[$shouldBtCheckedVarName]["varExist"],所檢查的變數是否存在,"false"代表不存在;"true"代表存在
865
		#$result[$shouldBtCheckedVarName]["varType"],所檢查的變數型態是否正確,"false"代表錯誤;"true"代表正確
866
		#$result[$shouldBtCheckedVarName]["error"],每個參數設定的錯誤訊息
867
		#$result["argu"],字串陣列,目前輸入的參數名稱陣列.
868
		#$result["legalVarName"],字串陣列,合法可用的參數名稱陣列.
869
		#$result["notNeedVar"],字串陣列,多餘的參數名稱.
870
		#必填寫的參數:
871
		#$conf["variableCheck::checkArguments"]["varInput"],陣列變數,要檢查的陣列變數,請在要檢查的參數前面加上&,這樣變動的結果才能被套用。
872
		$conf["variableCheck::checkArguments"]["varInput"]=&$conf;
873
		#$conf["variableCheck::checkArguments"]["mustBeFilledVariableName"],爲必填參數的變數名稱陣列,形態爲陣列變數,元素數量需要跟"mustBeFilledVariableType"參數的元素數量一致,例如: $conf["mustBeFilledVariableName"] = array("id","account","password");
874
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableName"]=array("phpFile","fileArgu");
226 liveuser 875
		#$conf["variableCheck::checkArguments"]["mustBeFilledVariableType"],爲必填參數的變數陣列應該爲何種變數形態,形態爲陣列,元素數量需要跟"mustBeFilledVariableName"參數的元素數量一致,例如: $conf["mustBeFilledVariableType"] = array("string",integer,"double","resource","object");
3 liveuser 876
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableType"]=array("string","string");
877
		#$conf["variableCheck::checkArguments"]["referenceVarKey"],字串,$conf參數後面的key值,用於移除不要的參考陣列.
878
		$conf["variableCheck::checkArguments"]["referenceVarKey"]="variableCheck::checkArguments";
879
		#可以省略的參數:
880
		#$conf["canBeEmptyString"],必填變數內容如果是空字串就不能算是有設置的話,請設為"false",預設爲"true"。
881
		#$conf["canBeEmptyString"]="false";
882
		#$conf["variableCheck::checkArguments"]["skipableVariableName"],爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableName"] = array("id","account","password");
883
		#$conf["variableCheck::checkArguments"]["skipableVariableName"]=array("useBase64");
226 liveuser 884
		#$conf["variableCheck::checkArguments"]["skipableVariableType"],爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableType"] = array("string",integer,"double");
3 liveuser 885
		#$conf["variableCheck::checkArguments"]["skipableVariableType"]=array("string");
886
		#$conf["variableCheck::checkArguments"]["skipableVarDefaultValue"],字串陣列,每個不存在的可省略變數要初始化為什麼,null與代表不指定,若預設值是參數之一,請將$conf["mustBeFilledVar"]改成"\$conf["\mustBeFilledVar\"]".
887
		#$conf["variableCheck::checkArguments"]["skipableVarDefaultValue"]=array("true");
888
		#$conf["arrayCountEqualCheck"],字串陣列,為檢查哪些陣列參數的元素數量要一樣,$conf["arrayCountEqualCheck"][$i]=array()為第$i組key為哪些的變數其元素數量要相等.
889
		#$conf["arrayCountEqualCheck"][]=array();
890
		#參考資料來源:
891
		#array_keys=>http://php.net/manual/en/function.array-keys.php
892
		$checkArguments=variableCheck::checkArguments($conf["variableCheck::checkArguments"]);
893
		unset($conf["variableCheck::checkArguments"]);
226 liveuser 894
 
3 liveuser 895
		#如果檢查失敗
896
		if($checkArguments["status"]=="false"){
226 liveuser 897
 
3 liveuser 898
			#設置執行失敗
899
			$result["status"]="false";
226 liveuser 900
 
3 liveuser 901
			#設置執行錯誤訊息
902
			$result["error"]=$checkArguments;
903
 
904
			#回傳結果
905
			return $result;
226 liveuser 906
 
907
			}#if end
908
 
3 liveuser 909
		#如果檢查不通過
910
		if($checkArguments["passed"]=="false"){
226 liveuser 911
 
3 liveuser 912
			#設置執行失敗
913
			$result["status"]="false";
226 liveuser 914
 
3 liveuser 915
			#設置執行錯誤訊息
916
			$result["error"]=$checkArguments;
917
 
918
			#回傳結果
919
			return $result;
226 liveuser 920
 
3 liveuser 921
			}#if end
226 liveuser 922
 
3 liveuser 923
		#函式說明:
924
		#依據行號分隔抓取檔案的內容,結果會回傳一個陣列
925
		#回傳的變數說明:
926
		#$result["status"],執行是否成功,"true"代表成功;"fasle"代表失敗.
927
		#$result["error"],錯誤訊息提示.
928
		#$result["warning"],警告訊息.
929
		#$result["function"],當前執行的函數名稱.
930
		#$result["fileContent"],爲檔案的內容陣列.
931
		#$result["lineCount"],爲檔案內容總共的行數.
932
		#$result["fullContent"],為檔案的完整內容.
933
		#$result["base64data"],為檔案的base64內容.
934
		#$result["mimeType"],為檔案的mime type.
935
		#必填參數:
936
		#$conf["filePositionAndName"],字串,爲檔案的位置以及名稱.
937
		$conf["fileAccess::getFileContent"]["filePositionAndName"]=$conf["phpFile"];
938
		#$conf["fileArgu"],字串,php變數__FILE__的內容,亦即該檔案在檔案系統的絕對路徑
939
		$conf["fileAccess::getFileContent"]["fileArgu"]=$conf["fileArgu"];
940
		#可省略參數:
941
		#$conf["web"],是要取得網路上的檔案則為"true";反之則為"false".
942
		$conf["fileAccess::getFileContent"]["web"]="false";
943
		#參考資料:
944
		#file(),取得檔案內容的行數.
945
		#file=>http:#php.net/manual/en/function.file.php
946
		#rtrim(),剔除透過file()取得每行內容結尾的換行符號.
947
		#filesize=>http://php.net/manual/en/function.filesize.php
948
		$getFileContent=fileAccess::getFileContent($conf["fileAccess::getFileContent"]);
949
		unset($conf["fileAccess::getFileContent"]);
226 liveuser 950
 
3 liveuser 951
		#如果讀取檔案內容失敗
952
		if($getFileContent["status"]==="false"){
226 liveuser 953
 
3 liveuser 954
			#設置執行失敗
955
			$result["status"]="false";
226 liveuser 956
 
3 liveuser 957
			#設置執行錯誤訊息
958
			$result["error"]=$getFileContent;
959
 
960
			#回傳結果
961
			return $result;
226 liveuser 962
 
3 liveuser 963
			}#if end
226 liveuser 964
 
3 liveuser 965
		#加密過後的php內容
966
		$contentWithoutPhpTagArray=array();
226 liveuser 967
 
3 liveuser 968
		#識別是否開始php語法了.
969
		$isPHP=false;
226 liveuser 970
 
3 liveuser 971
		#識別是否讀取到php tag開頭
972
		$phpStart=false;
226 liveuser 973
 
3 liveuser 974
		#識別是否讀取到php tag結尾
975
		$phpEed=true;
226 liveuser 976
 
3 liveuser 977
		#針對每行內容
978
		foreach($getFileContent["fileContent"] as $index=>$line){
226 liveuser 979
 
3 liveuser 980
			#debug
981
			#echo "處理第".($index+1)."行".PHP_EOL;
226 liveuser 982
 
3 liveuser 983
			#函式說明:
984
			#將固定格式的字串分開,並回傳分開的結果。
985
			#回傳結果:
986
			#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
987
			#$result["error"],錯誤訊息陣列
988
			#$result["function"],當前執行的函數名稱.
989
			#$result["argu"],使用的參數.
990
			#$result["oriStr"],要分割的原始字串內容
991
			#$result["dataArray"],爲分割好字串的陣列內容,$result["dataArray"][$i]爲第($i+1)段的內容。
992
			#$result["dataCounts"],爲總共分成幾段
993
			#$result["found"],是否有在$conf["stringIn"]找到$conf["spiltSymbol"],"true"代表有找到,"false"代表沒有找到.
994
			#必填的參數:
995
			#$conf["stringIn"],字串,要處理的字串.
996
			$conf["stringProcess::spiltString"]["stringIn"]=$line;
997
			#$conf["spiltSymbol"],字串,爲以哪個符號作爲分割.
998
			$conf["stringProcess::spiltString"]["spiltSymbol"]="<?php";
999
			#可省略參數:
1000
			#$conf["allowEmptyStr"],是否允許分割出來空字串,預設為"false"不允許;"true"代表允許.
1001
			$conf["stringProcess::spiltString"]["allowEmptyStr"]="false";
1002
			$spiltString=stringProcess::spiltString($conf["stringProcess::spiltString"]);
1003
			unset($conf["stringProcess::spiltString"]);
1004
 
1005
			#如果執行失敗
1006
			if($spiltString["status"]==="false"){
226 liveuser 1007
 
3 liveuser 1008
				#設置執行失敗
1009
				$result["status"]="false";
226 liveuser 1010
 
3 liveuser 1011
				#設置執行錯誤訊息
1012
				$result["error"]=$spiltString;
1013
 
1014
				#回傳結果
1015
				return $result;
226 liveuser 1016
 
3 liveuser 1017
				}#if end
226 liveuser 1018
 
3 liveuser 1019
			#初始化該行的資訊描述
1020
			$lineInfo=array();
226 liveuser 1021
 
3 liveuser 1022
			#如果沒有關鍵字
1023
			if($spiltString["found"]==="false" && $isPHP===false){
226 liveuser 1024
 
3 liveuser 1025
				#初始化暫存的資訊
1026
				$tempLineInfo=array();
226 liveuser 1027
 
3 liveuser 1028
				#預設該行不是php的內容
1029
				$tempLineInfo["isPHP"]=false;
226 liveuser 1030
 
3 liveuser 1031
				#放置內容
1032
				$tempLineInfo["content"]=$line;
226 liveuser 1033
 
3 liveuser 1034
				#儲存一行資訊描述
1035
				$lineInfo[]=$tempLineInfo;
226 liveuser 1036
 
3 liveuser 1037
				}#if end
1038
 
1039
			#反之有關鍵字且 現在是屬於 php 的範圍
1040
			else if($spiltString["found"]==="false" && $isPHP===true){
226 liveuser 1041
 
3 liveuser 1042
				#確認該段目前沒有 "?".">" 結尾
226 liveuser 1043
 
3 liveuser 1044
				#函式說明:
1045
				#將固定格式的字串分開,並回傳分開的結果。
1046
				#回傳結果:
1047
				#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
1048
				#$result["error"],錯誤訊息陣列
1049
				#$result["function"],當前執行的函數名稱.
1050
				#$result["argu"],使用的參數.
1051
				#$result["oriStr"],要分割的原始字串內容
1052
				#$result["dataArray"],爲分割好字串的陣列內容,$result["dataArray"][$i]爲第($i+1)段的內容。
1053
				#$result["dataCounts"],爲總共分成幾段
1054
				#$result["found"],是否有在$conf["stringIn"]找到$conf["spiltSymbol"],"true"代表有找到,"false"代表沒有找到.
1055
				#必填的參數:
1056
				#$conf["stringIn"],字串,要處理的字串.
1057
				$conf["stringProcess::spiltString"]["stringIn"]=$line;
1058
				#$conf["spiltSymbol"],字串,爲以哪個符號作爲分割.
1059
				$conf["stringProcess::spiltString"]["spiltSymbol"]="?>";
1060
				#可省略參數:
1061
				#$conf["allowEmptyStr"],是否允許分割出來空字串,預設為"false"不允許;"true"代表允許.
1062
				$conf["stringProcess::spiltString"]["allowEmptyStr"]="false";
1063
				$spiltString=stringProcess::spiltString($conf["stringProcess::spiltString"]);
1064
				unset($conf["stringProcess::spiltString"]);
1065
 
1066
				#如果執行失敗
1067
				if($spiltString["status"]==="false"){
226 liveuser 1068
 
3 liveuser 1069
					#設置執行失敗
1070
					$result["status"]="false";
226 liveuser 1071
 
3 liveuser 1072
					#設置執行錯誤訊息
1073
					$result["error"]=$spiltString;
1074
 
1075
					#回傳結果
1076
					return $result;
226 liveuser 1077
 
3 liveuser 1078
					}#if end
226 liveuser 1079
 
3 liveuser 1080
				#反之有關鍵字且 現在是屬於 php 的範圍
1081
				if($spiltString["found"]==="false" && $isPHP===true){
226 liveuser 1082
 
3 liveuser 1083
					#初始化暫存的資訊
1084
					$tempLineInfo=array();
226 liveuser 1085
 
3 liveuser 1086
					#預設該行不是php的內容
1087
					$tempLineInfo["isPHP"]=true;
226 liveuser 1088
 
3 liveuser 1089
					#放置內容
1090
					$tempLineInfo["content"]=$line;
226 liveuser 1091
 
3 liveuser 1092
					#儲存一行資訊描述
1093
					$lineInfo[]=$tempLineInfo;
226 liveuser 1094
 
3 liveuser 1095
					}#if end
226 liveuser 1096
 
3 liveuser 1097
				#反之有找到關鍵字,且現在屬於 php 的範圍
1098
				else if($spiltString["found"]==="true" && $isPHP===true){
1099
 
1100
					#如果分割成0段
1101
					if($spiltString["dataCounts"]===0){
226 liveuser 1102
 
3 liveuser 1103
						#識別是否開始php語法了.
1104
						$isPHP=false;
226 liveuser 1105
 
3 liveuser 1106
						#識別是否讀取到php tag開頭
1107
						$phpStart=false;
226 liveuser 1108
 
3 liveuser 1109
						#識別是否讀取到php tag結尾
1110
						$phpEed=true;
226 liveuser 1111
 
3 liveuser 1112
						}#if end
226 liveuser 1113
 
3 liveuser 1114
					#如果分割成其他段落
1115
					else{
226 liveuser 1116
 
3 liveuser 1117
						#設置執行錯誤訊息
1118
						$result["error"][]="not supported now";
226 liveuser 1119
 
3 liveuser 1120
						}#else end
226 liveuser 1121
 
3 liveuser 1122
					}#if end
226 liveuser 1123
 
3 liveuser 1124
				}#if end
1125
 
1126
			#反之有關鍵字
1127
			else if($spiltString["found"]==="true"){
226 liveuser 1128
 
3 liveuser 1129
				#識別是否開始php語法了.
1130
				$isPHP=true;
226 liveuser 1131
 
3 liveuser 1132
				#識別是否讀取到php tag開頭
1133
				$phpStart=true;
226 liveuser 1134
 
3 liveuser 1135
				#識別是否讀取到php tag結尾
1136
				$phpEed=false;
226 liveuser 1137
 
3 liveuser 1138
				#如果切成兩段
1139
				if($spiltString["dataCounts"]===2){
226 liveuser 1140
 
3 liveuser 1141
					#儲存非 php 的字串
1142
					$noPHPstr=$spiltString["dataArray"][0];
226 liveuser 1143
 
3 liveuser 1144
					#初始化暫存的資訊
1145
					$tempLineInfo=array();
226 liveuser 1146
 
3 liveuser 1147
					#預設該行不是php的內容
1148
					$tempLineInfo["isPHP"]=false;
226 liveuser 1149
 
3 liveuser 1150
					#放置內容
1151
					$tempLineInfo["content"]=$noPHPstr;
226 liveuser 1152
 
3 liveuser 1153
					#儲存屬於 php 的字串
1154
					$phpStr=$spiltString["dataArray"][1];
226 liveuser 1155
 
3 liveuser 1156
					#初始化暫存的資訊
1157
					$tempLineInfo=array();
226 liveuser 1158
 
3 liveuser 1159
					#預設該行不是php的內容
1160
					$tempLineInfo["isPHP"]=true;
226 liveuser 1161
 
3 liveuser 1162
					#放置內容
1163
					$tempLineInfo["content"]=$noPHPstr;
226 liveuser 1164
 
3 liveuser 1165
					}#if end
226 liveuser 1166
 
3 liveuser 1167
				#反之切成一段
1168
				else if($spiltString["dataCounts"]===1){
226 liveuser 1169
 
3 liveuser 1170
					#設置執行失敗
1171
					$result["status"]="false";
226 liveuser 1172
 
3 liveuser 1173
					#設置執行錯誤訊息
1174
					$result["error"][]="not supported now";
1175
 
1176
					#回傳結果
1177
					return $result;
226 liveuser 1178
 
3 liveuser 1179
					}#else end
226 liveuser 1180
 
3 liveuser 1181
				#反之切成0段
1182
				else if($spiltString["dataCounts"]===0){
226 liveuser 1183
 
3 liveuser 1184
					#do nothing
226 liveuser 1185
 
3 liveuser 1186
					}#else end
226 liveuser 1187
 
3 liveuser 1188
				#反之
1189
				else{
1190
					#設置執行失敗
1191
					$result["status"]="false";
226 liveuser 1192
 
3 liveuser 1193
					#設置執行錯誤訊息
1194
					$result["error"][]="not supported now";
1195
 
1196
					#回傳結果
1197
					return $result;
226 liveuser 1198
 
3 liveuser 1199
					}#else end
226 liveuser 1200
 
3 liveuser 1201
				}#else end
1202
 
1203
			#真對每個字串
1204
			foreach($lineInfo as $linfo){
226 liveuser 1205
 
1206
				#記錄起來
3 liveuser 1207
				$contentWithoutPhpTagArray[]=$linfo;
226 liveuser 1208
 
3 liveuser 1209
				}#foreach end
226 liveuser 1210
 
3 liveuser 1211
			}#foreach end
226 liveuser 1212
 
3 liveuser 1213
		#debug
1214
		#var_dump($contentWithoutPhpTagArray);
226 liveuser 1215
 
3 liveuser 1216
		#儲存每行的檔案內容
1217
		$res=array();
226 liveuser 1218
 
3 liveuser 1219
		#php段落
1220
		$phpSection="";
226 liveuser 1221
 
3 liveuser 1222
		#針對每行程式
1223
		foreach($contentWithoutPhpTagArray as $lineInfo){
226 liveuser 1224
 
3 liveuser 1225
			#如果不是 php
1226
			if($lineInfo["isPHP"]===false){
226 liveuser 1227
 
3 liveuser 1228
				#如果有php段落
1229
				if(!empty($phpSection)){
226 liveuser 1230
 
1231
					#加密php程式
3 liveuser 1232
					$encodedPHP=base64_encode($phpSection);
226 liveuser 1233
 
3 liveuser 1234
					#串接內容
1235
					$res[]="<?php eval(base64_decode(\"".$encodedPHP."\")); ?>";
226 liveuser 1236
 
3 liveuser 1237
					}#if end
226 liveuser 1238
 
3 liveuser 1239
				#清空php段落
1240
				$phpSection="";
226 liveuser 1241
 
3 liveuser 1242
				#串接內容
1243
				$res[]=$lineInfo["content"].PHP_EOL;
226 liveuser 1244
 
3 liveuser 1245
				}#if end
226 liveuser 1246
 
3 liveuser 1247
			#反之是 PHP 內容
1248
			else{
1249
				#有內容才處理
1250
				if(!empty($lineInfo["content"])){
226 liveuser 1251
 
3 liveuser 1252
					#串接php語法
1253
					$phpSection=$phpSection.$lineInfo["content"].PHP_EOL;
226 liveuser 1254
 
3 liveuser 1255
					}#if end
226 liveuser 1256
 
3 liveuser 1257
				}#else end
226 liveuser 1258
 
3 liveuser 1259
			}#foreach end
226 liveuser 1260
 
3 liveuser 1261
		#如果有php段落
1262
		if(!empty($phpSection)){
226 liveuser 1263
 
1264
			#加密php程式
3 liveuser 1265
			$encodedPHP=base64_encode($phpSection);
226 liveuser 1266
 
3 liveuser 1267
			#串接內容
1268
			$res[]="<?php eval(base64_decode(\"".$encodedPHP."\")); ?>";
226 liveuser 1269
 
3 liveuser 1270
			}#if end
226 liveuser 1271
 
3 liveuser 1272
		#var_dump($res);exit;
226 liveuser 1273
 
3 liveuser 1274
		#針對每個要寫入的行內容
1275
		foreach($res as $line){
226 liveuser 1276
 
3 liveuser 1277
			$result["content"]=$result["content"].$line;
226 liveuser 1278
 
3 liveuser 1279
			}#foreach end
226 liveuser 1280
 
3 liveuser 1281
		#設置執行正常
1282
		$result["status"]="true";
226 liveuser 1283
 
3 liveuser 1284
		#回傳結果
1285
		return $result;
226 liveuser 1286
 
3 liveuser 1287
		}#function encodePHP end
368 liveuser 1288
 
1289
	/*
1290
	#函式說明:
1291
	#檢查 apache http(s) log 中疑似攻擊的記錄.
1292
	#回傳結果:
1293
	#$result["status"],字串,執行是否正常,"true"代表正常,"false"代表不正常.
1294
	#$result["error"],錯誤訊息陣列.
1295
	#$result["function"],字串,當前執行的函式名稱.
1296
	#$result["content"],陣列,攻擊記錄資訊,每個元素為陣列key為"ip"者為攻擊者的ip;key為info者為其資訊陣列,其key為"log"者代表log的行內容;key為"time"者代表時間點;key為ip者代表ip.
1297
	#必填參數:
1298
	#無.
1299
	#可省略參數:
1300
	#$conf["logPath"],http log的路徑,預設為"/var/log/httpd".
1301
	#$conf["logPath"]="/var/log/httpd";
1302
	#$conf["https"],字串,是否為要查https的log,預設為"false",代表為http.
1303
	#$conf["https"]="false";
1304
	#參考資料:
1305
	#無.
1306
	#備註:
1307
	#目前僅支援 apache 提供的 http(s) 服務.
1308
	#攻擊者的定義包含http回應的code為4開頭或用戶使用 HTTP/1.0 協定或用戶使用 CONNECT method,且時間間隔不超過1秒鐘,次數達到3次.
1309
	*/
1310
	public static function checkHttpAttackLog(&$conf){
1311
 
1312
		#初始化要回傳的結果
1313
		$result=array();
3 liveuser 1314
 
368 liveuser 1315
		#取得當前執行的函數名稱
1316
		$result["function"]=__FUNCTION__;
1317
 
1318
		#取得參數
1319
		$result["argu"]=$conf;
1320
 
1321
		#如果 $conf 不為陣列
1322
		if(gettype($conf)!="array"){
1323
 
1324
			#設置執行失敗
1325
			$result["status"]="false";
1326
 
1327
			#設置執行錯誤訊息
1328
			$result["error"][]="\$conf變數須為陣列形態";
1329
 
1330
			#如果傳入的參數為 null
1331
			if(is_null($conf)){
1332
 
1333
				#設置執行錯誤訊息
1334
				$result["error"][]="\$conf變數不得為null,請檢查函數「".$result["function"]."」的參數設置有無正確!";
1335
 
1336
				}#if end
1337
 
1338
			#回傳結果
1339
			return $result;
1340
 
1341
			}#if end
1342
 
1343
		#函式說明:
1344
		#檢查必填與可省略的參數,可省略參數可指定預設要給與什麼數值內容.
1345
		#回傳結果:
1346
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
1347
		#$result["error"],執行不正常結束的錯訊息陣列.
1348
		#$result["simpleError"],簡單表示的錯誤訊息.
1349
		#$result["function"],當前執行的函式名稱.
1350
		#$result["argu"],設置給予的參數.
1351
		#$result["passed"],識別要檢查的全體變數是否存在以及型態是否正確的變數,"true"代表檢查全部通過;"false"代表檢查不通過
1352
		#$result[$shouldBeCheckedVarName]["varExist"],所檢查的變數是否存在,"false"代表不存在;"true"代表存在
1353
		#$result[$shouldBeCheckedVarName]["varType"],所檢查的變數型態是否正確,"false"代表錯誤;"true"代表正確
1354
		#$result[$shouldBeCheckedVarName]["error"],每個參數設定的錯誤訊息
1355
		#$result["shouldNotBeEmpty"],不應該為空字串或控陣列的變數.
1356
		#$result["argu"],字串陣列,目前輸入的參數名稱陣列.
1357
		#$result["legalVarName"],字串陣列,合法可用的參數名稱陣列.
1358
		#$result["notNeedVar"],字串陣列,多餘的參數名稱.
1359
		#必填參數:
1360
		#$conf["varInput"],陣列變數,要檢查的陣列變數,請在要檢查的參數前面加上&,這樣變動的結果才能被套用。
1361
		$conf["variableCheck::checkArguments"]["varInput"]=&$conf;
1362
		#$conf["referenceVarKey"],字串,$conf參數後面的key值,用於移除不要的參考陣列.
1363
		$conf["variableCheck::checkArguments"]["referenceVarKey"]="variableCheck::checkArguments";
1364
		#可省略參數:
1365
		#$conf["mustBeFilledVariableName"],爲必填參數的變數名稱陣列,形態爲陣列變數,元素數量需要跟"mustBeFilledVariableType"參數的元素數量一致,例如: $conf["mustBeFilledVariableName"] = array("id","account","password");
1366
		#$conf["mustBeFilledVariableName"]=array();
1367
		#$conf["mustBeFilledVariableType"],爲必填參數的變數陣列應該爲何種變數形態,形態爲陣列,元素數量需要跟"mustBeFilledVariableName"參數的元素數量一致,例如: $conf["mustBeFilledVariableType"] = array("string",integer,"double","resource","object"); , null、any代表不指定變數形態.其中 resource也包含"resource (closed)".
1368
		#$conf["mustBeFilledVariableType"]=array();
1369
		#$conf["canBeEmptyString"],字串,必填變數內容如果是空字串就不能算是有設置的話,請設為"false",預設爲"true",可以為空字串.
1370
		#$conf["canBeEmptyString"]="false";
1371
		#$conf["canNotBeEmpty"],字串陣列,哪些必填參數的內容不得為空字串或空陣列,僅當$conf["canBeEmptyString"]為"true"時會生效.
1372
		#$conf["canNotBeEmpty"]=array();
1373
		#$conf["canBeEmpty"],字串陣列,哪些必填參數的內容可為空字串或空陣列,僅當$conf["canBeEmptyString"]為"false"時會生效.
1374
		#$conf["canBeEmpty"]=array();
1375
		#$conf["skipableVariableCanNotBeEmpty"],字串陣列,哪些可省略參數不可以為空字串或空陣列.
1376
		$conf["variableCheck::checkArguments"]["skipableVariableCanNotBeEmpty"]=array("logPath","https");
1377
		#$conf["skipableVariableName"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableName"] = array("id","account","password");
1378
		$conf["variableCheck::checkArguments"]["skipableVariableName"]=array("logPath","https");
1379
		#$conf["skipableVariableType"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableType"] = array("string",integer,"double");
1380
		$conf["variableCheck::checkArguments"]["skipableVariableType"]=array("string","string");
1381
		#$conf["skipableVarDefaultValue"],字串陣列,每個不存在的可省略變數要初始化為什麼,null與代表不指定,若預設值是參數之一,請將$conf["mustBeFilledVar"]改成"\$conf["\mustBeFilledVar\"]".
1382
		$conf["variableCheck::checkArguments"]["skipableVarDefaultValue"]=array("/var/log/httpd","false");
1383
		#$conf["disallowAllSkipableVarIsEmpty"],字串,是否允許每個可省略參數都為空字串,預設為"true"允許,反之為"false".
1384
		#$conf["disallowAllSkipableVarIsEmpty"]="";
1385
		#$conf["disallowAllSkipableVarIsEmptyArray"],字串,是否允許每個可省略參數都為空陣列,預設為"true"允許,反之為"false".
1386
		#$conf["disallowAllSkipableVarIsEmptyArray"]="";
1387
		#$conf["disallowAllSkipableVarNotExist"],字串,是否不允許每個可省略參數都不存在,預設為"false"代表允許,反之為"true".
1388
		#$conf["disallowAllSkipableVarNotExist"]="";
1389
		#$conf["arrayCountEqualCheck"],字串陣列,為檢查哪些陣列參數的元素數量要一樣,$conf["arrayCountEqualCheck"][$i]=array()為第$i組key為哪些的變數其元素數量要相等.
1390
		#$conf["arrayCountEqualCheck"][]=array();
1391
		#參考資料:
1392
		#array_keys=>http://php.net/manual/en/function.array-keys.php
1393
		#備註:
1394
		#無.
1395
		$checkArguments=variableCheck::checkArguments($conf["variableCheck::checkArguments"]);
1396
		unset($conf["variableCheck::checkArguments"]);
1397
 
1398
		#預設為http的log
1399
		$logFile="access_log";
1400
 
1401
		#如果 https 為 "true"
1402
		if($conf["https"]==="true"){
1403
 
1404
			#設置為 https 的 log
1405
			$logFile="ssl_access_log";
1406
 
1407
			}#if end
1408
 
1409
		#取得 http 存取記錄的 log
1410
		#函式說明:
1411
		#依據行號分隔抓取檔案的內容,結果會回傳一個陣列
1412
		#回傳的變數說明:
1413
		#$result["status"],執行是否成功,"true"代表成功;"fasle"代表失敗.
1414
		#$result["error"],錯誤訊息提示.
376 liveuser 1415
		#$result["fileNotExist"],字串,"true"代表目標檔案不存在;"false"代表目標檔案存在.
1416
		#$result["fileCreated"],字串,"true"代表目標檔案被本函式建立;"false"代表檔案不是透過本函式建立.
368 liveuser 1417
		#$result["function"],當前執行的函數名稱.
1418
		#$result["fileContent"],爲檔案的內容陣列.
1419
		#$result["lineCount"],爲檔案內容總共的行數.
1420
		#$result["fullContent"],為檔案的完整內容.
1421
		#$result["base64dataOnly"],檔案的base64data.
1422
		#$result["base64data"],為在網頁上給予src參數的數值.
1423
		#$result["mimeType"],為檔案的mime type.
1424
		#必填參數:
1425
		#$conf["filePositionAndName"],字串,爲檔案的位置以及名稱.
1426
		$conf["fileAccess::getFileContent"]["filePositionAndName"]=$conf["logPath"]."/".$logFile;
1427
		#$conf["fileArgu"],字串,php變數__FILE__的內容,亦即該檔案在檔案系統的絕對路徑
1428
		$conf["fileAccess::getFileContent"]["fileArgu"]=__FILE__;
1429
		#可省略參數:
1430
		#$conf["web"],是要取得網路上的檔案則為"true";反之預設為"false".
1431
		#$conf["web"]="true";
1432
		#$conf["createIfnotExist"],字串,預設為"false"代表檔案不存在也不需要建立;反之為"true".
1433
		#$conf["createIfnotExist"]="false";
1434
		#$conf["autoDeleteSpaceOnEachLineStart"],字串,預設為"false",不做額外處理;反之為"true"
1435
		#$conf["autoDeleteSpaceOnEachLineStart"]="false";
392 liveuser 1436
		#$conf["disableReturnBase64"],字串,預設為"false"代表要回傳base64結果,反之為"true".
1437
		$conf["fileAccess::getFileContent"]["disableReturnBase64"]="true";
368 liveuser 1438
		#參考資料:
1439
		#file(),取得檔案內容的行數.
1440
		#file=>http:#php.net/manual/en/function.file.php
1441
		#rtrim(),剔除透過file()取得每行內容結尾的換行符號.
1442
		#filesize=>http://php.net/manual/en/function.filesize.php
1443
		#參考資料:
1444
		#無.
1445
		#備註:
1446
		#無.
1447
		$getFileContent=fileAccess::getFileContent($conf["fileAccess::getFileContent"]);
1448
		unset($conf["fileAccess::getFileContent"]);
1449
 
1450
		#如果執行失敗
1451
		if($getFileContent["status"]==="false"){
1452
 
376 liveuser 1453
			#如果檔案不存在
1454
			if($getFileContent["fileNotExist"]==="true"){
1455
 
1456
				#設置結果
1457
				$result["content"]=array();
1458
 
1459
				#設置執行正常
1460
				$result["status"]="true";
1461
 
1462
				#回傳結果
1463
				return $result;
1464
 
1465
				}#if end
1466
 
368 liveuser 1467
			#設置執行失敗
1468
			$result["status"]="false";
1469
 
1470
			#設置錯誤訊息
1471
			$result["error"]=$getFileContent;
1472
 
1473
			#回傳結果
1474
			return $result;
1475
 
1476
			}#if end
1477
 
1478
		/*
1479
		http log 範例:
1480
		36.149.205.198 - - [22/Jun/2026:15:49:21 +0800] "CONNECT api.ipapi.is:443 HTTP/1.1" 200 -
1481
		36.149.205.198 - - [22/Jun/2026:15:49:24 +0800] "CONNECT ipwho.is:443 HTTP/1.1" 200 -
1482
		36.149.205.198 - - [22/Jun/2026:15:49:18 +0800] "CONNECT push.services.mozilla.com:443 HTTP/1.1" 200 -
1483
		120.48.6.159 - - [22/Jun/2026:15:49:20 +0800] "CONNECT ifconfig.me:443 HTTP/1.1" 200 -
1484
		36.149.205.198 - - [22/Jun/2026:15:49:24 +0800] "CONNECT ipwho.is:443 HTTP/1.1" 200 -
1485
		36.149.205.198 - - [22/Jun/2026:15:49:25 +0800] "CONNECT api.ipapi.is:443 HTTP/1.1" 200 -
1486
		36.149.205.198 - - [22/Jun/2026:15:49:28 +0800] "CONNECT ipwho.is:443 HTTP/1.1" 200 -
1487
		36.149.205.198 - - [22/Jun/2026:15:49:30 +0800] "CONNECT nexus.officeapps.live.com:443 HTTP/1.1" 200 -
1488
		172.238.244.28 - - [22/Jun/2026:15:49:31 +0800] "GET / HTTP/1.0" 400 402
1489
		36.149.205.198 - - [22/Jun/2026:15:49:29 +0800] "CONNECT api.ipapi.is:443 HTTP/1.1" 200 -
1490
		36.149.205.198 - - [22/Jun/2026:15:49:33 +0800] "CONNECT qaz23.com:2869 HTTP/1.1" 403 353
1491
		36.149.205.198 - - [22/Jun/2026:15:49:34 +0800] "CONNECT qaz23.com:2869 HTTP/1.1" 403 353
1492
		*/
1493
 
1494
		#初始化給予 search::getMatchFormatsStrings 使用的 formats 參數
1495
		$formatsParamsOfsearchGetMatchFormatsStrings=array();		
1496
		$formatsParamsOfsearchGetMatchFormatsStrings[]="\${ip} \${doNotNeed} [\${day}/\${month}/\${year}:\${hour}:\${min}:\${sec} \${timezone}] \${method} \${path} \${protocol} \${responseCode} \${bytesSend}";
1497
 
1498
		#尋找 http code 為 4xx 的內容行
1499
		#函式說明:
1500
		#尋找多個字串中是否含有符合多個格式之一的內容,且回傳解析好的變數數值.
1501
		#回傳結果:
1502
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
1503
		#$reuslt["error"],執行不正常結束的錯訊息陣列.
1504
		#$result["function"],當前執行的函式名稱.
1505
		#$result["argu"],所使用的參數.
1506
		#$result["found"],是否有找到符合格式的字串內容,"true"代表有找到,"false"代表沒有找到.
1507
		#$result["content"],陣列,第一維為對應formats參數的索引,第二維的key為lineNo者為inputs參數的索引;第二維的key為content者為符合的資訊,若為n個${*},則當found為"true"時,就會回傳n個元素;第二維的key為parsedVar者為符合的資訊,其數值以變數名稱作為索引,元素的索引為0~N,代表有幾個符合的同名變數.
1508
		#必填參數:
1509
		#$conf["inputs"],字串陣列,要檢查的字串集合.
1510
		$conf["search::getMatchFormatsStrings"]["inputs"]=$getFileContent["fileContent"];
1511
		#$conf["format"],格式字串陣列,要尋找的可能格式字串集合.格式為固定的字串("fixedStr format")與變數("${keyWordVarName}")組成.
1512
		$conf["search::getMatchFormatsStrings"]["formats"]=$formatsParamsOfsearchGetMatchFormatsStrings;
1513
		#可省略參數:
1514
		#無.
1515
		#參考資料:
1516
		#無.
1517
		#備註:
1518
		#無.
1519
		$getMatchFormatsStrings=search::getMatchFormatsStrings($conf["search::getMatchFormatsStrings"]);
1520
		unset($conf["search::getMatchFormatsStrings"]);
1521
 
1522
		#如果執行異常
1523
		if($getMatchFormatsStrings["status"]==="false"){
1524
 
1525
			#設置執行失敗
1526
			$result["status"]="false";
1527
 
1528
			#設置錯誤訊息
1529
			$result["error"]=$getMatchFormatsStrings;
1530
 
1531
			#回傳結果
1532
			return $result;
1533
 
1534
			}#if end
1535
 
1536
		#如果沒有符合的項目
1537
		if($getMatchFormatsStrings["found"]==="false"){
1538
 
1539
			#設置結果
1540
			$result["content"]=array();
1541
 
1542
			#設置執行正常
1543
			$result["status"]="true";
1544
 
1545
			#回傳結果
1546
			return $result;
1547
 
1548
			}#if end
1549
 
1550
		#初始化要處理的ip資訊
1551
		$ips=array();
1552
 
1553
		#初始化用 ip 為索引來儲存資料行
1554
		$ips_byIp=array();
1555
 
1556
		#針對每個符合的規則
1557
		foreach($getMatchFormatsStrings["content"] as $matchInfo){
1558
 
1559
			#取得符合條件的行索引
1560
			$index=$matchInfo["lineNo"];
1561
 
1562
			#取得用戶要求的method
1563
			$method=$matchInfo["parsedVar"][0]["method"][0];
1564
 
1565
			#取得用戶要求的protocal
1566
			$protocol=$matchInfo["parsedVar"][0]["protocol"][0];
1567
 
1568
			#取得回應的code
1569
			$responseCode=$matchInfo["parsedVar"][0]["responseCode"][0];
1570
 
1571
			#如果 method 為 "CONNECT"
1572
			if($method==="CONNECT"){
1573
 
1574
				#這裡不做事情,但後面繼續執行
1575
 
1576
				}#if end
1577
 
1578
			#如果 protocol 為 "HTTP/1.0"
1579
			else if($protocol==="HTTP/1.0"){
1580
 
1581
				#這裡不做事情,但後面繼續執行
1582
 
1583
				}#if end
1584
 
1585
			#如果回應的 code 不為 4 開頭
1586
			else if($responseCode[0]!=="4"){
1587
 
1588
				#略過,看下一行
1589
				continue;
1590
 
1591
				}#if end
1592
 
1593
			#取得用戶要求的路徑
1594
			$path=$matchInfo["parsedVar"][0]["path"][0];
1595
 
1596
			#剔除要求的資源名稱結尾為 ".css" ".js" "favicon.ico" ".jpg" ".png" 者. - start
1597
 
1598
			#函式說明:
1599
			#尋找字串中是否含有符合多個格式之一的內容,且回傳解析好的變數數值.
1600
			#回傳結果:
1601
			#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
1602
			#$reuslt["error"],執行不正常結束的錯訊息陣列.
1603
			#$result["function"],當前執行的函式名稱.
1604
			#$result["argu"],所使用的參數.
1605
			#$result["found"],是否有找到符合格式的字串內容,"true"代表有找到,"false"代表沒有找到.
1606
			#$result["content"],陣列,若為n個${*},則當found為"true"時,就會回傳n個元素.
1607
			#必填參數:
1608
			#$conf["input"],字串,要檢查的字串.
1609
			$conf["search::findSpecifyStrFormats"]["input"]=$getFileContent["fileContent"][$index];
1610
			#$conf["format"],格式字串陣列,要尋找的可能格式字串集合.格式為固定的字串("fixedStr format")與變數("${keyWordVarName}")組成.
1611
			$conf["search::findSpecifyStrFormats"]["formats"]=array("\${str}.css","\${str}.js","\${str}.favicon.ico","\${str}.jpg","\${str}.jpeg","\${str}.png","\${str}.webp");
1612
			#可省略參數:
1613
			#無.
1614
			#參考資料:
1615
			#無.
1616
			#備註:
1617
			#無.
1618
			$findSpecifyStrFormats=search::findSpecifyStrFormats($conf["search::findSpecifyStrFormats"]);
1619
			unset($conf["search::findSpecifyStrFormats"]);
1620
 
1621
			#如果執行異常
1622
			if($findSpecifyStrFormats["status"]==="false"){
1623
 
1624
				#設置執行失敗
1625
				$result["status"]="false";
1626
 
1627
				#設置錯誤訊息
1628
				$result["error"]=$findSpecifyStrFormats;
1629
 
1630
				#回傳結果
1631
				return $result;
1632
 
1633
				}#if end
1634
 
1635
			#如果有符合的項目
1636
			if($findSpecifyStrFormats["found"]==="true"){
1637
 
1638
				#略過,看下一行
1639
				continue;
1640
 
1641
				}#if end
1642
 
1643
			#剔除要求的資源名稱結尾為 ".css" ".js" "favicon.ico" ".jpg" ".jpeg" ".png" ".webp" 者. - end
1644
 
1645
			#時間格式的參考
1646
			# [\${day}/\${month}/\${year}:\${hour}:\${min}:\${sec} \${timezone}]
1647
 
1648
			#取得 log 的時間點
1649
			$time=$matchInfo["parsedVar"][0]["day"][0]."/".$matchInfo["parsedVar"][0]["month"][0]."/".$matchInfo["parsedVar"][0]["year"][0].":".$matchInfo["parsedVar"][0]["hour"][0].":".$matchInfo["parsedVar"][0]["min"][0].":".$matchInfo["parsedVar"][0]["sec"][0]." ".$matchInfo["parsedVar"][0]["timezone"][0];
1650
 
1651
			#以 ip 為索引來儲存資料行
1652
			$ips_byIp[$matchInfo["parsedVar"][0]["ip"][0]][]=array("log"=>$getFileContent["fileContent"][$index],"time"=>$time,"ip"=>$matchInfo["parsedVar"][0]["ip"][0]);
1653
 
1654
			}#foreach end
1655
 
1656
		#針對每個可能有問題的IP
1657
		foreach($ips_byIp as $ip => $infos){
1658
 
1659
			#計數 ip 於同時間前來的計數
1660
			$ipSameTimeCount=0;
1661
 
1662
			#用來存放來存取的同一時間
1663
			$ipSameTime="";
1664
 
1665
			#看來拜訪的時間點
1666
			foreach($infos as $info){
1667
 
1668
				#如果是初次
1669
				if($ipSameTime===""){
1670
 
1671
					#記錄時間點
1672
					$ipSameTime=$info["time"];
1673
 
1674
					#同時間點計數加1
1675
					$ipSameTimeCount++;
1676
 
1677
					}#if end
1678
 
1679
				#反之如果時間點相同
1680
				else if($ipSameTime===$info["time"]){
1681
 
1682
					#同時間點計數加1
1683
					$ipSameTimeCount++;
1684
 
1685
					}#if end
1686
 
1687
				#反之時間點不相同
1688
				else{
1689
 
1690
					#記錄時間點
1691
					$ipSameTime=$info["time"];
1692
 
1693
					#同時間點計數重設為1
1694
					$ipSameTimeCount=1;
1695
 
1696
					}#else end
1697
 
1698
				#如果同時間的計數達到3
1699
				if($ipSameTimeCount===3){
1700
 
1701
					#初始化暫存的陣列
1702
					$tmp=array();
1703
 
1704
					#儲存資訊
1705
					$tmp["info"]=$infos;
1706
 
1707
					#儲存ip
1708
					$tmp["ip"]=$info["ip"];
1709
 
1710
					#取得有問題的IP
1711
					$ips[]=$tmp;
1712
 
1713
					#換檢查下一個IP
1714
					continue 2;
1715
 
1716
					}#if end
1717
 
1718
				}#foreach end
1719
 
1720
			}#foreach end
1721
 
1722
		#設置結果
1723
		$result["content"]=$ips;
1724
 
1725
		#設置執行正常
1726
		$result["status"]="true";
1727
 
1728
		#回傳結果
1729
		return $result;
1730
 
1731
		}#funcion checkHttpAttackLog end
1732
 
1733
	/*
1734
	#函式說明:
1735
	#檢查 postfixv log 中疑似攻擊的記錄.
1736
	#回傳結果:
1737
	#$result["status"],字串,執行是否正常,"true"代表正常,"false"代表不正常.
1738
	#$result["error"],錯誤訊息陣列.
1739
	#$result["function"],字串,當前執行的函式名稱.
1740
	#$result["content"],陣列,攻擊記錄資訊,每個元素為陣列key為"ip"者為攻擊者的ip;key為info者為其資訊陣列,其key為"log"者代表log的行內容;key為"time"者代表時間點;key為ip者代表ip.
1741
	#必填參數:
1742
	#無.
1743
	#可省略參數:
1744
	#無
1745
	#參考資料:
1746
	#無.
1747
	#備註:
1748
	#無.
1749
	*/
1750
	public static function checkPostfixAttackLog(){
1751
 
1752
		#初始化要回傳的結果
1753
		$result=array();
1754
 
1755
		#取得當前執行的函數名稱
1756
		$result["function"]=__FUNCTION__;
1757
 
1758
		#透過 journalctl -a -e -f --unit=postfix.service | grep "authentication failed" 來取得認證失敗的 ip
1759
		#函式說明:
1760
		#呼叫shell執行系統命令,並取得回傳的內容.
1761
		#回傳的結果:
1762
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
1763
		#$result["error"],錯誤訊息陣列.
1764
		#$result["function"],當前執行的函式名稱.
1765
		#$result["argu"],使用的參數.
1766
		#$result["cmd"],執行的指令內容.
1767
		#$result["fullCmd"],如果參數 $conf["inBackGround"] 為 "true" 則會回傳該值.
1768
		#$result["output"],爲執行完二元碼後的輸出陣列,若 $conf["inBackGround"] 為 "true",則為當下的輸出.
1769
		#$result["tmpFileOutput"],儲存輸出的暫存檔案名稱,若 $conf["inBackGround"] 為 "true" 則會回傳該值.
1770
		#$result["running"],是否還在執行.
1771
		#$result["pid"],pid.
1772
		#$result["statusCode"],執行結束後的代碼.
1773
		#必填參數:
1774
		#$conf["command"],字串,要執行的指令與.
1775
		$conf["external::callShell"]["command"]="journalctl";
1776
		#$conf["fileArgu"],字串,變數__FILE__的內容.
1777
		$conf["external::callShell"]["fileArgu"]=__FILE__;
1778
		#可省略參數:
1779
		#$conf["argu"],陣列字串,指令搭配的參數,預設為空陣列.
1780
		$conf["external::callShell"]["argu"]=array("-a","-e","--unit=postfix.service","|","grep","authentication failed","|","cat");
1781
		#$conf["arguIsAddr"],陣列字串,指令搭配的哪些參數為路徑,為路徑的參數會進行轉換以便符合呼叫當前函式的位置,預設不指定,若有3個參數,其中第3個參數為路徑,則表示為array("false","false","true").
1782
		#$conf["arguIsAddr"]=array();
1783
		#$conf["pre"],陣列,要在本指令前執行的每個指令與參數.
1784
		#$conf["pre"][$i]["cmd"],字串,要在本指令前執行的第$i+1個指令.
1785
		#$conf["pre"][$i]["param"],陣列字串,要在本指令前執行的第$i+1個指令的參數.
1786
		#$conf["enablePrintDescription"],字串,是否要印出$conf["printDescription"]的內容,"true"代表要,"false"代表不要,預設為"false".
1787
		#$conf["enablePrintDescription"]="true";
1788
		#$conf["printDescription"],字串,執行該外部程式前要印出來的的文字,預設為$conf["command"]的內容加上使用的$conf["argu"]參數.
1789
		#$conf["printDescription"]="";
1790
		#$conf["escapeshellarg"],字串,是否要啟用過濾參數,用了比較安全,但可能會出錯,"true"為啟用,"false"為不啟用,預設為"false".
1791
		$conf["external::callShell"]["escapeshellarg"]="true";
1792
		#$conf["username"],字串,要用什麼使用者來執行,預設為執行php的使用者,該參數不適用於apache環境.
1793
		#$conf["username"]="";
1794
		#$conf["password"],字串,root的使用者密碼,預設不使用密碼,該參數不適用於apache環境.
1795
		#$conf["password"]="";
1796
		#$conf["useScript"],字串,是否要啟用Linux的script指令來記錄輸出,"true"代表要,Fedora的selinux會擋住該操作;"false"代表不要,預設為"false".
1797
		#$conf["useScript"]="";
1798
		#$conf["logFilePath"],字串,當 $conf["useScript"] 為 "true" 時,輸出的內容要暫存到哪裡,預設為 "/tmp/.qbpwcf_tmp/external/callShell/".
1799
		#$conf["logFilePath"]=".qbpwcf_tmp/external/callShell/";
1800
		#$conf["inBackGround"],字串,是否要在背景執行,且不會等待程式執行結束再執行下一個指令,"true"代表是,"false"代表不要,預設為"false",如果$conf["command"]有用「;」區隔的多個指令將會出錯.
1801
		#$conf["inBackGround"]="";
1802
		#$conf["getErr"],字串,"true"代表將錯誤輸出變成標準輸出,反之"false"為不變動.
1803
		#$conf["getErr"]="false";
1804
		#備註:
1805
		#不是所有指令都能用apache的身份執行,目前已知java,javac指令無法執行,使用root身份可能會被selinux阻擋.
1806
		#參考資料:
1807
		#exec=>http://php.net/manual/en/function.exec.php
1808
		#escapeshellcmd=>http://php.net/manual/en/function.escapeshellcmd.php
1809
		#escapeshellarg=>http://php.net/manual/en/function.escapeshellarg.php
1810
		$callShell=external::callShell($conf["external::callShell"]);
1811
		unset($conf["external::callShell"]);
1812
 
1813
		if($callShell["status"]==="false"){
1814
 
1815
			#如果有 statusCode
1816
			if(isset($callShell["statusCode"])){
1817
 
1818
				#如果shell回傳不為0也不為1
1819
				if($callShell["statusCode"]!==0 && $callShell["statusCode"]!==1){
1820
 
1821
					#設置執行失敗
1822
					$result["status"]="false";
1823
 
1824
					#設置錯誤訊息
1825
					$result["error"]=$callShell;
1826
 
1827
					#回傳結果
1828
					return $result;
1829
 
1830
					}#if end
1831
 
1832
				}#if end
1833
 
1834
			#設置執行失敗
1835
			$result["status"]="false";
1836
 
1837
			#設置錯誤訊息
1838
			$result["error"]=$callShell;
1839
 
1840
			#回傳結果
1841
			return $result;
1842
 
1843
			}#if end
1844
 
1845
		#儲存有問題的smtp IP
1846
		$ips_smtp=array();
1847
 
1848
		#狀態碼不為1才執行
1849
		if($callShell["statusCode"]!==1){
1850
 
1851
			#初始化記錄每行log的時間點
1852
			$occurTime=array();
1853
 
1854
			#初始化儲存log行資訊的變數
1855
			$oriLog=array();
1856
 
1857
			#根據每筆記錄
1858
			foreach($callShell["output"] as $index => $line){
1859
 
1860
				#截取出的格式
1861
				#Sep 28 07:54:16 qbpwcf.org postfix/smtpd[2766456]: warning: unknown[158.94.208.72]: SASL LOGIN authentication failed: (reason unavailable), sasl_username=1q2w
1862
				#Sep 28 07:57:15 qbpwcf.org postfix/smtpd[2768441]: warning: unknown[213.209.157.249]: SASL LOGIN authentication failed: (reason unavailable), sasl_username=sybase
1863
				#Sep 28 08:01:09 qbpwcf.org postfix/smtpd[2771112]: warning: unknown[213.209.157.165]: SASL LOGIN authentication failed: (reason unavailable), sasl_username=spam
1864
				#Sep 28 08:01:51 qbpwcf.org postfix/smtpd[2771112]: warning: unknown[103.109.20.174]: SASL LOGIN authentication failed: (reason unavailable), sasl_username=print@qbpwcf.org
1865
				#Sep 28 08:03:14 qbpwcf.org postfix/smtpd[2771112]: warning: unknown[62.60.130.148]: SASL LOGIN authentication failed: (reason unavailable), sasl_username=admin2
1866
				#Sep 28 08:16:06 qbpwcf.org postfix/smtpd[2781279]: warning: unknown[103.109.20.174]: SASL LOGIN authentication failed: (reason unavailable), sasl_username=user@qbpwcf.org
1867
				#Sep 28 08:16:44 qbpwcf.org postfix/smtpd[2781279]: warning: unknown[178.16.53.142]: SASL LOGIN authentication failed: (reason unavailable), sasl_username=hualing@qbpwcf.org
1868
				#Sep 28 08:16:53 qbpwcf.org postfix/smtpd[2781279]: warning: unknown[178.16.53.142]: SASL LOGIN authentication failed: (reason unavailable), sasl_username=hualing@qbpwcf.org
1869
				#Sep 28 08:17:06 qbpwcf.org postfix/smtpd[2781279]: warning: unknown[178.16.53.142]: SASL LOGIN authentication failed: (reason unavailable), sasl_username=hualing@qbpwcf.org
1870
				#Sep 28 08:17:16 qbpwcf.org postfix/smtpd[2781279]: warning: unknown[178.16.53.142]: SASL LOGIN authentication failed: Connection lost to authentication server, sasl_username=hualing@qbpwcf.org
1871
				#Sep 28 08:20:28 qbpwcf.org postfix/smtpd[2784204]: warning: unknown[158.94.208.72]: SASL LOGIN authentication failed: (reason unavailable), sasl_username=1q2w1q2w
1872
				#Sep 28 08:23:09 qbpwcf.org postfix/smtpd[2785986]: warning: unknown[213.209.157.249]: SASL LOGIN authentication failed: (reason unavailable), sasl_username=informix
1873
				#Sep 28 08:23:39 qbpwcf.org postfix/smtpd[2785986]: warning: unknown[62.60.130.148]: SASL LOGIN authentication failed: (reason unavailable), sasl_username=admin3
1874
				#May 22 12:58:54 qbpwcf.org postfix/smtpd[2059124]: warning: unknown[80.94.95.242]: SASL LOGIN authentication failed: Invalid authentication mechanism: 'LOGIN', sasl_username=(unavailable)
1875
				#May 22 12:58:59 qbpwcf.org postfix/smtpd[2059124]: warning: unknown[80.94.95.242]: SASL PLAIN authentication failed: (reason unavailable), sasl_username=nonexistent_user_26@qbpwcf.org
1876
				#May 22 12:59:07 qbpwcf.org postfix/smtpd[2059124]: warning: unknown[80.94.95.242]: SASL PLAIN authentication failed: (reason unavailable), sasl_username=finance@qbpwcf.org#"${doNotNeed} postfix/smtpd[${pid}]${doNotNeed}[${ip}]"
1877
 
1878
				#用 " " 分割 以取得 月日時分秒
1879
				#函式說明:
1880
				#將固定格式的字串分開,並回傳分開的結果.
1881
				#回傳結果:
1882
				#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
1883
				#$result["error"],錯誤訊息陣列
1884
				#$result["function"],當前執行的函數名稱.
1885
				#$result["argu"],使用的參數.
1886
				#$result["oriStr"],要分割的原始字串內容
1887
				#$result["dataArray"],爲分割好字串的陣列內容,$result["dataArray"][$i]爲第($i+1)段的內容。
1888
				#$result["dataCounts"],爲總共分成幾段
1889
				#$result["found"],是否有在$conf["stringIn"]找到$conf["spiltSymbol"],"true"代表有找到,"false"代表沒有找到.
1890
				#必填參數:
1891
				#$conf["stringIn"],字串,要處理的字串.
1892
				$conf["stringProcess::spiltString"]["stringIn"]=$line;
1893
				#$conf["spiltSymbol"],字串,爲以哪個符號作爲分割.
1894
				$conf["stringProcess::spiltString"]["spiltSymbol"]=" ";
1895
				#可省略參數:
1896
				#$conf["allowEmptyStr"],是否允許分割出來空字串,預設為"false"不允許;"true"代表允許.
1897
				#$conf["allowEmptyStr"]="false";
1898
				#參考資料:
1899
				#無.
1900
				#備註:
1901
				#無.
1902
				$spiltString=stringProcess::spiltString($conf["stringProcess::spiltString"]);
1903
				unset($conf["stringProcess::spiltString"]);
1904
 
1905
				#如果分割失敗
1906
				if($spiltString["status"]==="false"){
1907
 
1908
					#設置執行失敗
1909
					$result["status"]="false";
1910
 
1911
					#設置錯誤訊息
1912
					$result["error"]=$spiltString;
1913
 
1914
					#回傳結果
1915
					return $result;
1916
 
1917
					}#if end
1918
 
1919
				#如果分割失敗
1920
				if($spiltString["dataCounts"]<3){
1921
 
1922
					#設置執行失敗
1923
					$result["status"]="false";
1924
 
1925
					#設置錯誤訊息
1926
					$result["error"]=$spiltString;
1927
 
1928
					#回傳結果
1929
					return $result;
1930
 
1931
					}#if end
1932
 
1933
				#儲存時間
1934
				$occurTime[$index]=strtotime($spiltString["dataArray"][0]." ".$spiltString["dataArray"][1]." ".$spiltString["dataArray"][2]);
1935
 
1936
				#取得 ip
1937
				#函式說明:
1938
				#尋找字串中是否含有符合格式的內容,且回傳解析好的變數數值.
1939
				#回傳結果:
1940
				#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
1941
				#$reuslt["error"],執行不正常結束的錯訊息陣列.
1942
				#$result["function"],當前執行的函式名稱.
1943
				#$result["argu"],所使用的參數.
1944
				#$result["found"],是否有找到符合格式的字串內容,"true"代表有找到,"false"代表沒有找到.
1945
				#$result["content"],陣列,若為n個${*},則當found為"true"時,就會回傳n個元素.
1946
				#$result["parsedVar"][varName],陣列,解析好的變數陣列,varName為${}中的內容.
1947
				#必填參數:
1948
				#$conf["input"],字串,要檢查的字串.
1949
				$conf["search::findSpecifyStrFormat"]["input"]=$line;
1950
				#$conf["format"],格式字串,要尋找的格式字串.格式為固定的字串("fixedStr format")與變數("${keyWordVarName}")組成.
1951
				$conf["search::findSpecifyStrFormat"]["format"]="\${doNotNeed} postfix/smtpd[\${pid}]\${doNotNeed}[\${ip}]:[\${reason}]";
1952
				#可省略參數:
1953
				#$conf["varEqual"],陣列,變數對應的數值,null代表不指定,其他內容代表該變數解析出來必須要為該內容.
1954
				#$conf["search::findSpecifyStrFormat"]["varEqual"]=array(null,"found");
1955
				#$conf["varCon"],陣列,每個varEqual為null者,其是否有其他條件,預設為null代表無其他條件,條件的表示是用陣列的key與value來表達,例如:array("no_tail"=>" not"),就代表變數的結尾不能為" not",可以用的key有"head",代表開頭要有什麼;"no_head",代表不能為什麼開頭;"tail",代表要什麼結尾;"no_tail",代表不能什麼結尾.
1956
				#$conf["varCon"]=array("no_tail"=>" not");
1957
				#參考資料:
1958
				#無.
1959
				#備註:
1960
				#無.
1961
				$findSpecifyStrFormat=search::findSpecifyStrFormat($conf["search::findSpecifyStrFormat"]);
1962
				unset($conf["search::findSpecifyStrFormat"]);
1963
 
1964
				#如果分割失敗
1965
				if($findSpecifyStrFormat["status"]==="false"){
1966
 
1967
					#設置執行失敗
1968
					$result["status"]="false";
1969
 
1970
					#設置錯誤訊息
1971
					$result["error"]=$findSpecifyStrFormat;
1972
 
1973
					#回傳結果
1974
					return $result;
1975
 
1976
					}#if end
1977
 
1978
				#如果沒有符合格式
1979
				if($findSpecifyStrFormat["found"]==="false"){
1980
 
1981
					#剔除時間點 記錄
1982
					array_pop($occurTime);
1983
 
1984
					#跳過該行
1985
					continue;
1986
 
1987
					}#if end
1988
 
1989
				#取得解析好的ip
1990
				$ip=$findSpecifyStrFormat["parsedVar"]["ip"];
1991
 
1992
				#儲存原始的log行內容
1993
				$oriLog[$index]=$spiltMutiString["spiltString"][$index ]["oriStr"];
1994
 
1995
				#初始化暫存的陣列
1996
				$tmp=array();
1997
 
1998
				#設置log、time
1999
				$tmp["info"][]=array("log"=>$oriLog[$index],"time"=>$occurTime[$index]);
2000
 
2001
				#設置問題ip
2002
				$tmp["ip"]=$ip;
2003
 
2004
				#取得所需的有問題的IP
2005
				$ips_smtp[]=$tmp;
2006
 
2007
				}#foreach end
2008
 
2009
			}#if end
2010
 
2011
		#設置結果
2012
		$result["content"]=$ips_smtp;
2013
 
2014
		#設置執行正常
2015
		$result["status"]="true";
2016
 
2017
		#回傳結果
2018
		return $result;
2019
 
2020
		}#function checkPostfixAttackLog end
2021
 
2022
	/*
2023
	#函式說明:
2024
	#檢查 named log 中疑似攻擊的記錄.
2025
	#回傳結果:
2026
	#$result["status"],字串,執行是否正常,"true"代表正常,"false"代表不正常.
2027
	#$result["error"],錯誤訊息陣列.
2028
	#$result["function"],字串,當前執行的函式名稱.
2029
	#$result["content"],陣列,攻擊記錄資訊,每個元素為陣列key為"ip"者為攻擊者的ip;key為info者為其資訊陣列,其key為"log"者代表log的行內容;key為"time"者代表時間點;key為ip者代表ip.
2030
	#必填參數:
2031
	#無.
2032
	#可省略參數:
2033
	#無
2034
	#參考資料:
2035
	#無.
2036
	#備註:
2037
	#無.
2038
	*/
2039
	public static function checkNamedAttackLog(){
2040
 
2041
		#初始化要回傳的結果
2042
		$result=array();
2043
 
2044
		#取得當前執行的函數名稱
2045
		$result["function"]=__FUNCTION__;
2046
 
2047
		#透過 journalctl -a -e -f --unit=named.service | grep ' query ' 來取得 IP
2048
		#函式說明:
2049
		#呼叫shell執行系統命令,並取得回傳的內容.
2050
		#回傳的結果:
2051
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
2052
		#$result["error"],錯誤訊息陣列.
2053
		#$result["function"],當前執行的函式名稱.
2054
		#$result["argu"],使用的參數.
2055
		#$result["cmd"],執行的指令內容.
2056
		#$result["fullCmd"],如果參數 $conf["inBackGround"] 為 "true" 則會回傳該值.
2057
		#$result["output"],爲執行完二元碼後的輸出陣列,若 $conf["inBackGround"] 為 "true",則為當下的輸出.
2058
		#$result["tmpFileOutput"],儲存輸出的暫存檔案名稱,若 $conf["inBackGround"] 為 "true" 則會回傳該值.
2059
		#$result["running"],是否還在執行.
2060
		#$result["pid"],pid.
2061
		#$result["statusCode"],執行結束後的代碼.
2062
		#必填參數:
2063
		#$conf["command"],字串,要執行的指令與.
2064
		$conf["external::callShell"]["command"]="journalctl";
2065
		#$conf["fileArgu"],字串,變數__FILE__的內容.
2066
		$conf["external::callShell"]["fileArgu"]=__FILE__;
2067
		#可省略參數:
2068
		#$conf["argu"],陣列字串,指令搭配的參數,預設為空陣列.
2069
		$conf["external::callShell"]["argu"]=array("-a","-e","--unit=named.service","|","grep"," query ","|","cat");
2070
		#$conf["arguIsAddr"],陣列字串,指令搭配的哪些參數為路徑,為路徑的參數會進行轉換以便符合呼叫當前函式的位置,預設不指定,若有3個參數,其中第3個參數為路徑,則表示為array("false","false","true").
2071
		#$conf["arguIsAddr"]=array();
2072
		#$conf["pre"],陣列,要在本指令前執行的每個指令與參數.
2073
		#$conf["pre"][$i]["cmd"],字串,要在本指令前執行的第$i+1個指令.
2074
		#$conf["pre"][$i]["param"],陣列字串,要在本指令前執行的第$i+1個指令的參數.
2075
		#$conf["enablePrintDescription"],字串,是否要印出$conf["printDescription"]的內容,"true"代表要,"false"代表不要,預設為"false".
2076
		#$conf["enablePrintDescription"]="true";
2077
		#$conf["printDescription"],字串,執行該外部程式前要印出來的的文字,預設為$conf["command"]的內容加上使用的$conf["argu"]參數.
2078
		#$conf["printDescription"]="";
2079
		#$conf["escapeshellarg"],字串,是否要啟用過濾參數,用了比較安全,但可能會出錯,"true"為啟用,"false"為不啟用,預設為"false".
2080
		$conf["external::callShell"]["escapeshellarg"]="true";
2081
		#$conf["username"],字串,要用什麼使用者來執行,預設為執行php的使用者,該參數不適用於apache環境.
2082
		#$conf["username"]="";
2083
		#$conf["password"],字串,root的使用者密碼,預設不使用密碼,該參數不適用於apache環境.
2084
		#$conf["password"]="";
2085
		#$conf["useScript"],字串,是否要啟用Linux的script指令來記錄輸出,"true"代表要,Fedora的selinux會擋住該操作;"false"代表不要,預設為"false".
2086
		#$conf["useScript"]="";
2087
		#$conf["logFilePath"],字串,當 $conf["useScript"] 為 "true" 時,輸出的內容要暫存到哪裡,預設為 "/tmp/.qbpwcf_tmp/external/callShell/".
2088
		#$conf["logFilePath"]=".qbpwcf_tmp/external/callShell/";
2089
		#$conf["inBackGround"],字串,是否要在背景執行,且不會等待程式執行結束再執行下一個指令,"true"代表是,"false"代表不要,預設為"false",如果$conf["command"]有用「;」區隔的多個指令將會出錯.
2090
		#$conf["inBackGround"]="";
2091
		#$conf["getErr"],字串,"true"代表將錯誤輸出變成標準輸出,反之"false"為不變動.
2092
		#$conf["getErr"]="false";
2093
		#備註:
2094
		#不是所有指令都能用apache的身份執行,目前已知java,javac指令無法執行,使用root身份可能會被selinux阻擋.
2095
		#參考資料:
2096
		#exec=>http://php.net/manual/en/function.exec.php
2097
		#escapeshellcmd=>http://php.net/manual/en/function.escapeshellcmd.php
2098
		#escapeshellarg=>http://php.net/manual/en/function.escapeshellarg.php
2099
		$callShell=external::callShell($conf["external::callShell"]);
2100
		unset($conf["external::callShell"]);
2101
 
2102
		#如果執行失敗
2103
		if($callShell["status"]==="false"){
2104
 
2105
			#如果有 statusCode
2106
			if(isset($callShell["statusCode"])){
2107
 
2108
				#如果shell回傳不為0也不為1
2109
				if($callShell["statusCode"]!==0 && $callShell["statusCode"]!==1){
2110
 
2111
					#設置執行失敗
2112
					$result["status"]="false";
2113
 
2114
					#設置錯誤訊息
2115
					$result["error"]=$callShell;
2116
 
2117
					#回傳結果
2118
					return $result;
2119
 
2120
					}#if end
2121
 
2122
				}#if end
2123
 
2124
			#設置執行失敗
2125
			$result["status"]="false";
2126
 
2127
			#設置錯誤訊息
2128
			$result["error"]=$callShell;
2129
 
2130
			#回傳結果
2131
			return $result;
2132
 
2133
			}#if end
2134
 
2135
		#記錄攻擊者的IP
2136
		$attacker_ips_namd=array();
2137
 
2138
		#狀態碼不為1才執行
2139
		if($callShell["statusCode"]!==1){
2140
 
2141
			#截取出的格式
2142
			#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
2143
			#Nov 24 20:55:15 localhost.localdomain named[99512]: client @0x7f77180297c0 191.7.219.100#6238 (PEACECORPS.GOV): query (cache) 'PEACECORPS.GOV/ANY/IN' denied
2144
			#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
2145
			#Nov 24 20:55:15 localhost.localdomain named[99512]: client @0x7f77180297c0 191.7.219.100#6238 (PEACECORPS.GOV): query (cache) 'PEACECORPS.GOV/ANY/IN' denied
2146
			#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
2147
			#Nov 24 20:55:17 localhost.localdomain named[99512]: client @0x7f7714041d10 34.80.86.198#31220 (PEACECORPS.GOV): query (cache) 'PEACECORPS.GOV/ANY/IN' denied
2148
			#Nov 24 20:55:17 localhost.localdomain named[99512]: client @0x7f7714041d10 34.80.86.198#31220 (PEACECORPS.GOV): query (cache) 'PEACECORPS.GOV/ANY/IN' denied
2149
			#Nov 24 20:55:17 localhost.localdomain named[99512]: client @0x7f7714041d10 34.80.86.198#31220 (PEACECORPS.GOV): query (cache) 'PEACECORPS.GOV/ANY/IN' denied
2150
			#Nov 24 20:55:17 localhost.localdomain named[99512]: client @0x7f77180297c0 34.80.86.198#31220 (PEACECORPS.GOV): query (cache) 'PEACECORPS.GOV/ANY/IN' denied
2151
			#Nov 24 20:55:17 localhost.localdomain named[99512]: client @0x7f770c077bf0 34.80.86.198#31220 (PEACECORPS.GOV): query (cache) 'PEACECORPS.GOV/ANY/IN' denied
2152
			#Nov 24 20:55:17 localhost.localdomain named[99512]: client @0x7f770c077bf0 191.7.219.100#8794 (PEACECORPS.GOV): query (cache) 'PEACECORPS.GOV/ANY/IN' denied
2153
			#Nov 24 20:55:17 localhost.localdomain named[99512]: client @0x7f77180297c0 191.7.219.100#8794 (PEACECORPS.GOV): query (cache) 'PEACECORPS.GOV/ANY/IN' denied
2154
			#Nov 24 20:55:17 localhost.localdomain named[99512]: client @0x7f770c077bf0 191.7.219.100#8794 (PEACECORPS.GOV): query (cache) 'PEACECORPS.GOV/ANY/IN' denied
2155
			#Nov 24 20:55:17 localhost.localdomain named[99512]: client @0x7f7714041d10 191.7.219.100#8794 (PEACECORPS.GOV): query (cache) 'PEACECORPS.GOV/ANY/IN' denied
2156
			#Nov 24 20:55:18 localhost.localdomain named[99512]: client @0x7f770c077bf0 5.29.224.190#10027 (PEACECORPS.GOV): query (cache) 'PEACECORPS.GOV/ANY/IN' denied
2157
			#Nov 24 20:55:18 localhost.localdomain named[99512]: client @0x7f770c077bf0 5.29.224.190#10027 (PEACECORPS.GOV): query (cache) 'PEACECORPS.GOV/ANY/IN' denied
2158
			#Nov 24 20:55:18 localhost.localdomain named[99512]: client @0x7f7714041d10 5.29.224.190#10027 (PEACECORPS.GOV): query (cache) 'PEACECORPS.GOV/ANY/IN' denied
2159
			#Nov 24 20:55:18 localhost.localdomain named[99512]: client @0x7f77180297c0 5.29.224.190#10027 (PEACECORPS.GOV): query (cache) 'PEACECORPS.GOV/ANY/IN' denied
2160
			#Nov 24 20:55:18 localhost.localdomain named[99512]: client @0x7f7714041d10 5.29.224.190#10027 (PEACECORPS.GOV): query (cache) 'PEACECORPS.GOV/ANY/IN' denied
2161
			#Nov 24 20:55:18 localhost.localdomain named[99512]: client @0x7f77180297c0 5.29.224.190#10027 (PEACECORPS.GOV): query (cache) 'PEACECORPS.GOV/ANY/IN' denied
2162
			#Nov 24 20:55:18 localhost.localdomain named[99512]: client @0x7f7714041d10 5.29.224.190#10027 (PEACECORPS.GOV): query (cache) 'PEACECORPS.GOV/ANY/IN' denied
2163
			#Nov 24 20:55:22 localhost.localdomain named[99512]: client @0x7f7714041d10 123.253.64.16#54404 (PEACECORPS.GOV): query (cache) 'PEACECORPS.GOV/ANY/IN' denied
2164
			#Nov 24 20:55:22 localhost.localdomain named[99512]: client @0x7f7714041d10 123.253.64.16#54404 (PEACECORPS.GOV): query (cache) 'PEACECORPS.GOV/ANY/IN' denied
2165
			#Nov 24 20:55:22 localhost.localdomain named[99512]: client @0x7f7714041d10 123.253.64.16#54404 (PEACECORPS.GOV): query (cache) 'PEACECORPS.GOV/ANY/IN' denied
2166
			#Dec 14 18:51:45 localhost.localdomain named[1159]: client @0x7f3dc801bc80 61.220.11.198#40052 (dns.qbpwcf.org): query 'dns.qbpwcf.org/AAAA/IN' denied
2167
			#Dec 14 18:51:45 localhost.localdomain named[1159]: client @0x7f3dc8003700 61.220.11.198#48628 (aesopower-cms-sock-latest.qbpwcf.org): query 'aesopower-cms-sock-latest.qbpwcf.org/A/IN' denied
2168
			#Dec 14 18:51:45 localhost.localdomain named[1159]: client @0x7f3dc8003700 61.220.11.198#52460 (dns.qbpwcf.org): query 'dns.qbpwcf.org/AAAA/IN' denied
2169
			#Dec 14 18:51:45 localhost.localdomain named[1159]: client @0x7f3dc801bc80 61.220.11.198#60457 (aesopower-cms-sock-latest.qbpwcf.org): query 'aesopower-cms-sock-latest.qbpwcf.org/A/IN' denied
2170
			#Dec 14 18:51:45 localhost.localdomain named[1159]: client @0x7f3dc801bc80 61.220.11.198#10213 (dns.qbpwcf.org): query 'dns.qbpwcf.org/AAAA/IN' denied
2171
			#Dec 14 18:51:45 localhost.localdomain named[1159]: client @0x7f3dc801bc80 61.220.11.198#44377 (aesopower-cms-sock-latest.qbpwcf.org): query 'aesopower-cms-sock-latest.qbpwcf.org/A/IN' denied
2172
			#Dec 14 18:51:45 localhost.localdomain named[1159]: client @0x7f3dc8003700 61.220.11.198#4481 (dns.qbpwcf.org): query 'dns.qbpwcf.org/AAAA/IN' denied
2173
			#Dec 14 18:51:45 localhost.localdomain named[1159]: client @0x7f3dc8003700 61.220.11.198#53061 (aesopower-cms-sock-latest.qbpwcf.org): query 'aesopower-cms-sock-latest.qbpwcf.org/A/IN' denied
2174
			#Dec 14 18:51:45 localhost.localdomain named[1159]: client @0x7f3dc8003700 61.220.11.198#31654 (dns.qbpwcf.org): query 'dns.qbpwcf.org/AAAA/IN' denied
2175
			#Dec 14 18:51:45 localhost.localdomain named[1159]: client @0x7f3dc802a410 61.220.11.198#57701 (aesopower-cms-sock-latest.qbpwcf.org): query 'aesopower-cms-sock-latest.qbpwcf.org/A/IN' denied
2176
			#Sep 29 03:37:20 dns.qbpwcf.org named[94]: client @0x7f60e00734e8 61.166.210.84#49954 (twitter.com): query failed (REFUSED) for twitter.com/IN/AAAA at ../../../lib/ns/query.c:5691
2177
			#Sep 29 03:37:20 dns.qbpwcf.org named[94]: client @0x7f60e006f428 61.166.210.84#49954 (twitter.com): query failed (REFUSED) for twitter.com/IN/A at ../../../lib/ns/query.c:5691
2178
			#Sep 29 03:37:21 dns.qbpwcf.org named[94]: client @0x7f60e80889a8 61.166.210.84#50057 (astrill4u.com): query failed (REFUSED) for astrill4u.com/IN/AAAA at ../../../lib/ns/query.c:5691
2179
			#Sep 29 03:37:21 dns.qbpwcf.org named[94]: client @0x7f60e805ed08 61.166.210.84#50057 (astrill4u.com): query failed (REFUSED) for astrill4u.com/IN/A at ../../../lib/ns/query.c:5691
2180
			#Sep 29 03:46:33 dns.qbpwcf.org named[94]: client @0x7f60d402b618 165.22.223.147#16200 (tool.lu): query failed (REFUSED) for tool.lu/IN/A at ../../../lib/ns/query.c:5691
2181
			#Sep 29 03:49:16 dns.qbpwcf.org named[94]: client @0x7f60e0060a28 76.20.229.207#80 (sl): query failed (REFUSED) for sl/IN/ANY at ../../../lib/ns/query.c:5691
2182
			#Sep 29 04:19:10 dns.qbpwcf.org named[94]: client @0x7f60e0060a28 76.20.229.207#80 (sl): query failed (REFUSED) for sl/IN/ANY at ../../../lib/ns/query.c:5691
2183
			#Sep 29 04:20:28 dns.qbpwcf.org named[94]: client @0x7f60e0060a28 76.20.229.207#80 (sl): query failed (REFUSED) for sl/IN/ANY at ../../../lib/ns/query.c:5691
2184
			#Sep 29 04:24:20 dns.qbpwcf.org named[94]: client @0x7f60e0060a28 76.20.229.207#80 (sl): query failed (REFUSED) for sl/IN/ANY at ../../../lib/ns/query.c:5691
2185
			#Sep 29 04:24:59 dns.qbpwcf.org named[94]: client @0x7f60e0060a28 76.20.229.207#80 (sl): query failed (REFUSED) for sl/IN/ANY at ../../../lib/ns/query.c:5691
2186
			#Sep 29 04:40:48 dns.qbpwcf.org named[94]: client @0x7f60f9377888 174.96.56.126#80 (sl): query failed (REFUSED) for sl/IN/ANY at ../../../lib/ns/query.c:5691
2187
			#${month} ${day} ${hour}:${min}:${sec} ${doNotNeed} client ${doNotNeed} ${ip}#${remoteRevPort} (${$queryTarget}): ${doNotNeed}
2188
 
2189
			#函式說明:
2190
			#檢查多個字串中的每個字串是否有多個關鍵字
2191
			#回傳結果:
2192
			#$result["status"],整體來說,執行是否成功,"true"代表執行成功,"false"代表執行失敗。
2193
			#$result["function"],當前執行的函數名稱.
2194
			#$result["error"],錯誤訊息.
2195
			#$result["argu"],使用的參數.
2196
			#$result["foundedTrueKey"],結果為"true"的被搜尋元素key陣列,與其數值內容.
2197
			#$result["foundedKeyWords"],找到的關鍵字陣列.
2198
			#$result["foundedFalseKey"],結果為"false"的被搜尋元素key陣列,與其數值內容.
2199
			#$result["foundedTrueKeyWords"],二維陣列,各個字串有找到的關鍵字陣列.
2200
			#$result["foundedAll"],是否每個關鍵字都有找到,"true"代表每個都有找到,"false"代表沒有每個都找到.
2201
			#$result["keyWordsIncludeStr"],陣列,儲存有找到關鍵字的來源的索引(sourceIndex)與其內容(sourceVal)跟找到的關鍵字項目陣列(KeyWords).
2202
			#必填參數:
2203
			#$conf["keyWords"],字串陣列,想要搜尋的關鍵字.
2204
			$conf["search::findManyKeyWordsFromManyString"]["keyWords"]=array("(REFUSED)"," denied");
2205
			#$conf["stringArray"],字串陣列,要被搜尋的字串內容陣列.
2206
			$conf["search::findManyKeyWordsFromManyString"]["stringArray"]=$callShell["output"];
2207
			#可省略參數:
2208
			#$conf["completeEqual"],字串,是否內容要完全符合,不能多出任何不符合的內容,預設為"false"不需要完全符合.
2209
			#$conf["completeEqual"]="true";
2210
			#參考資料:
2211
			#無.
2212
			#備註:
2213
			#無.
2214
			$findManyKeyWordsFromManyString=search::findManyKeyWordsFromManyString($conf["search::findManyKeyWordsFromManyString"]);
2215
			unset($conf["search::findManyKeyWordsFromManyString"]);
2216
 
2217
			#如果執行失敗
2218
			if($findManyKeyWordsFromManyString["status"]==="false"){
2219
 
2220
				#設置執行失敗
2221
				$result["status"]="false";
2222
 
2223
				#設置錯誤訊息
2224
				$result["error"]=$findManyKeyWordsFromManyString;
2225
 
2226
				#回傳結果
2227
				return $result;
2228
 
2229
				}#if end
2230
 
2231
			#初始化儲存原始log行內容
2232
			#$oriLog=array();
2233
 
2234
			#儲存疑似有問題的IP
2235
			$ips_named=array();
2236
 
2237
			#初始化儲存確定有問題的ip
2238
			$attacker_ips_namd=array();
2239
 
2240
			#針對每個符合的行
2241
			foreach($findManyKeyWordsFromManyString["foundedTrueKey"] as $oriLog){
2242
 
2243
				#初始化儲存資訊的暫存陣列
2244
				$info=array();
2245
 
2246
				#解析時間與來源ip
2247
				#函式說明:
2248
				#尋找字串中是否含有符合格式的內容,且回傳解析好的變數數值.
2249
				#回傳結果:
2250
				#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
2251
				#$reuslt["error"],執行不正常結束的錯訊息陣列.
2252
				#$result["function"],當前執行的函式名稱.
2253
				#$result["argu"],所使用的參數.
2254
				#$result["found"],是否有找到符合格式的字串內容,"true"代表有找到,"false"代表沒有找到.
2255
				#$result["content"],陣列,若為n個${*},則當found為"true"時,就會回傳n個元素.
2256
				#$result["parsedVar"][varName],陣列,解析好的變數陣列,varName為${}中的內容.
2257
				#必填參數:
2258
				#$conf["input"],字串,要檢查的字串.
2259
				$conf["search::findSpecifyStrFormat"]["input"]=$oriLog;
2260
				#$conf["format"],格式字串,要尋找的格式字串.格式為固定的字串("fixedStr format")與變數("${keyWordVarName}")組成.
2261
				$conf["search::findSpecifyStrFormat"]["format"]="\${month} \${day} \${hour}:\${min}:\${sec} \${doNotNeed} client \${doNotNeed} \${ip}#\${remoteRevPort} (\${queryTarget}): \${doNotNeed}";
2262
				#可省略參數:
2263
				#$conf["varEqual"],陣列,變數對應的數值,null代表不指定,其他內容代表該變數解析出來必須要為該內容.
2264
				#$conf["search::findSpecifyStrFormat"]["varEqual"]=array(null,"found");
2265
				#$conf["varCon"],陣列,每個varEqual為null者,其是否有其他條件,預設為null代表無其他條件,條件的表示是用陣列的key與value來表達,例如:array("no_tail"=>" not"),就代表變數的結尾不能為" not",可以用的key有"head",代表開頭要有什麼;"no_head",代表不能為什麼開頭;"tail",代表要什麼結尾;"no_tail",代表不能什麼結尾.
2266
				#$conf["varCon"]=array("no_tail"=>" not");
2267
				#參考資料:
2268
				#無.
2269
				#備註:
2270
				#無.
2271
				$findSpecifyStrFormat=search::findSpecifyStrFormat($conf["search::findSpecifyStrFormat"]);
2272
				unset($conf["search::findSpecifyStrFormat"]);
2273
 
2274
				#如果分割失敗
2275
				if($findSpecifyStrFormat["status"]==="false"){
2276
 
2277
					#設置執行失敗
2278
					$result["status"]="false";
2279
 
2280
					#設置錯誤訊息
2281
					$result["error"]=$findSpecifyStrFormat;
2282
 
2283
					#回傳結果
2284
					return $result;
2285
 
2286
					}#if end
2287
 
2288
				#如果沒有符合格式
2289
				if($findSpecifyStrFormat["found"]==="false"){
2290
 
2291
					#跳過該行
2292
					continue;
2293
 
2294
					}#if end
2295
 
2296
				#儲存時間點
2297
				$info["time"]=$findSpecifyStrFormat["parsedVar"]["month"][0]." ".$findSpecifyStrFormat["parsedVar"]["day"][0]." ".$findSpecifyStrFormat["parsedVar"]["hour"][0].":".$findSpecifyStrFormat["parsedVar"]["min"][0].":".$findSpecifyStrFormat["parsedVar"]["sec"][0];
2298
 
2299
				#儲存ip
2300
				$info["ip"]=$findSpecifyStrFormat["parsedVar"]["ip"][0];
2301
 
2302
				#儲存log
2303
				$info["log"]=$oriLog;
2304
 
2305
				#儲存查詢的目標
2306
				$info["queryTarget"]=$findSpecifyStrFormat["parsedVar"]["queryTarget"][0];
2307
 
2308
				#儲存疑似有問題的ip
2309
				$ips_named[$info["ip"]][]=$info;
2310
 
2311
				}#foreach end
2312
 
2313
			#針對每個可能有問題ip的每個log行
2314
			foreach($ips_named as $ip => $infos){
2315
 
2316
				#初始化記錄ip來訪不大於1分鐘的計數
2317
				$count=0;
2318
 
2319
				#初始化記錄歷史log跟time
2320
				$history=array();
2321
 
2322
				#針對每個log行資訊
2323
				foreach($infos as $index => $info){
2324
 
2325
					#unixtime
2326
					$time=strtotime($info["time"]);
2327
 
2328
					#如果沒有下筆記錄
2329
					if(!isset($infos[$index+1])){
2330
 
2331
						#結束 foreach
2332
						break;
2333
 
2334
						}#if end
2335
 
2336
					#取得unixtime
2337
					$next_time=strtotime($infos[$index+1]["time"]);
2338
 
2339
					#如果時間間隔大於60秒
2340
					if($next_time-$time>60){
2341
 
2342
						#跳過,看下筆記錄
2343
						continue;
2344
 
2345
						}#if end
2346
 
2347
					#計數+1
2348
					$count++;
2349
 
2350
					#記錄歷史資訊
2351
					$history[]=array("time"=>$time,"log"=>$info["log"]);
2352
 
2353
					}#foreach end
2354
 
2355
				#如果有達到3次
2356
				if($count>=3){
2357
 
2358
					#初始化暫存的陣列
2359
					$tmp=array();
2360
 
2361
					#設置ip
2362
					$tmp["ip"]=$ip;
2363
 
2364
					#設置info
2365
					$tmp["info"]=$history;
2366
 
2367
					#記錄攻擊者的IP
2368
					$attacker_ips_namd[]=$tmp;
2369
 
2370
					}#if end
2371
 
2372
				}#foreach end
2373
 
2374
			}#if end
2375
 
2376
		#設置結果
2377
		$result["content"]=$attacker_ips_namd;
2378
 
2379
		#設置執行正常
2380
		$result["status"]="true";
2381
 
2382
		#回傳結果
2383
		return $result;
2384
 
2385
		}#function checkNamedAttackLog end
2386
 
2387
	/*
2388
	#函式說明:
2389
	#檢查 dovecot log 中疑似攻擊的記錄.
2390
	#回傳結果:
2391
	#$result["status"],字串,執行是否正常,"true"代表正常,"false"代表不正常.
2392
	#$result["error"],錯誤訊息陣列.
2393
	#$result["function"],字串,當前執行的函式名稱.
2394
	#$result["content"],陣列,攻擊記錄資訊,每個元素為陣列key為"ip"者為攻擊者的ip;key為info者為其資訊陣列,其key為"log"者代表log的行內容;key為"time"者代表時間點;key為ip者代表ip.
2395
	#必填參數:
2396
	#無.
2397
	#可省略參數:
2398
	#無
2399
	#參考資料:
2400
	#無.
2401
	#備註:
2402
	#無.
2403
	*/
2404
	public static function checkDovecotAttackLog(){
2405
 
2406
		#初始化要回傳的結果
2407
		$result=array();
2408
 
2409
		#取得當前執行的函數名稱
2410
		$result["function"]=__FUNCTION__;
2411
 
2412
		#透過 journalctl -a -e --unit=dovecot.service 來取得 IP
2413
		#函式說明:
2414
		#呼叫shell執行系統命令,並取得回傳的內容.
2415
		#回傳的結果:
2416
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
2417
		#$result["error"],錯誤訊息陣列.
2418
		#$result["function"],當前執行的函式名稱.
2419
		#$result["argu"],使用的參數.
2420
		#$result["cmd"],執行的指令內容.
2421
		#$result["fullCmd"],如果參數 $conf["inBackGround"] 為 "true" 則會回傳該值.
2422
		#$result["output"],爲執行完二元碼後的輸出陣列,若 $conf["inBackGround"] 為 "true",則為當下的輸出.
2423
		#$result["tmpFileOutput"],儲存輸出的暫存檔案名稱,若 $conf["inBackGround"] 為 "true" 則會回傳該值.
2424
		#$result["running"],是否還在執行.
2425
		#$result["pid"],pid.
2426
		#$result["statusCode"],執行結束後的代碼.
2427
		#必填參數:
2428
		#$conf["command"],字串,要執行的指令與.
2429
		$conf["external::callShell"]["command"]="journalctl";
2430
		#$conf["fileArgu"],字串,變數__FILE__的內容.
2431
		$conf["external::callShell"]["fileArgu"]=__FILE__;
2432
		#可省略參數:
2433
		#$conf["argu"],陣列字串,指令搭配的參數,預設為空陣列.
2434
		$conf["external::callShell"]["argu"]=array("-a","-e","--unit=dovecot.service");
2435
		#$conf["arguIsAddr"],陣列字串,指令搭配的哪些參數為路徑,為路徑的參數會進行轉換以便符合呼叫當前函式的位置,預設不指定,若有3個參數,其中第3個參數為路徑,則表示為array("false","false","true").
2436
		#$conf["arguIsAddr"]=array();
2437
		#$conf["pre"],陣列,要在本指令前執行的每個指令與參數.
2438
		#$conf["pre"][$i]["cmd"],字串,要在本指令前執行的第$i+1個指令.
2439
		#$conf["pre"][$i]["param"],陣列字串,要在本指令前執行的第$i+1個指令的參數.
2440
		#$conf["enablePrintDescription"],字串,是否要印出$conf["printDescription"]的內容,"true"代表要,"false"代表不要,預設為"false".
2441
		#$conf["enablePrintDescription"]="true";
2442
		#$conf["printDescription"],字串,執行該外部程式前要印出來的的文字,預設為$conf["command"]的內容加上使用的$conf["argu"]參數.
2443
		#$conf["printDescription"]="";
2444
		#$conf["escapeshellarg"],字串,是否要啟用過濾參數,用了比較安全,但可能會出錯,"true"為啟用,"false"為不啟用,預設為"false".
2445
		$conf["external::callShell"]["escapeshellarg"]="true";
2446
		#$conf["username"],字串,要用什麼使用者來執行,預設為執行php的使用者,該參數不適用於apache環境.
2447
		#$conf["username"]="";
2448
		#$conf["password"],字串,root的使用者密碼,預設不使用密碼,該參數不適用於apache環境.
2449
		#$conf["password"]="";
2450
		#$conf["useScript"],字串,是否要啟用Linux的script指令來記錄輸出,"true"代表要,Fedora的selinux會擋住該操作;"false"代表不要,預設為"false".
2451
		#$conf["useScript"]="";
2452
		#$conf["logFilePath"],字串,當 $conf["useScript"] 為 "true" 時,輸出的內容要暫存到哪裡,預設為 "/tmp/.qbpwcf_tmp/external/callShell/".
2453
		#$conf["logFilePath"]=".qbpwcf_tmp/external/callShell/";
2454
		#$conf["inBackGround"],字串,是否要在背景執行,且不會等待程式執行結束再執行下一個指令,"true"代表是,"false"代表不要,預設為"false",如果$conf["command"]有用「;」區隔的多個指令將會出錯.
2455
		#$conf["inBackGround"]="";
2456
		#$conf["getErr"],字串,"true"代表將錯誤輸出變成標準輸出,反之"false"為不變動.
2457
		#$conf["getErr"]="false";
2458
		#備註:
2459
		#不是所有指令都能用apache的身份執行,目前已知java,javac指令無法執行,使用root身份可能會被selinux阻擋.
2460
		#參考資料:
2461
		#exec=>http://php.net/manual/en/function.exec.php
2462
		#escapeshellcmd=>http://php.net/manual/en/function.escapeshellcmd.php
2463
		#escapeshellarg=>http://php.net/manual/en/function.escapeshellarg.php
2464
		$callShell=external::callShell($conf["external::callShell"]);
2465
		unset($conf["external::callShell"]);
2466
 
2467
		#如果執行失敗
2468
		if($callShell["status"]==="false"){
2469
 
2470
			#如果有 statusCode
2471
			if(isset($callShell["statusCode"])){
2472
 
2473
				#如果shell回傳不為0也不為1
2474
				if($callShell["statusCode"]!==0 && $callShell["statusCode"]!==1){
2475
 
2476
					#設置執行失敗
2477
					$result["status"]="false";
2478
 
2479
					#設置錯誤訊息
2480
					$result["error"]=$callShell;
2481
 
2482
					#回傳結果
2483
					return $result;
2484
 
2485
					}#if end
2486
 
2487
				}#if end
2488
 
2489
			#設置執行失敗
2490
			$result["status"]="false";
2491
 
2492
			#設置錯誤訊息
2493
			$result["error"]=$callShell;
2494
 
2495
			#回傳結果
2496
			return $result;
2497
 
2498
			}#if end
2499
 
2500
		#記錄攻擊者的IP
2501
		$attacker_ips_imap=array();
2502
 
2503
		/* $callShell["output"] 範例截取結果
2504
		Feb 23 00:24:58 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=<MxQuPu+73xpliNc9>
2505
		Feb 23 00:24:58 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=<hH8xPu+7dBtliNc9>
2506
		Feb 23 00:24:58 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=<nmI0Pu+7zhtliNc9>
2507
		Feb 23 00:24:58 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=<1GU2Pu+7NBhliNc9>
2508
		Feb 23 00:24:59 localhost.localdomain dovecot[1427]: imap-login: Disconnected (no auth attempts in 1 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=<0Io5Pu+7sRhliNc9>
2509
		Feb 23 00:24:59 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=<zbQ+Pu+7rhlliNc9>
2510
		Feb 23 00:24:59 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=<0P5APu+7/BlliNc9>
2511
		Feb 23 00:24:59 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=<gKRDPu+7XhpliNc9>
2512
		Feb 23 00:24:59 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=<4hNHPu+77hpliNc9>
2513
		Feb 23 00:25:00 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=<belIPu+7bBtliNc9>
2514
		Feb 23 00:25:00 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=<VhRLPu+7xBtliNc9>
2515
		Feb 23 00:46:19 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=<loiMiu+7cxhliNc9>
2516
		Feb 23 00:46:19 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=<RNCQiu+7/xhliNc9>
2517
		Feb 23 00:46:20 localhost.localdomain dovecot[1427]: imap-login: Disconnected (no auth attempts in 1 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=<NWCTiu+7PBlliNc9>
2518
		Feb 23 00:46:20 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=<2tiViu+7hBlliNc9>
2519
		Feb 23 00:46:20 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=<w6Sbiu+7/xlliNc9>
2520
		Feb 23 00:46:21 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=<SkWkiu+7gBtliNc9>
2521
		Feb 23 00:46:21 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=<bGCmiu+7qBtliNc9>
2522
		Feb 23 00:46:21 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=<0E+oiu+76RtliNc9>
2523
		Feb 23 00:46:21 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=<FBGriu+7UhhliNc9>
2524
		Feb 23 00:46:21 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=<AeSsiu+7iBhliNc9>
2525
		Feb 23 00:46:21 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=<gpSuiu+70hhliNc9>
2526
		Feb 23 01:40:38 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=<zYfITPC7RBlliNc9>
2527
		Feb 23 01:40:38 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=<GULMTPC7zhlliNc9>
2528
		Feb 23 01:40:38 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=<3jjOTPC7CBpliNc9>
2529
		Feb 23 01:40:38 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=<vhHQTPC7UBpliNc9>
2530
		Feb 23 01:40:38 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=<vArTTPC7rxpliNc9>
2531
		Feb 23 01:40:39 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=<hDTXTPC7GhtliNc9>
2532
		Feb 23 01:40:39 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=<c6vZTPC7SRtliNc9>
2533
		Feb 23 01:40:39 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=<rQzcTPC7jBtliNc9>
2534
		Feb 23 01:40:39 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=<LSffTPC78htliNc9>
2535
		Feb 23 01:40:39 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=<XLThTPC7KBhliNc9>
2536
		Feb 23 01:40:40 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=<tZfjTPC7dxhliNc9>
2537
		Feb 23 03:27:10 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=<i3bIyfG7AxtliNc9>
2538
		Feb 23 03:27:11 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=<0sLVyfG7uxtliNc9>
2539
		Feb 23 03:27:11 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=<BJXZyfG7BhhliNc9>
2540
		Feb 23 03:27:11 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=<xK3cyfG7SxhliNc9>
2541
		Feb 23 03:27:12 localhost.localdomain dovecot[1427]: imap-login: Disconnected (no auth attempts in 1 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=<q43gyfG7aRhliNc9>
2542
		Feb 23 03:27:12 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=<Oj3syfG7FBlliNc9>
2543
		Feb 23 03:27:12 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=<SF7uyfG7RhlliNc9>
2544
		Feb 23 03:27:13 localhost.localdomain dovecot[1427]: imap-login: Disconnected (no auth attempts in 1 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=<IM/wyfG7ZRlliNc9>
2545
		Feb 23 03:27:13 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=<pXv1yfG7vBlliNc9>
2546
		Feb 23 03:27:13 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=<8ub4yfG7/xlliNc9>
2547
		Feb 23 03:27:13 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=<H0j7yfG7NRpliNc9>
2548
		Feb 23 06:10:07 localhost.localdomain dovecot[1427]: imap-login: Disconnected (no auth attempts in 1 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=<Zw6FEPS7WxhliNc9>
2549
		Feb 23 06:10:08 localhost.localdomain dovecot[1427]: imap-login: Disconnected (no auth attempts in 1 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=<vmKTEPS7cRpliNc9>
2550
		Feb 23 06:10:08 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=<SkOXEPS7BxtliNc9>
2551
		Feb 23 06:10:08 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=<H42bEPS7WRtliNc9>
2552
		Feb 23 06:10:09 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=<jFqoEPS7SRhliNc9>
2553
		Feb 23 06:10:10 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=<TNy4EPS7DhpliNc9>
2554
		Feb 23 06:10:10 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=<JYW7EPS7mBpliNc9>
2555
		Feb 23 06:10:10 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=</Ve+EPS76hpliNc9>
2556
		Feb 23 06:10:11 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=<StLGEPS7qhtliNc9>
2557
		Feb 23 06:10:11 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=<7RnLEPS7DBhliNc9>
2558
		Feb 23 06:10:11 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=<6xTOEPS7eBhliNc9>
2559
		Feb 23 06:29:27 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=<YHy0VfS7uBhliNc9>
2560
		Feb 23 06:29:28 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=<WLW4VfS7fxlliNc9>
2561
		Feb 23 06:29:28 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=<lM66VfS73BlliNc9>
2562
		Feb 23 06:29:28 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=<Q4K9VfS7NxpliNc9>
2563
		Feb 23 06:29:28 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=<JiLBVfS7rRpliNc9>
2564
		Feb 23 06:29: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=<DETIVfS7qxtliNc9>
2565
		Feb 23 06:29: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=<UlLLVfS7GhhliNc9>
2566
		Feb 23 06:29: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=<safNVfS7txhliNc9>
2567
		Feb 23 06:29: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=<M/DQVfS7LxlliNc9>
2568
		Feb 23 06:29: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=<+zPTVfS7eRlliNc9>
2569
		Feb 23 06:29:30 localhost.localdomain dovecot[1427]: imap-login: Disconnected (no auth attempts in 1 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=<dxXWVfS72hlliNc9>
2570
		Feb 23 06:44:28 localhost.localdomain dovecot[1427]: imap-login: Disconnected (no auth attempts in 1 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=<S0pci/S7SxhliNc9>
2571
		Feb 23 06:44:28 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=<zThji/S78RhliNc9>
2572
		Feb 23 06:44:28 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=<8PJoi/S7ixlliNc9>
2573
		Feb 23 06: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=<Qkhui/S7PBpliNc9>
2574
		Feb 23 06: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=<SXVzi/S7hhtliNc9>
2575
		Feb 23 06: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=</X55i/S7uhhliNc9>
2576
		Feb 23 06:44:30 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=<MHJ9i/S74hlliNc9>
2577
		Feb 23 06:44:30 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=<RBWBi/S7pRpliNc9>
2578
		Feb 23 06:44:30 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=<NJeGi/S7yhtliNc9>
2579
		Feb 23 06:44:31 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=<QsaMi/S7rxhliNc9>
2580
		Feb 23 06:44:31 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=<8fiPi/S7uBlliNc9>
2581
		Feb 23 07:01:29 localhost.localdomain dovecot[1427]: imap-login: Disconnected (no auth attempts in 1 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=<dt04yPS7KBlliNc9>
2582
		Feb 23 07:01: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=<ZMI9yPS7WxpliNc9>
2583
		Feb 23 07:01: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=<nTVAyPS7ARtliNc9>
2584
		Feb 23 07:01: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=<wj1CyPS7lxtliNc9>
2585
		Feb 23 07:01: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=<u7RFyPS7YRhliNc9>
2586
		Feb 23 07:01:30 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=<tpBLyPS7ZhlliNc9>
2587
		Feb 23 07:01:30 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=<CRdOyPS7wxlliNc9>
2588
		Feb 23 07:01:30 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=<v9NQyPS7JxpliNc9>
2589
		Feb 23 07:01:30 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=<81lUyPS73hpliNc9>
2590
		Feb 23 07:01:31 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=<PCZXyPS7TRtliNc9>
2591
		Feb 23 07:01:31 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=<VnNZyPS7qxtliNc9>
2592
		Feb 23 07:14:28 localhost.localdomain dovecot[1427]: imap-login: Disconnected (no auth attempts in 1 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=<op+l9vS7ZxhliNc9>
2593
		Feb 23 07:14:28 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=<aBCr9vS7CBlliNc9>
2594
		Feb 23 07:14:28 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=<0sOt9vS7dRlliNc9>
2595
		Feb 23 07:14:28 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=<NFaw9vS7xhlliNc9>
2596
		Feb 23 07:14:28 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=<QS609vS7SRpliNc9>
2597
		Feb 23 07:14: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=<4FW79vS76htliNc9>
2598
		Feb 23 07:14: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=<Fxu+9vS7gBhliNc9>
2599
		Feb 23 07:14: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=<3djA9vS75RhliNc9>
2600
		Feb 23 07:14:30 localhost.localdomain dovecot[1427]: imap-login: Disconnected (no auth attempts in 1 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=<hgzE9vS7mxlliNc9>
2601
		Feb 23 07:14:30 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=<J8TG9vS7GBpliNc9>
2602
		Feb 23 07:14:30 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=<t87I9vS7mBpliNc9>
2603
		Feb 23 07:29:27 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=<1xBILPW7MRtliNc9>
2604
		Feb 23 07:29:28 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=<IXZNLPW79htliNc9>
2605
		Feb 23 07:29:28 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=<6OdPLPW7chhliNc9>
2606
		Feb 23 07:29:28 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=<M5BSLPW78hhliNc9>
2607
		Feb 23 07:29:28 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=<Nv9VLPW7UxlliNc9>
2608
		Feb 23 07:29: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=<foJbLPW7KRpliNc9>
2609
		Feb 23 07:29: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=<EoVeLPW7nxpliNc9>
2610
		Feb 23 07:29: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=<DwNhLPW7JRtliNc9>
2611
		Feb 23 07:29: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=<mKhkLPW7ohtliNc9>
2612
		Feb 23 07:29: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=<3nhnLPW7/htliNc9>
2613
		Feb 23 07:29:30 localhost.localdomain dovecot[1427]: imap-login: Disconnected (no auth attempts in 1 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=<e+lpLPW7XRhliNc9>
2614
		Feb 23 07:44:27 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=<KtTtYfW7dBhliNc9>
2615
		Feb 23 07:44:28 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=<MLTxYfW77BhliNc9>
2616
		Feb 23 07:44:28 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=<9GL0YfW7KBlliNc9>
2617
		Feb 23 07:44:28 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=<JNT2YfW7fRlliNc9>
2618
		Feb 23 07:44:28 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=<8Zv5YfW72RlliNc9>
2619
		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=<lbv/YfW73BpliNc9>
2620
		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=<5zsCYvW7EBtliNc9>
2621
		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=<aE8EYvW7bRtliNc9>
2622
		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=<LEIHYvW75RtliNc9>
2623
		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=<rLsJYvW7MRhliNc9>
2624
		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>
2625
		Feb 23 07:59:28 localhost.localdomain dovecot[1427]: imap-login: Disconnected (no auth attempts in 1 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=<x7SUl/W7mBpliNc9>
2626
		Feb 23 07:59:28 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=<k1KZl/W73xtliNc9>
2627
		Feb 23 07:59:28 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=<Veabl/W7PxhliNc9>
2628
		Feb 23 07:59:28 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=<Yamel/W7sxhliNc9>
2629
		Feb 23 07:59:28 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=<wpGil/W7OBlliNc9>
2630
		Feb 23 07:59: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=<+VCol/W7aBpliNc9>
2631
		Feb 23 07:59: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=<TMaql/W7zhpliNc9>
2632
		Feb 23 07:59: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=<KnKtl/W7GBtliNc9>
2633
		Feb 23 07:59: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=<Lkixl/W7ixtliNc9>
2634
		Feb 23 07:59:30 localhost.localdomain dovecot[1427]: imap-login: Disconnected (no auth attempts in 1 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=<8bWzl/W7ARhliNc9>
2635
		Feb 23 07:59:30 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=<70q2l/W7PBhliNc9>
2636
		Sep 29 06:53:42 qbpwcf.org dovecot[98]: imap-login: Disconnected: Connection closed (no auth attempts in 0 secs): user=<>, rip=3.231.151.171, lip=169.254.2.1, TLS, session=<MaKQGOs/wIMD55er>
2637
		Sep 29 07:42:58 qbpwcf.org auth[3737748]: pam_unix(dovecot:auth): check pass; user unknown
2638
		Sep 29 07:42:58 qbpwcf.org auth[3737748]: pam_unix(dovecot:auth): authentication failure; logname=liveuser uid=0 euid=0 tty=dovecot ruser=account@qbpwcf.org rhost=62.60.131.29
2639
		Sep 29 08:10:02 qbpwcf.org dovecot[98]: imap(liveuser)<3755807><SvyIKew/xLpyIuFn>: Disconnected: Connection closed (UID SEARCH finished 0.039 secs ago) in=119 out=1504 deleted=0 expunged=0 trashed=0 hdr_count=0 hdr_bytes=0 body_count=0 body_bytes=0
2640
		Sep 29 08:12:02 qbpwcf.org dovecot[98]: imap-login: Login: user=<liveuser>, method=PLAIN, rip=149.102.158.38, lip=169.254.2.1, mpid=3757116, TLS, session=<B2O9MOw/TrmVZp4m>
2641
		Sep 29 08:12:04 qbpwcf.org dovecot[98]: imap(liveuser)<3757116><B2O9MOw/TrmVZp4m>: Disconnected: Logged out in=240 out=21891 deleted=0 expunged=0 trashed=0 hdr_count=0 hdr_bytes=0 body_count=0 body_bytes=0
2642
		Sep 29 08:12:06 qbpwcf.org dovecot[98]: imap-login: Login: user=<liveuser>, method=PLAIN, rip=149.102.158.38, lip=169.254.2.1, mpid=3757144, TLS, session=<S0rwMOw/XLmVZp4m>
2643
		Sep 29 08:12:09 qbpwcf.org dovecot[98]: imap(liveuser)<3757144><S0rwMOw/XLmVZp4m>: Disconnected: Logged out in=885 out=25454 deleted=0 expunged=0 trashed=0 hdr_count=2 hdr_bytes=21658 body_count=0 body_bytes=0
2644
		Sep 29 08:28:48 qbpwcf.org dovecot[98]: imap-login: Login: user=<liveuser>, method=PLAIN, rip=114.34.225.103, lip=169.254.2.1, mpid=3768144, TLS, session=<Gk6ybOw/nNpyIuFn>
2645
		Sep 29 08:28:51 qbpwcf.org dovecot[98]: imap(liveuser)<3768144><Gk6ybOw/nNpyIuFn>: Disconnected: Connection closed (LIST finished 1.939 secs ago) in=50 out=17609 deleted=0 expunged=0 trashed=0 hdr_count=0 hdr_bytes=0 body_count=0 body_bytes=0
2646
		Sep 29 08:28:51 qbpwcf.org dovecot[98]: imap-login: Login: user=<liveuser>, method=PLAIN, rip=114.34.225.103, lip=169.254.2.1, mpid=3768149, TLS, session=<ct7bbOw/qtpyIuFn>
2647
		Sep 29 08:28:52 qbpwcf.org dovecot[98]: imap(liveuser)<3768149><ct7bbOw/qtpyIuFn>: Disconnected: Connection closed (UID FETCH finished 0.045 secs ago) in=196 out=2381 deleted=0 expunged=0 trashed=0 hdr_count=0 hdr_bytes=0 body_count=0 body_bytes=0
2648
		Sep 29 08:28:53 qbpwcf.org dovecot[98]: imap-login: Login: user=<liveuser>, method=PLAIN, rip=114.34.225.103, lip=169.254.2.1, mpid=3768155, TLS, session=<DvP1bOw/tNpyIuFn>
2649
		Sep 29 08:28:55 qbpwcf.org dovecot[98]: imap(liveuser)<3768155><DvP1bOw/tNpyIuFn>: Disconnected: Connection closed (UID SEARCH finished 0.180 secs ago) in=119 out=1504 deleted=0 expunged=0 trashed=0 hdr_count=0 hdr_bytes=0 body_count=0 body_bytes=0
2650
		Sep 29 08:39:24 qbpwcf.org auth[3775219]: pam_unix(dovecot:auth): check pass; user unknown
2651
		Sep 29 08:39:24 qbpwcf.org auth[3775219]: pam_unix(dovecot:auth): authentication failure; logname=liveuser uid=0 euid=0 tty=dovecot ruser=test rhost=196.251.92.78
2652
		Sep 29 08:40:44 qbpwcf.org auth[3776113]: pam_unix(dovecot:auth): check pass; user unknown
2653
		Sep 29 08:40:44 qbpwcf.org auth[3776113]: pam_unix(dovecot:auth): authentication failure; logname=liveuser uid=0 euid=0 tty=dovecot ruser=1q2w3e4r5t4567 rhost=158.94.208.72
2654
		Sep 29 08:41:18 qbpwcf.org auth[3776113]: pam_unix(dovecot:auth): check pass; user unknown
2655
		Sep 29 08:41:18 qbpwcf.org auth[3776113]: pam_unix(dovecot:auth): authentication failure; logname=liveuser uid=0 euid=0 tty=dovecot ruser=spam rhost=62.60.130.148
2656
		*/
2657
 
2658
		#認證失敗的關鍵字
2659
		$keyWordAF="authentication failure";
2660
 
2661
		#未認證或SSL錯誤
2662
		$keyWordNAA="no auth attempts";
2663
 
2664
		#搜尋符合關鍵字的log行
2665
		#函式說明:
2666
		#檢查多個字串中的每個字串是否有多個關鍵字
2667
		#回傳結果:
2668
		#$result["status"],整體來說,執行是否成功,"true"代表執行成功,"false"代表執行失敗。
2669
		#$result["function"],當前執行的函數名稱.
2670
		#$result["error"],錯誤訊息.
2671
		#$result["argu"],使用的參數.
2672
		#$result["foundedTrueKey"],結果為"true"的被搜尋元素key陣列,與其數值內容.
2673
		#$result["foundedKeyWords"],找到的關鍵字陣列.
2674
		#$result["foundedFalseKey"],結果為"false"的被搜尋元素key陣列,與其數值內容.
2675
		#$result["foundedTrueKeyWords"],二維陣列,各個字串有找到的關鍵字陣列.
2676
		#$result["foundedAll"],是否每個關鍵字都有找到,"true"代表每個都有找到,"false"代表沒有每個都找到.
2677
		#$result["keyWordsIncludeStr"],陣列,儲存有找到關鍵字的來源的索引(sourceIndex)與其內容(sourceVal)跟找到的關鍵字項目陣列(KeyWords).
2678
		#必填參數:
2679
		#$conf["keyWords"],字串陣列,想要搜尋的關鍵字.
2680
		$conf["search::findManyKeyWordsFromManyString"]["keyWords"]=array($keyWordAF,$keyWordNAA);
2681
		#$conf["stringArray"],字串陣列,要被搜尋的字串內容陣列.
2682
		$conf["search::findManyKeyWordsFromManyString"]["stringArray"]=$callShell["output"];
2683
		#可省略參數:
2684
		#$conf["completeEqual"],字串,是否內容要完全符合,不能多出任何不符合的內容,預設為"false"不需要完全符合.
2685
		#$conf["completeEqual"]="true";
2686
		#參考資料:
2687
		#無.
2688
		#備註:
2689
		#無.
2690
		$findManyKeyWordsFromManyString=search::findManyKeyWordsFromManyString($conf["search::findManyKeyWordsFromManyString"]);
2691
		unset($conf["search::findManyKeyWordsFromManyString"]);
2692
 
2693
		#如果執行失敗
2694
		if($findManyKeyWordsFromManyString["status"]==="false"){
2695
 
2696
			#設置執行失敗
2697
			$result["status"]="false";
2698
 
2699
			#設置錯誤訊息
2700
			$result["error"]=$findManyKeyWordsFromManyString;
2701
 
2702
			#回傳結果
2703
			return $result;
2704
 
2705
			}#if end
2706
 
2707
		#初始化儲存可能有問題的存取Dovecot服務遠端ip
2708
		$rickyIpsOfDocecot=array();
2709
 
2710
		#針對每個符合的log行
2711
		foreach($findManyKeyWordsFromManyString["foundedTrueKey"] as $index => $oriLog){
2712
 
2713
			#找到的關鍵字
2714
			$foundKeyWord=$findManyKeyWordsFromManyString["foundedTrueKeyWords"][$index][0];
2715
 
2716
			#依照符合的關鍵字
2717
			switch($foundKeyWord){
2718
 
2719
				#如果是認證失敗
2720
				case $keyWordAF:
2721
 
2722
					#範例
2723
					#Sep 29 08:41:18 qbpwcf.org auth[3776113]: pam_unix(dovecot:auth): authentication failure; logname=liveuser uid=0 euid=0 tty=dovecot ruser=spam rhost=62.60.130.148
2724
					#${month} ${day} ${hour}:${min}:${sec} ${doNotNeed} : authentication failure; logname=${account} ${doNotNeed} rhost=${ip}
2725
 
2726
					#取得時間點跟遠端IP
2727
					#函式說明:
2728
					#尋找字串中是否含有符合格式的內容,且回傳解析好的變數數值.
2729
					#回傳結果:
2730
					#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
2731
					#$reuslt["error"],執行不正常結束的錯訊息陣列.
2732
					#$result["function"],當前執行的函式名稱.
2733
					#$result["argu"],所使用的參數.
2734
					#$result["found"],是否有找到符合格式的字串內容,"true"代表有找到,"false"代表沒有找到.
2735
					#$result["content"],陣列,若為n個${*},則當found為"true"時,就會回傳n個元素.
2736
					#$result["parsedVar"][varName],陣列,解析好的變數陣列,varName為${}中的內容.
2737
					#必填參數:
2738
					#$conf["input"],字串,要檢查的字串.
2739
					$conf["search::findSpecifyStrFormat"]["input"]=$oriLog;
2740
					#$conf["format"],格式字串,要尋找的格式字串.格式為固定的字串("fixedStr format")與變數("${keyWordVarName}")組成.
2741
					$conf["search::findSpecifyStrFormat"]["format"]="\${month} \${day} \${hour}:\${min}:\${sec} \${doNotNeed} : authentication failure; logname=\${account} \${doNotNeed} rhost=\${ip}";
2742
					#可省略參數:
2743
					#$conf["varEqual"],陣列,變數對應的數值,null代表不指定,其他內容代表該變數解析出來必須要為該內容.
2744
					#$conf["search::findSpecifyStrFormat"]["varEqual"]=array(null,"found");
2745
					#$conf["varCon"],陣列,每個varEqual為null者,其是否有其他條件,預設為null代表無其他條件,條件的表示是用陣列的key與value來表達,例如:array("no_tail"=>" not"),就代表變數的結尾不能為" not",可以用的key有"head",代表開頭要有什麼;"no_head",代表不能為什麼開頭;"tail",代表要什麼結尾;"no_tail",代表不能什麼結尾.
2746
					#$conf["varCon"]=array("no_tail"=>" not");
2747
					#參考資料:
2748
					#無.
2749
					#備註:
2750
					#無.
2751
					$findSpecifyStrFormat=search::findSpecifyStrFormat($conf["search::findSpecifyStrFormat"]);
2752
					unset($conf["search::findSpecifyStrFormat"]);
2753
 
2754
					#如果分割失敗
2755
					if($findSpecifyStrFormat["status"]==="false"){
2756
 
2757
						#設置執行失敗
2758
						$result["status"]="false";
2759
 
2760
						#設置錯誤訊息
2761
						$result["error"]=$findSpecifyStrFormat;
2762
 
2763
						#回傳結果
2764
						return $result;
2765
 
2766
						}#if end
2767
 
2768
					#如果沒有符合格式
2769
					if($findSpecifyStrFormat["found"]==="false"){
2770
 
2771
						#跳過該行
2772
						continue 2;
2773
 
2774
						}#if end
2775
 
2776
					#取得時間點
2777
					$time=$findSpecifyStrFormat["parsedVar"]["month"][0]." ".$findSpecifyStrFormat["parsedVar"]["day"][0]." ".$findSpecifyStrFormat["parsedVar"]["hour"][0].":".$findSpecifyStrFormat["parsedVar"]["min"][0].":".$findSpecifyStrFormat["parsedVar"]["sec"][0];
2778
 
2779
					#取得ip
2780
					$ip=$findSpecifyStrFormat["parsedVar"]["ip"][0];
2781
 
2782
					#儲存其資訊
2783
					$rickyIpsOfDocecot[$ip][]=array("time"=>$time,"ip"=>$ip,"log"=>$oriLog);
2784
 
2785
					#跳出  switch
2786
					break;
2787
 
2788
				#如果是未認證或SSL錯誤
2789
				case $keyWordNAA:
2790
 
2791
					#範例
2792
					#Feb 23 07:59:30 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=<70q2l/W7PBhliNc9>
2793
					#Sep 29 06:53:42 qbpwcf.org dovecot[98]: imap-login: Disconnected: Connection closed (no auth attempts in 0 secs): user=<>, rip=3.231.151.171, lip=169.254.2.1, TLS, session=<MaKQGOs/wIMD55er>
2794
					#${month} ${day} ${hour}:${min}:${sec} ${doNotNeed} ( no auth attempts in ${doNotNeed} user=<${account}>, rip=${ip}, ${doNotNeed}
2795
 
2796
					#取得時間點跟遠端IP
2797
					#函式說明:
2798
					#尋找字串中是否含有符合格式的內容,且回傳解析好的變數數值.
2799
					#回傳結果:
2800
					#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
2801
					#$reuslt["error"],執行不正常結束的錯訊息陣列.
2802
					#$result["function"],當前執行的函式名稱.
2803
					#$result["argu"],所使用的參數.
2804
					#$result["found"],是否有找到符合格式的字串內容,"true"代表有找到,"false"代表沒有找到.
2805
					#$result["content"],陣列,若為n個${*},則當found為"true"時,就會回傳n個元素.
2806
					#$result["parsedVar"][varName],陣列,解析好的變數陣列,varName為${}中的內容.
2807
					#必填參數:
2808
					#$conf["input"],字串,要檢查的字串.
2809
					$conf["search::findSpecifyStrFormat"]["input"]=$oriLog;
2810
					#$conf["format"],格式字串,要尋找的格式字串.格式為固定的字串("fixedStr format")與變數("${keyWordVarName}")組成.
2811
					$conf["search::findSpecifyStrFormat"]["format"]="\${month} \${day} \${hour}:\${min}:\${sec} \${doNotNeed} ( no auth attempts in \${doNotNeed} user=<\${account}>, rip=\${ip}, \${doNotNeed}";
2812
					#可省略參數:
2813
					#$conf["varEqual"],陣列,變數對應的數值,null代表不指定,其他內容代表該變數解析出來必須要為該內容.
2814
					#$conf["search::findSpecifyStrFormat"]["varEqual"]=array(null,"found");
2815
					#$conf["varCon"],陣列,每個varEqual為null者,其是否有其他條件,預設為null代表無其他條件,條件的表示是用陣列的key與value來表達,例如:array("no_tail"=>" not"),就代表變數的結尾不能為" not",可以用的key有"head",代表開頭要有什麼;"no_head",代表不能為什麼開頭;"tail",代表要什麼結尾;"no_tail",代表不能什麼結尾.
2816
					#$conf["varCon"]=array("no_tail"=>" not");
2817
					#參考資料:
2818
					#無.
2819
					#備註:
2820
					#無.
2821
					$findSpecifyStrFormat=search::findSpecifyStrFormat($conf["search::findSpecifyStrFormat"]);
2822
					unset($conf["search::findSpecifyStrFormat"]);
2823
 
2824
					#如果分割失敗
2825
					if($findSpecifyStrFormat["status"]==="false"){
2826
 
2827
						#設置執行失敗
2828
						$result["status"]="false";
2829
 
2830
						#設置錯誤訊息
2831
						$result["error"]=$findSpecifyStrFormat;
2832
 
2833
						#回傳結果
2834
						return $result;
2835
 
2836
						}#if end
2837
 
2838
					#如果沒有符合格式
2839
					if($findSpecifyStrFormat["found"]==="false"){
2840
 
2841
						#跳過該行
2842
						continue 2;
2843
 
2844
						}#if end
2845
 
2846
					#取得時間點
2847
					$time=$findSpecifyStrFormat["parsedVar"]["month"][0]." ".$findSpecifyStrFormat["parsedVar"]["day"][0]." ".$findSpecifyStrFormat["parsedVar"]["hour"][0].":".$findSpecifyStrFormat["parsedVar"]["min"][0].":".$findSpecifyStrFormat["parsedVar"]["sec"][0];
2848
 
2849
					#取得ip
2850
					$ip=$findSpecifyStrFormat["parsedVar"]["ip"][0];
2851
 
2852
					#儲存其資訊
2853
					$rickyIpsOfDocecot[$ip][]=array("time"=>$time,"ip"=>$ip,"log"=>$oriLog);
2854
 
2855
					#跳出  switch
2856
					break;
2857
 
2858
				#不應該執行到這邊
2859
				default:
2860
 
2861
					#設置執行失敗
2862
					$result["status"]="false";
2863
 
2864
					#設置錯誤訊息
2865
					$result["error"][]="unexpected error";
2866
 
2867
					#設置錯誤訊息
2868
					$result["error"][]=$findManyKeyWordsFromManyString;
2869
 
2870
					#回傳結果
2871
					return $result;
2872
 
2873
				}#switch end
2874
 
2875
			}#foreach end
2876
 
2877
		#初始化儲存可能有問題的ip資訊
2878
		$risky_ips=array();
2879
 
2880
		#針對每個ip
2881
		foreach($rickyIpsOfDocecot as $ip => $info){
2882
 
2883
			#如果同樣ip不到3次
2884
			if(count($rickyIpsOfDocecot[$ip])<3){
2885
 
2886
				#換看下個ip
2887
				continue;
2888
 
2889
				}#if end
2890
 
2891
			#儲存可能有問題的ip資訊
2892
			$risky_ips[]=$rickyIpsOfDocecot[$ip];
2893
 
2894
			}#foreach end
2895
 
2896
		#針對每個可能有問題ip的每個log行
2897
		foreach($risky_ips as $ip => $infos){
2898
 
2899
			#初始化暫存歷史資訊的陣列
2900
			$history=array();
2901
 
2902
			#初始化記錄ip來訪不大於1分鐘的計數
2903
			$count=0;
2904
 
2905
			#針對每個log行資訊
2906
			foreach($infos as $index => $info){
2907
 
2908
				#unixtime
2909
				$time=strtotime($info["time"]);
2910
 
2911
				#如果沒有下筆記錄
2912
				if(!isset($infos[$index+1])){
2913
 
2914
					#結束 foreach
2915
					break;
2916
 
2917
					}#if end
2918
 
2919
				#取得unixtime
2920
				$next_time=strtotime($infos[$index+1]["time"]);
2921
 
2922
				#如果時間間隔大於60秒
2923
				if($next_time-$time>60){
2924
 
2925
					#跳過,看下筆記錄
2926
					continue;
2927
 
2928
					}#if end
2929
 
2930
				#計數+1
2931
				$count++;
2932
 
2933
				#記錄該次事件資訊
2934
				$history[]=array("time"=>$time,"log"=>$info["log"]);
2935
 
2936
				}#foreach end
2937
 
2938
			#如果有達到3次
2939
			if($count>=3){
2940
 
2941
				#初始化陣列
2942
				$tmp=array();
2943
 
2944
				#記錄ip
2945
				$tmp["ip"]=$ip;
2946
 
2947
				#記錄歷史資訊
2948
				$tmp["info"]=$history;
2949
 
2950
				#記錄攻擊者的IP
2951
				$attacker_ips_imap[]=$ip;
2952
 
2953
				}#if end
2954
 
2955
			}#foreach end
2956
 
2957
		#設置結果
2958
		$result["content"]=$attacker_ips_imap;
2959
 
2960
		#設置執行正常
2961
		$result["status"]="true";
2962
 
2963
		#回傳結果
2964
		return $result;
2965
 
2966
		}#function checkDovecotAttackLog end
2967
 
2968
	/*
2969
	#函式說明:
2970
	#檢查 ssh log 中疑似攻擊的記錄.
2971
	#回傳結果:
2972
	#$result["status"],字串,執行是否正常,"true"代表正常,"false"代表不正常.
2973
	#$result["error"],錯誤訊息陣列.
2974
	#$result["function"],字串,當前執行的函式名稱.
2975
	#$result["content"],陣列,攻擊記錄資訊,每個元素為陣列key為"ip"者為攻擊者的ip;key為info者為其資訊陣列,其key為"log"者代表log的行內容;key為"time"者代表時間點;key為ip者代表ip.
2976
	#必填參數:
2977
	#無.
2978
	#可省略參數:
2979
	#無
2980
	#參考資料:
2981
	#無.
2982
	#備註:
2983
	#無.
2984
	*/
2985
	public static function checkSshAttackLog(){
2986
 
2987
		#初始化要回傳的結果
2988
		$result=array();
2989
 
2990
		#取得當前執行的函數名稱
2991
		$result["function"]=__FUNCTION__;
2992
 
2993
		#記錄ssh攻擊者的IP
2994
		$attacker_ips_ssh=array();
2995
 
2996
		#透過 journalctl -a -e --unit=sshd.service來取得 ssh 攻擊者的 IP
2997
		#函式說明:
2998
		#呼叫shell執行系統命令,並取得回傳的內容.
2999
		#回傳的結果:
3000
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
3001
		#$result["error"],錯誤訊息陣列.
3002
		#$result["function"],當前執行的函式名稱.
3003
		#$result["argu"],使用的參數.
3004
		#$result["cmd"],執行的指令內容.
3005
		#$result["fullCmd"],如果參數 $conf["inBackGround"] 為 "true" 則會回傳該值.
3006
		#$result["output"],爲執行完二元碼後的輸出陣列,若 $conf["inBackGround"] 為 "true",則為當下的輸出.
3007
		#$result["tmpFileOutput"],儲存輸出的暫存檔案名稱,若 $conf["inBackGround"] 為 "true" 則會回傳該值.
3008
		#$result["running"],是否還在執行.
3009
		#$result["pid"],pid.
3010
		#$result["statusCode"],執行結束後的代碼.
3011
		#必填參數:
3012
		#$conf["command"],字串,要執行的指令與.
3013
		$conf["external::callShell"]["command"]="journalctl";
3014
		#$conf["fileArgu"],字串,變數__FILE__的內容.
3015
		$conf["external::callShell"]["fileArgu"]=__FILE__;
3016
		#可省略參數:
3017
		#$conf["argu"],陣列字串,指令搭配的參數,預設為空陣列.
3018
		$conf["external::callShell"]["argu"]=array("-a","-e","--unit=sshd.service");
3019
		#$conf["arguIsAddr"],陣列字串,指令搭配的哪些參數為路徑,為路徑的參數會進行轉換以便符合呼叫當前函式的位置,預設不指定,若有3個參數,其中第3個參數為路徑,則表示為array("false","false","true").
3020
		#$conf["arguIsAddr"]=array();
3021
		#$conf["pre"],陣列,要在本指令前執行的每個指令與參數.
3022
		#$conf["pre"][$i]["cmd"],字串,要在本指令前執行的第$i+1個指令.
3023
		#$conf["pre"][$i]["param"],陣列字串,要在本指令前執行的第$i+1個指令的參數.
3024
		#$conf["enablePrintDescription"],字串,是否要印出$conf["printDescription"]的內容,"true"代表要,"false"代表不要,預設為"false".
3025
		#$conf["enablePrintDescription"]="true";
3026
		#$conf["printDescription"],字串,執行該外部程式前要印出來的的文字,預設為$conf["command"]的內容加上使用的$conf["argu"]參數.
3027
		#$conf["printDescription"]="";
3028
		#$conf["escapeshellarg"],字串,是否要啟用過濾參數,用了比較安全,但可能會出錯,"true"為啟用,"false"為不啟用,預設為"false".
3029
		$conf["external::callShell"]["escapeshellarg"]="true";
3030
		#$conf["username"],字串,要用什麼使用者來執行,預設為執行php的使用者,該參數不適用於apache環境.
3031
		#$conf["username"]="";
3032
		#$conf["password"],字串,root的使用者密碼,預設不使用密碼,該參數不適用於apache環境.
3033
		#$conf["password"]="";
3034
		#$conf["useScript"],字串,是否要啟用Linux的script指令來記錄輸出,"true"代表要,Fedora的selinux會擋住該操作;"false"代表不要,預設為"false".
3035
		#$conf["useScript"]="";
3036
		#$conf["logFilePath"],字串,當 $conf["useScript"] 為 "true" 時,輸出的內容要暫存到哪裡,預設為 "/tmp/.qbpwcf_tmp/external/callShell/".
3037
		#$conf["logFilePath"]=".qbpwcf_tmp/external/callShell/";
3038
		#$conf["inBackGround"],字串,是否要在背景執行,且不會等待程式執行結束再執行下一個指令,"true"代表是,"false"代表不要,預設為"false",如果$conf["command"]有用「;」區隔的多個指令將會出錯.
3039
		#$conf["inBackGround"]="";
3040
		#$conf["getErr"],字串,"true"代表將錯誤輸出變成標準輸出,反之"false"為不變動.
3041
		#$conf["getErr"]="false";
3042
		#備註:
3043
		#不是所有指令都能用apache的身份執行,目前已知java,javac指令無法執行,使用root身份可能會被selinux阻擋.
3044
		#參考資料:
3045
		#exec=>http://php.net/manual/en/function.exec.php
3046
		#escapeshellcmd=>http://php.net/manual/en/function.escapeshellcmd.php
3047
		#escapeshellarg=>http://php.net/manual/en/function.escapeshellarg.php
3048
		$callShell=external::callShell($conf["external::callShell"]);
3049
		unset($conf["external::callShell"]);
3050
 
3051
		#如果執行失敗
3052
		if($callShell["status"]==="false"){
3053
 
3054
			#如果有 statusCode
3055
			if(isset($callShell["statusCode"])){
3056
 
3057
				#如果shell回傳不為0也不為1
3058
				if($callShell["statusCode"]!==0 && $callShell["statusCode"]!==1){
3059
 
3060
					#設置執行失敗
3061
					$result["status"]="false";
3062
 
3063
					#設置錯誤訊息
3064
					$result["error"]=$callShell;
3065
 
3066
					#回傳結果
3067
					return $result;
3068
 
3069
					}#if end
3070
 
3071
				}#if end
3072
 
3073
			#設置執行失敗
3074
			$result["status"]="false";
3075
 
3076
			#設置錯誤訊息
3077
			$result["error"]=$callShell;
3078
 
3079
			#回傳結果
3080
			return $result;
3081
 
3082
			}#if end
3083
 
3084
		/*
3085
		得到的範例輸出
3086
		Sep 30 00:36:36 silverblue-guest.qbpwcf.org sshd-session[1607010]: Invalid user lizepeng from 60.213.10.69 port 39156
3087
		Sep 30 00:36:36 silverblue-guest.qbpwcf.org sshd-session[1607010]: pam_unix(sshd:auth): check pass; user unknown
3088
		Sep 30 00:36:36 silverblue-guest.qbpwcf.org sshd-session[1607010]: pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=60.213.10.69
3089
		Sep 30 00:36:38 silverblue-guest.qbpwcf.org sshd-session[1607010]: Failed password for invalid user lizepeng from 60.213.10.69 port 39156 ssh2
3090
		Sep 30 00:36:40 silverblue-guest.qbpwcf.org sshd-session[1607010]: Connection closed by invalid user lizepeng 60.213.10.69 port 39156 [preauth]
3091
		Sep 30 05:54:01 silverblue-guest.qbpwcf.org sshd-session[2346022]: pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=60.213.10.81  user=root
3092
		Sep 30 05:54:03 silverblue-guest.qbpwcf.org sshd-session[2346022]: Failed password for root from 60.213.10.81 port 41644 ssh2
3093
		Sep 30 05:54:04 silverblue-guest.qbpwcf.org sshd-session[2346022]: Connection closed by authenticating user root 60.213.10.81 port 41644 [preauth]
3094
		Sep 30 05:54:20 silverblue-guest.qbpwcf.org sshd-session[2346860]: Invalid user qy from 60.213.10.81 port 42960
3095
		Sep 30 05:54:21 silverblue-guest.qbpwcf.org sshd-session[2346860]: pam_unix(sshd:auth): check pass; user unknown
3096
		Sep 30 05:54:21 silverblue-guest.qbpwcf.org sshd-session[2346860]: pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=60.213.10.81
3097
		Sep 30 05:54:22 silverblue-guest.qbpwcf.org sshd-session[2346860]: Failed password for invalid user qy from 60.213.10.81 port 42960 ssh2
3098
		Sep 30 05:54:23 silverblue-guest.qbpwcf.org sshd-session[2346860]: Connection closed by invalid user qy 60.213.10.81 port 42960 [preauth]
3099
		Sep 30 06:08:06 silverblue-guest.qbpwcf.org sshd-session[2378295]: Connection closed by 167.94.145.105 port 55712 [preauth]
3100
		Sep 30 08:09:51 silverblue-guest.qbpwcf.org sshd-session[2662907]: pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=183.13.207.69  user=root
3101
		Sep 30 08:09:54 silverblue-guest.qbpwcf.org sshd-session[2662907]: Failed password for root from 183.13.207.69 port 18258 ssh2
3102
		Sep 30 08:09:54 silverblue-guest.qbpwcf.org sshd-session[2662907]: Connection closed by authenticating user root 183.13.207.69 port 18258 [preauth]
3103
		Sep 30 08:10:11 silverblue-guest.qbpwcf.org sshd-session[2663658]: pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=183.13.207.69  user=root
3104
		Sep 30 08:10:13 silverblue-guest.qbpwcf.org sshd-session[2663658]: Failed password for root from 183.13.207.69 port 17293 ssh2
3105
		Sep 30 08:10:13 silverblue-guest.qbpwcf.org sshd-session[2663658]: Connection closed by authenticating user root 183.13.207.69 port 17293 [preauth]
3106
		*/
3107
 
3108
		#認證失敗的關鍵字
3109
		$keyWordFP=" Failed password ";
3110
 
3111
		#不存在使用者的關鍵字
3112
		$keyWordIU=" Invalid user ";
3113
 
3114
		#搜尋符合關鍵字的log行
3115
		#函式說明:
3116
		#檢查多個字串中的每個字串是否有多個關鍵字
3117
		#回傳結果:
3118
		#$result["status"],整體來說,執行是否成功,"true"代表執行成功,"false"代表執行失敗。
3119
		#$result["function"],當前執行的函數名稱.
3120
		#$result["error"],錯誤訊息.
3121
		#$result["argu"],使用的參數.
3122
		#$result["foundedTrueKey"],結果為"true"的被搜尋元素key陣列,與其數值內容.
3123
		#$result["foundedKeyWords"],找到的關鍵字陣列.
3124
		#$result["foundedFalseKey"],結果為"false"的被搜尋元素key陣列,與其數值內容.
3125
		#$result["foundedTrueKeyWords"],二維陣列,各個字串有找到的關鍵字陣列.
3126
		#$result["foundedAll"],是否每個關鍵字都有找到,"true"代表每個都有找到,"false"代表沒有每個都找到.
3127
		#$result["keyWordsIncludeStr"],陣列,儲存有找到關鍵字的來源的索引(sourceIndex)與其內容(sourceVal)跟找到的關鍵字項目陣列(KeyWords).
3128
		#必填參數:
3129
		#$conf["keyWords"],字串陣列,想要搜尋的關鍵字.
3130
		$conf["search::findManyKeyWordsFromManyString"]["keyWords"]=array($keyWordFP,$keyWordIU);
3131
		#$conf["stringArray"],字串陣列,要被搜尋的字串內容陣列.
3132
		$conf["search::findManyKeyWordsFromManyString"]["stringArray"]=$callShell["output"];
3133
		#可省略參數:
3134
		#$conf["completeEqual"],字串,是否內容要完全符合,不能多出任何不符合的內容,預設為"false"不需要完全符合.
3135
		#$conf["completeEqual"]="true";
3136
		#參考資料:
3137
		#無.
3138
		#備註:
3139
		#無.
3140
		$findManyKeyWordsFromManyString=search::findManyKeyWordsFromManyString($conf["search::findManyKeyWordsFromManyString"]);
3141
		unset($conf["search::findManyKeyWordsFromManyString"]);
3142
 
3143
		#如果執行失敗
3144
		if($findManyKeyWordsFromManyString["status"]==="false"){
3145
 
3146
			#設置執行失敗
3147
			$result["status"]="false";
3148
 
3149
			#設置錯誤訊息
3150
			$result["error"]=$findManyKeyWordsFromManyString;
3151
 
3152
			#回傳結果
3153
			return $result;
3154
 
3155
			}#if end
3156
 
3157
		#初始化儲存可能有問題的存取ssh服務遠端ip
3158
		$risky_ips=array();
3159
 
3160
		#針對每個符合的log行
3161
		foreach($findManyKeyWordsFromManyString["foundedTrueKey"] as $index => $oriLog){
3162
 
3163
			#找到的關鍵字
3164
			$foundKeyWord=$findManyKeyWordsFromManyString["foundedTrueKeyWords"][$index][0];
3165
 
3166
			#依照符合的關鍵字
3167
			switch($foundKeyWord){
3168
 
3169
				#如果是秘密碼錯誤
3170
				case $keyWordFP:
3171
 
3172
					#範例
3173
					#Sep 30 08:10:13 silverblue-guest.qbpwcf.org sshd-session[2663658]: Failed password for root from 183.13.207.69 port 17293 ssh2
3174
					#${month} ${day} ${hour}:${min}:${sec} ${doNotNeed} Failed password for ${account} from ${ip} ${doNotNeed}
3175
 
3176
					#取得時間點跟遠端IP
3177
					#函式說明:
3178
					#尋找字串中是否含有符合格式的內容,且回傳解析好的變數數值.
3179
					#回傳結果:
3180
					#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
3181
					#$reuslt["error"],執行不正常結束的錯訊息陣列.
3182
					#$result["function"],當前執行的函式名稱.
3183
					#$result["argu"],所使用的參數.
3184
					#$result["found"],是否有找到符合格式的字串內容,"true"代表有找到,"false"代表沒有找到.
3185
					#$result["content"],陣列,若為n個${*},則當found為"true"時,就會回傳n個元素.
3186
					#$result["parsedVar"][varName],陣列,解析好的變數陣列,varName為${}中的內容.
3187
					#必填參數:
3188
					#$conf["input"],字串,要檢查的字串.
3189
					$conf["search::findSpecifyStrFormat"]["input"]=$oriLog;
3190
					#$conf["format"],格式字串,要尋找的格式字串.格式為固定的字串("fixedStr format")與變數("${keyWordVarName}")組成.
3191
					$conf["search::findSpecifyStrFormat"]["format"]="\${month} \${day} \${hour}:\${min}:\${sec} \${doNotNeed} Failed password for \${account} from \${ip} \${doNotNeed}";
3192
					#可省略參數:
3193
					#$conf["varEqual"],陣列,變數對應的數值,null代表不指定,其他內容代表該變數解析出來必須要為該內容.
3194
					#$conf["search::findSpecifyStrFormat"]["varEqual"]=array(null,"found");
3195
					#$conf["varCon"],陣列,每個varEqual為null者,其是否有其他條件,預設為null代表無其他條件,條件的表示是用陣列的key與value來表達,例如:array("no_tail"=>" not"),就代表變數的結尾不能為" not",可以用的key有"head",代表開頭要有什麼;"no_head",代表不能為什麼開頭;"tail",代表要什麼結尾;"no_tail",代表不能什麼結尾.
3196
					#$conf["varCon"]=array("no_tail"=>" not");
3197
					#參考資料:
3198
					#無.
3199
					#備註:
3200
					#無.
3201
					$findSpecifyStrFormat=search::findSpecifyStrFormat($conf["search::findSpecifyStrFormat"]);
3202
					unset($conf["search::findSpecifyStrFormat"]);
3203
 
3204
					#如果分割失敗
3205
					if($findSpecifyStrFormat["status"]==="false"){
3206
 
3207
						#設置執行失敗
3208
						$result["status"]="false";
3209
 
3210
						#設置錯誤訊息
3211
						$result["error"]=$findSpecifyStrFormat;
3212
 
3213
						#回傳結果
3214
						return $result;
3215
 
3216
						}#if end
3217
 
3218
					#如果沒有符合格式
3219
					if($findSpecifyStrFormat["found"]==="false"){
3220
 
3221
						#跳過該行
3222
						continue 2;
3223
 
3224
						}#if end
3225
 
3226
					#取得時間點
3227
					$time=$findSpecifyStrFormat["parsedVar"]["month"][0]." ".$findSpecifyStrFormat["parsedVar"]["day"][0]." ".$findSpecifyStrFormat["parsedVar"]["hour"][0].":".$findSpecifyStrFormat["parsedVar"]["min"][0].":".$findSpecifyStrFormat["parsedVar"]["sec"][0];
3228
 
3229
					#取得ip
3230
					$ip=$findSpecifyStrFormat["parsedVar"]["ip"][0];
3231
 
3232
					#儲存其資訊
3233
					$risky_ips[$ip][]=array("time"=>$time,"ip"=>$ip,"log"=>$oriLog);
3234
 
3235
					#跳出  switch
3236
					break;
3237
 
3238
				#如果是不存在的使用者
3239
				case $keyWordIU:
3240
 
3241
					#範例
3242
					#Sep 30 00:36:36 silverblue-guest.qbpwcf.org sshd-session[1607010]: Invalid user lizepeng from 60.213.10.69 port 39156
3243
					#${month} ${day} ${hour}:${min}:${sec} ${doNotNeed} Invalid user ${account} from ${ip} port ${doNotNeed}
3244
 
3245
					#取得時間點跟遠端IP
3246
					#函式說明:
3247
					#尋找字串中是否含有符合格式的內容,且回傳解析好的變數數值.
3248
					#回傳結果:
3249
					#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
3250
					#$reuslt["error"],執行不正常結束的錯訊息陣列.
3251
					#$result["function"],當前執行的函式名稱.
3252
					#$result["argu"],所使用的參數.
3253
					#$result["found"],是否有找到符合格式的字串內容,"true"代表有找到,"false"代表沒有找到.
3254
					#$result["content"],陣列,若為n個${*},則當found為"true"時,就會回傳n個元素.
3255
					#$result["parsedVar"][varName],陣列,解析好的變數陣列,varName為${}中的內容.
3256
					#必填參數:
3257
					#$conf["input"],字串,要檢查的字串.
3258
					$conf["search::findSpecifyStrFormat"]["input"]=$oriLog;
3259
					#$conf["format"],格式字串,要尋找的格式字串.格式為固定的字串("fixedStr format")與變數("${keyWordVarName}")組成.
3260
					$conf["search::findSpecifyStrFormat"]["format"]="\${month} \${day} \${hour}:\${min}:\${sec} \${doNotNeed} Invalid user \${account} from \${ip} port \${doNotNeed}";
3261
					#可省略參數:
3262
					#$conf["varEqual"],陣列,變數對應的數值,null代表不指定,其他內容代表該變數解析出來必須要為該內容.
3263
					#$conf["search::findSpecifyStrFormat"]["varEqual"]=array(null,"found");
3264
					#$conf["varCon"],陣列,每個varEqual為null者,其是否有其他條件,預設為null代表無其他條件,條件的表示是用陣列的key與value來表達,例如:array("no_tail"=>" not"),就代表變數的結尾不能為" not",可以用的key有"head",代表開頭要有什麼;"no_head",代表不能為什麼開頭;"tail",代表要什麼結尾;"no_tail",代表不能什麼結尾.
3265
					#$conf["varCon"]=array("no_tail"=>" not");
3266
					#參考資料:
3267
					#無.
3268
					#備註:
3269
					#無.
3270
					$findSpecifyStrFormat=search::findSpecifyStrFormat($conf["search::findSpecifyStrFormat"]);
3271
					unset($conf["search::findSpecifyStrFormat"]);
3272
 
3273
					#如果分割失敗
3274
					if($findSpecifyStrFormat["status"]==="false"){
3275
 
3276
						#設置執行失敗
3277
						$result["status"]="false";
3278
 
3279
						#設置錯誤訊息
3280
						$result["error"]=$findSpecifyStrFormat;
3281
 
3282
						#回傳結果
3283
						return $result;
3284
 
3285
						}#if end
3286
 
3287
					#如果沒有符合格式
3288
					if($findSpecifyStrFormat["found"]==="false"){
3289
 
3290
						#跳過該行
3291
						continue 2;
3292
 
3293
						}#if end
3294
 
3295
					#取得時間點
3296
					$time=$findSpecifyStrFormat["parsedVar"]["month"][0]." ".$findSpecifyStrFormat["parsedVar"]["day"][0]." ".$findSpecifyStrFormat["parsedVar"]["hour"][0].":".$findSpecifyStrFormat["parsedVar"]["min"][0].":".$findSpecifyStrFormat["parsedVar"]["sec"][0];
3297
 
3298
					#取得ip
3299
					$ip=$findSpecifyStrFormat["parsedVar"]["ip"][0];
3300
 
3301
					#儲存其資訊
3302
					$risky_ips[$ip][]=array("time"=>$time,"ip"=>$ip,"log"=>$oriLog);
3303
 
3304
					#跳出  switch
3305
					break;
3306
 
3307
				#不應該執行到這邊
3308
				default:
3309
 
3310
					#設置執行失敗
3311
					$result["status"]="false";
3312
 
3313
					#設置錯誤訊息
3314
					$result["error"][]="unexpected error";
3315
 
3316
					#設置錯誤訊息
3317
					$result["error"][]=$findManyKeyWordsFromManyString;
3318
 
3319
					#回傳結果
3320
					return $result;
3321
 
3322
				}#switch end
3323
 
3324
			}#foreach end
3325
 
3326
		#針對每個可能有問題ip的每個log行
3327
		foreach($risky_ips as $ip => $infos){
3328
 
3329
			#初始化暫存歷史記錄的陣列
3330
			$history=array();
3331
 
3332
			#初始化記錄ip來訪不大於1分鐘的計數
3333
			$count=0;
3334
 
3335
			#針對每個log行資訊
3336
			foreach($infos as $index => $info){
3337
 
3338
				#unixtime
3339
				$time=strtotime($info["time"]);
3340
 
3341
				#如果沒有下筆記錄
3342
				if(!isset($infos[$index+1])){
3343
 
3344
					#結束 foreach
3345
					break;
3346
 
3347
					}#if end
3348
 
3349
				#取得unixtime
3350
				$next_time=strtotime($infos[$index+1]["time"]);
3351
 
3352
				#如果下筆時間記錄與當前這筆間隔大於60秒
3353
				if($next_time-$time>60){
3354
 
3355
					#跳過,看下筆記錄
3356
					continue;
3357
 
3358
					}#if end
3359
 
3360
				#計數+1
3361
				$count++;
3362
 
3363
				#記錄該次記錄
3364
				$history[]=array("time"=>$time,"log"=>$info["log"]);
3365
 
3366
				}#foreach end
3367
 
3368
			#如果有達到3次
3369
			if($count>=3){
3370
 
3371
				#初始化暫存的陣列
3372
				$tmp=array();
3373
 
3374
				#取得資訊
3375
				$tmp["info"]=$history;
3376
 
3377
				#取得問題ip
3378
				$tmp["ip"]=$ip;
3379
 
3380
				#記錄攻擊者的IP
3381
				$attacker_ips_ssh[]=$tmp;
3382
 
3383
				}#if end
3384
 
3385
			}#foreach end
3386
 
3387
		#設置結果
3388
		$result["content"]=$attacker_ips_ssh;
3389
 
3390
		#設置執行正常
3391
		$result["status"]="true";
3392
 
3393
		#回傳結果
3394
		return $result;
3395
 
3396
		}#function checkSshAttackLog end
3397
 
3 liveuser 3398
	}#class security end
3399
 
3400
?>