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

Implement RBAC index templates #303

Open
wants to merge 38 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 37 commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
dc33ed9
Add roles ECS reference
QU3B1M Mar 6, 2025
a1124e0
Add users ECS reference
QU3B1M Mar 6, 2025
2cc6cd5
Add role ECS mapping and template settings
QU3B1M Mar 6, 2025
769ef71
Add users ECS mapping and template settings
QU3B1M Mar 6, 2025
4c04afe
Add new ECS definitions to script mapping
QU3B1M Mar 6, 2025
a74546a
Fix ECS templates generator script
QU3B1M Mar 6, 2025
3f51e5d
Check ECS templates dir exist and create when not
QU3B1M Mar 6, 2025
b6fd528
Make roles ECS custom fields non-top level
QU3B1M Mar 6, 2025
1c558d1
Add description to custom ECS fields
QU3B1M Mar 6, 2025
8ebf9fc
Make policy and rule custom ECS fields as root level
QU3B1M Mar 6, 2025
e86b72b
Remove id as query default field
QU3B1M Mar 6, 2025
aebe53a
Rename rule and policy objects to avoid naming conflicts
QU3B1M Mar 6, 2025
d6757bf
Add role events generator
QU3B1M Mar 6, 2025
912a358
Update ECS templates for modified modules: roles states-vulnerabiliti…
wazuh-devel-xdrsiem-indexer Mar 6, 2025
316c65f
Add event generator script for user mappings
QU3B1M Mar 6, 2025
d4ec5af
Add rules and policies ECS mappings and custom fields definitions
QU3B1M Mar 6, 2025
59b68b7
Add new rules and policies index templates to ECS generation script
QU3B1M Mar 6, 2025
917c8dc
Update ECS templates for modified modules: policies roles rules state…
wazuh-devel-xdrsiem-indexer Mar 6, 2025
ed2cc8a
Update default query filter for roles index
QU3B1M Mar 6, 2025
93bd87a
Update ECS templates for modified modules: policies roles rules state…
wazuh-devel-xdrsiem-indexer Mar 6, 2025
8cbf846
Update changelog
QU3B1M Mar 7, 2025
f1fa4ac
Merge branch 'main' into enhancement/288-rbac-index-templates
QU3B1M Mar 7, 2025
dfedbc4
Add custom fields to user ECS definition
QU3B1M Mar 12, 2025
6450971
Unify rules, roles, policies and user ECS definitions
QU3B1M Mar 12, 2025
ae4b7a7
Update ECS templates for modified modules: users
wazuh-devel-xdrsiem-indexer Mar 12, 2025
088d9a9
Remove deprecated templates
QU3B1M Mar 12, 2025
b990940
Improve fields descriptions
QU3B1M Mar 12, 2025
140b9b2
Update query default field setting
QU3B1M Mar 12, 2025
155d787
Update ECS templates for modified modules: users
wazuh-devel-xdrsiem-indexer Mar 12, 2025
5c9b826
Update event generator
QU3B1M Mar 12, 2025
9cbbd1e
Update setup plugin to automatically generate the user indices with i…
QU3B1M Mar 12, 2025
6531b69
Rename hidden index to .internal-users
QU3B1M Mar 12, 2025
fc533ff
Update ECS templates for modified modules: users
wazuh-devel-xdrsiem-indexer Mar 12, 2025
14eda50
Remove references to deprecated mappings
QU3B1M Mar 12, 2025
ff688f0
Merge branch 'main' into enhancement/288-rbac-index-templates
QU3B1M Mar 12, 2025
a44b910
Fix body field
QU3B1M Mar 12, 2025
6daa91c
Update ECS templates for modified modules: users
wazuh-devel-xdrsiem-indexer Mar 12, 2025
05865a2
Simplify hidden setting implementation on .internal-users template
QU3B1M Mar 13, 2025
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
5 changes: 4 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
## [Unreleased 5.0.x]

### Added
- Internal and custom Users ECS mappings and index templates with its corresponding event generator. (#288).

### Dependencies

Expand All @@ -19,7 +20,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
### Removed

### Fixed
- Add a validation to the order of the action arguments to force action.name to come before action.arg so that they can always be validated. (#260).

- Error on `generate-and-push-templates.sh` script when index template file does not exist on setup plugin resources. (#288).
- Add a validation to the order of the action arguments to force action.name to come before action.arg so that they can always be validated. (#260).

### Security

Expand Down
2 changes: 1 addition & 1 deletion ecs/generator/mapping-generator.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@ services:
volumes:
- ${REPO_PATH:-.}/ecs:/source/ecs
environment:
- ECS_MODULE=${ECS_MODULE}
- ECS_MODULE=${ECS_MODULE:-""}
7 changes: 6 additions & 1 deletion ecs/scripts/generate-and-push-templates.sh
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ detect_modified_modules() {
[states-inventory-scheduled-commands]="index-template-scheduled-commands.json"
[states-inventory-system]="index-template-system.json"
[states-vulnerabilities]="index-template-vulnerabilities.json"
[users]="index-template-users.json"
)

relevant_modules=()
Expand Down Expand Up @@ -118,6 +119,7 @@ configure_git() {
chmod 644 ~/.ssh/id_ed25519_bot.pub

# Setup commit signing
eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_ed25519_bot
git config --global gpg.format ssh
git config --global commit.gpgsign true
Expand Down Expand Up @@ -146,6 +148,10 @@ commit_and_push_changes() {
cp "$CURRENT_PATH/ecs/$ecs_module/$MAPPINGS_SUBPATH" "$OUTPUT_PATH/$target_file"
# Copy the template to the plugins repository
echo " - Copy template for module '$ecs_module' to '$target_file'"
# If the target file does not exist, create it.
if [ ! -f "$TEMPLATES_PATH/$target_file" ]; then
touch "$TEMPLATES_PATH/$target_file"
fi
cp "$CURRENT_PATH/ecs/$ecs_module/$MAPPINGS_SUBPATH" "$TEMPLATES_PATH/$target_file"
done

Expand Down Expand Up @@ -250,7 +256,6 @@ main() {
validate_dependencies
detect_modified_modules
run_ecs_generator # Exit if no changes on relevant modules.
clone_target_repo
commit_and_push_changes # Exit if no changes detected.
create_or_update_pr
}
Expand Down
131 changes: 131 additions & 0 deletions ecs/users/event-generator/event_generator.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
import argparse
import datetime
import json
import logging
import random
import requests
import urllib3
import uuid

LOG_FILE = 'generate_data.log'
GENERATED_DATA_FILE = 'generatedData.json'
DATE_FORMAT = "%Y-%m-%dT%H:%M:%S.%fZ"
INDEX_NAME = "wazuh-custom-users"
USERNAME = "admin"
PASSWORD = "admin"
IP = "127.0.0.1"
PORT = "9200"

logging.basicConfig(filename=LOG_FILE, level=logging.INFO)
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)


def generate_random_date():
return datetime.datetime.now(datetime.timezone.utc).strftime('%Y-%m-%dT%H:%M:%SZ')


def generate_random_policy():
return {
"name": f"policy-{random.randint(1, 5)}",
"actions": [random.choice(["agent:create", "agent:remove"])],
"resources": ["*:*:*"],
"effect": random.choice(["allow", "deny"]),
"level": random.randint(0, 5),
"created_at": generate_random_date()
}


def generate_random_rule():
return {
"name": f"rule-{random.randint(1, 3)}",
"body": {},
"created_at": generate_random_date()
}


def generate_random_role():
return {
"name": f"role-{random.randint(1, 5)}",
"created_at": generate_random_date(),
"level": random.randint(0, 5),
"policies": [generate_random_policy() for _ in range(random.randint(1, 2))],
"rules": [generate_random_rule() for _ in range(random.randint(1, 2))]
}


def generate_random_user():
return {
"id": str(uuid.uuid4()),
"name": f"user_{random.randint(1, 1000)}",
"password": f"password{random.randint(1000, 9999)}",
"allow_run_as": random.choice([True, False]),
"created_at": generate_random_date(),
"roles": [generate_random_role() for _ in range(random.randint(1, 2))]
}


def generate_random_data(number):
return [{"user": generate_random_user()} for _ in range(number)]


def inject_events(protocol, ip, port, index, username, password, data):
try:
for event_data in data:
doc_id = str(uuid.uuid4())
url = f'{protocol}://{ip}:{port}/{index}/_doc/{doc_id}'
send_post_request(username, password, url, event_data)
logging.info('Data injection completed successfully.')
except Exception as e:
logging.error(f'Error: {str(e)}')


def send_post_request(username, password, url, event_data):
session = requests.Session()
session.auth = (username, password)
session.verify = False
headers = {'Content-Type': 'application/json'}
response = session.post(url, data=json.dumps(event_data), headers=headers)
if response.status_code not in [201, 200]:
logging.error(f'Error: {response.status_code}')
logging.error(response.text)
return response


def main():
parser = argparse.ArgumentParser(
description="Generate and inject events into Wazuh Custom Users index.")
parser.add_argument("--protocol", choices=['http', 'https'],
default='https', help="Specify the protocol to use: http or https.")
args = parser.parse_args()

try:
number = int(input("How many events do you want to generate? "))
except ValueError:
logging.error("Invalid input. Please enter a valid number.")
return

logging.info(f"Generating {number} events...")
data = generate_random_data(number)

with open(GENERATED_DATA_FILE, 'a') as outfile:
json.dump(data, outfile)
outfile.write('\n')

logging.info('Data generation completed.')

inject = input(
"Do you want to inject the generated data into your index? (y/n) ").strip().lower()
if inject == 'y':
ip = input(f"Enter the IP of your Indexer (default: '{IP}'): ") or IP
port = input(
f"Enter the port of your Indexer (default: '{PORT}'): ") or PORT
index = input(
f"Enter the index name (default: '{INDEX_NAME}'): ") or INDEX_NAME
username = input(f"Username (default: '{USERNAME}'): ") or USERNAME
password = input(f"Password (default: '{PASSWORD}'): ") or PASSWORD

inject_events(args.protocol, ip, port, index, username, password, data)


if __name__ == "__main__":
main()
38 changes: 38 additions & 0 deletions ecs/users/fields/custom/policy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
---
- name: policy
title: Wazuh's User Policy
description: Policy assigned to a role.
reusable:
top_level: true
expected:
- { at: role, as: policies }
level: nested
fields:
- name: name
type: keyword
level: custom
description: Policy name.
- name: actions
type: keyword
level: custom
multi_fields:
- name: raw
level: custom
type: keyword
description: Actions allowed by the policy.
- name: resources
type: keyword
level: custom
description: Resources affected by the policy.
- name: effect
type: keyword
level: custom
description: The effect of the policy (allow/deny).
- name: level
type: integer
level: custom
description: Policy level.
- name: created_at
type: date
level: custom
description: Timestamp when the policy was created.
22 changes: 22 additions & 0 deletions ecs/users/fields/custom/role.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
---
- name: role
title: Wazuh's User Role
description: List of roles assigned to a user.
reusable:
top_level: true
expected:
- { at: user, as: roles }
level: nested
fields:
- name: name
type: keyword
level: custom
description: The role name.
- name: created_at
type: date
level: custom
description: The timestamp when the role was created.
- name: level
type: integer
level: custom
description: The permission level of the role.
23 changes: 23 additions & 0 deletions ecs/users/fields/custom/rule.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
---
- name: rule
title: Wazuh's User Rule
description: Rule assigned to a role.
reusable:
top_level: true
expected:
- { at: role, as: rules }
level: nested
fields:
- name: name
type: keyword
level: custom
description: Rule name.
- name: body
type: object
level: custom
enabled: true
description: Rule body.
- name: created_at
type: date
level: custom
description: Timestamp when the rule was created.
28 changes: 28 additions & 0 deletions ecs/users/fields/custom/user.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
- name: user
title: Wazuh User
short: Internal system user for Wazuh.
description: >
Internal users managed by Wazuh. These are not customizable by users.
type: group
group: 2
fields:
- name: id
type: keyword
level: custom
description: Unique identifier of the internal user.
- name: name
type: keyword
level: custom
description: The internal user’s name.
- name: password
type: keyword
level: custom
description: The hashed password of the internal user.
- name: allow_run_as
type: boolean
level: custom
description: Whether the internal user can run as admin.
- name: created_at
type: date
level: custom
description: Timestamp when the internal user was created.
4 changes: 4 additions & 0 deletions ecs/users/fields/mapping-settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"dynamic": "strict",
"date_detection": false
}
31 changes: 31 additions & 0 deletions ecs/users/fields/subset.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
---
name: wazuh-users
fields:
base:
fields:
tags: []
user:
fields:
id: {}
name: {}
password: {}
allow_run_as: {}
created_at: {}
roles:
fields:
name: {}
created_at: {}
level: {}
rules:
fields:
name: {}
body: {}
created_at: {}
policies:
fields:
name: {}
actions: {}
resources: {}
effect: {}
level: {}
created_at: {}
17 changes: 17 additions & 0 deletions ecs/users/fields/template-settings-legacy.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"index_patterns": [".internal-users*", "wazuh-custom-users*"],
"order": 1,
"settings": {
"index": {
"number_of_shards": "1",
"number_of_replicas": "0",
"refresh_interval": "5s",
"query.default_field": [
"user.name",
"user.roles.name",
"user.roles.policies.name",
"user.roles.rules.name"
]
}
}
}
22 changes: 22 additions & 0 deletions ecs/users/fields/template-settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"index_patterns": [
".internal-users*",
"wazuh-custom-users*"
],
"priority": 1,
"template": {
"settings": {
"index": {
"number_of_shards": "1",
"number_of_replicas": "0",
"refresh_interval": "5s",
"query.default_field": [
"user.name",
"user.roles.name",
"user.roles.policies.name",
"user.roles.rules.name"
]
}
}
}
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
grant {
permission java.net.SocketPermission "*", "connect,resolve";
permission java.net.SocketPermission "*", "connect,resolve,write";
};
Loading