Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

OCSF Mappings for OpenSearch #202

Merged
merged 66 commits into from
Jan 15, 2025
Merged
Changes from 1 commit
Commits
Show all changes
66 commits
Select commit Hold shift + click to select a range
4dcc128
Docker applicative network name getting started docker (#193)
YANG-DB Aug 8, 2024
e35f378
Update README.md (#187)
YANG-DB Aug 8, 2024
12c65cd
first commit
Kevlw-AWS Aug 28, 2024
1c5514e
first commit
Kevlw-AWS Aug 28, 2024
a59669d
aDded ocsf stuff
Kevlw-AWS Aug 28, 2024
032f919
added init scripts and templates pointing to aliases
Kevlw-AWS Aug 28, 2024
4535940
fixed init scripts
Kevlw-AWS Aug 30, 2024
54a75c6
created init script
Kevlw-AWS Aug 30, 2024
6bbea6a
modified init scriot
Kevlw-AWS Aug 30, 2024
163627d
made some changes
Kevlw-AWS Sep 1, 2024
b70bf5f
changed init script to put ISM policy first so that it will be associ…
Kevlw-AWS Sep 2, 2024
49fa489
Update OSI-pipeline.yaml
kffallis Sep 10, 2024
bf95cd7
minor changes for shard counts
kffallis Sep 20, 2024
adb9b10
added readme and json file for integration
Kevlw-AWS Sep 23, 2024
3aa9579
fixed init script
Kevlw-AWS Sep 24, 2024
111e1df
updated readme
Kevlw-AWS Sep 25, 2024
5a9749b
added ndjson
Kevlw-AWS Sep 25, 2024
bd1b4b0
Bump org.json:json (#186)
dependabot[bot] Sep 6, 2024
2982600
modified readme
Kevlw-AWS Sep 30, 2024
184fc9d
added the cfn scripts
Kevlw-AWS Oct 2, 2024
0962304
added zip files
Kevlw-AWS Oct 2, 2024
1155658
changed shard count to 1
Kevlw-AWS Oct 2, 2024
0051d4c
modified mappings
Kevlw-AWS Oct 2, 2024
ade8a8e
fixed 5001
Kevlw-AWS Oct 2, 2024
ed595ad
added modified init scripts
Kevlw-AWS Oct 5, 2024
a1141f6
fixed init python function to work in lambda
Kevlw-AWS Oct 7, 2024
765ad1c
got the init function working
Kevlw-AWS Oct 8, 2024
ea81320
standardised index templates with index.number of XX"
Kevlw-AWS Oct 8, 2024
d06ff8b
standardised the index templates with .index.number of xxx
Kevlw-AWS Oct 8, 2024
2c4eaab
updated mappings and readme
Kevlw-AWS Oct 29, 2024
71566c0
fixed readme
Kevlw-AWS Oct 29, 2024
33aaca9
added cfn files
Kevlw-AWS Nov 3, 2024
aade7e8
region parameter removed - thanks Jeremy for pointing it out!
Kevlw-AWS Nov 4, 2024
3823822
Update Security-lake-objects.ndjson
kffallis Nov 8, 2024
c1ff066
fixed unmapped in base-event
Kevlw-AWS Nov 6, 2024
1d5a160
increased doc value fields in index templates to 4000
Kevlw-AWS Nov 6, 2024
4392300
modified saved objects and added two more index patterns
Kevlw-AWS Nov 11, 2024
9429263
updated component templates
Kevlw-AWS Nov 13, 2024
9572826
fixed data - text issues with component templates`
Kevlw-AWS Nov 14, 2024
a47d07a
fixed typos
Kevlw-AWS Nov 14, 2024
62a779f
[Bug Fix] Fix VPC's table creation query (#196)
RyanL1997 Nov 7, 2024
1224312
added unmampped base event
Kevlw-AWS Dec 10, 2024
9b9b42a
made small changes to component and index templates to remove unmappe…
Kevlw-AWS Dec 17, 2024
c215814
fixed OSI-pipeline.yaml
Kevlw-AWS Dec 17, 2024
1072f5f
added init script with basic auth
Kevlw-AWS Dec 18, 2024
bbf10da
cleaned up the scripts folder
Kevlw-AWS Dec 19, 2024
0e39da1
updated OSI pipelines
Kevlw-AWS Dec 19, 2024
7475b34
modified script instructions
Kevlw-AWS Dec 19, 2024
9386637
updated zip files
Kevlw-AWS Dec 20, 2024
0496d44
added readme
Kevlw-AWS Dec 20, 2024
65bcd71
added images
Kevlw-AWS Dec 20, 2024
f5b5a4b
modified images
Kevlw-AWS Dec 20, 2024
1043a69
updated readme
Kevlw-AWS Dec 20, 2024
dbddd2e
updated readme
Kevlw-AWS Dec 20, 2024
ff43e80
updated readme
Kevlw-AWS Dec 20, 2024
113f264
fixed images
Kevlw-AWS Dec 20, 2024
4883c80
added list of classes
Kevlw-AWS Dec 20, 2024
fe028b0
Update readme.md
kffallis Dec 27, 2024
6703d01
updated folder structure to match the rest of the integrations
Kevlw-AWS Dec 27, 2024
be0a7b1
removed DS_store
Kevlw-AWS Dec 27, 2024
7128342
removed .DS_store files from repo
Kevlw-AWS Dec 30, 2024
0451f1e
updated readme with more verbose instructions around instlalation
Kevlw-AWS Dec 30, 2024
f349c37
Merge branch 'opensearch-project:main' into security-lake
Kevlw-AWS Dec 31, 2024
fc4d68a
made changes to conform to integration standard. Integration json sti…
Kevlw-AWS Dec 31, 2024
000b33f
updated format to follow integrations schema. Added OCSF-1.1.0.json f…
Kevlw-AWS Dec 31, 2024
d487b82
modified ocsf.json to work. Requires the mappings from Apache, no clu…
Kevlw-AWS Dec 31, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
added init script with basic auth
Signed-off-by: Kevin Low <kevlw@amazon.com>
Kevlw-AWS committed Dec 27, 2024
commit 1072f5fe0c1864ec7929b35d60788f5793d2ffee
Binary file modified integrations/security/OCSF_1_1_0/.DS_Store
Binary file not shown.
270 changes: 270 additions & 0 deletions integrations/security/OCSF_1_1_0/Init_scripts/os_init_IAM_auth.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,270 @@
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
# Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so.
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

from urllib.parse import urlparse
import boto3
from botocore.exceptions import ClientError
import zipfile
import os
import json
from boto3 import Session
from opensearchpy import AWSV4SignerAuth, OpenSearch, RequestsHttpConnection
from datetime import datetime

## Initialise variables
OSEndpoint = 'ES_ENDPOINT'
region = 'AWS_REGION'
# Specify the bucket and location of the component and index templates
bucket_name = 'SPECIFY THE BUCKET NAME'
component_templates = 'PREFIX/component_templates.zip'
index_templates = 'PREFIX/index_templates.zip'

url = urlparse(OSEndpoint)

credentials = Session().get_credentials()

auth = AWSV4SignerAuth(credentials, region)

client = OpenSearch(
hosts=[{
'host': url.netloc,
'port': url.port or 443
}],
http_auth=auth,
use_ssl=True,
verify_certs=True,
connection_class=RequestsHttpConnection
)
info = client.info()
print(f"{info['version']['distribution']}: {info['version']['number']}")

def ISM_INIT():
## This function creates the ISM policy
ism_policy = {
"policy": {
"policy_id": "rollover-expiration-policy",
"description": "This policy rollsover the index daily or if it reaches 40gb. It also expires logs older than 15 days",
"default_state": "rollover",
"states": [
{
"name": "rollover",
"actions": [
{
"retry": {
"count": 3,
"backoff": "exponential",
"delay": "1h"
},
"rollover": {
"min_size": "40gb",
"min_index_age": "1d",
"copy_alias": False
}
}
],
"transitions": [
{
"state_name": "hot"
}
]
},
{
"name": "hot",
"actions": [],
"transitions": [
{
"state_name": "delete",
"conditions": {
"min_index_age": "15d"
}
}
]
},
{
"name": "delete",
"actions": [
{
"timeout": "5h",
"retry": {
"count": 3,
"backoff": "exponential",
"delay": "1h"
},
"delete": {}
}
],
"transitions": []
}
],
"ism_template": [
{
"index_patterns": [
"ocsf-*"
],
"priority": 9
}
]
}
}
try:
client.plugins.index_management.put_policy(policy = "rollover-expiration-policy", body=ism_policy)
print ("ISM Policy created")
except Exception as e:
print(f"Error creating ISM Policy: {e}")
pass

def alias_init():
index_date = datetime.now().strftime("%Y.%m.%d")
index_list = ["ocsf-1.1.0-2002-vulnerability_finding", "ocsf-1.1.0-2003-compliance_finding", "ocsf-1.1.0-2004-detection_finding", "ocsf-1.1.0-3001-account_change","ocsf-1.1.0-3002-authentication", "ocsf-1.1.0-4001-network_activity","ocsf-1.1.0-4002-http_activity","ocsf-1.1.0-4003-dns_activity","ocsf-1.1.0-6003-api_activity",]
for index in index_list:
# Create the index
try:
index_name = f"<{index}-{{now/d}}-000000>"
client.indices.create(index=index_name, body = {})
print (f"created index {index}")
except Exception as e:
print(f"Error creating {index} index: {e}")
pass

# Create the alias
try:
alias_name = index
alias_index = f"{index}-*"
client.indices.put_alias(index=alias_index, name=alias_name)
print (f"created alias {alias_name}")
except Exception as e:
print(f"Error creating {alias_name} alias: {e}")
pass

## Set the index settings
settings = {
"settings": {
"index": {
"plugins": {
"index_state_management": {
"rollover_alias": f"{index}"
}
}
}
}
}

client.indices.put_settings(index=index_name, body=settings)
print (f"Applied settings to {index_name}")

def install_component_templates():
# Set up the S3 client
s3 = boto3.client('s3')
file_key = component_templates

try:
# Use the get_object API to download the file
response = s3.get_object(Bucket=bucket_name, Key=file_key)

# Get the file content from the response
file_content = response['Body'].read()

# Save the file content to a local file
local_file_path = '/tmp/component_templates.zip'
with open(local_file_path, 'wb') as f:
f.write(file_content)

# Unzip the file
with zipfile.ZipFile(local_file_path, 'r') as zip_ref:
zip_ref.extractall('/tmp')

print(f'File downloaded and unzipped successfully: {file_key}')

for root, dirs, files in os.walk('/tmp/component_templates'):
for file in files:
if file.endswith('_body.json'):
file_path = os.path.join(root, file)
template_name = os.path.splitext(file)[0][:-5] # Remove the "_body" suffix

with open(file_path, 'r') as f:
template_content = json.load(f)

try:
response = client.cluster.put_component_template(name=template_name, body=template_content)
if response['acknowledged']:
print(f'Created component template: {template_name}')
else:
print(f'Error creating component template: {template_name} - {response}')
except Exception as e:
print(f'Error creating component template: {template_name} - {e}')

except ClientError as e:
error_code = e.response['Error']['Code']
if error_code == 'NoSuchKey':
print(f'Error: The file {file_key} does not exist in the bucket {bucket_name}')
else:
print(f'Error downloading file: {e}')

return {
'statusCode': 200,
'body': 'File download complete'
}

def install_index_templates():
# Set up the S3 client
s3 = boto3.client('s3')

# Specify the bucket and file to download
bucket_name = 'SPECIFY THE BUCKET NAME'
file_key = 'PREFIX/index_templates.zip'

try:
# Use the get_object API to download the file
response = s3.get_object(Bucket=bucket_name, Key=file_key)

# Get the file content from the response
file_content = response['Body'].read()

# Save the file content to a local file
local_file_path = '/tmp/index_templates.zip'
with open(local_file_path, 'wb') as f:
f.write(file_content)

# Unzip the file
with zipfile.ZipFile(local_file_path, 'r') as zip_ref:
zip_ref.extractall('/tmp')

print(f'File downloaded and unzipped successfully: {file_key}')

for root, dirs, files in os.walk('/tmp/index_templates'):
for file in files:
if file.endswith('_body.json'):
file_path = os.path.join(root, file)
template_name = os.path.splitext(file)[0][:-5] # Remove the "_body" suffix

with open(file_path, 'r') as f:
template_content = json.load(f)

try:
response = client.indices.put_index_template(name=template_name, body=template_content)
if response['acknowledged']:
print(f'Created index template: {template_name}')
else:
print(f'Error creating index template: {template_name} - {response}')
except Exception as e:
print(f'Error creating index template: {template_name} - {e}')

except ClientError as e:
error_code = e.response['Error']['Code']
if error_code == 'NoSuchKey':
print(f'Error: The file {file_key} does not exist in the bucket {bucket_name}')
else:
print(f'Error downloading file: {e}')

return {
'statusCode': 200,
'body': 'OS Initialisation complete'
}


def lambda_handler(event, context):
install_component_templates()
install_index_templates()
ISM_INIT()
alias_init()
271 changes: 271 additions & 0 deletions integrations/security/OCSF_1_1_0/Init_scripts/os_init_basic_auth.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,271 @@
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
# Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so.
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

from urllib.parse import urlparse
import boto3
from botocore.exceptions import ClientError
import zipfile
import os
import json
from opensearchpy import OpenSearch, RequestsHttpConnection
from datetime import datetime

## Initialise variables
OSEndpoint = 'ES_ENDPOINT'
OS_USERNAME = 'OS_USERNAME'
OS_PASSWORD = 'OS_PASSWORD'
# Specify the bucket and location of the component and index templates
bucket_name = 'SPECIFY THE BUCKET NAME'
component_templates = 'PREFIX/component_templates.zip'
index_templates = 'PREFIX/index_templates.zip'

print(OSEndpoint)
region = os.environ.get('AWS_REGION')
print(region)

url = urlparse(OSEndpoint)

# Modified client configuration to use basic auth
client = OpenSearch(
hosts=[{
'host': url.netloc,
'port': url.port or 443
}],
http_auth=(OS_USERNAME, OS_PASSWORD), # Using basic auth instead of AWS4Auth
use_ssl=True,
verify_certs=True,
connection_class=RequestsHttpConnection
)

info = client.info()
print(f"{info['version']['distribution']}: {info['version']['number']}")

def ISM_INIT():
## This function creates the ISM policy
ism_policy = {
"policy": {
"policy_id": "rollover-expiration-policy",
"description": "This policy rollsover the index daily or if it reaches 40gb. It also expires logs older than 15 days",
"default_state": "rollover",
"states": [
{
"name": "rollover",
"actions": [
{
"retry": {
"count": 3,
"backoff": "exponential",
"delay": "1h"
},
"rollover": {
"min_size": "40gb",
"min_index_age": "1d",
"copy_alias": False
}
}
],
"transitions": [
{
"state_name": "hot"
}
]
},
{
"name": "hot",
"actions": [],
"transitions": [
{
"state_name": "delete",
"conditions": {
"min_index_age": "15d"
}
}
]
},
{
"name": "delete",
"actions": [
{
"timeout": "5h",
"retry": {
"count": 3,
"backoff": "exponential",
"delay": "1h"
},
"delete": {}
}
],
"transitions": []
}
],
"ism_template": [
{
"index_patterns": [
"ocsf-*"
],
"priority": 9
}
]
}
}
try:
client.plugins.index_management.put_policy(policy = "rollover-expiration-policy", body=ism_policy)
print ("ISM Policy created")
except Exception as e:
print(f"Error creating ISM Policy: {e}")
pass

def alias_init():
index_date = datetime.now().strftime("%Y.%m.%d")
index_list = ["ocsf-1.1.0-2002-vulnerability_finding", "ocsf-1.1.0-2003-compliance_finding", "ocsf-1.1.0-2004-detection_finding", "ocsf-1.1.0-3001-account_change","ocsf-1.1.0-3002-authentication", "ocsf-1.1.0-4001-network_activity","ocsf-1.1.0-4002-http_activity","ocsf-1.1.0-4003-dns_activity","ocsf-1.1.0-6003-api_activity",]
for index in index_list:
# Create the index
try:
index_name = f"<{index}-{{now/d}}-000000>"
client.indices.create(index=index_name, body = {})
print (f"created index {index}")
except Exception as e:
print(f"Error creating {index} index: {e}")
pass

# Create the alias
try:
alias_name = index
alias_index = f"{index}-*"
client.indices.put_alias(index=alias_index, name=alias_name)
print (f"created alias {alias_name}")
except Exception as e:
print(f"Error creating {alias_name} alias: {e}")
pass

## Set the index settings
settings = {
"settings": {
"index": {
"plugins": {
"index_state_management": {
"rollover_alias": f"{index}"
}
}
}
}
}

client.indices.put_settings(index=index_name, body=settings)
print (f"Applied settings to {index_name}")

def install_component_templates():
# Set up the S3 client
s3 = boto3.client('s3')
file_key = component_templates

try:
# Use the get_object API to download the file
response = s3.get_object(Bucket=bucket_name, Key=file_key)

# Get the file content from the response
file_content = response['Body'].read()

# Save the file content to a local file
local_file_path = '/tmp/component_templates.zip'
with open(local_file_path, 'wb') as f:
f.write(file_content)

# Unzip the file
with zipfile.ZipFile(local_file_path, 'r') as zip_ref:
zip_ref.extractall('/tmp')

print(f'File downloaded and unzipped successfully: {file_key}')

for root, dirs, files in os.walk('/tmp/component_templates'):
for file in files:
if file.endswith('_body.json'):
file_path = os.path.join(root, file)
template_name = os.path.splitext(file)[0][:-5] # Remove the "_body" suffix

with open(file_path, 'r') as f:
template_content = json.load(f)

try:
response = client.cluster.put_component_template(name=template_name, body=template_content)
if response['acknowledged']:
print(f'Created component template: {template_name}')
else:
print(f'Error creating component template: {template_name} - {response}')
except Exception as e:
print(f'Error creating component template: {template_name} - {e}')

except ClientError as e:
error_code = e.response['Error']['Code']
if error_code == 'NoSuchKey':
print(f'Error: The file {file_key} does not exist in the bucket {bucket_name}')
else:
print(f'Error downloading file: {e}')

return {
'statusCode': 200,
'body': 'File download complete'
}

def install_index_templates():
# Set up the S3 client
s3 = boto3.client('s3')

# Specify the bucket and location of the component templates
file_key = index_templates

try:
# Use the get_object API to download the file
response = s3.get_object(Bucket=bucket_name, Key=file_key)

# Get the file content from the response
file_content = response['Body'].read()

# Save the file content to a local file
local_file_path = '/tmp/index_templates.zip'
with open(local_file_path, 'wb') as f:
f.write(file_content)

# Unzip the file
with zipfile.ZipFile(local_file_path, 'r') as zip_ref:
zip_ref.extractall('/tmp')

print(f'File downloaded and unzipped successfully: {file_key}')

for root, dirs, files in os.walk('/tmp/index_templates'):
for file in files:
if file.endswith('_body.json'):
file_path = os.path.join(root, file)
template_name = os.path.splitext(file)[0][:-5] # Remove the "_body" suffix

with open(file_path, 'r') as f:
template_content = json.load(f)

try:
response = client.indices.put_index_template(name=template_name, body=template_content)
if response['acknowledged']:
print(f'Created index template: {template_name}')
else:
print(f'Error creating index template: {template_name} - {response}')
except Exception as e:
print(f'Error creating index template: {template_name} - {e}')

except ClientError as e:
error_code = e.response['Error']['Code']
if error_code == 'NoSuchKey':
print(f'Error: The file {file_key} does not exist in the bucket {bucket_name}')
else:
print(f'Error downloading file: {e}')

return {
'statusCode': 200,
'body': 'OS Initialisation complete'
}


def lambda_handler(event, context):
install_component_templates()
install_index_templates()
ISM_INIT()
alias_init()