Merge pull request #1951 from socprime/cloudflare_data_conn
Cloudflare Data Connector
This commit is contained in:
Коммит
c5280bc226
|
@ -0,0 +1,417 @@
|
|||
{
|
||||
"Name": "Cloudflare_CL",
|
||||
"Properties": [
|
||||
{
|
||||
"Name": "BotScore_d",
|
||||
"Type": "Double"
|
||||
},
|
||||
{
|
||||
"Name": "BotScoreSrc_s",
|
||||
"Type": "String"
|
||||
},
|
||||
{
|
||||
"Name": "CacheCacheStatus_s",
|
||||
"Type": "String"
|
||||
},
|
||||
{
|
||||
"Name": "CacheResponseBytes_d",
|
||||
"Type": "Double"
|
||||
},
|
||||
{
|
||||
"Name": "CacheResponseStatus_d",
|
||||
"Type": "Double"
|
||||
},
|
||||
{
|
||||
"Name": "CacheTieredFill_b",
|
||||
"Type": "Bool"
|
||||
},
|
||||
{
|
||||
"Name": "ClientASN_d",
|
||||
"Type": "Double"
|
||||
},
|
||||
{
|
||||
"Name": "ClientCountry_s",
|
||||
"Type": "String"
|
||||
},
|
||||
{
|
||||
"Name": "ClientDeviceType_s",
|
||||
"Type": "String"
|
||||
},
|
||||
{
|
||||
"Name": "ClientIP_s",
|
||||
"Type": "String"
|
||||
},
|
||||
{
|
||||
"Name": "ClientIPClass_s",
|
||||
"Type": "String"
|
||||
},
|
||||
{
|
||||
"Name": "ClientRequestBytes_d",
|
||||
"Type": "Double"
|
||||
},
|
||||
{
|
||||
"Name": "ClientRequestHost_s",
|
||||
"Type": "String"
|
||||
},
|
||||
{
|
||||
"Name": "ClientRequestMethod_s",
|
||||
"Type": "String"
|
||||
},
|
||||
{
|
||||
"Name": "ClientRequestPath_s",
|
||||
"Type": "String"
|
||||
},
|
||||
{
|
||||
"Name": "ClientRequestProtocol_s",
|
||||
"Type": "String"
|
||||
},
|
||||
{
|
||||
"Name": "ClientRequestReferer_s",
|
||||
"Type": "String"
|
||||
},
|
||||
{
|
||||
"Name": "ClientRequestURI_s",
|
||||
"Type": "String"
|
||||
},
|
||||
{
|
||||
"Name": "ClientRequestUserAgent_s",
|
||||
"Type": "String"
|
||||
},
|
||||
{
|
||||
"Name": "ClientSSLCipher_s",
|
||||
"Type": "String"
|
||||
},
|
||||
{
|
||||
"Name": "ClientSSLProtocol_s",
|
||||
"Type": "String"
|
||||
},
|
||||
{
|
||||
"Name": "ClientSrcPort_d",
|
||||
"Type": "Double"
|
||||
},
|
||||
{
|
||||
"Name": "ClientXRequestedWith_s",
|
||||
"Type": "String"
|
||||
},
|
||||
{
|
||||
"Name": "EdgeColoCode_s",
|
||||
"Type": "String"
|
||||
},
|
||||
{
|
||||
"Name": "EdgeColoID_d",
|
||||
"Type": "Double"
|
||||
},
|
||||
{
|
||||
"Name": "EdgeEndTimestamp_t",
|
||||
"Type": "DateTime"
|
||||
},
|
||||
{
|
||||
"Name": "EdgePathingOp_s",
|
||||
"Type": "String"
|
||||
},
|
||||
{
|
||||
"Name": "EdgePathingSrc_s",
|
||||
"Type": "String"
|
||||
},
|
||||
{
|
||||
"Name": "EdgePathingStatus_s",
|
||||
"Type": "String"
|
||||
},
|
||||
{
|
||||
"Name": "EdgeRateLimitAction_s",
|
||||
"Type": "String"
|
||||
},
|
||||
{
|
||||
"Name": "EdgeRateLimitID_d",
|
||||
"Type": "Double"
|
||||
},
|
||||
{
|
||||
"Name": "EdgeRequestHost_s",
|
||||
"Type": "String"
|
||||
},
|
||||
{
|
||||
"Name": "EdgeResponseBytes_d",
|
||||
"Type": "Double"
|
||||
},
|
||||
{
|
||||
"Name": "EdgeResponseCompressionRatio_d",
|
||||
"Type": "Double"
|
||||
},
|
||||
{
|
||||
"Name": "EdgeResponseContentType_s",
|
||||
"Type": "String"
|
||||
},
|
||||
{
|
||||
"Name": "EdgeResponseStatus_d",
|
||||
"Type": "Double"
|
||||
},
|
||||
{
|
||||
"Name": "EdgeServerIP_s",
|
||||
"Type": "String"
|
||||
},
|
||||
{
|
||||
"Name": "EdgeStartTimestamp_t",
|
||||
"Type": "DateTime"
|
||||
},
|
||||
{
|
||||
"Name": "FirewallMatchesActions_s",
|
||||
"Type": "String"
|
||||
},
|
||||
{
|
||||
"Name": "FirewallMatchesRuleIDs_s",
|
||||
"Type": "String"
|
||||
},
|
||||
{
|
||||
"Name": "FirewallMatchesSources_s",
|
||||
"Type": "String"
|
||||
},
|
||||
{
|
||||
"Name": "OriginIP_s",
|
||||
"Type": "String"
|
||||
},
|
||||
{
|
||||
"Name": "OriginResponseBytes_d",
|
||||
"Type": "Double"
|
||||
},
|
||||
{
|
||||
"Name": "OriginResponseHTTPExpires_s",
|
||||
"Type": "String"
|
||||
},
|
||||
{
|
||||
"Name": "OriginResponseHTTPLastModified_s",
|
||||
"Type": "String"
|
||||
},
|
||||
{
|
||||
"Name": "OriginResponseStatus_d",
|
||||
"Type": "Double"
|
||||
},
|
||||
{
|
||||
"Name": "OriginResponseTime_d",
|
||||
"Type": "Double"
|
||||
},
|
||||
{
|
||||
"Name": "OriginSSLProtocol_s",
|
||||
"Type": "String"
|
||||
},
|
||||
{
|
||||
"Name": "ParentRayID_s",
|
||||
"Type": "String"
|
||||
},
|
||||
{
|
||||
"Name": "RayID_s",
|
||||
"Type": "String"
|
||||
},
|
||||
{
|
||||
"Name": "SecurityLevel_s",
|
||||
"Type": "String"
|
||||
},
|
||||
{
|
||||
"Name": "WAFAction_s",
|
||||
"Type": "String"
|
||||
},
|
||||
{
|
||||
"Name": "WAFFlags_s",
|
||||
"Type": "String"
|
||||
},
|
||||
{
|
||||
"Name": "WAFMatchedVar_s",
|
||||
"Type": "String"
|
||||
},
|
||||
{
|
||||
"Name": "WAFProfile_s",
|
||||
"Type": "String"
|
||||
},
|
||||
{
|
||||
"Name": "WAFRuleID_s",
|
||||
"Type": "String"
|
||||
},
|
||||
{
|
||||
"Name": "WAFRuleMessage_s",
|
||||
"Type": "String"
|
||||
},
|
||||
{
|
||||
"Name": "WorkerCPUTime_d",
|
||||
"Type": "Double"
|
||||
},
|
||||
{
|
||||
"Name": "WorkerStatus_s",
|
||||
"Type": "String"
|
||||
},
|
||||
{
|
||||
"Name": "WorkerSubrequest_b",
|
||||
"Type": "Bool"
|
||||
},
|
||||
{
|
||||
"Name": "WorkerSubrequestCount_d",
|
||||
"Type": "Double"
|
||||
},
|
||||
{
|
||||
"Name": "ZoneID_d",
|
||||
"Type": "Double"
|
||||
},
|
||||
{
|
||||
"Name": "Application_s",
|
||||
"Type": "String"
|
||||
},
|
||||
{
|
||||
"Name": "ClientBytes_d",
|
||||
"Type": "Double"
|
||||
},
|
||||
{
|
||||
"Name": "ClientMatchedIpFirewall_s",
|
||||
"Type": "String"
|
||||
},
|
||||
{
|
||||
"Name": "ClientPort_d",
|
||||
"Type": "Double"
|
||||
},
|
||||
{
|
||||
"Name": "ClientProto_s",
|
||||
"Type": "String"
|
||||
},
|
||||
{
|
||||
"Name": "ClientTcpRtt_d",
|
||||
"Type": "Double"
|
||||
},
|
||||
{
|
||||
"Name": "ClientTlsCipher_s",
|
||||
"Type": "String"
|
||||
},
|
||||
{
|
||||
"Name": "ClientTlsClientHelloServerName_s",
|
||||
"Type": "String"
|
||||
},
|
||||
{
|
||||
"Name": "ClientTlsProtocol_s",
|
||||
"Type": "String"
|
||||
},
|
||||
{
|
||||
"Name": "ClientTlsStatus_s",
|
||||
"Type": "String"
|
||||
},
|
||||
{
|
||||
"Name": "ColoCode_s",
|
||||
"Type": "String"
|
||||
},
|
||||
{
|
||||
"Name": "ConnectTimestamp_t",
|
||||
"Type": "DateTime"
|
||||
},
|
||||
{
|
||||
"Name": "DisconnectTimestamp_t",
|
||||
"Type": "DateTime"
|
||||
},
|
||||
{
|
||||
"Name": "Event_s",
|
||||
"Type": "String"
|
||||
},
|
||||
{
|
||||
"Name": "IpFirewall_b",
|
||||
"Type": "Bool"
|
||||
},
|
||||
{
|
||||
"Name": "OriginBytes_d",
|
||||
"Type": "Double"
|
||||
},
|
||||
{
|
||||
"Name": "OriginPort_d",
|
||||
"Type": "Double"
|
||||
},
|
||||
{
|
||||
"Name": "OriginProto_s",
|
||||
"Type": "String"
|
||||
},
|
||||
{
|
||||
"Name": "OriginTcpRtt_d",
|
||||
"Type": "Double"
|
||||
},
|
||||
{
|
||||
"Name": "OriginTlsCipher_s",
|
||||
"Type": "String"
|
||||
},
|
||||
{
|
||||
"Name": "OriginTlsFingerprint_s",
|
||||
"Type": "String"
|
||||
},
|
||||
{
|
||||
"Name": "OriginTlsMode_s",
|
||||
"Type": "String"
|
||||
},
|
||||
{
|
||||
"Name": "OriginTlsProtocol_s",
|
||||
"Type": "String"
|
||||
},
|
||||
{
|
||||
"Name": "OriginTlsStatus_s",
|
||||
"Type": "String"
|
||||
},
|
||||
{
|
||||
"Name": "ProxyProtocol_s",
|
||||
"Type": "String"
|
||||
},
|
||||
{
|
||||
"Name": "Status_d",
|
||||
"Type": "Double"
|
||||
},
|
||||
{
|
||||
"Name": "Timestamp_t",
|
||||
"Type": "DateTime"
|
||||
},
|
||||
{
|
||||
"Name": "Action_s",
|
||||
"Type": "String"
|
||||
},
|
||||
{
|
||||
"Name": "ClientASNDescription_s",
|
||||
"Type": "String"
|
||||
},
|
||||
{
|
||||
"Name": "ClientRefererHost_s",
|
||||
"Type": "String"
|
||||
},
|
||||
{
|
||||
"Name": "ClientRefererPath_s",
|
||||
"Type": "String"
|
||||
},
|
||||
{
|
||||
"Name": "ClientRefererQuery_s",
|
||||
"Type": "String"
|
||||
},
|
||||
{
|
||||
"Name": "ClientRefererScheme_s",
|
||||
"Type": "String"
|
||||
},
|
||||
{
|
||||
"Name": "ClientRequestQuery_s",
|
||||
"Type": "String"
|
||||
},
|
||||
{
|
||||
"Name": "ClientRequestScheme_s",
|
||||
"Type": "String"
|
||||
},
|
||||
{
|
||||
"Name": "Datetime_t",
|
||||
"Type": "DateTime"
|
||||
},
|
||||
{
|
||||
"Name": "Kind_s",
|
||||
"Type": "String"
|
||||
},
|
||||
{
|
||||
"Name": "MatchIndex_d",
|
||||
"Type": "Double"
|
||||
},
|
||||
{
|
||||
"Name": "OriginatorRayID_s",
|
||||
"Type": "String"
|
||||
},
|
||||
{
|
||||
"Name": "RuleID_s",
|
||||
"Type": "String"
|
||||
},
|
||||
{
|
||||
"Name": "Source_s",
|
||||
"Type": "String"
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
"scriptFile": "main.py",
|
||||
"bindings": [
|
||||
{
|
||||
"name": "mytimer",
|
||||
"type": "timerTrigger",
|
||||
"direction": "in",
|
||||
"schedule": "0 */2 * * * *"
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,263 @@
|
|||
import os
|
||||
import asyncio
|
||||
from azure.storage.blob.aio import ContainerClient
|
||||
import json
|
||||
import logging
|
||||
from dateutil.parser import parse as parse_date
|
||||
import datetime
|
||||
import azure.functions as func
|
||||
import re
|
||||
|
||||
from .sentinel_connector_async import AzureSentinelMultiConnectorAsync
|
||||
from .state_manager import StateManagerAsync
|
||||
|
||||
|
||||
# interval of script execution
|
||||
SCRIPT_EXECUTION_INTERVAL_MINUTES = 2
|
||||
# if ts of last processed file is older than now - MAX_PERIOD_MINUTES -> script will get events from now - SCRIPT_EXECUTION_INTERVAL_MINUTES
|
||||
MAX_PERIOD_MINUTES = 1440
|
||||
|
||||
MAX_SCRIPT_EXEC_TIME_MINUTES = 35
|
||||
|
||||
|
||||
AZURE_STORAGE_CONNECTION_STRING = os.environ['AZURE_STORAGE_CONNECTION_STRING']
|
||||
CONTAINER_NAME = os.environ['CONTAINER_NAME']
|
||||
WORKSPACE_ID = os.environ['WORKSPACE_ID']
|
||||
SHARED_KEY = os.environ['SHARED_KEY']
|
||||
LOG_TYPE = 'Cloudflare'
|
||||
|
||||
|
||||
LOG_ANALYTICS_URI = os.environ.get('logAnalyticsUri')
|
||||
|
||||
if not LOG_ANALYTICS_URI or str(LOG_ANALYTICS_URI).isspace():
|
||||
LOG_ANALYTICS_URI = 'https://' + WORKSPACE_ID + '.ods.opinsights.azure.com'
|
||||
|
||||
pattern = r'https:\/\/([\w\-]+)\.ods\.opinsights\.azure.([a-zA-Z\.]+)$'
|
||||
match = re.match(pattern, str(LOG_ANALYTICS_URI))
|
||||
if not match:
|
||||
raise Exception("Invalid Log Analytics Uri.")
|
||||
|
||||
|
||||
async def main(mytimer: func.TimerRequest):
|
||||
checkpoint_manager = CheckpointManager(conn_string=os.environ['AzureWebJobsStorage'])
|
||||
script_is_active = await checkpoint_manager.script_is_active()
|
||||
last_date = await checkpoint_manager.get_last_date()
|
||||
exclude_files = await checkpoint_manager.get_exclude_files()
|
||||
include_files = await checkpoint_manager.get_include_files()
|
||||
now = datetime.datetime.utcnow().replace(tzinfo=datetime.timezone.utc)
|
||||
|
||||
if last_date and (now - last_date).seconds > MAX_SCRIPT_EXEC_TIME_MINUTES * 60:
|
||||
script_is_active = False
|
||||
|
||||
if script_is_active:
|
||||
print('Script is running now. Exit.')
|
||||
logging.info('Script is running now. Exit.')
|
||||
return
|
||||
|
||||
if not last_date or (now - last_date).seconds > MAX_PERIOD_MINUTES * 60:
|
||||
last_date = now - datetime.timedelta(minutes=SCRIPT_EXECUTION_INTERVAL_MINUTES)
|
||||
print('Getting files updated after {}'.format(last_date))
|
||||
logging.info('Getting files updated after {}'.format(last_date))
|
||||
|
||||
await checkpoint_manager.mark_script_as_active()
|
||||
|
||||
conn = AzureBlobStorageConnector(AZURE_STORAGE_CONNECTION_STRING, CONTAINER_NAME)
|
||||
await conn.get_blobs(updated_after=last_date, exclude_files=exclude_files, include_files=include_files)
|
||||
await conn.process_blobs()
|
||||
|
||||
message = 'Program finished. {} events have been sent. {} events have not been sent'.format(
|
||||
conn.sentinel.successfull_sent_events_number,
|
||||
conn.sentinel.failed_sent_events_number
|
||||
)
|
||||
print(message)
|
||||
logging.info(message)
|
||||
|
||||
if conn.sentinel.failed_sent_events_number:
|
||||
raise Exception('Program finished with errors. {} events have not been sent'.format(conn.sentinel.failed_sent_events_number))
|
||||
if conn.has_errors():
|
||||
raise Exception('Program finished with errors')
|
||||
|
||||
await conn.delete_old_blobs()
|
||||
|
||||
await checkpoint_manager.mark_script_as_inactive()
|
||||
|
||||
|
||||
class AzureBlobStorageConnector:
|
||||
def __init__(self, conn_string, container_name, queue_max_size=10):
|
||||
self.__conn_string = conn_string
|
||||
self.__container_name = container_name
|
||||
self.semaphore = asyncio.Semaphore(queue_max_size)
|
||||
self.blobs = []
|
||||
self.log_type = LOG_TYPE
|
||||
self.sentinel = AzureSentinelMultiConnectorAsync(LOG_ANALYTICS_URI, WORKSPACE_ID, SHARED_KEY, queue_size=10000)
|
||||
self._processed_blobs = []
|
||||
self._processed_blob_names = set()
|
||||
self._blobs_to_delete = []
|
||||
self.checkpoint_manager = CheckpointManager(conn_string=os.environ['AzureWebJobsStorage'])
|
||||
self.checkpoint_lock = asyncio.Lock()
|
||||
self.last_saved_date = None
|
||||
self.last_saved_exclude_files = None
|
||||
self.last_saved_include_files = set()
|
||||
|
||||
def _create_container_client(self):
|
||||
return ContainerClient.from_connection_string(self.__conn_string, self.__container_name, logging_enable=False)
|
||||
|
||||
async def get_blobs(self, updated_after: datetime.datetime, exclude_files: list, include_files: set):
|
||||
print('Start getting blobs')
|
||||
logging.info('Start getting blobs')
|
||||
container_client = self._create_container_client()
|
||||
async with container_client:
|
||||
async for blob in container_client.list_blobs():
|
||||
if 'ownership-challenge' in blob['name']:
|
||||
continue
|
||||
if blob['name'] in include_files:
|
||||
self.blobs.append(blob)
|
||||
continue
|
||||
if updated_after and blob['last_modified'] < updated_after:
|
||||
self._blobs_to_delete.append(blob)
|
||||
continue
|
||||
if blob['name'] in exclude_files:
|
||||
self._blobs_to_delete.append(blob)
|
||||
continue
|
||||
self.blobs.append(blob)
|
||||
print('Finish getting blobs. Count {}'.format(len(self.blobs)))
|
||||
logging.info('Finish getting blobs. Count {}'.format(len(self.blobs)))
|
||||
|
||||
async def process_blobs(self):
|
||||
if self.blobs:
|
||||
container_client = self._create_container_client()
|
||||
async with container_client:
|
||||
await asyncio.wait([self._process_blob(blob, container_client) for blob in self.blobs])
|
||||
await self.sentinel.flush()
|
||||
|
||||
async def delete_old_blobs(self):
|
||||
if self._blobs_to_delete:
|
||||
container_client = self._create_container_client()
|
||||
async with container_client:
|
||||
await asyncio.wait([self._delete_blob(blob, container_client) for blob in self._blobs_to_delete])
|
||||
|
||||
async def _delete_blob(self, blob, container_client):
|
||||
print("Deleting blob {}".format(blob['name']))
|
||||
logging.info("Deleting blob {}".format(blob['name']))
|
||||
await container_client.delete_blob(blob['name'])
|
||||
|
||||
async def _process_blob(self, blob, container_client):
|
||||
async with self.semaphore:
|
||||
print("Start processing {}".format(blob['name']))
|
||||
logging.info("Start processing {}".format(blob['name']))
|
||||
blob_cor = await container_client.download_blob(blob['name'])
|
||||
s = ''
|
||||
async for chunk in blob_cor.chunks():
|
||||
s += chunk.decode()
|
||||
lines = s.splitlines()
|
||||
for n, line in enumerate(lines):
|
||||
if n < len(lines) - 1:
|
||||
if line:
|
||||
event = json.loads(line)
|
||||
await self.sentinel.send(event, log_type=self.log_type)
|
||||
s = line
|
||||
if s:
|
||||
event = json.loads(s)
|
||||
await self.sentinel.send(event, log_type=self.log_type)
|
||||
print("Finish processing {}".format(blob['name']))
|
||||
logging.info("Finish processing {}".format(blob['name']))
|
||||
await self.save_checkpoint(blob)
|
||||
|
||||
def has_errors(self):
|
||||
return len(self._processed_blobs) != len(self.blobs)
|
||||
|
||||
async def save_checkpoint(self, blob):
|
||||
async with self.checkpoint_lock:
|
||||
self._processed_blobs.append(blob)
|
||||
self._processed_blob_names.add(blob['name'])
|
||||
include_files = self.get_not_processed_files_names()
|
||||
last_date = self.get_last_blob_date()
|
||||
exlude_files = self.get_last_date_blob_names()
|
||||
cors = []
|
||||
if not self.last_saved_date or self.last_saved_date <= last_date:
|
||||
cors.append(self.checkpoint_manager.post_last_date(last_date))
|
||||
if self.last_saved_exclude_files != exlude_files:
|
||||
cors.append(self.checkpoint_manager.post_exclude_files(exlude_files))
|
||||
if self.last_saved_include_files != include_files:
|
||||
cors.append(self.checkpoint_manager.post_include_files(include_files))
|
||||
|
||||
if cors:
|
||||
await asyncio.wait(cors)
|
||||
self.last_saved_date = last_date
|
||||
self.last_saved_exclude_files = exlude_files
|
||||
self.last_saved_include_files = include_files
|
||||
print('Checkpoint {} saved'.format(last_date))
|
||||
logging.info('Checkpoint {} saved'.format(last_date))
|
||||
|
||||
def get_last_blob_date(self):
|
||||
if self._processed_blobs:
|
||||
return max([x['last_modified'] for x in self._processed_blobs])
|
||||
else:
|
||||
return None
|
||||
|
||||
def get_last_date_blob_names(self):
|
||||
last_modified = self.get_last_blob_date()
|
||||
names = []
|
||||
for b in self._processed_blobs:
|
||||
if b['last_modified'] == last_modified:
|
||||
names.append(b['name'])
|
||||
return names
|
||||
|
||||
def get_not_processed_files_names(self):
|
||||
return set([x['name'] for x in self.blobs if x['name'] not in self._processed_blob_names])
|
||||
|
||||
|
||||
class CheckpointManager:
|
||||
def __init__(self, conn_string):
|
||||
self.last_date_state_manager = StateManagerAsync(connection_string=conn_string, file_path='last_date')
|
||||
self.exclude_files_state_manager = StateManagerAsync(connection_string=conn_string, file_path='exclude_files')
|
||||
self.exec_marker_state_manager = StateManagerAsync(connection_string=conn_string, file_path='exec_marker')
|
||||
self.include_files_state_manager = StateManagerAsync(connection_string=conn_string, file_path='include_files')
|
||||
|
||||
async def get_last_date(self):
|
||||
res = await self.last_date_state_manager.get()
|
||||
if res:
|
||||
return parse_date(res)
|
||||
|
||||
async def post_last_date(self, date: datetime.datetime):
|
||||
if date:
|
||||
await self.last_date_state_manager.post(date.isoformat())
|
||||
|
||||
async def get_exclude_files(self):
|
||||
res = await self.exclude_files_state_manager.get()
|
||||
if res:
|
||||
return [row.strip() for row in res.split('\n') if row.strip()]
|
||||
else:
|
||||
return []
|
||||
|
||||
async def post_exclude_files(self, exclude_files: list):
|
||||
if exclude_files:
|
||||
data = '\n'.join(exclude_files)
|
||||
await self.exclude_files_state_manager.post(data)
|
||||
|
||||
async def script_is_active(self):
|
||||
res = await self.exec_marker_state_manager.get()
|
||||
if res == '1':
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
async def mark_script_as_inactive(self):
|
||||
await self.exec_marker_state_manager.post('0')
|
||||
|
||||
async def mark_script_as_active(self):
|
||||
await self.exec_marker_state_manager.post('1')
|
||||
|
||||
async def get_include_files(self):
|
||||
res = await self.include_files_state_manager.get()
|
||||
if res:
|
||||
return set([row.strip() for row in res.split('\n') if row.strip()])
|
||||
else:
|
||||
return set()
|
||||
|
||||
async def post_include_files(self, include_files: list):
|
||||
if include_files:
|
||||
data = '\n'.join(include_files)
|
||||
else:
|
||||
data = ''
|
||||
await self.include_files_state_manager.post(data)
|
|
@ -0,0 +1,120 @@
|
|||
import datetime
|
||||
import logging
|
||||
import json
|
||||
import hashlib
|
||||
import hmac
|
||||
import base64
|
||||
import aiohttp
|
||||
import asyncio
|
||||
from collections import deque
|
||||
|
||||
|
||||
class AzureSentinelConnectorAsync:
|
||||
def __init__(self, log_analytics_uri, workspace_id, shared_key, log_type, queue_size=1000, queue_size_bytes=25 * (2**20)):
|
||||
self.log_analytics_uri = log_analytics_uri
|
||||
self.workspace_id = workspace_id
|
||||
self.shared_key = shared_key
|
||||
self.log_type = log_type
|
||||
self.queue_size = queue_size
|
||||
self.queue_size_bytes = queue_size_bytes
|
||||
self._queue = deque()
|
||||
self.successfull_sent_events_number = 0
|
||||
self.failed_sent_events_number = 0
|
||||
self.lock = asyncio.Lock()
|
||||
|
||||
async def send(self, event):
|
||||
events = None
|
||||
async with self.lock:
|
||||
self._queue.append(event)
|
||||
if len(self._queue) >= self.queue_size:
|
||||
events = list(self._queue)
|
||||
self._queue.clear()
|
||||
if events:
|
||||
await self._flush(events)
|
||||
|
||||
async def flush(self):
|
||||
await self._flush(list(self._queue))
|
||||
|
||||
async def _flush(self, data: list):
|
||||
if data:
|
||||
data = self._split_big_request(data)
|
||||
async with aiohttp.ClientSession() as session:
|
||||
await asyncio.wait([self._post_data(session, self.workspace_id, self.shared_key, d, self.log_type) for d in data])
|
||||
|
||||
def _build_signature(self, workspace_id, shared_key, date, content_length, method, content_type, resource):
|
||||
x_headers = 'x-ms-date:' + date
|
||||
string_to_hash = method + "\n" + str(content_length) + "\n" + content_type + "\n" + x_headers + "\n" + resource
|
||||
bytes_to_hash = bytes(string_to_hash, encoding="utf-8")
|
||||
decoded_key = base64.b64decode(shared_key)
|
||||
encoded_hash = base64.b64encode(hmac.new(decoded_key, bytes_to_hash, digestmod=hashlib.sha256).digest()).decode()
|
||||
authorization = "SharedKey {}:{}".format(workspace_id, encoded_hash)
|
||||
return authorization
|
||||
|
||||
async def _post_data(self, session: aiohttp.ClientSession, workspace_id, shared_key, body, log_type):
|
||||
logging.info('Start sending data to sentinel')
|
||||
print('Start sending data to sentinel')
|
||||
events_number = len(body)
|
||||
body = json.dumps(body)
|
||||
method = 'POST'
|
||||
content_type = 'application/json'
|
||||
resource = '/api/logs'
|
||||
rfc1123date = datetime.datetime.utcnow().strftime('%a, %d %b %Y %H:%M:%S GMT')
|
||||
content_length = len(body)
|
||||
signature = self._build_signature(workspace_id, shared_key, rfc1123date, content_length, method, content_type, resource)
|
||||
uri = self.log_analytics_uri + resource + '?api-version=2016-04-01'
|
||||
|
||||
headers = {
|
||||
'content-type': content_type,
|
||||
'Authorization': signature,
|
||||
'Log-Type': log_type,
|
||||
'x-ms-date': rfc1123date
|
||||
}
|
||||
|
||||
async with session.post(uri, data=body, headers=headers) as response:
|
||||
if (response.status >= 200 and response.status <= 299):
|
||||
logging.info('{} events have been successfully sent to Azure Sentinel'.format(events_number))
|
||||
print('{} events have been successfully sent to Azure Sentinel'.format(events_number))
|
||||
self.successfull_sent_events_number += events_number
|
||||
else:
|
||||
logging.error("Error during sending events to Azure Sentinel. Response code: {}".format(response.status))
|
||||
print("Error during sending events to Azure Sentinel. Response code: {}".format(response.status))
|
||||
self.failed_sent_events_number += events_number
|
||||
|
||||
def _check_size(self, queue):
|
||||
data_bytes_len = len(json.dumps(queue).encode())
|
||||
return data_bytes_len < self.queue_size_bytes
|
||||
|
||||
def _split_big_request(self, queue):
|
||||
if self._check_size(queue):
|
||||
return [queue]
|
||||
else:
|
||||
middle = int(len(queue) / 2)
|
||||
queues_list = [queue[:middle], queue[middle:]]
|
||||
return self._split_big_request(queues_list[0]) + self._split_big_request(queues_list[1])
|
||||
|
||||
|
||||
class AzureSentinelMultiConnectorAsync:
|
||||
def __init__(self, log_analytics_uri, workspace_id, shared_key, queue_size=1000, queue_size_bytes=25 * (2**20)):
|
||||
self.log_analytics_uri = log_analytics_uri
|
||||
self.workspace_id = workspace_id
|
||||
self.shared_key = shared_key
|
||||
self.queue_size = queue_size
|
||||
self.queue_size_bytes = queue_size_bytes
|
||||
self.connectors = dict()
|
||||
|
||||
async def send(self, event, log_type):
|
||||
if log_type not in self.connectors:
|
||||
self.connectors[log_type] = AzureSentinelConnectorAsync(self.log_analytics_uri, self.workspace_id, self.shared_key, log_type, self.queue_size, self.queue_size_bytes)
|
||||
conn = self.connectors[log_type]
|
||||
await conn.send(event)
|
||||
|
||||
async def flush(self):
|
||||
await asyncio.wait([conn.flush() for conn in self.connectors.values()])
|
||||
|
||||
@property
|
||||
def successfull_sent_events_number(self):
|
||||
return sum([conn.successfull_sent_events_number for conn in self.connectors.values()])
|
||||
|
||||
@property
|
||||
def failed_sent_events_number(self):
|
||||
return sum([conn.failed_sent_events_number for conn in self.connectors.values()])
|
|
@ -0,0 +1,37 @@
|
|||
from azure.storage.fileshare.aio import ShareClient
|
||||
from azure.storage.fileshare.aio import ShareFileClient
|
||||
from azure.core.exceptions import ResourceNotFoundError
|
||||
|
||||
|
||||
class StateManagerAsync:
|
||||
def __init__(self, connection_string, share_name='funcstatemarkershare', file_path='funcstatemarkerfile'):
|
||||
self.connection_string = connection_string
|
||||
self.share_name = share_name
|
||||
self.file_path = file_path
|
||||
|
||||
def _get_file_cli(self):
|
||||
return ShareFileClient.from_connection_string(conn_str=self.connection_string, share_name=self.share_name, file_path=self.file_path)
|
||||
|
||||
def _get_share_cli(self):
|
||||
return ShareClient.from_connection_string(conn_str=self.connection_string, share_name=self.share_name)
|
||||
|
||||
async def post(self, marker_text: str):
|
||||
file_cli = self._get_file_cli()
|
||||
async with file_cli:
|
||||
try:
|
||||
await file_cli.upload_file(marker_text)
|
||||
except ResourceNotFoundError:
|
||||
share_cli = self._get_share_cli()
|
||||
async with share_cli:
|
||||
await share_cli.create_share()
|
||||
await file_cli.upload_file(marker_text)
|
||||
|
||||
async def get(self):
|
||||
file_cli = self._get_file_cli()
|
||||
async with file_cli:
|
||||
try:
|
||||
cor = await file_cli.download_file()
|
||||
f = await cor.readall()
|
||||
return f.decode()
|
||||
except ResourceNotFoundError:
|
||||
return None
|
Двоичный файл не отображается.
|
@ -0,0 +1,130 @@
|
|||
{
|
||||
"id": "CloudflareDataConnector",
|
||||
"title": "Cloudflare",
|
||||
"publisher": "Cloudflare",
|
||||
"descriptionMarkdown": "The Cloudflare data connector provides the capability to ingest [Cloudflare logs](https://developers.cloudflare.com/logs/) into Azure Sentinel using the Cloudflare Logpush and Azure Blob Storage. Refer to [Cloudflare documentation](https://developers.cloudflare.com/logs/logpush) for more information.",
|
||||
"additionalRequirementBanner": "These queries and workbooks are dependent on a parser based on Kusto to work as expected. Follow the steps to use this Kusto functions alias **Cloudflare** in queries and workbooks. [Follow steps to get this Kusto functions>](https://aka.ms/sentinel-CloudflareDataConnector-parser) ",
|
||||
"graphQueries": [
|
||||
{
|
||||
"metricName": "Cloudflare logs",
|
||||
"legend": "Cloudflare_CL",
|
||||
"baseQuery": "Cloudflare_CL"
|
||||
}
|
||||
],
|
||||
"sampleQueries": [
|
||||
{
|
||||
"description" : "All Cloudflare logs",
|
||||
"query": "Cloudflare_CL\n| sort by TimeGenerated desc"
|
||||
}
|
||||
],
|
||||
"dataTypes": [
|
||||
{
|
||||
"name": "Cloudflare_CL",
|
||||
"lastDataReceivedQuery": "Cloudflare_CL\n | summarize Time = max(TimeGenerated)\n | where isnotempty(Time)"
|
||||
}
|
||||
],
|
||||
"connectivityCriterias": [
|
||||
{
|
||||
"type": "IsConnectedQuery",
|
||||
"value": [
|
||||
"Cloudflare_CL\n | summarize LastLogReceived = max(TimeGenerated)\n | project IsConnected = LastLogReceived > ago(1d)"
|
||||
]
|
||||
}
|
||||
],
|
||||
"availability": {
|
||||
"status": 2,
|
||||
"isPreview": true
|
||||
},
|
||||
"permissions": {
|
||||
"resourceProvider": [
|
||||
{
|
||||
"provider": "Microsoft.OperationalInsights/workspaces",
|
||||
"permissionsDisplayText": "read and write permissions on the workspace are required.",
|
||||
"providerDisplayName": "Workspace",
|
||||
"scope": "Workspace",
|
||||
"requiredPermissions": {
|
||||
"write": true,
|
||||
"read": true,
|
||||
"delete": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"provider": "Microsoft.OperationalInsights/workspaces/sharedKeys",
|
||||
"permissionsDisplayText": "read permissions to shared keys for the workspace are required. [See the documentation to learn more about workspace keys](https://docs.microsoft.com/azure/azure-monitor/platform/agent-windows#obtain-workspace-id-and-key).",
|
||||
"providerDisplayName": "Keys",
|
||||
"scope": "Workspace",
|
||||
"requiredPermissions": {
|
||||
"action": true
|
||||
}
|
||||
}
|
||||
],
|
||||
"customs": [
|
||||
{
|
||||
"name": "Microsoft.Web/sites permissions",
|
||||
"description": "Read and write permissions to Azure Functions to create a Function App is required. [See the documentation to learn more about Azure Functions](https://docs.microsoft.com/azure/azure-functions/)."
|
||||
},
|
||||
{
|
||||
"name": "Azure Blob Storage connection string and container name",
|
||||
"description": "Azure Blob Storage connection string and container name where the logs are pushed to by Cloudflare Logpush. [See the documentation to learn more about creating Azure Blob Storage container.](https://developers.cloudflare.com/logs/logpush/azure/)"
|
||||
}
|
||||
]
|
||||
},
|
||||
"instructionSteps": [
|
||||
{
|
||||
"title": "",
|
||||
"description": ">**NOTE:** This connector uses Azure Functions to connect to the Azure Blob Storage API to pull logs into Azure Sentinel. This might result in additional costs for data ingestion and for storing data in Azure Blob Storage costs. Check the [Azure Functions pricing page](https://azure.microsoft.com/pricing/details/functions/) and [Azure Blob Storage pricing page](https://azure.microsoft.com/pricing/details/storage/blobs/) for details."
|
||||
},
|
||||
{
|
||||
"title": "",
|
||||
"description": ">**(Optional Step)** Securely store workspace and API authorization key(s) or token(s) in Azure Key Vault. Azure Key Vault provides a secure mechanism to store and retrieve key values. [Follow these instructions](https://docs.microsoft.com/azure/app-service/app-service-key-vault-references) to use Azure Key Vault with an Azure Function App."
|
||||
},
|
||||
{
|
||||
"title": "",
|
||||
"description": ">**NOTE:** This connector uses a parser based on a Kusto Function to normalize fields. [Follow these steps](https://aka.ms/sentinel-CloudflareDataConnector-parser) to create the Kusto function alias **Cloudflare**."
|
||||
},
|
||||
{
|
||||
"title": "",
|
||||
"description": "**STEP 1 - Configuration of the Cloudflare Logpush**\n\nSee documentation to [setup Cloudflare Logpush to Microsoft Azure](https://developers.cloudflare.com/logs/logpush/logpush-dashboard)"
|
||||
},
|
||||
{
|
||||
"title": "",
|
||||
"description": "**STEP 2 - Choose ONE from the following two deployment options to deploy the connector and the associated Azure Function**\n\n>**IMPORTANT:** Before deploying the Cloudflare data connector, have the Workspace ID and Workspace Primary Key (can be copied from the following), as well as Azure Blob Storage connection string and container name, readily available.",
|
||||
"instructions":[
|
||||
{
|
||||
"parameters": {
|
||||
"fillWith": [
|
||||
"WorkspaceId"
|
||||
],
|
||||
"label": "Workspace ID"
|
||||
},
|
||||
"type": "CopyableLabel"
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"fillWith": [
|
||||
"PrimaryKey"
|
||||
],
|
||||
"label": "Primary Key"
|
||||
},
|
||||
"type": "CopyableLabel"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"title": "Option 1 - Azure Resource Manager (ARM) Template",
|
||||
"description": "Use this method for automated deployment of the Cloudflare data connector using an ARM Tempate.\n\n1. Click the **Deploy to Azure** button below. \n\n\t[![Deploy To Azure](https://aka.ms/deploytoazurebutton)](https://aka.ms/sentinel-CloudflareDataConnector-azuredeploy)\n2. Select the preferred **Subscription**, **Resource Group** and **Location**. \n3. Enter the **Azure Blob Storage Container Name**, **Azure Blob Storage Connection String**, **Azure Sentinel Workspace Id**, **Azure Sentinel Shared Key**\n4. Mark the checkbox labeled **I agree to the terms and conditions stated above**.\n5. Click **Purchase** to deploy."
|
||||
},
|
||||
{
|
||||
"title": "Option 2 - Manual Deployment of Azure Functions",
|
||||
"description": "Use the following step-by-step instructions to deploy the Cloudflare data connector manually with Azure Functions (Deployment via Visual Studio Code)."
|
||||
},
|
||||
{
|
||||
"title": "",
|
||||
"description": "**1. Deploy a Function App**\n\n> **NOTE:** You will need to [prepare VS code](https://docs.microsoft.com/azure/azure-functions/create-first-function-vs-code-python) for Azure function development.\n\n1. Download the [Azure Function App](https://aka.ms/sentinel-CloudflareDataConnector-functionapp) file. Extract archive to your local development computer.\n2. Start VS Code. Choose File in the main menu and select Open Folder.\n3. Select the top level folder from extracted files.\n4. Choose the Azure icon in the Activity bar, then in the **Azure: Functions** area, choose the **Deploy to function app** button.\nIf you aren't already signed in, choose the Azure icon in the Activity bar, then in the **Azure: Functions** area, choose **Sign in to Azure**\nIf you're already signed in, go to the next step.\n5. Provide the following information at the prompts:\n\n\ta. **Select folder:** Choose a folder from your workspace or browse to one that contains your function app.\n\n\tb. **Select Subscription:** Choose the subscription to use.\n\n\tc. Select **Create new Function App in Azure** (Don't choose the Advanced option)\n\n\td. **Enter a globally unique name for the function app:** Type a name that is valid in a URL path. The name you type is validated to make sure that it's unique in Azure Functions. (e.g. CloudflareXX).\n\n\te. **Select a runtime:** Choose Python 3.8.\n\n\tf. Select a location for new resources. For better performance and lower costs choose the same [region](https://azure.microsoft.com/regions/) where Azure Sentinel is located.\n\n6. Deployment will begin. A notification is displayed after your function app is created and the deployment package is applied.\n7. Go to Azure Portal for the Function App configuration."
|
||||
},
|
||||
{
|
||||
"title": "",
|
||||
"description": "**2. Configure the Function App**\n\n1. In the Function App, select the Function App Name and select **Configuration**.\n2. In the **Application settings** tab, select **+ New application setting**.\n3. Add each of the following application settings individually, with their respective string values (case-sensitive): \n\t\tCONTAINER_NAME\n\t\tAZURE_STORAGE_CONNECTION_STRING\n\t\tWORKSPACE_ID\n\t\tSHARED_KEY\n\t\tlogAnalyticsUri (Optional)\n - Use logAnalyticsUri to override the log analytics API endpoint for dedicated cloud. For example, for public cloud, leave the value empty; for Azure GovUS cloud environment, specify the value in the following format: https://WORKSPACE_ID.ods.opinsights.azure.us. \n4. Once all application settings have been entered, click **Save**."
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,200 @@
|
|||
{
|
||||
"$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
|
||||
"contentVersion": "1.0.0.0",
|
||||
"parameters": {
|
||||
"FunctionName": {
|
||||
"defaultValue": "Cloudflare",
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"maxLength": 11
|
||||
},
|
||||
"AzureBlobStorageContainerName": {
|
||||
"type": "string",
|
||||
"defaultValue": ""
|
||||
},
|
||||
"AzureBlobStorageConnectionString": {
|
||||
"type": "securestring",
|
||||
"defaultValue": ""
|
||||
},
|
||||
"AzureSentinelWorkspaceId": {
|
||||
"type": "string",
|
||||
"defaultValue": ""
|
||||
},
|
||||
"AzureSentinelSharedKey": {
|
||||
"type": "securestring",
|
||||
"defaultValue": ""
|
||||
}
|
||||
},
|
||||
"variables": {
|
||||
"FunctionName": "[concat(toLower(parameters('FunctionName')), uniqueString(resourceGroup().id))]",
|
||||
"StorageSuffix": "[environment().suffixes.storage]",
|
||||
"LogAnaltyicsUri": "[replace(environment().portal, 'https://portal', concat('https://', toLower(parameters('AzureSentinelWorkspaceId')), '.ods.opinsights'))]"
|
||||
},
|
||||
"resources": [
|
||||
{
|
||||
"type": "Microsoft.Insights/components",
|
||||
"apiVersion": "2015-05-01",
|
||||
"name": "[variables('FunctionName')]",
|
||||
"location": "[resourceGroup().location]",
|
||||
"kind": "web",
|
||||
"properties": {
|
||||
"Application_Type": "web",
|
||||
"ApplicationId": "[variables('FunctionName')]"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "Microsoft.Storage/storageAccounts",
|
||||
"apiVersion": "2019-06-01",
|
||||
"name": "[tolower(variables('FunctionName'))]",
|
||||
"location": "[resourceGroup().location]",
|
||||
"sku": {
|
||||
"name": "Standard_LRS",
|
||||
"tier": "Standard"
|
||||
},
|
||||
"kind": "StorageV2",
|
||||
"properties": {
|
||||
"networkAcls": {
|
||||
"bypass": "AzureServices",
|
||||
"virtualNetworkRules": [],
|
||||
"ipRules": [],
|
||||
"defaultAction": "Allow"
|
||||
},
|
||||
"supportsHttpsTrafficOnly": true,
|
||||
"encryption": {
|
||||
"services": {
|
||||
"file": {
|
||||
"keyType": "Account",
|
||||
"enabled": true
|
||||
},
|
||||
"blob": {
|
||||
"keyType": "Account",
|
||||
"enabled": true
|
||||
}
|
||||
},
|
||||
"keySource": "Microsoft.Storage"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "Microsoft.Storage/storageAccounts/blobServices",
|
||||
"apiVersion": "2019-06-01",
|
||||
"name": "[concat(variables('FunctionName'), '/default')]",
|
||||
"dependsOn": [
|
||||
"[resourceId('Microsoft.Storage/storageAccounts', tolower(variables('FunctionName')))]"
|
||||
],
|
||||
"sku": {
|
||||
"name": "Standard_LRS",
|
||||
"tier": "Standard"
|
||||
},
|
||||
"properties": {
|
||||
"cors": {
|
||||
"corsRules": []
|
||||
},
|
||||
"deleteRetentionPolicy": {
|
||||
"enabled": false
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "Microsoft.Storage/storageAccounts/fileServices",
|
||||
"apiVersion": "2019-06-01",
|
||||
"name": "[concat(variables('FunctionName'), '/default')]",
|
||||
"dependsOn": [
|
||||
"[resourceId('Microsoft.Storage/storageAccounts', tolower(variables('FunctionName')))]"
|
||||
],
|
||||
"sku": {
|
||||
"name": "Standard_LRS",
|
||||
"tier": "Standard"
|
||||
},
|
||||
"properties": {
|
||||
"cors": {
|
||||
"corsRules": []
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "Microsoft.Web/sites",
|
||||
"apiVersion": "2018-11-01",
|
||||
"name": "[variables('FunctionName')]",
|
||||
"location": "[resourceGroup().location]",
|
||||
"dependsOn": [
|
||||
"[resourceId('Microsoft.Storage/storageAccounts', tolower(variables('FunctionName')))]",
|
||||
"[resourceId('Microsoft.Insights/components', variables('FunctionName'))]"
|
||||
],
|
||||
"kind": "functionapp,linux",
|
||||
"identity": {
|
||||
"type": "SystemAssigned"
|
||||
},
|
||||
"properties": {
|
||||
"name": "[variables('FunctionName')]",
|
||||
"httpsOnly": true,
|
||||
"clientAffinityEnabled": true,
|
||||
"alwaysOn": true,
|
||||
"reserved": true,
|
||||
"siteConfig": {
|
||||
"linuxFxVersion": "python|3.8"
|
||||
}
|
||||
},
|
||||
|
||||
"resources": [
|
||||
{
|
||||
"apiVersion": "2018-11-01",
|
||||
"type": "config",
|
||||
"name": "appsettings",
|
||||
"dependsOn": [
|
||||
"[concat('Microsoft.Web/sites/', variables('FunctionName'))]"
|
||||
],
|
||||
"properties": {
|
||||
"FUNCTIONS_EXTENSION_VERSION": "~3",
|
||||
"FUNCTIONS_WORKER_RUNTIME": "python",
|
||||
"APPINSIGHTS_INSTRUMENTATIONKEY": "[reference(resourceId('Microsoft.insights/components', variables('FunctionName')), '2015-05-01').InstrumentationKey]",
|
||||
"APPLICATIONINSIGHTS_CONNECTION_STRING": "[reference(resourceId('microsoft.insights/components', variables('FunctionName')), '2015-05-01').ConnectionString]",
|
||||
"AzureWebJobsStorage": "[concat('DefaultEndpointsProtocol=https;AccountName=', toLower(variables('FunctionName')),';AccountKey=',listKeys(resourceId('Microsoft.Storage/storageAccounts', toLower(variables('FunctionName'))), '2019-06-01').keys[0].value, ';EndpointSuffix=',toLower(variables('StorageSuffix')))]",
|
||||
"CONTAINER_NAME": "[parameters('AzureBlobStorageContainerName')]",
|
||||
"AZURE_STORAGE_CONNECTION_STRING": "[parameters('AzureBlobStorageConnectionString')]",
|
||||
"WORKSPACE_ID": "[parameters('AzureSentinelWorkspaceId')]",
|
||||
"SHARED_KEY": "[parameters('AzureSentinelSharedKey')]",
|
||||
"logAnalyticsUri": "[variables('LogAnaltyicsUri')]",
|
||||
"WEBSITE_RUN_FROM_PACKAGE": "https://aka.ms/sentinel-CloudflareDataConnector-functionapp"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "Microsoft.Storage/storageAccounts/blobServices/containers",
|
||||
"apiVersion": "2019-06-01",
|
||||
"name": "[concat(variables('FunctionName'), '/default/azure-webjobs-hosts')]",
|
||||
"dependsOn": [
|
||||
"[resourceId('Microsoft.Storage/storageAccounts/blobServices', variables('FunctionName'), 'default')]",
|
||||
"[resourceId('Microsoft.Storage/storageAccounts', variables('FunctionName'))]"
|
||||
],
|
||||
"properties": {
|
||||
"publicAccess": "None"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "Microsoft.Storage/storageAccounts/blobServices/containers",
|
||||
"apiVersion": "2019-06-01",
|
||||
"name": "[concat(variables('FunctionName'), '/default/azure-webjobs-secrets')]",
|
||||
"dependsOn": [
|
||||
"[resourceId('Microsoft.Storage/storageAccounts/blobServices', variables('FunctionName'), 'default')]",
|
||||
"[resourceId('Microsoft.Storage/storageAccounts', variables('FunctionName'))]"
|
||||
],
|
||||
"properties": {
|
||||
"publicAccess": "None"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "Microsoft.Storage/storageAccounts/fileServices/shares",
|
||||
"apiVersion": "2019-06-01",
|
||||
"name": "[concat(variables('FunctionName'), '/default/', tolower(variables('FunctionName')))]",
|
||||
"dependsOn": [
|
||||
"[resourceId('Microsoft.Storage/storageAccounts/fileServices', variables('FunctionName'), 'default')]",
|
||||
"[resourceId('Microsoft.Storage/storageAccounts', variables('FunctionName'))]"
|
||||
],
|
||||
"properties": {
|
||||
"shareQuota": 5120
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
{
|
||||
"version": "2.0",
|
||||
"logging": {
|
||||
"applicationInsights": {
|
||||
"samplingSettings": {
|
||||
"isEnabled": true,
|
||||
"excludedTypes": "Request"
|
||||
}
|
||||
}
|
||||
},
|
||||
"extensionBundle": {
|
||||
"id": "Microsoft.Azure.Functions.ExtensionBundle",
|
||||
"version": "[1.*, 2.0.0)"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"$schema": "http://json.schemastore.org/proxies",
|
||||
"proxies": {}
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
azure-storage-blob
|
||||
aiohttp
|
||||
azure-functions
|
||||
azure-storage-file-share
|
||||
python-dateutil
|
|
@ -0,0 +1,5 @@
|
|||
<svg width="75" height="75" viewBox="0 0 75 75" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M57.9129 36.0524L56.4192 35.4482C49.3989 51.4259 21.471 41.7122 19.7906 46.4654C19.5104 49.676 35.0419 47.0759 46.1454 47.6201C49.5313 47.7859 51.2293 50.3713 49.7915 54.5854L52.6234 54.5942C55.8901 44.2933 66.3155 49.5503 66.7512 46.1507C66.0354 43.9155 54.7696 46.1507 57.9129 36.0524Z" fill="white"/>
|
||||
<path d="M50.5934 52.8234C51.0414 51.3125 50.8921 49.8016 50.1453 48.895C49.3983 47.9883 48.3527 47.3841 47.0083 47.233L21.0166 46.9306C20.8672 46.9306 20.7179 46.7796 20.5685 46.7796C20.4192 46.6285 20.4192 46.4775 20.5685 46.3264C20.7179 46.0243 20.8672 45.8729 21.1659 45.8729L47.307 45.5708C50.444 45.4198 53.7304 42.8512 54.9252 39.8294L56.4192 35.901C56.4192 35.7496 56.5685 35.5986 56.4192 35.4475C54.7758 27.7417 47.9046 22 39.8381 22C32.3692 22 25.946 26.8351 23.7053 33.6345C22.2116 32.5768 20.4192 31.9723 18.3278 32.1236C14.7427 32.4257 11.9046 35.4475 11.4563 39.0738C11.307 39.9804 11.4563 40.8871 11.6059 41.7935C5.78012 41.9445 1 46.7796 1 52.8234C1 53.4277 1 53.8811 1.14934 54.4854C1.14934 54.7878 1.44803 54.9388 1.59766 54.9388H49.5477C49.8464 54.9388 50.1453 54.7878 50.1453 54.4854L50.5934 52.8234Z" fill="#F4811F"/>
|
||||
<path d="M58.8091 35.9013H58.0621C57.9128 35.9013 57.7635 36.0524 57.6141 36.2034L56.5684 39.8298C56.1204 41.3406 56.2697 42.8518 57.0167 43.7582C57.7634 44.6648 58.8091 45.2691 60.1535 45.4204L65.6806 45.7225C65.83 45.7225 65.9793 45.8736 66.1287 45.8736C66.278 46.0246 66.278 46.1757 66.1287 46.3268C65.9793 46.6292 65.83 46.7802 65.531 46.7802L59.8548 47.0824C56.7178 47.2334 53.4316 49.802 52.2366 52.8238L51.9376 54.1839C51.7883 54.335 51.9376 54.6371 52.2366 54.6371H71.9545C72.2532 54.6371 72.4025 54.486 72.4025 54.1839C72.7012 52.9751 72.9999 51.6153 72.9999 50.2552C72.9999 42.3983 66.5767 35.9013 58.8091 35.9013Z" fill="#FAAD3F"/>
|
||||
</svg>
|
После Ширина: | Высота: | Размер: 1.9 KiB |
|
@ -0,0 +1,216 @@
|
|||
// Usage Instruction :
|
||||
// Paste below query in log analytics, click on Save button and select as Function from drop down by specifying function name and alias as Cloudflare.
|
||||
// Function usually takes 10-15 minutes to activate. You can then use function alias from any other queries (e.g. Cloudflare | take 10).
|
||||
// Reference : Using functions in Azure monitor log queries : https://docs.microsoft.com/azure/azure-monitor/log-query/functions
|
||||
Cloudflare_CL
|
||||
| extend
|
||||
BotScore_d=column_ifexists('BotScore_d', ''),
|
||||
BotScoreSrc_s=column_ifexists('BotScoreSrc_s', ''),
|
||||
CacheCacheStatus_s=column_ifexists('CacheCacheStatus_s', ''),
|
||||
CacheResponseBytes_d=column_ifexists('CacheResponseBytes_d', ''),
|
||||
CacheResponseStatus_d=column_ifexists('CacheResponseStatus_d', ''),
|
||||
CacheTieredFill_b=column_ifexists('CacheTieredFill_b', ''),
|
||||
ClientASN_d=column_ifexists('ClientASN_d', ''),
|
||||
ClientCountry_s=column_ifexists('ClientCountry_s', ''),
|
||||
ClientDeviceType_s=column_ifexists('ClientDeviceType_s', ''),
|
||||
ClientIP_s=column_ifexists('ClientIP_s', ''),
|
||||
ClientIPClass_s=column_ifexists('ClientIPClass_s', ''),
|
||||
ClientRequestHost_s=column_ifexists('ClientRequestHost_s', ''),
|
||||
ClientRequestMethod_s=column_ifexists('ClientRequestMethod_s', ''),
|
||||
ClientRequestPath_s=column_ifexists('ClientRequestPath_s', ''),
|
||||
ClientRequestProtocol_s=column_ifexists('ClientRequestProtocol_s', ''),
|
||||
ClientRequestReferer_s=column_ifexists('ClientRequestReferer_s', ''),
|
||||
ClientRequestURI_s=column_ifexists('ClientRequestURI_s', ''),
|
||||
ClientRequestUserAgent_s=column_ifexists('ClientRequestUserAgent_s', ''),
|
||||
ClientSSLCipher_s=column_ifexists('ClientSSLCipher_s', ''),
|
||||
ClientSSLProtocol_s=column_ifexists('ClientSSLProtocol_s', ''),
|
||||
ClientXRequestedWith_s=column_ifexists('ClientXRequestedWith_s', ''),
|
||||
EdgeColoCode_s=column_ifexists('EdgeColoCode_s', ''),
|
||||
EdgeColoID_d=column_ifexists('EdgeColoID_d', ''),
|
||||
EdgeEndTimestamp_t=column_ifexists('EdgeEndTimestamp_t', ''),
|
||||
EdgePathingOp_s=column_ifexists('EdgePathingOp_s', ''),
|
||||
EdgePathingSrc_s=column_ifexists('EdgePathingSrc_s', ''),
|
||||
EdgePathingStatus_s=column_ifexists('EdgePathingStatus_s', ''),
|
||||
EdgeRateLimitAction_s=column_ifexists('EdgeRateLimitAction_s', ''),
|
||||
EdgeRateLimitID_d=column_ifexists('EdgeRateLimitID_d', ''),
|
||||
EdgeRequestHost_s=column_ifexists('EdgeRequestHost_s', ''),
|
||||
EdgeResponseBytes_d=column_ifexists('EdgeResponseBytes_d', ''),
|
||||
EdgeResponseCompressionRatio_d=column_ifexists('EdgeResponseCompressionRatio_d', ''),
|
||||
EdgeResponseContentType_s=column_ifexists('EdgeResponseContentType_s', ''),
|
||||
EdgeResponseStatus_d=column_ifexists('EdgeResponseStatus_d', ''),
|
||||
EdgeServerIP_s=column_ifexists('EdgeServerIP_s', ''),
|
||||
EdgeStartTimestamp_t=column_ifexists('EdgeStartTimestamp_t', ''),
|
||||
FirewallMatchesActions_s=column_ifexists('FirewallMatchesActions_s', ''),
|
||||
FirewallMatchesRuleIDs_s=column_ifexists('FirewallMatchesRuleIDs_s', ''),
|
||||
FirewallMatchesSources_s=column_ifexists('FirewallMatchesSources_s', ''),
|
||||
OriginIP_s=column_ifexists('OriginIP_s', ''),
|
||||
OriginResponseBytes_d=column_ifexists('OriginResponseBytes_d', ''),
|
||||
OriginResponseHTTPExpires_s=column_ifexists('OriginResponseHTTPExpires_s', ''),
|
||||
OriginResponseHTTPLastModified_s=column_ifexists('OriginResponseHTTPLastModified_s', ''),
|
||||
OriginResponseStatus_d=column_ifexists('OriginResponseStatus_d', ''),
|
||||
OriginResponseTime_d=column_ifexists('OriginResponseTime_d', ''),
|
||||
OriginSSLProtocol_s=column_ifexists('OriginSSLProtocol_s', ''),
|
||||
ParentRayID_s=column_ifexists('ParentRayID_s', ''),
|
||||
RayID_s=column_ifexists('RayID_s', ''),
|
||||
SecurityLevel_s=column_ifexists('SecurityLevel_s', ''),
|
||||
WAFAction_s=column_ifexists('WAFAction_s', ''),
|
||||
WAFFlags_s=column_ifexists('WAFFlags_s', ''),
|
||||
WAFMatchedVar_s=column_ifexists('WAFMatchedVar_s', ''),
|
||||
WAFProfile_s=column_ifexists('WAFProfile_s', ''),
|
||||
WAFRuleID_s=column_ifexists('WAFRuleID_s', ''),
|
||||
WAFRuleMessage_s=column_ifexists('WAFRuleMessage_s', ''),
|
||||
WorkerCPUTime_d=column_ifexists('WorkerCPUTime_d', ''),
|
||||
WorkerStatus_s=column_ifexists('WorkerStatus_s', ''),
|
||||
WorkerSubrequest_b=column_ifexists('WorkerSubrequest_b', ''),
|
||||
WorkerSubrequestCount_d=column_ifexists('WorkerSubrequestCount_d', ''),
|
||||
ZoneID_d=column_ifexists('ZoneID_d', ''),
|
||||
Application_s=column_ifexists('Application_s', ''),
|
||||
ClientMatchedIpFirewall_s=column_ifexists('ClientMatchedIpFirewall_s', ''),
|
||||
ClientProto_s=column_ifexists('ClientProto_s', ''),
|
||||
ClientTcpRtt_d=column_ifexists('ClientTcpRtt_d', ''),
|
||||
ClientTlsCipher_s=column_ifexists('ClientTlsCipher_s', ''),
|
||||
ClientTlsClientHelloServerName_s=column_ifexists('ClientTlsClientHelloServerName_s', ''),
|
||||
ClientTlsProtocol_s=column_ifexists('ClientTlsProtocol_s', ''),
|
||||
ClientTlsStatus_s=column_ifexists('ClientTlsStatus_s', ''),
|
||||
ColoCode_s=column_ifexists('ColoCode_s', ''),
|
||||
ConnectTimestamp_t=column_ifexists('ConnectTimestamp_t', ''),
|
||||
DisconnectTimestamp_t=column_ifexists('DisconnectTimestamp_t', ''),
|
||||
Event_s=column_ifexists('Event_s', ''),
|
||||
IpFirewall_b=column_ifexists('IpFirewall_b', ''),
|
||||
OriginBytes_d=column_ifexists('OriginBytes_d', ''),
|
||||
OriginPort_d=column_ifexists('OriginPort_d', ''),
|
||||
OriginProto_s=column_ifexists('OriginProto_s', ''),
|
||||
OriginTcpRtt_d=column_ifexists('OriginTcpRtt_d', ''),
|
||||
OriginTlsCipher_s=column_ifexists('OriginTlsCipher_s', ''),
|
||||
OriginTlsFingerprint_s=column_ifexists('OriginTlsFingerprint_s', ''),
|
||||
OriginTlsMode_s=column_ifexists('OriginTlsMode_s', ''),
|
||||
OriginTlsProtocol_s=column_ifexists('OriginTlsProtocol_s', ''),
|
||||
OriginTlsStatus_s=column_ifexists('OriginTlsStatus_s', ''),
|
||||
ProxyProtocol_s=column_ifexists('ProxyProtocol_s', ''),
|
||||
Status_d=column_ifexists('Status_d', ''),
|
||||
Timestamp_t=column_ifexists('Timestamp_t', ''),
|
||||
Action_s=column_ifexists('Action_s', ''),
|
||||
ClientASNDescription_s=column_ifexists('ClientASNDescription_s', ''),
|
||||
ClientRefererHost_s=column_ifexists('ClientRefererHost_s', ''),
|
||||
ClientRefererPath_s=column_ifexists('ClientRefererPath_s', ''),
|
||||
ClientRefererQuery_s=column_ifexists('ClientRefererQuery_s', ''),
|
||||
ClientRefererScheme_s=column_ifexists('ClientRefererScheme_s', ''),
|
||||
ClientRequestQuery_s=column_ifexists('ClientRequestQuery_s', ''),
|
||||
ClientRequestScheme_s=column_ifexists('ClientRequestScheme_s', ''),
|
||||
Datetime_t=column_ifexists('Datetime_t', ''),
|
||||
Kind_s=column_ifexists('Kind_s', ''),
|
||||
MatchIndex_d=column_ifexists('MatchIndex_d', ''),
|
||||
OriginatorRayID_s=column_ifexists('OriginatorRayID_s', ''),
|
||||
RuleID_s=column_ifexists('RuleID_s', ''),
|
||||
Source_s=column_ifexists('Source_s', '')
|
||||
| extend
|
||||
SrcDvcType=iff(isempty(ClientDeviceType_s), iff(isempty(Source_s), '', Source_s), ClientDeviceType_s),
|
||||
TlsCipher=iff(isempty(ClientSSLCipher_s), iff(isempty(ClientTlsCipher_s), '', ClientTlsCipher_s), ClientSSLCipher_s),
|
||||
TlsVersion=iff(isempty(ClientSSLProtocol_s), iff(isempty(ClientTlsProtocol_s), '', ClientTlsProtocol_s), ClientSSLProtocol_s),
|
||||
DvcAction=iff(isempty(FirewallMatchesActions_s), iff(isempty(Event_s), iff(isempty(Action_s), '', Action_s), Event_s), FirewallMatchesActions_s),
|
||||
NetworkRuleName=iff(isempty(FirewallMatchesRuleIDs_s), iff(isempty(RuleID_s), '', RuleID_s), FirewallMatchesRuleIDs_s),
|
||||
ClientRequestBytes_d=column_ifexists('ClientRequestBytes_d', column_ifexists('ClientBytes_d', '')),
|
||||
ClientSrcPort_d=column_ifexists('ClientSrcPort_d', column_ifexists('ClientPort_d', '')),
|
||||
EdgeResponseBytes_d=column_ifexists('EdgeResponseBytes_d', column_ifexists('OriginBytes_d', ''))
|
||||
| project-rename
|
||||
SrcBytes=ClientRequestBytes_d,
|
||||
SrcPortNumber=ClientSrcPort_d,
|
||||
DstBytes=EdgeResponseBytes_d,
|
||||
BotScore=BotScore_d,
|
||||
BotScoreSrc=BotScoreSrc_s,
|
||||
CacheCacheStatus=CacheCacheStatus_s,
|
||||
CacheResponseBytes=CacheResponseBytes_d,
|
||||
CacheResponseStatus=CacheResponseStatus_d,
|
||||
CacheTieredFill=CacheTieredFill_b,
|
||||
ClientASN=ClientASN_d,
|
||||
SrcGeoCountry=ClientCountry_s,
|
||||
SrcIpAddr=ClientIP_s,
|
||||
ClientIPClass=ClientIPClass_s,
|
||||
HttpRequestHeaderHost=ClientRequestHost_s,
|
||||
HttpRequestMethod=ClientRequestMethod_s,
|
||||
ClientRequestPath=ClientRequestPath_s,
|
||||
ClientRequestProtocol=ClientRequestProtocol_s,
|
||||
HttpReferrerOriginal=ClientRequestReferer_s,
|
||||
ClientRequestURI=ClientRequestURI_s,
|
||||
HttpUserAgentOriginal=ClientRequestUserAgent_s,
|
||||
ClientXRequestedWith=ClientXRequestedWith_s,
|
||||
EdgeColoCode=EdgeColoCode_s,
|
||||
EdgeColoID=EdgeColoID_d,
|
||||
EdgeEndTimestamp=EdgeEndTimestamp_t,
|
||||
EdgePathingOp=EdgePathingOp_s,
|
||||
EdgePathingSrc=EdgePathingSrc_s,
|
||||
EdgePathingStatus=EdgePathingStatus_s,
|
||||
EdgeRateLimitAction=EdgeRateLimitAction_s,
|
||||
EdgeRateLimitID=EdgeRateLimitID_d,
|
||||
EdgeRequestHost=EdgeRequestHost_s,
|
||||
EdgeResponseCompressionRatio=EdgeResponseCompressionRatio_d,
|
||||
HttpContentType=EdgeResponseContentType_s,
|
||||
EdgeResponseStatus=EdgeResponseStatus_d,
|
||||
EdgeServerIP=EdgeServerIP_s,
|
||||
EdgeStartTimestamp=EdgeStartTimestamp_t,
|
||||
FirewallMatchesSources=FirewallMatchesSources_s,
|
||||
DstIpAddr=OriginIP_s,
|
||||
OriginResponseBytes=OriginResponseBytes_d,
|
||||
OriginResponseHTTPExpires=OriginResponseHTTPExpires_s,
|
||||
OriginResponseHTTPLastModified=OriginResponseHTTPLastModified_s,
|
||||
HttpStatusCode=OriginResponseStatus_d,
|
||||
OriginResponseTime=OriginResponseTime_d,
|
||||
OriginSSLProtocol=OriginSSLProtocol_s,
|
||||
ParentRayID=ParentRayID_s,
|
||||
RayID=RayID_s,
|
||||
SecurityLevel=SecurityLevel_s,
|
||||
WAFAction=WAFAction_s,
|
||||
WAFFlags=WAFFlags_s,
|
||||
WAFMatchedVar=WAFMatchedVar_s,
|
||||
WAFProfile=WAFProfile_s,
|
||||
WAFRuleID=WAFRuleID_s,
|
||||
WAFRuleMessage=WAFRuleMessage_s,
|
||||
WorkerCPUTime=WorkerCPUTime_d,
|
||||
WorkerStatus=WorkerStatus_s,
|
||||
WorkerSubrequest=WorkerSubrequest_b,
|
||||
WorkerSubrequestCount=WorkerSubrequestCount_d,
|
||||
ZoneID=ZoneID_d,
|
||||
Application=Application_s,
|
||||
ClientMatchedIpFirewall=ClientMatchedIpFirewall_s,
|
||||
NetworkProtocol=ClientProto_s,
|
||||
ClientTcpRtt=ClientTcpRtt_d,
|
||||
ClientTlsClientHelloServerName=ClientTlsClientHelloServerName_s,
|
||||
ClientTlsStatus=ClientTlsStatus_s,
|
||||
ColoCode=ColoCode_s,
|
||||
ConnectTimestamp=ConnectTimestamp_t,
|
||||
DisconnectTimestamp=DisconnectTimestamp_t,
|
||||
IpFirewall=IpFirewall_b,
|
||||
DstPortNumber=OriginPort_d,
|
||||
OriginProto=OriginProto_s,
|
||||
OriginTcpRtt=OriginTcpRtt_d,
|
||||
OriginTlsCipher=OriginTlsCipher_s,
|
||||
OriginTlsFingerprint=OriginTlsFingerprint_s,
|
||||
OriginTlsMode=OriginTlsMode_s,
|
||||
OriginTlsProtocol=OriginTlsProtocol_s,
|
||||
OriginTlsStatus=OriginTlsStatus_s,
|
||||
ProxyProtocol=ProxyProtocol_s,
|
||||
EventResult=Status_d,
|
||||
Timestamp=Timestamp_t,
|
||||
ClientASNDescription=ClientASNDescription_s,
|
||||
ClientRefererHost=ClientRefererHost_s,
|
||||
ClientRefererPath=ClientRefererPath_s,
|
||||
ClientRefererQuery=ClientRefererQuery_s,
|
||||
ClientRefererScheme=ClientRefererScheme_s,
|
||||
ClientRequestQuery=ClientRequestQuery_s,
|
||||
ClientRequestScheme=ClientRequestScheme_s,
|
||||
Datetime=Datetime_t,
|
||||
EventSubType=Kind_s,
|
||||
MatchIndex=MatchIndex_d,
|
||||
OriginatorRayID=OriginatorRayID_s
|
||||
| project-away
|
||||
ClientDeviceType_s,
|
||||
Source_s,
|
||||
ClientSSLCipher_s,
|
||||
ClientTlsCipher_s,
|
||||
ClientSSLProtocol_s,
|
||||
ClientTlsProtocol_s,
|
||||
FirewallMatchesActions_s,
|
||||
Event_s,
|
||||
Action_s,
|
||||
FirewallMatchesRuleIDs_s,
|
||||
RuleID_s
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -0,0 +1,981 @@
|
|||
{
|
||||
"version": "Notebook/1.0",
|
||||
"items": [
|
||||
{
|
||||
"type": 1,
|
||||
"content": {
|
||||
"json": ">**NOTE:** This workbook uses a parser based on a Kusto Function to normalize fields. [Follow these steps](https://aka.ms/sentinel-CloudflareDataConnector-parser) to create the Kusto function alias **Cloudflare**."
|
||||
},
|
||||
"name": "text - 0"
|
||||
},
|
||||
{
|
||||
"type": 11,
|
||||
"content": {
|
||||
"version": "LinkItem/1.0",
|
||||
"style": "tabs",
|
||||
"links": [
|
||||
{
|
||||
"id": "2088f290-65ee-4357-badb-55ce732a5004",
|
||||
"cellValue": "tab",
|
||||
"linkTarget": "parameter",
|
||||
"linkLabel": "Cloudflare Web Traffic Overview",
|
||||
"subTarget": "cloudflare_web_traffic_overview",
|
||||
"style": "link"
|
||||
},
|
||||
{
|
||||
"id": "25df6ee6-dcf7-4aa2-b90e-50f8a4b6548d",
|
||||
"cellValue": "tab",
|
||||
"linkTarget": "parameter",
|
||||
"linkLabel": "Cloudflare Security Overview",
|
||||
"subTarget": "cloudflare_security_overview",
|
||||
"style": "link"
|
||||
},
|
||||
{
|
||||
"id": "a2108bc6-5769-4c86-a5c0-201f531ed929",
|
||||
"cellValue": "tab",
|
||||
"linkTarget": "parameter",
|
||||
"linkLabel": "Cloudflare Reliability Summary",
|
||||
"subTarget": "cloudflare_reliability_summary",
|
||||
"style": "link"
|
||||
}
|
||||
]
|
||||
},
|
||||
"name": "links - 1"
|
||||
},
|
||||
{
|
||||
"type": 9,
|
||||
"content": {
|
||||
"version": "KqlParameterItem/1.0",
|
||||
"parameters": [
|
||||
{
|
||||
"id": "c64d5d3d-90c6-484a-ab88-c70652b75b6e",
|
||||
"version": "KqlParameterItem/1.0",
|
||||
"name": "TimeRange",
|
||||
"type": 4,
|
||||
"isRequired": true,
|
||||
"value": {
|
||||
"durationMs": 172800000
|
||||
},
|
||||
"typeSettings": {
|
||||
"selectableValues": [
|
||||
{
|
||||
"durationMs": 300000
|
||||
},
|
||||
{
|
||||
"durationMs": 900000
|
||||
},
|
||||
{
|
||||
"durationMs": 1800000
|
||||
},
|
||||
{
|
||||
"durationMs": 3600000
|
||||
},
|
||||
{
|
||||
"durationMs": 14400000
|
||||
},
|
||||
{
|
||||
"durationMs": 43200000
|
||||
},
|
||||
{
|
||||
"durationMs": 86400000
|
||||
},
|
||||
{
|
||||
"durationMs": 172800000
|
||||
},
|
||||
{
|
||||
"durationMs": 259200000
|
||||
},
|
||||
{
|
||||
"durationMs": 604800000
|
||||
},
|
||||
{
|
||||
"durationMs": 1209600000
|
||||
},
|
||||
{
|
||||
"durationMs": 2419200000
|
||||
},
|
||||
{
|
||||
"durationMs": 2592000000
|
||||
},
|
||||
{
|
||||
"durationMs": 5184000000
|
||||
},
|
||||
{
|
||||
"durationMs": 7776000000
|
||||
}
|
||||
],
|
||||
"allowCustom": true
|
||||
},
|
||||
"timeContext": {
|
||||
"durationMs": 86400000
|
||||
}
|
||||
}
|
||||
],
|
||||
"style": "pills",
|
||||
"queryType": 0,
|
||||
"resourceType": "microsoft.operationalinsights/workspaces"
|
||||
},
|
||||
"name": "parameters - 1"
|
||||
},
|
||||
{
|
||||
"type": 3,
|
||||
"content": {
|
||||
"version": "KqlItem/1.0",
|
||||
"query": "Cloudflare_CL\n| summarize count() by ClientDeviceType_s",
|
||||
"size": 0,
|
||||
"title": "Traffic Type",
|
||||
"timeContext": {
|
||||
"durationMs": 0
|
||||
},
|
||||
"timeContextFromParameter": "TimeRange",
|
||||
"queryType": 0,
|
||||
"resourceType": "microsoft.operationalinsights/workspaces",
|
||||
"visualization": "piechart"
|
||||
},
|
||||
"conditionalVisibility": {
|
||||
"parameterName": "tab",
|
||||
"comparison": "isEqualTo",
|
||||
"value": "cloudflare_web_traffic_overview"
|
||||
},
|
||||
"customWidth": "25",
|
||||
"name": "Traffic Type"
|
||||
},
|
||||
{
|
||||
"type": 3,
|
||||
"content": {
|
||||
"version": "KqlItem/1.0",
|
||||
"query": "Cloudflare_CL\n| summarize count() by ClientRequestProtocol_s",
|
||||
"size": 0,
|
||||
"title": "HTTP Protocols",
|
||||
"timeContext": {
|
||||
"durationMs": 0
|
||||
},
|
||||
"timeContextFromParameter": "TimeRange",
|
||||
"queryType": 0,
|
||||
"resourceType": "microsoft.operationalinsights/workspaces",
|
||||
"visualization": "piechart"
|
||||
},
|
||||
"conditionalVisibility": {
|
||||
"parameterName": "tab",
|
||||
"comparison": "isEqualTo",
|
||||
"value": "cloudflare_web_traffic_overview"
|
||||
},
|
||||
"customWidth": "25",
|
||||
"name": "HTTP Protocols"
|
||||
},
|
||||
{
|
||||
"type": 3,
|
||||
"content": {
|
||||
"version": "KqlItem/1.0",
|
||||
"query": "Cloudflare_CL\n| summarize count() by ClientRequestMethod_s",
|
||||
"size": 0,
|
||||
"title": "Request Methods",
|
||||
"timeContext": {
|
||||
"durationMs": 0
|
||||
},
|
||||
"timeContextFromParameter": "TimeRange",
|
||||
"queryType": 0,
|
||||
"resourceType": "microsoft.operationalinsights/workspaces",
|
||||
"visualization": "piechart"
|
||||
},
|
||||
"conditionalVisibility": {
|
||||
"parameterName": "tab",
|
||||
"comparison": "isEqualTo",
|
||||
"value": "cloudflare_web_traffic_overview"
|
||||
},
|
||||
"customWidth": "25",
|
||||
"name": "Request Methods"
|
||||
},
|
||||
{
|
||||
"type": 3,
|
||||
"content": {
|
||||
"version": "KqlItem/1.0",
|
||||
"query": "Cloudflare_CL\n| extend EdgeResponseContentType = iif(isempty(EdgeResponseContentType_s),\"empty\",EdgeResponseContentType_s )\n| summarize count() by EdgeResponseContentType",
|
||||
"size": 0,
|
||||
"title": "Content Types",
|
||||
"timeContext": {
|
||||
"durationMs": 0
|
||||
},
|
||||
"timeContextFromParameter": "TimeRange",
|
||||
"queryType": 0,
|
||||
"resourceType": "microsoft.operationalinsights/workspaces",
|
||||
"visualization": "piechart"
|
||||
},
|
||||
"conditionalVisibility": {
|
||||
"parameterName": "tab",
|
||||
"comparison": "isEqualTo",
|
||||
"value": "cloudflare_web_traffic_overview"
|
||||
},
|
||||
"customWidth": "25",
|
||||
"name": "Content Types"
|
||||
},
|
||||
{
|
||||
"type": 3,
|
||||
"content": {
|
||||
"version": "KqlItem/1.0",
|
||||
"query": "Cloudflare_CL\n| summarize Count=count() by ClientRequestURI_s\n| sort by Count | project-rename ClientRequestURI=ClientRequestURI_s | take 50",
|
||||
"size": 0,
|
||||
"title": "Top Requested URIs",
|
||||
"timeContext": {
|
||||
"durationMs": 0
|
||||
},
|
||||
"timeContextFromParameter": "TimeRange",
|
||||
"queryType": 0,
|
||||
"resourceType": "microsoft.operationalinsights/workspaces",
|
||||
"visualization": "table"
|
||||
},
|
||||
"conditionalVisibility": {
|
||||
"parameterName": "tab",
|
||||
"comparison": "isEqualTo",
|
||||
"value": "cloudflare_web_traffic_overview"
|
||||
},
|
||||
"customWidth": "25",
|
||||
"name": "Top Requested URIs"
|
||||
},
|
||||
{
|
||||
"type": 3,
|
||||
"content": {
|
||||
"version": "KqlItem/1.0",
|
||||
"query": "Cloudflare_CL\n| summarize Count=count() by ClientIP_s\n| sort by Count | take 50 | project-rename ClientIP=ClientIP_s",
|
||||
"size": 0,
|
||||
"title": "Top Traffic IPs",
|
||||
"timeContext": {
|
||||
"durationMs": 0
|
||||
},
|
||||
"timeContextFromParameter": "TimeRange",
|
||||
"queryType": 0,
|
||||
"resourceType": "microsoft.operationalinsights/workspaces",
|
||||
"visualization": "table"
|
||||
},
|
||||
"conditionalVisibility": {
|
||||
"parameterName": "tab",
|
||||
"comparison": "isEqualTo",
|
||||
"value": "cloudflare_web_traffic_overview"
|
||||
},
|
||||
"customWidth": "25",
|
||||
"name": "Top Traffic IPs"
|
||||
},
|
||||
{
|
||||
"type": 3,
|
||||
"content": {
|
||||
"version": "KqlItem/1.0",
|
||||
"query": "Cloudflare_CL\n| extend ClientRequestReferer = iif(isempty(ClientRequestReferer_s),\"empty\",ClientRequestReferer_s )\n| summarize Count=count() by ClientRequestReferer\n| sort by Count | take 50\n",
|
||||
"size": 0,
|
||||
"title": "Top Referer",
|
||||
"timeContext": {
|
||||
"durationMs": 0
|
||||
},
|
||||
"timeContextFromParameter": "TimeRange",
|
||||
"queryType": 0,
|
||||
"resourceType": "microsoft.operationalinsights/workspaces",
|
||||
"visualization": "table"
|
||||
},
|
||||
"conditionalVisibility": {
|
||||
"parameterName": "tab",
|
||||
"comparison": "isEqualTo",
|
||||
"value": "cloudflare_web_traffic_overview"
|
||||
},
|
||||
"customWidth": "25",
|
||||
"name": "Top Referer"
|
||||
},
|
||||
{
|
||||
"type": 3,
|
||||
"content": {
|
||||
"version": "KqlItem/1.0",
|
||||
"query": "Cloudflare_CL\n| summarize Count=count() by ClientIPClass_s | project-rename ClientIPClass=ClientIPClass_s\n| sort by Count | take 50\n",
|
||||
"size": 0,
|
||||
"title": "Top Traffic Types",
|
||||
"timeContext": {
|
||||
"durationMs": 0
|
||||
},
|
||||
"timeContextFromParameter": "TimeRange",
|
||||
"queryType": 0,
|
||||
"resourceType": "microsoft.operationalinsights/workspaces",
|
||||
"visualization": "piechart"
|
||||
},
|
||||
"conditionalVisibility": {
|
||||
"parameterName": "tab",
|
||||
"comparison": "isEqualTo",
|
||||
"value": "cloudflare_web_traffic_overview"
|
||||
},
|
||||
"customWidth": "25",
|
||||
"name": "Top Traffic Types"
|
||||
},
|
||||
{
|
||||
"type": 3,
|
||||
"content": {
|
||||
"version": "KqlItem/1.0",
|
||||
"query": "Cloudflare_CL\n| summarize Count=count() by ClientRequestUserAgent_s | project-rename ClientRequestUserAgent=ClientRequestUserAgent_s\n| sort by Count | take 50",
|
||||
"size": 0,
|
||||
"title": "Top User Agents",
|
||||
"timeContext": {
|
||||
"durationMs": 86400000
|
||||
},
|
||||
"queryType": 0,
|
||||
"resourceType": "microsoft.operationalinsights/workspaces",
|
||||
"gridSettings": {
|
||||
"formatters": [
|
||||
{
|
||||
"columnMatch": "ClientRequestUserAgent",
|
||||
"formatter": 0,
|
||||
"formatOptions": {
|
||||
"customColumnWidthSetting": "75%"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"conditionalVisibility": {
|
||||
"parameterName": "tab",
|
||||
"comparison": "isEqualTo",
|
||||
"value": "cloudflare_web_traffic_overview"
|
||||
},
|
||||
"name": "Top User Agents"
|
||||
},
|
||||
{
|
||||
"type": 3,
|
||||
"content": {
|
||||
"version": "KqlItem/1.0",
|
||||
"query": "let total_number_of_requests =\nCloudflare_CL\n| summarize Count=count()\n| extend title=\"Total Number Of Requests\";\n\nlet threats_stopped =\nCloudflare_CL \n| extend threat=case(EdgePathingSrc_s ==\"user\" and EdgePathingOp_s == \"ban\" and EdgePathingStatus_s has \"ip\" ,\"IP Block\",EdgePathingSrc_s==\"user\" and EdgePathingOp_s==\"ban\" and EdgePathingStatus_s==\"ctry\",\"Country Block\",EdgePathingSrc_s==\"user\" and EdgePathingOp_s==\"ban\" and EdgePathingStatus_s==\"zl\", \"Routed by Zone Lockdown\", EdgePathingSrc_s==\"user\" and EdgePathingOp_s==\"ban\" and EdgePathingStatus_s==\"ua\", \"Blocked User Agent\", EdgePathingSrc_s==\"user\" and EdgePathingOp_s==\"ban\" and EdgePathingStatus_s==\"rateLimit\", \"Blocked by Rate Limiting\", EdgePathingSrc_s==\"filterBasedFirewall\" and EdgePathingOp_s==\"ban\" and EdgePathingStatus_s==\"unknown\", \"Blocked by Filter Based Firewall\", EdgePathingSrc_s==\"filterBasedFirewall\" and EdgePathingOp_s==\"chl\", \"Challenged by Filter Based Firewall\", EdgePathingSrc_s==\"bic\" and EdgePathingOp_s==\"ban\" and EdgePathingStatus_s==\"unknown\", \"Browser Integrity Check\", EdgePathingSrc_s==\"hot\" and EdgePathingOp_s==\"ban\" and EdgePathingStatus_s==\"ctry\", \"Blocked Hotlink\", EdgePathingSrc_s==\"hot\" and EdgePathingOp_s==\"ban\" and EdgePathingStatus_s==\"ip\", \"Blocked Hotlink\", EdgePathingSrc_s==\"macro\" and EdgePathingOp_s==\"chl\" and EdgePathingStatus_s==\"captchaErr\", \"CAPTCHA Error\", EdgePathingSrc_s==\"macro\" and EdgePathingOp_s==\"chl\" and EdgePathingStatus_s==\"captchaFail\", \"CAPTCHA Challenge Failed\", EdgePathingSrc_s==\"macro\" and EdgePathingOp_s==\"chl\" and EdgePathingStatus_s==\"captchaNew\", \"New CAPTCHA\", EdgePathingSrc_s==\"macro\" and EdgePathingOp_s==\"chl\" and EdgePathingStatus_s==\"jschlErr\", \"Java Script Challenge Error\", EdgePathingSrc_s==\"macro\" and EdgePathingOp_s==\"chl\" and EdgePathingStatus_s==\"jschlFail\", \"Java Script Challenge Failed\", EdgePathingSrc_s==\"macro\" and EdgePathingOp_s==\"chl\" and EdgePathingStatus_s==\"jschlNew\", \"New Java Script Challenge\", EdgePathingSrc_s==\"protect\" and EdgePathingOp_s==\"ban\" and EdgePathingStatus_s==\"17ddos\", \"L7 DDos Mitigation\",\"\")\n| where isnotempty(threat) | summarize Count=count()\n| extend title=\"Stopped Threats\";\n\nlet result_table = union total_number_of_requests, threats_stopped; \nresult_table \n| sort by Count\n\n",
|
||||
"size": 0,
|
||||
"timeContext": {
|
||||
"durationMs": 0
|
||||
},
|
||||
"timeContextFromParameter": "TimeRange",
|
||||
"queryType": 0,
|
||||
"resourceType": "microsoft.operationalinsights/workspaces",
|
||||
"visualization": "tiles",
|
||||
"tileSettings": {
|
||||
"titleContent": {
|
||||
"columnMatch": "title",
|
||||
"formatter": 1
|
||||
},
|
||||
"leftContent": {
|
||||
"columnMatch": "Count",
|
||||
"formatter": 12,
|
||||
"formatOptions": {
|
||||
"palette": "auto"
|
||||
},
|
||||
"numberFormat": {
|
||||
"unit": 17,
|
||||
"options": {
|
||||
"maximumSignificantDigits": 3,
|
||||
"maximumFractionDigits": 2
|
||||
}
|
||||
}
|
||||
},
|
||||
"showBorder": false,
|
||||
"sortCriteriaField": "Count",
|
||||
"sortOrderField": 2,
|
||||
"size": "auto"
|
||||
}
|
||||
},
|
||||
"conditionalVisibility": {
|
||||
"parameterName": "tab",
|
||||
"comparison": "isEqualTo",
|
||||
"value": "cloudflare_security_overview"
|
||||
},
|
||||
"customWidth": "33",
|
||||
"name": "Req_Threats_title"
|
||||
},
|
||||
{
|
||||
"type": 3,
|
||||
"content": {
|
||||
"version": "KqlItem/1.0",
|
||||
"query": "Cloudflare_CL \n| extend threat=case(EdgePathingSrc_s ==\"user\" and EdgePathingOp_s == \"ban\" and EdgePathingStatus_s has \"ip\" ,\"IP Block\",EdgePathingSrc_s==\"user\" and EdgePathingOp_s==\"ban\" and EdgePathingStatus_s==\"ctry\",\"Country Block\",EdgePathingSrc_s==\"user\" and EdgePathingOp_s==\"ban\" and EdgePathingStatus_s==\"zl\", \"Routed by Zone Lockdown\", EdgePathingSrc_s==\"user\" and EdgePathingOp_s==\"ban\" and EdgePathingStatus_s==\"ua\", \"Blocked User Agent\", EdgePathingSrc_s==\"user\" and EdgePathingOp_s==\"ban\" and EdgePathingStatus_s==\"rateLimit\", \"Blocked by Rate Limiting\", EdgePathingSrc_s==\"filterBasedFirewall\" and EdgePathingOp_s==\"ban\" and EdgePathingStatus_s==\"unknown\", \"Blocked by Filter Based Firewall\", EdgePathingSrc_s==\"filterBasedFirewall\" and EdgePathingOp_s==\"chl\", \"Challenged by Filter Based Firewall\", EdgePathingSrc_s==\"bic\" and EdgePathingOp_s==\"ban\" and EdgePathingStatus_s==\"unknown\", \"Browser Integrity Check\", EdgePathingSrc_s==\"hot\" and EdgePathingOp_s==\"ban\" and EdgePathingStatus_s==\"ctry\", \"Blocked Hotlink\", EdgePathingSrc_s==\"hot\" and EdgePathingOp_s==\"ban\" and EdgePathingStatus_s==\"ip\", \"Blocked Hotlink\", EdgePathingSrc_s==\"macro\" and EdgePathingOp_s==\"chl\" and EdgePathingStatus_s==\"captchaErr\", \"CAPTCHA Error\", EdgePathingSrc_s==\"macro\" and EdgePathingOp_s==\"chl\" and EdgePathingStatus_s==\"captchaFail\", \"CAPTCHA Challenge Failed\", EdgePathingSrc_s==\"macro\" and EdgePathingOp_s==\"chl\" and EdgePathingStatus_s==\"captchaNew\", \"New CAPTCHA\", EdgePathingSrc_s==\"macro\" and EdgePathingOp_s==\"chl\" and EdgePathingStatus_s==\"jschlErr\", \"Java Script Challenge Error\", EdgePathingSrc_s==\"macro\" and EdgePathingOp_s==\"chl\" and EdgePathingStatus_s==\"jschlFail\", \"Java Script Challenge Failed\", EdgePathingSrc_s==\"macro\" and EdgePathingOp_s==\"chl\" and EdgePathingStatus_s==\"jschlNew\", \"New Java Script Challenge\", EdgePathingSrc_s==\"protect\" and EdgePathingOp_s==\"ban\" and EdgePathingStatus_s==\"17ddos\", \"L7 DDos Mitigation\",\"\")\n| where isnotempty(threat)\n| summarize Count=count() by threat",
|
||||
"size": 0,
|
||||
"title": "Top Threats",
|
||||
"timeContext": {
|
||||
"durationMs": 0
|
||||
},
|
||||
"timeContextFromParameter": "TimeRange",
|
||||
"queryType": 0,
|
||||
"resourceType": "microsoft.operationalinsights/workspaces",
|
||||
"visualization": "categoricalbar",
|
||||
"tileSettings": {
|
||||
"titleContent": {
|
||||
"columnMatch": "title",
|
||||
"formatter": 1
|
||||
},
|
||||
"leftContent": {
|
||||
"columnMatch": "Count",
|
||||
"formatter": 12,
|
||||
"formatOptions": {
|
||||
"palette": "auto"
|
||||
},
|
||||
"numberFormat": {
|
||||
"unit": 17,
|
||||
"options": {
|
||||
"maximumSignificantDigits": 3,
|
||||
"maximumFractionDigits": 2
|
||||
}
|
||||
}
|
||||
},
|
||||
"showBorder": false,
|
||||
"sortCriteriaField": "Count",
|
||||
"sortOrderField": 2,
|
||||
"size": "auto"
|
||||
}
|
||||
},
|
||||
"conditionalVisibility": {
|
||||
"parameterName": "tab",
|
||||
"comparison": "isEqualTo",
|
||||
"value": "cloudflare_security_overview"
|
||||
},
|
||||
"customWidth": "33",
|
||||
"name": "Top Threats"
|
||||
},
|
||||
{
|
||||
"type": 3,
|
||||
"content": {
|
||||
"version": "KqlItem/1.0",
|
||||
"query": "let total_number_of_requests =\nCloudflare_CL\n| summarize Count=count()\n| extend title=\"Total Number Of Requests\";\n\nlet threats_stopped =\nCloudflare_CL \n| extend threat=case(EdgePathingSrc_s ==\"user\" and EdgePathingOp_s == \"ban\" and EdgePathingStatus_s has \"ip\" ,\"IP Block\",EdgePathingSrc_s==\"user\" and EdgePathingOp_s==\"ban\" and EdgePathingStatus_s==\"ctry\",\"Country Block\",EdgePathingSrc_s==\"user\" and EdgePathingOp_s==\"ban\" and EdgePathingStatus_s==\"zl\", \"Routed by Zone Lockdown\", EdgePathingSrc_s==\"user\" and EdgePathingOp_s==\"ban\" and EdgePathingStatus_s==\"ua\", \"Blocked User Agent\", EdgePathingSrc_s==\"user\" and EdgePathingOp_s==\"ban\" and EdgePathingStatus_s==\"rateLimit\", \"Blocked by Rate Limiting\", EdgePathingSrc_s==\"filterBasedFirewall\" and EdgePathingOp_s==\"ban\" and EdgePathingStatus_s==\"unknown\", \"Blocked by Filter Based Firewall\", EdgePathingSrc_s==\"filterBasedFirewall\" and EdgePathingOp_s==\"chl\", \"Challenged by Filter Based Firewall\", EdgePathingSrc_s==\"bic\" and EdgePathingOp_s==\"ban\" and EdgePathingStatus_s==\"unknown\", \"Browser Integrity Check\", EdgePathingSrc_s==\"hot\" and EdgePathingOp_s==\"ban\" and EdgePathingStatus_s==\"ctry\", \"Blocked Hotlink\", EdgePathingSrc_s==\"hot\" and EdgePathingOp_s==\"ban\" and EdgePathingStatus_s==\"ip\", \"Blocked Hotlink\", EdgePathingSrc_s==\"macro\" and EdgePathingOp_s==\"chl\" and EdgePathingStatus_s==\"captchaErr\", \"CAPTCHA Error\", EdgePathingSrc_s==\"macro\" and EdgePathingOp_s==\"chl\" and EdgePathingStatus_s==\"captchaFail\", \"CAPTCHA Challenge Failed\", EdgePathingSrc_s==\"macro\" and EdgePathingOp_s==\"chl\" and EdgePathingStatus_s==\"captchaNew\", \"New CAPTCHA\", EdgePathingSrc_s==\"macro\" and EdgePathingOp_s==\"chl\" and EdgePathingStatus_s==\"jschlErr\", \"Java Script Challenge Error\", EdgePathingSrc_s==\"macro\" and EdgePathingOp_s==\"chl\" and EdgePathingStatus_s==\"jschlFail\", \"Java Script Challenge Failed\", EdgePathingSrc_s==\"macro\" and EdgePathingOp_s==\"chl\" and EdgePathingStatus_s==\"jschlNew\", \"New Java Script Challenge\", EdgePathingSrc_s==\"protect\" and EdgePathingOp_s==\"ban\" and EdgePathingStatus_s==\"17ddos\", \"L7 DDos Mitigation\",\"\")\n| where isnotempty(threat) | summarize Count=count()\n| extend title=\"Stopped Threats\";\n\nlet result_table = union total_number_of_requests, threats_stopped; \nresult_table \n| sort by Count\n\n",
|
||||
"size": 0,
|
||||
"title": "Requests vs Threats",
|
||||
"timeContext": {
|
||||
"durationMs": 0
|
||||
},
|
||||
"timeContextFromParameter": "TimeRange",
|
||||
"queryType": 0,
|
||||
"resourceType": "microsoft.operationalinsights/workspaces",
|
||||
"visualization": "piechart",
|
||||
"tileSettings": {
|
||||
"titleContent": {
|
||||
"columnMatch": "title",
|
||||
"formatter": 1
|
||||
},
|
||||
"leftContent": {
|
||||
"columnMatch": "Count",
|
||||
"formatter": 12,
|
||||
"formatOptions": {
|
||||
"palette": "auto"
|
||||
},
|
||||
"numberFormat": {
|
||||
"unit": 17,
|
||||
"options": {
|
||||
"maximumSignificantDigits": 3,
|
||||
"maximumFractionDigits": 2
|
||||
}
|
||||
}
|
||||
},
|
||||
"showBorder": false,
|
||||
"sortCriteriaField": "Count",
|
||||
"sortOrderField": 2,
|
||||
"size": "auto"
|
||||
}
|
||||
},
|
||||
"conditionalVisibility": {
|
||||
"parameterName": "tab",
|
||||
"comparison": "isEqualTo",
|
||||
"value": "cloudflare_security_overview"
|
||||
},
|
||||
"customWidth": "33",
|
||||
"name": "Requests vs Threats"
|
||||
},
|
||||
{
|
||||
"type": 3,
|
||||
"content": {
|
||||
"version": "KqlItem/1.0",
|
||||
"query": "Cloudflare_CL \n| extend threat=case(EdgePathingSrc_s ==\"user\" and EdgePathingOp_s == \"ban\" and EdgePathingStatus_s has \"ip\" ,\"IP Block\",EdgePathingSrc_s==\"user\" and EdgePathingOp_s==\"ban\" and EdgePathingStatus_s==\"ctry\",\"Country Block\",EdgePathingSrc_s==\"user\" and EdgePathingOp_s==\"ban\" and EdgePathingStatus_s==\"zl\", \"Routed by Zone Lockdown\", EdgePathingSrc_s==\"user\" and EdgePathingOp_s==\"ban\" and EdgePathingStatus_s==\"ua\", \"Blocked User Agent\", EdgePathingSrc_s==\"user\" and EdgePathingOp_s==\"ban\" and EdgePathingStatus_s==\"rateLimit\", \"Blocked by Rate Limiting\", EdgePathingSrc_s==\"filterBasedFirewall\" and EdgePathingOp_s==\"ban\" and EdgePathingStatus_s==\"unknown\", \"Blocked by Filter Based Firewall\", EdgePathingSrc_s==\"filterBasedFirewall\" and EdgePathingOp_s==\"chl\", \"Challenged by Filter Based Firewall\", EdgePathingSrc_s==\"bic\" and EdgePathingOp_s==\"ban\" and EdgePathingStatus_s==\"unknown\", \"Browser Integrity Check\", EdgePathingSrc_s==\"hot\" and EdgePathingOp_s==\"ban\" and EdgePathingStatus_s==\"ctry\", \"Blocked Hotlink\", EdgePathingSrc_s==\"hot\" and EdgePathingOp_s==\"ban\" and EdgePathingStatus_s==\"ip\", \"Blocked Hotlink\", EdgePathingSrc_s==\"macro\" and EdgePathingOp_s==\"chl\" and EdgePathingStatus_s==\"captchaErr\", \"CAPTCHA Error\", EdgePathingSrc_s==\"macro\" and EdgePathingOp_s==\"chl\" and EdgePathingStatus_s==\"captchaFail\", \"CAPTCHA Challenge Failed\", EdgePathingSrc_s==\"macro\" and EdgePathingOp_s==\"chl\" and EdgePathingStatus_s==\"captchaNew\", \"New CAPTCHA\", EdgePathingSrc_s==\"macro\" and EdgePathingOp_s==\"chl\" and EdgePathingStatus_s==\"jschlErr\", \"Java Script Challenge Error\", EdgePathingSrc_s==\"macro\" and EdgePathingOp_s==\"chl\" and EdgePathingStatus_s==\"jschlFail\", \"Java Script Challenge Failed\", EdgePathingSrc_s==\"macro\" and EdgePathingOp_s==\"chl\" and EdgePathingStatus_s==\"jschlNew\", \"New Java Script Challenge\", EdgePathingSrc_s==\"protect\" and EdgePathingOp_s==\"ban\" and EdgePathingStatus_s==\"17ddos\", \"L7 DDos Mitigation\",\"\")\n| where isnotempty(threat)\n| make-series Trend = count() on TimeGenerated from {TimeRange:start} to {TimeRange:end} step {TimeRange:grain};",
|
||||
"size": 0,
|
||||
"title": "Threats Over Time",
|
||||
"timeContext": {
|
||||
"durationMs": 0
|
||||
},
|
||||
"timeContextFromParameter": "TimeRange",
|
||||
"queryType": 0,
|
||||
"resourceType": "microsoft.operationalinsights/workspaces",
|
||||
"visualization": "timechart",
|
||||
"tileSettings": {
|
||||
"titleContent": {
|
||||
"columnMatch": "title",
|
||||
"formatter": 1
|
||||
},
|
||||
"leftContent": {
|
||||
"columnMatch": "Count",
|
||||
"formatter": 12,
|
||||
"formatOptions": {
|
||||
"palette": "auto"
|
||||
},
|
||||
"numberFormat": {
|
||||
"unit": 17,
|
||||
"options": {
|
||||
"maximumSignificantDigits": 3,
|
||||
"maximumFractionDigits": 2
|
||||
}
|
||||
}
|
||||
},
|
||||
"showBorder": false,
|
||||
"sortCriteriaField": "Count",
|
||||
"sortOrderField": 2,
|
||||
"size": "auto"
|
||||
}
|
||||
},
|
||||
"conditionalVisibility": {
|
||||
"parameterName": "tab",
|
||||
"comparison": "isEqualTo",
|
||||
"value": "cloudflare_security_overview"
|
||||
},
|
||||
"customWidth": "33",
|
||||
"name": "Threats Over Time"
|
||||
},
|
||||
{
|
||||
"type": 3,
|
||||
"content": {
|
||||
"version": "KqlItem/1.0",
|
||||
"query": "Cloudflare_CL \n| extend threat=case(EdgePathingSrc_s ==\"user\" and EdgePathingOp_s == \"ban\" and EdgePathingStatus_s has \"ip\" ,\"IP Block\",EdgePathingSrc_s==\"user\" and EdgePathingOp_s==\"ban\" and EdgePathingStatus_s==\"ctry\",\"Country Block\",EdgePathingSrc_s==\"user\" and EdgePathingOp_s==\"ban\" and EdgePathingStatus_s==\"zl\", \"Routed by Zone Lockdown\", EdgePathingSrc_s==\"user\" and EdgePathingOp_s==\"ban\" and EdgePathingStatus_s==\"ua\", \"Blocked User Agent\", EdgePathingSrc_s==\"user\" and EdgePathingOp_s==\"ban\" and EdgePathingStatus_s==\"rateLimit\", \"Blocked by Rate Limiting\", EdgePathingSrc_s==\"filterBasedFirewall\" and EdgePathingOp_s==\"ban\" and EdgePathingStatus_s==\"unknown\", \"Blocked by Filter Based Firewall\", EdgePathingSrc_s==\"filterBasedFirewall\" and EdgePathingOp_s==\"chl\", \"Challenged by Filter Based Firewall\", EdgePathingSrc_s==\"bic\" and EdgePathingOp_s==\"ban\" and EdgePathingStatus_s==\"unknown\", \"Browser Integrity Check\", EdgePathingSrc_s==\"hot\" and EdgePathingOp_s==\"ban\" and EdgePathingStatus_s==\"ctry\", \"Blocked Hotlink\", EdgePathingSrc_s==\"hot\" and EdgePathingOp_s==\"ban\" and EdgePathingStatus_s==\"ip\", \"Blocked Hotlink\", EdgePathingSrc_s==\"macro\" and EdgePathingOp_s==\"chl\" and EdgePathingStatus_s==\"captchaErr\", \"CAPTCHA Error\", EdgePathingSrc_s==\"macro\" and EdgePathingOp_s==\"chl\" and EdgePathingStatus_s==\"captchaFail\", \"CAPTCHA Challenge Failed\", EdgePathingSrc_s==\"macro\" and EdgePathingOp_s==\"chl\" and EdgePathingStatus_s==\"captchaNew\", \"New CAPTCHA\", EdgePathingSrc_s==\"macro\" and EdgePathingOp_s==\"chl\" and EdgePathingStatus_s==\"jschlErr\", \"Java Script Challenge Error\", EdgePathingSrc_s==\"macro\" and EdgePathingOp_s==\"chl\" and EdgePathingStatus_s==\"jschlFail\", \"Java Script Challenge Failed\", EdgePathingSrc_s==\"macro\" and EdgePathingOp_s==\"chl\" and EdgePathingStatus_s==\"jschlNew\", \"New Java Script Challenge\", EdgePathingSrc_s==\"protect\" and EdgePathingOp_s==\"ban\" and EdgePathingStatus_s==\"17ddos\", \"L7 DDos Mitigation\",\"\")\n| where isnotempty(threat)\n| summarize count() by ClientCountry_s | project-rename Country=ClientCountry_s | take 20",
|
||||
"size": 0,
|
||||
"title": "Top Threat Countries",
|
||||
"timeContext": {
|
||||
"durationMs": 0
|
||||
},
|
||||
"timeContextFromParameter": "TimeRange",
|
||||
"queryType": 0,
|
||||
"resourceType": "microsoft.operationalinsights/workspaces",
|
||||
"visualization": "table",
|
||||
"tileSettings": {
|
||||
"titleContent": {
|
||||
"columnMatch": "title",
|
||||
"formatter": 1
|
||||
},
|
||||
"leftContent": {
|
||||
"columnMatch": "Count",
|
||||
"formatter": 12,
|
||||
"formatOptions": {
|
||||
"palette": "auto"
|
||||
},
|
||||
"numberFormat": {
|
||||
"unit": 17,
|
||||
"options": {
|
||||
"maximumSignificantDigits": 3,
|
||||
"maximumFractionDigits": 2
|
||||
}
|
||||
}
|
||||
},
|
||||
"showBorder": false,
|
||||
"sortCriteriaField": "Count",
|
||||
"sortOrderField": 2,
|
||||
"size": "auto"
|
||||
}
|
||||
},
|
||||
"conditionalVisibility": {
|
||||
"parameterName": "tab",
|
||||
"comparison": "isEqualTo",
|
||||
"value": "cloudflare_security_overview"
|
||||
},
|
||||
"customWidth": "33",
|
||||
"name": "Top Threat Countries"
|
||||
},
|
||||
{
|
||||
"type": 3,
|
||||
"content": {
|
||||
"version": "KqlItem/1.0",
|
||||
"query": "Cloudflare_CL \n| extend threat=case(EdgePathingSrc_s ==\"user\" and EdgePathingOp_s == \"ban\" and EdgePathingStatus_s has \"ip\" ,\"IP Block\",EdgePathingSrc_s==\"user\" and EdgePathingOp_s==\"ban\" and EdgePathingStatus_s==\"ctry\",\"Country Block\",EdgePathingSrc_s==\"user\" and EdgePathingOp_s==\"ban\" and EdgePathingStatus_s==\"zl\", \"Routed by Zone Lockdown\", EdgePathingSrc_s==\"user\" and EdgePathingOp_s==\"ban\" and EdgePathingStatus_s==\"ua\", \"Blocked User Agent\", EdgePathingSrc_s==\"user\" and EdgePathingOp_s==\"ban\" and EdgePathingStatus_s==\"rateLimit\", \"Blocked by Rate Limiting\", EdgePathingSrc_s==\"filterBasedFirewall\" and EdgePathingOp_s==\"ban\" and EdgePathingStatus_s==\"unknown\", \"Blocked by Filter Based Firewall\", EdgePathingSrc_s==\"filterBasedFirewall\" and EdgePathingOp_s==\"chl\", \"Challenged by Filter Based Firewall\", EdgePathingSrc_s==\"bic\" and EdgePathingOp_s==\"ban\" and EdgePathingStatus_s==\"unknown\", \"Browser Integrity Check\", EdgePathingSrc_s==\"hot\" and EdgePathingOp_s==\"ban\" and EdgePathingStatus_s==\"ctry\", \"Blocked Hotlink\", EdgePathingSrc_s==\"hot\" and EdgePathingOp_s==\"ban\" and EdgePathingStatus_s==\"ip\", \"Blocked Hotlink\", EdgePathingSrc_s==\"macro\" and EdgePathingOp_s==\"chl\" and EdgePathingStatus_s==\"captchaErr\", \"CAPTCHA Error\", EdgePathingSrc_s==\"macro\" and EdgePathingOp_s==\"chl\" and EdgePathingStatus_s==\"captchaFail\", \"CAPTCHA Challenge Failed\", EdgePathingSrc_s==\"macro\" and EdgePathingOp_s==\"chl\" and EdgePathingStatus_s==\"captchaNew\", \"New CAPTCHA\", EdgePathingSrc_s==\"macro\" and EdgePathingOp_s==\"chl\" and EdgePathingStatus_s==\"jschlErr\", \"Java Script Challenge Error\", EdgePathingSrc_s==\"macro\" and EdgePathingOp_s==\"chl\" and EdgePathingStatus_s==\"jschlFail\", \"Java Script Challenge Failed\", EdgePathingSrc_s==\"macro\" and EdgePathingOp_s==\"chl\" and EdgePathingStatus_s==\"jschlNew\", \"New Java Script Challenge\", EdgePathingSrc_s==\"protect\" and EdgePathingOp_s==\"ban\" and EdgePathingStatus_s==\"17ddos\", \"L7 DDos Mitigation\",\"\")\n| where isnotempty(threat)\n| summarize count() by ClientIP_s | project-rename ClientIP=ClientIP_s",
|
||||
"size": 0,
|
||||
"title": "Top Threat Client IPs",
|
||||
"timeContext": {
|
||||
"durationMs": 0
|
||||
},
|
||||
"timeContextFromParameter": "TimeRange",
|
||||
"queryType": 0,
|
||||
"resourceType": "microsoft.operationalinsights/workspaces",
|
||||
"visualization": "table",
|
||||
"tileSettings": {
|
||||
"titleContent": {
|
||||
"columnMatch": "title",
|
||||
"formatter": 1
|
||||
},
|
||||
"leftContent": {
|
||||
"columnMatch": "Count",
|
||||
"formatter": 12,
|
||||
"formatOptions": {
|
||||
"palette": "auto"
|
||||
},
|
||||
"numberFormat": {
|
||||
"unit": 17,
|
||||
"options": {
|
||||
"maximumSignificantDigits": 3,
|
||||
"maximumFractionDigits": 2
|
||||
}
|
||||
}
|
||||
},
|
||||
"showBorder": false,
|
||||
"sortCriteriaField": "Count",
|
||||
"sortOrderField": 2,
|
||||
"size": "auto"
|
||||
}
|
||||
},
|
||||
"conditionalVisibility": {
|
||||
"parameterName": "tab",
|
||||
"comparison": "isEqualTo",
|
||||
"value": "cloudflare_security_overview"
|
||||
},
|
||||
"customWidth": "33",
|
||||
"name": "Top Threat Client IPs"
|
||||
},
|
||||
{
|
||||
"type": 3,
|
||||
"content": {
|
||||
"version": "KqlItem/1.0",
|
||||
"query": "Cloudflare_CL \n| extend threat=case(EdgePathingSrc_s ==\"user\" and EdgePathingOp_s == \"ban\" and EdgePathingStatus_s has \"ip\" ,\"IP Block\",EdgePathingSrc_s==\"user\" and EdgePathingOp_s==\"ban\" and EdgePathingStatus_s==\"ctry\",\"Country Block\",EdgePathingSrc_s==\"user\" and EdgePathingOp_s==\"ban\" and EdgePathingStatus_s==\"zl\", \"Routed by Zone Lockdown\", EdgePathingSrc_s==\"user\" and EdgePathingOp_s==\"ban\" and EdgePathingStatus_s==\"ua\", \"Blocked User Agent\", EdgePathingSrc_s==\"user\" and EdgePathingOp_s==\"ban\" and EdgePathingStatus_s==\"rateLimit\", \"Blocked by Rate Limiting\", EdgePathingSrc_s==\"filterBasedFirewall\" and EdgePathingOp_s==\"ban\" and EdgePathingStatus_s==\"unknown\", \"Blocked by Filter Based Firewall\", EdgePathingSrc_s==\"filterBasedFirewall\" and EdgePathingOp_s==\"chl\", \"Challenged by Filter Based Firewall\", EdgePathingSrc_s==\"bic\" and EdgePathingOp_s==\"ban\" and EdgePathingStatus_s==\"unknown\", \"Browser Integrity Check\", EdgePathingSrc_s==\"hot\" and EdgePathingOp_s==\"ban\" and EdgePathingStatus_s==\"ctry\", \"Blocked Hotlink\", EdgePathingSrc_s==\"hot\" and EdgePathingOp_s==\"ban\" and EdgePathingStatus_s==\"ip\", \"Blocked Hotlink\", EdgePathingSrc_s==\"macro\" and EdgePathingOp_s==\"chl\" and EdgePathingStatus_s==\"captchaErr\", \"CAPTCHA Error\", EdgePathingSrc_s==\"macro\" and EdgePathingOp_s==\"chl\" and EdgePathingStatus_s==\"captchaFail\", \"CAPTCHA Challenge Failed\", EdgePathingSrc_s==\"macro\" and EdgePathingOp_s==\"chl\" and EdgePathingStatus_s==\"captchaNew\", \"New CAPTCHA\", EdgePathingSrc_s==\"macro\" and EdgePathingOp_s==\"chl\" and EdgePathingStatus_s==\"jschlErr\", \"Java Script Challenge Error\", EdgePathingSrc_s==\"macro\" and EdgePathingOp_s==\"chl\" and EdgePathingStatus_s==\"jschlFail\", \"Java Script Challenge Failed\", EdgePathingSrc_s==\"macro\" and EdgePathingOp_s==\"chl\" and EdgePathingStatus_s==\"jschlNew\", \"New Java Script Challenge\", EdgePathingSrc_s==\"protect\" and EdgePathingOp_s==\"ban\" and EdgePathingStatus_s==\"17ddos\", \"L7 DDos Mitigation\",\"\")\n| where isnotempty(threat)\n| summarize Count=count() by ClientRequestURI_s | project-rename ClientRequestURI=ClientRequestURI_s",
|
||||
"size": 0,
|
||||
"title": "Top Threat URIs",
|
||||
"timeContext": {
|
||||
"durationMs": 0
|
||||
},
|
||||
"timeContextFromParameter": "TimeRange",
|
||||
"queryType": 0,
|
||||
"resourceType": "microsoft.operationalinsights/workspaces",
|
||||
"visualization": "table",
|
||||
"tileSettings": {
|
||||
"titleContent": {
|
||||
"columnMatch": "title",
|
||||
"formatter": 1
|
||||
},
|
||||
"leftContent": {
|
||||
"columnMatch": "Count",
|
||||
"formatter": 12,
|
||||
"formatOptions": {
|
||||
"palette": "auto"
|
||||
},
|
||||
"numberFormat": {
|
||||
"unit": 17,
|
||||
"options": {
|
||||
"maximumSignificantDigits": 3,
|
||||
"maximumFractionDigits": 2
|
||||
}
|
||||
}
|
||||
},
|
||||
"showBorder": false,
|
||||
"sortCriteriaField": "Count",
|
||||
"sortOrderField": 2,
|
||||
"size": "auto"
|
||||
}
|
||||
},
|
||||
"conditionalVisibility": {
|
||||
"parameterName": "tab",
|
||||
"comparison": "isEqualTo",
|
||||
"value": "cloudflare_security_overview"
|
||||
},
|
||||
"customWidth": "33",
|
||||
"name": "Top Threat URIs"
|
||||
},
|
||||
{
|
||||
"type": 3,
|
||||
"content": {
|
||||
"version": "KqlItem/1.0",
|
||||
"query": "Cloudflare_CL \n| extend threat=case(EdgePathingSrc_s ==\"user\" and EdgePathingOp_s == \"ban\" and EdgePathingStatus_s has \"ip\" ,\"IP Block\",EdgePathingSrc_s==\"user\" and EdgePathingOp_s==\"ban\" and EdgePathingStatus_s==\"ctry\",\"Country Block\",EdgePathingSrc_s==\"user\" and EdgePathingOp_s==\"ban\" and EdgePathingStatus_s==\"zl\", \"Routed by Zone Lockdown\", EdgePathingSrc_s==\"user\" and EdgePathingOp_s==\"ban\" and EdgePathingStatus_s==\"ua\", \"Blocked User Agent\", EdgePathingSrc_s==\"user\" and EdgePathingOp_s==\"ban\" and EdgePathingStatus_s==\"rateLimit\", \"Blocked by Rate Limiting\", EdgePathingSrc_s==\"filterBasedFirewall\" and EdgePathingOp_s==\"ban\" and EdgePathingStatus_s==\"unknown\", \"Blocked by Filter Based Firewall\", EdgePathingSrc_s==\"filterBasedFirewall\" and EdgePathingOp_s==\"chl\", \"Challenged by Filter Based Firewall\", EdgePathingSrc_s==\"bic\" and EdgePathingOp_s==\"ban\" and EdgePathingStatus_s==\"unknown\", \"Browser Integrity Check\", EdgePathingSrc_s==\"hot\" and EdgePathingOp_s==\"ban\" and EdgePathingStatus_s==\"ctry\", \"Blocked Hotlink\", EdgePathingSrc_s==\"hot\" and EdgePathingOp_s==\"ban\" and EdgePathingStatus_s==\"ip\", \"Blocked Hotlink\", EdgePathingSrc_s==\"macro\" and EdgePathingOp_s==\"chl\" and EdgePathingStatus_s==\"captchaErr\", \"CAPTCHA Error\", EdgePathingSrc_s==\"macro\" and EdgePathingOp_s==\"chl\" and EdgePathingStatus_s==\"captchaFail\", \"CAPTCHA Challenge Failed\", EdgePathingSrc_s==\"macro\" and EdgePathingOp_s==\"chl\" and EdgePathingStatus_s==\"captchaNew\", \"New CAPTCHA\", EdgePathingSrc_s==\"macro\" and EdgePathingOp_s==\"chl\" and EdgePathingStatus_s==\"jschlErr\", \"Java Script Challenge Error\", EdgePathingSrc_s==\"macro\" and EdgePathingOp_s==\"chl\" and EdgePathingStatus_s==\"jschlFail\", \"Java Script Challenge Failed\", EdgePathingSrc_s==\"macro\" and EdgePathingOp_s==\"chl\" and EdgePathingStatus_s==\"jschlNew\", \"New Java Script Challenge\", EdgePathingSrc_s==\"protect\" and EdgePathingOp_s==\"ban\" and EdgePathingStatus_s==\"17ddos\", \"L7 DDos Mitigation\",\"\")\n| where isnotempty(threat)\n| summarize Count=count() by ClientRequestUserAgent_s | project-rename ClientRequestUserAgent=ClientRequestUserAgent_s",
|
||||
"size": 0,
|
||||
"title": "Top Threat User Agents",
|
||||
"timeContext": {
|
||||
"durationMs": 0
|
||||
},
|
||||
"timeContextFromParameter": "TimeRange",
|
||||
"queryType": 0,
|
||||
"resourceType": "microsoft.operationalinsights/workspaces",
|
||||
"visualization": "table",
|
||||
"tileSettings": {
|
||||
"titleContent": {
|
||||
"columnMatch": "title",
|
||||
"formatter": 1
|
||||
},
|
||||
"leftContent": {
|
||||
"columnMatch": "Count",
|
||||
"formatter": 12,
|
||||
"formatOptions": {
|
||||
"palette": "auto"
|
||||
},
|
||||
"numberFormat": {
|
||||
"unit": 17,
|
||||
"options": {
|
||||
"maximumSignificantDigits": 3,
|
||||
"maximumFractionDigits": 2
|
||||
}
|
||||
}
|
||||
},
|
||||
"showBorder": false,
|
||||
"sortCriteriaField": "Count",
|
||||
"sortOrderField": 2,
|
||||
"size": "auto"
|
||||
}
|
||||
},
|
||||
"conditionalVisibility": {
|
||||
"parameterName": "tab",
|
||||
"comparison": "isEqualTo",
|
||||
"value": "cloudflare_security_overview"
|
||||
},
|
||||
"customWidth": "33",
|
||||
"name": "Top Threat User Agents"
|
||||
},
|
||||
{
|
||||
"type": 3,
|
||||
"content": {
|
||||
"version": "KqlItem/1.0",
|
||||
"query": "Cloudflare_CL \n| extend threat=case(EdgePathingSrc_s ==\"user\" and EdgePathingOp_s == \"ban\" and EdgePathingStatus_s has \"ip\" ,\"IP Block\",EdgePathingSrc_s==\"user\" and EdgePathingOp_s==\"ban\" and EdgePathingStatus_s==\"ctry\",\"Country Block\",EdgePathingSrc_s==\"user\" and EdgePathingOp_s==\"ban\" and EdgePathingStatus_s==\"zl\", \"Routed by Zone Lockdown\", EdgePathingSrc_s==\"user\" and EdgePathingOp_s==\"ban\" and EdgePathingStatus_s==\"ua\", \"Blocked User Agent\", EdgePathingSrc_s==\"user\" and EdgePathingOp_s==\"ban\" and EdgePathingStatus_s==\"rateLimit\", \"Blocked by Rate Limiting\", EdgePathingSrc_s==\"filterBasedFirewall\" and EdgePathingOp_s==\"ban\" and EdgePathingStatus_s==\"unknown\", \"Blocked by Filter Based Firewall\", EdgePathingSrc_s==\"filterBasedFirewall\" and EdgePathingOp_s==\"chl\", \"Challenged by Filter Based Firewall\", EdgePathingSrc_s==\"bic\" and EdgePathingOp_s==\"ban\" and EdgePathingStatus_s==\"unknown\", \"Browser Integrity Check\", EdgePathingSrc_s==\"hot\" and EdgePathingOp_s==\"ban\" and EdgePathingStatus_s==\"ctry\", \"Blocked Hotlink\", EdgePathingSrc_s==\"hot\" and EdgePathingOp_s==\"ban\" and EdgePathingStatus_s==\"ip\", \"Blocked Hotlink\", EdgePathingSrc_s==\"macro\" and EdgePathingOp_s==\"chl\" and EdgePathingStatus_s==\"captchaErr\", \"CAPTCHA Error\", EdgePathingSrc_s==\"macro\" and EdgePathingOp_s==\"chl\" and EdgePathingStatus_s==\"captchaFail\", \"CAPTCHA Challenge Failed\", EdgePathingSrc_s==\"macro\" and EdgePathingOp_s==\"chl\" and EdgePathingStatus_s==\"captchaNew\", \"New CAPTCHA\", EdgePathingSrc_s==\"macro\" and EdgePathingOp_s==\"chl\" and EdgePathingStatus_s==\"jschlErr\", \"Java Script Challenge Error\", EdgePathingSrc_s==\"macro\" and EdgePathingOp_s==\"chl\" and EdgePathingStatus_s==\"jschlFail\", \"Java Script Challenge Failed\", EdgePathingSrc_s==\"macro\" and EdgePathingOp_s==\"chl\" and EdgePathingStatus_s==\"jschlNew\", \"New Java Script Challenge\", EdgePathingSrc_s==\"protect\" and EdgePathingOp_s==\"ban\" and EdgePathingStatus_s==\"17ddos\", \"L7 DDos Mitigation\",\"\")\n| where isnotempty(threat)\n| summarize Count=count() by EdgePathingStatus_s | project-rename EdgePathingStatus=EdgePathingStatus_s",
|
||||
"size": 0,
|
||||
"title": "Top Threat User Agents",
|
||||
"timeContext": {
|
||||
"durationMs": 0
|
||||
},
|
||||
"timeContextFromParameter": "TimeRange",
|
||||
"queryType": 0,
|
||||
"resourceType": "microsoft.operationalinsights/workspaces",
|
||||
"visualization": "table",
|
||||
"tileSettings": {
|
||||
"titleContent": {
|
||||
"columnMatch": "title",
|
||||
"formatter": 1
|
||||
},
|
||||
"leftContent": {
|
||||
"columnMatch": "Count",
|
||||
"formatter": 12,
|
||||
"formatOptions": {
|
||||
"palette": "auto"
|
||||
},
|
||||
"numberFormat": {
|
||||
"unit": 17,
|
||||
"options": {
|
||||
"maximumSignificantDigits": 3,
|
||||
"maximumFractionDigits": 2
|
||||
}
|
||||
}
|
||||
},
|
||||
"showBorder": false,
|
||||
"sortCriteriaField": "Count",
|
||||
"sortOrderField": 2,
|
||||
"size": "auto"
|
||||
}
|
||||
},
|
||||
"conditionalVisibility": {
|
||||
"parameterName": "tab",
|
||||
"comparison": "isEqualTo",
|
||||
"value": "cloudflare_security_overview"
|
||||
},
|
||||
"customWidth": "33",
|
||||
"name": "Top Threat User Agents - Copy"
|
||||
},
|
||||
{
|
||||
"type": 3,
|
||||
"content": {
|
||||
"version": "KqlItem/1.0",
|
||||
"query": "let 5xx = Cloudflare_CL \n| where tostring(EdgeResponseStatus_d) startswith \"5\"\n| summarize Count=count()\n| extend title=\"5xx Errors (Edge)\";\n\nlet 4xx = Cloudflare_CL \n| where tostring(EdgeResponseStatus_d) startswith \"4\"\n| summarize Count=count()\n| extend title=\"4xx Errors (Edge)\";\n\nlet 3xx = Cloudflare_CL \n| where tostring(EdgeResponseStatus_d) startswith \"3\"\n| summarize Count=count()\n| extend title=\"3xx Errors (Edge)\";\n\nlet result_table = union 5xx, 4xx, 3xx; \nresult_table \n| sort by Count\n\n",
|
||||
"size": 0,
|
||||
"title": "ERRORS Counts (Edge)",
|
||||
"timeContext": {
|
||||
"durationMs": 0
|
||||
},
|
||||
"timeContextFromParameter": "TimeRange",
|
||||
"queryType": 0,
|
||||
"resourceType": "microsoft.operationalinsights/workspaces",
|
||||
"visualization": "tiles",
|
||||
"tileSettings": {
|
||||
"showBorder": false,
|
||||
"titleContent": {
|
||||
"columnMatch": "title",
|
||||
"formatter": 1
|
||||
},
|
||||
"leftContent": {
|
||||
"columnMatch": "Count",
|
||||
"formatter": 12,
|
||||
"formatOptions": {
|
||||
"palette": "auto"
|
||||
},
|
||||
"numberFormat": {
|
||||
"unit": 17,
|
||||
"options": {
|
||||
"maximumSignificantDigits": 3,
|
||||
"maximumFractionDigits": 2
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"conditionalVisibility": {
|
||||
"parameterName": "tab",
|
||||
"comparison": "isEqualTo",
|
||||
"value": "cloudflare_reliability_summary"
|
||||
},
|
||||
"customWidth": "33",
|
||||
"name": "Errors (Edge)"
|
||||
},
|
||||
{
|
||||
"type": 3,
|
||||
"content": {
|
||||
"version": "KqlItem/1.0",
|
||||
"query": "Cloudflare_CL \n| extend response_error_type= case(tostring(EdgeResponseStatus_d) startswith \"2\" , \"2xx\", tostring(EdgeResponseStatus_d) startswith \"3\" , \"3xx\", tostring(EdgeResponseStatus_d) startswith \"4\" , \"4xx\", tostring(EdgeResponseStatus_d) startswith \"5\" , \"5xx\",\"\")\n| where isnotempty(response_error_type)\n| summarize Count=count() by response_error_type",
|
||||
"size": 0,
|
||||
"title": "Edge Response Error Ratio",
|
||||
"timeContext": {
|
||||
"durationMs": 0
|
||||
},
|
||||
"timeContextFromParameter": "TimeRange",
|
||||
"queryType": 0,
|
||||
"resourceType": "microsoft.operationalinsights/workspaces",
|
||||
"visualization": "piechart",
|
||||
"tileSettings": {
|
||||
"showBorder": false,
|
||||
"titleContent": {
|
||||
"columnMatch": "title",
|
||||
"formatter": 1
|
||||
},
|
||||
"leftContent": {
|
||||
"columnMatch": "Count",
|
||||
"formatter": 12,
|
||||
"formatOptions": {
|
||||
"palette": "auto"
|
||||
},
|
||||
"numberFormat": {
|
||||
"unit": 17,
|
||||
"options": {
|
||||
"maximumSignificantDigits": 3,
|
||||
"maximumFractionDigits": 2
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"conditionalVisibility": {
|
||||
"parameterName": "tab",
|
||||
"comparison": "isEqualTo",
|
||||
"value": "cloudflare_reliability_summary"
|
||||
},
|
||||
"customWidth": "33",
|
||||
"name": "Edge Response Error Ratio"
|
||||
},
|
||||
{
|
||||
"type": 3,
|
||||
"content": {
|
||||
"version": "KqlItem/1.0",
|
||||
"query": "Cloudflare_CL \n| extend response_error_type= case(tostring(OriginResponseStatus_d) startswith \"2\" , \"2xx\", tostring(OriginResponseStatus_d) startswith \"3\" , \"3xx\", tostring(OriginResponseStatus_d) startswith \"4\" , \"4xx\", tostring(OriginResponseStatus_d) startswith \"5\" , \"5xx\",\"\")\n| where isnotempty(response_error_type)\n| summarize Count=count() by response_error_type",
|
||||
"size": 0,
|
||||
"title": "Origin Response Error Ratio",
|
||||
"timeContext": {
|
||||
"durationMs": 0
|
||||
},
|
||||
"timeContextFromParameter": "TimeRange",
|
||||
"queryType": 0,
|
||||
"resourceType": "microsoft.operationalinsights/workspaces",
|
||||
"visualization": "piechart",
|
||||
"tileSettings": {
|
||||
"showBorder": false,
|
||||
"titleContent": {
|
||||
"columnMatch": "title",
|
||||
"formatter": 1
|
||||
},
|
||||
"leftContent": {
|
||||
"columnMatch": "Count",
|
||||
"formatter": 12,
|
||||
"formatOptions": {
|
||||
"palette": "auto"
|
||||
},
|
||||
"numberFormat": {
|
||||
"unit": 17,
|
||||
"options": {
|
||||
"maximumSignificantDigits": 3,
|
||||
"maximumFractionDigits": 2
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"conditionalVisibility": {
|
||||
"parameterName": "tab",
|
||||
"comparison": "isEqualTo",
|
||||
"value": "cloudflare_reliability_summary"
|
||||
},
|
||||
"customWidth": "33",
|
||||
"name": "Origin Response Error Ratio"
|
||||
},
|
||||
{
|
||||
"type": 3,
|
||||
"content": {
|
||||
"version": "KqlItem/1.0",
|
||||
"query": "Cloudflare_CL \n| extend response_error_type= case(tostring(EdgeResponseStatus_d) startswith \"2\" , \"2xx\", tostring(EdgeResponseStatus_d) startswith \"3\" , \"3xx\", tostring(EdgeResponseStatus_d) startswith \"4\" , \"4xx\", tostring(EdgeResponseStatus_d) startswith \"5\" , \"5xx\",\"\")\n| where isnotempty(response_error_type)\n| make-series Trend = count() on TimeGenerated from {TimeRange:start} to {TimeRange:end} step {TimeRange:grain} by response_error_type;",
|
||||
"size": 0,
|
||||
"title": "Edge Response Status Over Time",
|
||||
"timeContext": {
|
||||
"durationMs": 0
|
||||
},
|
||||
"timeContextFromParameter": "TimeRange",
|
||||
"queryType": 0,
|
||||
"resourceType": "microsoft.operationalinsights/workspaces",
|
||||
"visualization": "timechart",
|
||||
"tileSettings": {
|
||||
"showBorder": false,
|
||||
"titleContent": {
|
||||
"columnMatch": "title",
|
||||
"formatter": 1
|
||||
},
|
||||
"leftContent": {
|
||||
"columnMatch": "Count",
|
||||
"formatter": 12,
|
||||
"formatOptions": {
|
||||
"palette": "auto"
|
||||
},
|
||||
"numberFormat": {
|
||||
"unit": 17,
|
||||
"options": {
|
||||
"maximumSignificantDigits": 3,
|
||||
"maximumFractionDigits": 2
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"conditionalVisibility": {
|
||||
"parameterName": "tab",
|
||||
"comparison": "isEqualTo",
|
||||
"value": "cloudflare_reliability_summary"
|
||||
},
|
||||
"customWidth": "50",
|
||||
"name": "Edge Response Status Over Time"
|
||||
},
|
||||
{
|
||||
"type": 3,
|
||||
"content": {
|
||||
"version": "KqlItem/1.0",
|
||||
"query": "Cloudflare_CL \n| extend response_error_type= case(tostring(OriginResponseStatus_d) startswith \"2\" , \"2xx\", tostring(OriginResponseStatus_d) startswith \"3\" , \"3xx\", tostring(OriginResponseStatus_d) startswith \"4\" , \"4xx\", tostring(OriginResponseStatus_d) startswith \"5\" , \"5xx\",\"\")\n| where isnotempty(response_error_type)\n| make-series Trend = count() on TimeGenerated from {TimeRange:start} to {TimeRange:end} step {TimeRange:grain} by response_error_type;",
|
||||
"size": 0,
|
||||
"title": "Origin Response Status Over Time",
|
||||
"timeContext": {
|
||||
"durationMs": 0
|
||||
},
|
||||
"timeContextFromParameter": "TimeRange",
|
||||
"queryType": 0,
|
||||
"resourceType": "microsoft.operationalinsights/workspaces",
|
||||
"visualization": "timechart",
|
||||
"tileSettings": {
|
||||
"showBorder": false,
|
||||
"titleContent": {
|
||||
"columnMatch": "title",
|
||||
"formatter": 1
|
||||
},
|
||||
"leftContent": {
|
||||
"columnMatch": "Count",
|
||||
"formatter": 12,
|
||||
"formatOptions": {
|
||||
"palette": "auto"
|
||||
},
|
||||
"numberFormat": {
|
||||
"unit": 17,
|
||||
"options": {
|
||||
"maximumSignificantDigits": 3,
|
||||
"maximumFractionDigits": 2
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"conditionalVisibility": {
|
||||
"parameterName": "tab",
|
||||
"comparison": "isEqualTo",
|
||||
"value": "cloudflare_reliability_summary"
|
||||
},
|
||||
"customWidth": "50",
|
||||
"name": "Origin Response Status Over Time"
|
||||
}
|
||||
],
|
||||
"fallbackResourceIds": [],
|
||||
"fromTemplateId": "sentinel-CloudflareWorkbook",
|
||||
"$schema": "https://github.com/Microsoft/Application-Insights-Workbooks/blob/master/schema/workbook.json"
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
<svg width="75" height="75" viewBox="0 0 75 75" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M57.9129 36.0524L56.4192 35.4482C49.3989 51.4259 21.471 41.7122 19.7906 46.4654C19.5104 49.676 35.0419 47.0759 46.1454 47.6201C49.5313 47.7859 51.2293 50.3713 49.7915 54.5854L52.6234 54.5942C55.8901 44.2933 66.3155 49.5503 66.7512 46.1507C66.0354 43.9155 54.7696 46.1507 57.9129 36.0524Z" fill="white"/>
|
||||
<path d="M50.5934 52.8234C51.0414 51.3125 50.8921 49.8016 50.1453 48.895C49.3983 47.9883 48.3527 47.3841 47.0083 47.233L21.0166 46.9306C20.8672 46.9306 20.7179 46.7796 20.5685 46.7796C20.4192 46.6285 20.4192 46.4775 20.5685 46.3264C20.7179 46.0243 20.8672 45.8729 21.1659 45.8729L47.307 45.5708C50.444 45.4198 53.7304 42.8512 54.9252 39.8294L56.4192 35.901C56.4192 35.7496 56.5685 35.5986 56.4192 35.4475C54.7758 27.7417 47.9046 22 39.8381 22C32.3692 22 25.946 26.8351 23.7053 33.6345C22.2116 32.5768 20.4192 31.9723 18.3278 32.1236C14.7427 32.4257 11.9046 35.4475 11.4563 39.0738C11.307 39.9804 11.4563 40.8871 11.6059 41.7935C5.78012 41.9445 1 46.7796 1 52.8234C1 53.4277 1 53.8811 1.14934 54.4854C1.14934 54.7878 1.44803 54.9388 1.59766 54.9388H49.5477C49.8464 54.9388 50.1453 54.7878 50.1453 54.4854L50.5934 52.8234Z" fill="#F4811F"/>
|
||||
<path d="M58.8091 35.9013H58.0621C57.9128 35.9013 57.7635 36.0524 57.6141 36.2034L56.5684 39.8298C56.1204 41.3406 56.2697 42.8518 57.0167 43.7582C57.7634 44.6648 58.8091 45.2691 60.1535 45.4204L65.6806 45.7225C65.83 45.7225 65.9793 45.8736 66.1287 45.8736C66.278 46.0246 66.278 46.1757 66.1287 46.3268C65.9793 46.6292 65.83 46.7802 65.531 46.7802L59.8548 47.0824C56.7178 47.2334 53.4316 49.802 52.2366 52.8238L51.9376 54.1839C51.7883 54.335 51.9376 54.6371 52.2366 54.6371H71.9545C72.2532 54.6371 72.4025 54.486 72.4025 54.1839C72.7012 52.9751 72.9999 51.6153 72.9999 50.2552C72.9999 42.3983 66.5767 35.9013 58.8091 35.9013Z" fill="#FAAD3F"/>
|
||||
</svg>
|
После Ширина: | Высота: | Размер: 1.9 KiB |
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 55 KiB |
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 38 KiB |
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 56 KiB |
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 44 KiB |
|
@ -1322,5 +1322,18 @@
|
|||
"templateRelativePath": "pfsense.json",
|
||||
"subtitle": "",
|
||||
"provider": "Azure Sentinel community"
|
||||
},
|
||||
{
|
||||
"workbookKey": "CloudflareWorkbook",
|
||||
"logoFileName": "cloudflare.svg",
|
||||
"description": "Gain insights into Cloudflare events. You will get visibility on your Cloudflare web traffic, security, reliability.",
|
||||
"dataTypesDependencies": [ "Cloudflare_CL" ],
|
||||
"dataConnectorsDependencies": [ "CloudflareDataConnector" ],
|
||||
"previewImagesFileNames": ["CloudflareOverviewWhite01.png", "CloudflareOverviewWhite02.png", "CloudflareOverviewBlack01.png", "CloudflareOverviewBlack02.png"],
|
||||
"version": "1.0",
|
||||
"title": "Cloudflare",
|
||||
"templateRelativePath": "Cloudflare.json",
|
||||
"subtitle": "",
|
||||
"provider": "Cloudflare"
|
||||
}
|
||||
]
|
||||
|
|
Загрузка…
Ссылка в новой задаче