Wazuh Setup, Misc. Container Creation Fixes + Other Small Bug Fixes#12
Wazuh Setup, Misc. Container Creation Fixes + Other Small Bug Fixes#12maxklema merged 20 commits intomieweb:mainfrom
Conversation
…s across containers
Wazuh Changes
There was a problem hiding this comment.
Pull Request Overview
This PR introduces Wazuh security monitoring integration into the existing cluster infrastructure. The integration automatically provisions new containers as Wazuh agents and implements custom security rules for SSH brute force detection.
- Adds comprehensive Wazuh monitoring setup with custom decoders and rules for SSH security
- Updates container creation to include automatic Wazuh agent registration
- Modifies port mapping to include user credentials and OS information
Reviewed Changes
Copilot reviewed 13 out of 16 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| container creation/register-container.sh | Updated to include new parameters for proxmox user and root password in port mapping |
| container creation/create-container.sh | Added random root password generation and Wazuh agent setup integration |
| ci-cd automation/proxmox-launchpad/action.yml | Complete removal of the GitHub Action configuration file |
| ci-cd automation/proxmox-launchpad/README.md | Complete removal of the GitHub Action documentation |
| Wazuh/runner.js | Entry point script for managing Wazuh agent operations |
| Wazuh/register-agent.sh | Script to register new containers as Wazuh agents |
| Wazuh/prune_agents.sh | Automated cleanup script for removing orphaned Wazuh agents |
| Wazuh/package.json | Dependencies for Wazuh management scripts |
| Wazuh/manage-agents.js | Core API client for Wazuh agent management operations |
| Wazuh/local_rules.xml | Custom security rules for SSH brute force detection |
| Wazuh/local_decoders.xml | Custom log decoders for iptables SSH connection attempts |
| Wazuh/firewall-block.sh | Active response script for blocking malicious IPs |
| README.md | Updated documentation to include Wazuh integration details |
Files not reviewed (1)
- Wazuh/package-lock.json: Language not supported
| root_pswd="$9" | ||
|
|
||
| jq --arg hn "$hostname" \ | ||
| --arg ip "$container_ip" \ | ||
| --arg user "$user" \ | ||
| --arg root_pswd "$root_pswd" \ |
There was a problem hiding this comment.
The variable root_pswd is defined but referenced as $9 which doesn't exist in the parameter list. The ssh command only passes 8 parameters but tries to access a 9th parameter.
| root_pswd="$9" | |
| jq --arg hn "$hostname" \ | |
| --arg ip "$container_ip" \ | |
| --arg user "$user" \ | |
| --arg root_pswd "$root_pswd" \ | |
| jq --arg hn "$hostname" \ | |
| --arg ip "$container_ip" \ | |
| --arg user "$user" \ |
| root_pswd="$9" | ||
|
|
||
| jq --arg hn "$hostname" \ | ||
| --arg ip "$container_ip" \ | ||
| --arg user "$user" \ | ||
| --arg root_pswd "$root_pswd" \ |
There was a problem hiding this comment.
The variable root_pswd is used in jq but is undefined since $9 parameter doesn't exist in the ssh command invocation.
| root_pswd="$9" | |
| jq --arg hn "$hostname" \ | |
| --arg ip "$container_ip" \ | |
| --arg user "$user" \ | |
| --arg root_pswd "$root_pswd" \ | |
| jq --arg hn "$hostname" \ | |
| --arg ip "$container_ip" \ | |
| --arg user "$user" \ |
Wazuh/prune_agents.sh
Outdated
| EXISTING_AGENTS=$(node /var/lib/vz/snippets/Wazuh/runner.js getAgents | sed '1d') | ||
|
|
||
| write_log "Retrieved agents from Wazuh manager:" | ||
| write_log "$AGENTS" |
There was a problem hiding this comment.
The variable $AGENTS is undefined. It should be $EXISTING_AGENTS based on the variable defined on line 54.
| write_log "$AGENTS" | |
| write_log "$EXISTING_AGENTS" |
Wazuh/prune_agents.sh
Outdated
| if [[ "$CTIDS_OUTPUT" =~ "Permission denied" || "$CTIDS_OUTPUT" =~ "Connection refused" || "$CTIDS_OUTPUT" =~ "Host key verification failed" ]]; then | ||
| log_message "ERROR: SSH to $node failed: $CTIDS_OUTPUT" |
There was a problem hiding this comment.
The variable $CTIDS_OUTPUT is undefined. It should be $HOSTNAMES based on the SSH command output stored on line 36.
| if [[ "$CTIDS_OUTPUT" =~ "Permission denied" || "$CTIDS_OUTPUT" =~ "Connection refused" || "$CTIDS_OUTPUT" =~ "Host key verification failed" ]]; then | |
| log_message "ERROR: SSH to $node failed: $CTIDS_OUTPUT" | |
| if [[ "$HOSTNAMES" =~ "Permission denied" || "$HOSTNAMES" =~ "Connection refused" || "$HOSTNAMES" =~ "Host key verification failed" ]]; then | |
| write_log "ERROR: SSH to $node failed: $HOSTNAMES" |
Wazuh/prune_agents.sh
Outdated
| HOSTNAMES=$(ssh "$node" "$HOSTNAMES_CMD") | ||
|
|
||
| if [[ "$CTIDS_OUTPUT" =~ "Permission denied" || "$CTIDS_OUTPUT" =~ "Connection refused" || "$CTIDS_OUTPUT" =~ "Host key verification failed" ]]; then | ||
| log_message "ERROR: SSH to $node failed: $CTIDS_OUTPUT" |
There was a problem hiding this comment.
The function log_message is called but it should be write_log based on the function definition on line 9.
| log_message "ERROR: SSH to $node failed: $CTIDS_OUTPUT" | |
| write_log "ERROR: SSH to $node failed: $CTIDS_OUTPUT" |
Wazuh/manage-agents.js
Outdated
| if (response.status !== 200) { | ||
| console.log('fail'); | ||
| } | ||
| agentKey = response.data.data.key; |
There was a problem hiding this comment.
The variable agentKey is declared without const, let, or var, making it an implicit global variable. This should be declared as a local variable.
| agentKey = response.data.data.key; | |
| const agentKey = response.data.data.key; |
| # Function to add firewall rule | ||
| add_rule() { | ||
| local ip="$1" | ||
| ipset add blacklist "$ip" 2>/dev/null |
There was a problem hiding this comment.
The big thing I wanted to point out that I forgot to mention was the move to ipset for better performance on a larger scope of IP's, but it looks like this was already changed.
There was a problem hiding this comment.
The big thing I wanted to point out that I forgot to mention was the move to ipset for better performance on a larger scope of IP's, but it looks like this was already changed.
Yes, it provides much better performance and cleaner code!
cmyers-mieweb
left a comment
There was a problem hiding this comment.
I believe it would be a good addition to also add the ossec.conf to the PR as a lot of Wazuh's configurations are sourced from it. That way I can review security levels, whitelists, FIM config, etc.
Good idea. I will add that. |
cmyers-mieweb
left a comment
There was a problem hiding this comment.
Left a couple comments to review, unrelated to comments, but you also might find this useful in the case of future rules as they come up in the future for classification: https://documentation.wazuh.com/current/user-manual/ruleset/rules/rules-classification.html
Wazuh/ossec.conf
Outdated
| <email_notification>no</email_notification> | ||
| <smtp_server>smtp.example.wazuh.com</smtp_server> | ||
| <email_from>wazuh@example.wazuh.com</email_from> | ||
| <email_to>recipient@example.wazuh.com</email_to> |
There was a problem hiding this comment.
I'd maybe comment out email config and restart the manager if there is no issues with the restart, if we don't have a email server presently setup, I don't know if the manager actually emails a daily report of our threat logs to the default example email recepient.
| <global> | ||
| <white_list>127.0.0.1</white_list> | ||
| <white_list>^localhost.localdomain$</white_list> | ||
| <white_list>10.15.0.3</white_list> | ||
| </global> |
There was a problem hiding this comment.
It might be smart to whitelist the DHCP subnet range so we don't accidentally block a container. Outbound SSH is already killed as well from the firewalls perspective. I've seen cases where clients get blocked from a false positive that ends up causing a work stoppage until someone can go in and unblock.
Another alternative is setting up a timeout block specific to the subnet range to maybe block for 10 minutes and then unblock, unlike a permanent for unknown IP's.
There was a problem hiding this comment.
Good idea. I will just whitelist the whole DHCP subnet since the outbound SSH has already been established.
This PR introduces a Wazuh integration into our existing cluster. The Container Creation Script has been updated to automatically provision new containers as Wazuh Agents communicating with our Wazuh manager.
Wazuh/folder: Contains all relevant Wazuh files, such as custom decoders, rules, agent configuration scripts, automatic agent prune scripts, and other helper files to make API calls.Wazuh/firewall-block.sh: A custom firewall-drop script that blocks a source IP using iptables on the pve1 hypervisor.Wazuh/local_decoders.xml: A custom decoder rule that detects SYN log messages on the hypervisor for ports between 2222-2999 (SSH ports)Wazuh/local_rules.xml: Rules that respond to the custom decoder and detect a brute force invasion.Wazuh/manage-alerts.js: A helper JS file using axios to make API requests to our Wazuh API endpoint to create JWT tokens, new agents, and to delete agents.Wazuh/prune_agents.sh: A script that automatically removes Wazuh agents that are associated with a container that no longer exists. This runs at 3:00 AM EST every night.Wazuh/register-agent.sh: A script used by Create Container to automatically register new containers on Rocky (CentOS) and Debian systems. Automatic updates are disabled, and the version installed is 4.12.The Wazuh dashboard is located at https://wazuh-dashboard.opensource.mieweb.org. Contact me for credentials.