From f8eba4f09ac22a2351e2e317d27943e396e8fed7 Mon Sep 17 00:00:00 2001 From: nikola Date: Tue, 19 May 2026 14:53:37 +0200 Subject: [PATCH] feat: initial commit --- AGENTS.md | 14 ++ docs/PLAN.md | 48 ++++ docs/RUNBOOK_WAZUH_RBMK.md | 201 ++++++++++++++++ sources/iac-test/.terraform.lock.hcl | 25 ++ sources/iac-test/main.tf | 61 +++++ sources/multi-vm-iac/.terraform.lock.hcl | 25 ++ sources/multi-vm-iac/README.md | 33 +++ sources/multi-vm-iac/main.tf | 218 ++++++++++++++++++ terraform/.gitignore | 8 + terraform/.terraform.lock.hcl | 25 ++ terraform/README.md | 109 +++++++++ terraform/main.tf | 51 ++++ terraform/outputs.tf | 19 ++ terraform/scripts/company-bootstrap-ubuntu.sh | 50 ++++ terraform/scripts/install-wazuh-aio.sh | 24 ++ terraform/scripts/verify-wazuh.sh | 19 ++ terraform/terraform.tfvars.example | 20 ++ terraform/tfplan | Bin 0 -> 5386 bytes terraform/tfplan-scale | Bin 0 -> 8443 bytes terraform/variables.tf | 100 ++++++++ terraform/versions.tf | 11 + 21 files changed, 1061 insertions(+) create mode 100644 AGENTS.md create mode 100644 docs/PLAN.md create mode 100644 docs/RUNBOOK_WAZUH_RBMK.md create mode 100644 sources/iac-test/.terraform.lock.hcl create mode 100644 sources/iac-test/main.tf create mode 100644 sources/multi-vm-iac/.terraform.lock.hcl create mode 100644 sources/multi-vm-iac/README.md create mode 100644 sources/multi-vm-iac/main.tf create mode 100644 terraform/.gitignore create mode 100644 terraform/.terraform.lock.hcl create mode 100644 terraform/README.md create mode 100644 terraform/main.tf create mode 100644 terraform/outputs.tf create mode 100755 terraform/scripts/company-bootstrap-ubuntu.sh create mode 100755 terraform/scripts/install-wazuh-aio.sh create mode 100755 terraform/scripts/verify-wazuh.sh create mode 100644 terraform/terraform.tfvars.example create mode 100644 terraform/tfplan create mode 100644 terraform/tfplan-scale create mode 100644 terraform/variables.tf create mode 100644 terraform/versions.tf diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..17498e1 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,14 @@ +# Project Rules - Wazuh Proxmox IaC + +## Scope +Build and operate Terraform-based deployment for one Wazuh VM on local Proxmox. + +## Source of Truth +- `sources/iac-test/` is the baseline for single-VM provisioning. +- `sources/multi-vm-iac/` is reference-only for future scale-out patterns. + +## Working Rules +- Do not commit secrets, token files, `.terraform/`, or `terraform.tfstate*`. +- Keep variables explicit in `terraform.tfvars.example`. +- Prefer one-step reproducible flow: `init -> plan -> apply -> verify`. + diff --git a/docs/PLAN.md b/docs/PLAN.md new file mode 100644 index 0000000..0b9a34e --- /dev/null +++ b/docs/PLAN.md @@ -0,0 +1,48 @@ +# Wazuh on Proxmox - Plan + +## Goal +Provision one VM on local Proxmox using Terraform and install Wazuh all-in-one +automatically. + +## Current Assets +- Ready single-VM Proxmox Terraform baseline in `sources/iac-test/main.tf`. +- Ready multi-VM reference in `sources/multi-vm-iac/main.tf`. +- Known working Proxmox params from existing code: + - endpoint `https://10.0.50.110:8006/` + - node `rbmk2` + - template VM ID `169` + - bridge `vmbr0` + - cloud-init user `devops` + +## Selected Base +Use `iac-test` as base because target is one VM for Wazuh. + +## Work Plan +1. Create clean Terraform project structure from single-VM base: + - `main.tf`, `variables.tf`, `outputs.tf`, `versions.tf` + - `terraform.tfvars.example` +2. Parameterize all environment-specific values: + - Proxmox endpoint/token file path/node/template/datastore/bridge + - VM name, CPU, RAM, disk, IP, gateway, SSH key, SSH port +3. Add cloud-init/user-data provisioning for Wazuh: + - OS packages and prerequisites + - run `wazuh-install.sh -a` + - ensure services are enabled and started +4. Add post-deploy validation outputs: + - VM IP + - dashboard URL + - quick health commands +5. Add runbook (`README.md`) with exact operator commands: + - `terraform init` + - `terraform plan -var-file=...` + - `terraform apply -var-file=...` + - access + agent enrollment steps +6. Optional hardening pass: + - split Wazuh install from VM creation (null_resource/ansible) + - add destroy safeguards and tags + +## Open Inputs Needed Before Apply +- Final static IP for Wazuh VM in LAN. +- Whether to keep default Wazuh ports (443, 1514, 1515) exposed as-is. +- Template `169` confirmation (cloud-init enabled and qemu-guest-agent present). + diff --git a/docs/RUNBOOK_WAZUH_RBMK.md b/docs/RUNBOOK_WAZUH_RBMK.md new file mode 100644 index 0000000..ab1d0a4 --- /dev/null +++ b/docs/RUNBOOK_WAZUH_RBMK.md @@ -0,0 +1,201 @@ +# Wazuh Lab Runbook (RBMK2, VMID/IP reuse) + +## Scope +- Rebuild VM `104` on `rbmk2` +- Keep IP `10.1.50.125/24` +- Use Ubuntu 22.04 template `9000` +- Install Wazuh all-in-one + +## 1) Create Ubuntu template on RBMK2 +Run on: `root@rbmk2` + +```bash +qm status 9000 || true +wget -O /var/lib/vz/template/iso/jammy-server-cloudimg-amd64.img https://cloud-images.ubuntu.com/jammy/current/jammy-server-cloudimg-amd64.img +qm create 9000 --name ubuntu2204-template-rbmk2 --memory 4096 --cores 2 --net0 virtio,bridge=vmbr0,firewall=1 +qm importdisk 9000 /var/lib/vz/template/iso/jammy-server-cloudimg-amd64.img local-lvm +qm set 9000 --scsihw virtio-scsi-single --scsi0 local-lvm:vm-9000-disk-0 +qm set 9000 --ide2 local-lvm:cloudinit +qm set 9000 --boot order=scsi0 +qm set 9000 --agent enabled=1 +qm template 9000 +qm resize 9000 scsi0 60G +qm config 9000 | egrep '^(name|template|ostype|agent|boot|scsihw|scsi0|ide2|net0):' +``` + +Expected: +- `template: 1` +- `ide2: ...cloudinit` +- `scsi0 ... size=60G` + +## 2) Prepare Terraform +Run on: local laptop +Path: `/home/nikola/codex-cli/projects/wazuh-proxmox-iac/terraform` + +```bash +cd /home/nikola/codex-cli/projects/wazuh-proxmox-iac/terraform +mkdir -p .secrets +cp terraform.tfvars.example terraform.tfvars +nano terraform.tfvars +nano .secrets/api_token +chmod 600 .secrets/api_token +terraform init +terraform fmt -recursive +terraform validate +terraform plan -out tfplan +``` + +Set in `terraform.tfvars`: +- `proxmox_template_vm_id = 9000` +- `vm_id = 104` +- `vm_ipv4_cidr = "10.1.50.125/24"` +- `vm_ssh_public_key = ""` + +Expected: +- `Success! The configuration is valid.` +- plan shows `+ create` for `vm_id = 104` + +## 3) Replace old VM 104 +Run on: `root@rbmk2` + +```bash +qm stop 104 || true +qm destroy 104 --purge 1 --destroy-unreferenced-disks 1 +``` + +Expected: +- old test VM removed + +## 4) Apply Terraform +Run on: local laptop +Path: `/home/nikola/codex-cli/projects/wazuh-proxmox-iac/terraform` + +```bash +terraform apply tfplan +terraform output +``` + +Expected: +- `Apply complete!` +- outputs include: + - `ssh devops@10.1.50.125 -p42315` + - `https://10.1.50.125` + +## 5) Fix guest agent if apply waits +Symptom: +- long `Still creating...` +- on rbmk2: `qm agent 104 ping` => `QEMU guest agent is not running` + +Run on: VM `10.1.50.125` (ssh `-p22` or `-p42315`) + +```bash +sudo apt-get update +sudo apt-get install -y qemu-guest-agent +sudo systemctl start qemu-guest-agent +sudo systemctl status qemu-guest-agent --no-pager +``` + +Verify on `rbmk2`: + +```bash +qm agent 104 ping +``` + +Expected: +- agent running; apply completes + +## 6) Apply company SSH baseline +Run on: local laptop +Path: `/home/nikola/codex-cli/projects/wazuh-proxmox-iac/terraform` + +```bash +chmod +x scripts/company-bootstrap-ubuntu.sh scripts/install-wazuh-aio.sh scripts/verify-wazuh.sh +scp -P22 scripts/company-bootstrap-ubuntu.sh devops@10.1.50.125:/tmp/ +ssh devops@10.1.50.125 -p22 "sudo bash /tmp/company-bootstrap-ubuntu.sh devops 42315 \"$(cat ~/.ssh/id_ed25519.pub)\"" +ssh devops@10.1.50.125 -p42315 "sudo sshd -T | egrep '^(port|permitrootlogin|passwordauthentication|pubkeyauthentication)'" +``` + +Expected: +- `port 42315` +- `permitrootlogin no` +- `passwordauthentication no` +- `pubkeyauthentication yes` + +## 7) Install Wazuh +Run on: local laptop +Path: `/home/nikola/codex-cli/projects/wazuh-proxmox-iac/terraform` + +```bash +scp -P42315 scripts/install-wazuh-aio.sh devops@10.1.50.125:/tmp/ +ssh devops@10.1.50.125 -p42315 "sudo bash /tmp/install-wazuh-aio.sh" +./scripts/verify-wazuh.sh 10.1.50.125 +ssh devops@10.1.50.125 -p42315 "sudo systemctl status wazuh-indexer wazuh-manager wazuh-dashboard filebeat --no-pager" +``` + +Expected: +- Installer summary with dashboard URL and admin password +- `verify-wazuh.sh` checks pass +- all 4 services `active (running)` + +## Common issues and fixes +1. `can't clone to non-shared storage 'local-lvm'` +- Cause: cross-node clone to non-shared storage. +- Fix: create template directly on `rbmk2`. + +2. `unable to find configuration file for VM 129 on node 'rbmk2'` +- Cause: source VM exists on another node. +- Fix: run actions on the correct source node or avoid cross-node clone. + +3. SSH host key changed warning +- Fix: +```bash +ssh-keygen -f ~/.ssh/known_hosts -R '[10.1.50.125]:42315' +``` + +4. `QEMU guest agent is not running` +- Fix: install/start `qemu-guest-agent` inside VM, then retry/check. + +5. Thin pool warnings during import/resize +- Cause: local-lvm oversubscription warning. +- Fix: monitor storage free space before new clones and log growth. + +## Post-install hardening checklist (Wazuh lab) +Run on: VM `10.1.50.125` (`ssh devops@10.1.50.125 -p42315`) + +1. Rotate default admin password +- In dashboard: `https://10.1.50.125` -> change `admin` password immediately. + +2. Restrict API exposure (if not needed externally) +```bash +sudo ss -tulpen | egrep '(:443|:1514|:1515|:55000)' +``` +- confirm only required ports are listening. + +3. Enable host firewall baseline +```bash +sudo apt-get install -y ufw +sudo ufw default deny incoming +sudo ufw default allow outgoing +sudo ufw allow 42315/tcp +sudo ufw allow 443/tcp +sudo ufw allow 1514/tcp +sudo ufw allow 1515/tcp +sudo ufw allow 55000/tcp +sudo ufw --force enable +sudo ufw status verbose +``` +- keep only Wazuh + SSH management ports open. + +4. Verify services are enabled and healthy +```bash +sudo systemctl is-active wazuh-indexer wazuh-manager wazuh-dashboard filebeat +sudo systemctl is-enabled wazuh-indexer wazuh-manager wazuh-dashboard filebeat +``` +- all should be active/enabled. + +5. Backup install artifacts and credentials file +```bash +sudo ls -l /root/wazuh-install-files.tar /var/log/wazuh-install.log +``` +- copy to a secure internal vault/location. + diff --git a/sources/iac-test/.terraform.lock.hcl b/sources/iac-test/.terraform.lock.hcl new file mode 100644 index 0000000..d81c0d3 --- /dev/null +++ b/sources/iac-test/.terraform.lock.hcl @@ -0,0 +1,25 @@ +# This file is maintained automatically by "terraform init". +# Manual edits may be lost in future updates. + +provider "registry.terraform.io/bpg/proxmox" { + version = "0.68.0" + constraints = "0.68.0" + hashes = [ + "h1:4Q+bUZoRz7o2ij/oPS3SsAy1D2CDdIMasegk+ll7oho=", + "zh:012f3fce033a7921335576edba0f2d2dad7dcaec2e5ed3b68ced692845131656", + "zh:1853ddbaef049b14e738bf8531a2c8e45d9ac409676a7f7f997d40ae794db783", + "zh:2a284f49f95bfe022f8b5bfed6ae56df5577f590ff26ae12322767f23e3b6c50", + "zh:491a7d5a3cf47fc3016213ca047fcf20288200901f5c0195314c32925fcd36c0", + "zh:4a198ab0b40b02a35955156d9a195c76a22f92d4078195ce94316b793d0d58d4", + "zh:63f0e62c5805b48893f9a106ed11e628f1a3bc3d34360a2bb31a88cfcc2051dd", + "zh:64cdc6a3bdd56e2285a2d65a17d87ee284fcdbbe69246baed4aeaf465a955007", + "zh:6721eaaa4998795c0caed3225aa2bc8ff796a6de86114431194b9770f98e2600", + "zh:79ef8a813d1b3d5ef69f2a00a3160fde9ca65c541db42c998c69db6dea66558f", + "zh:96aa2d4a6cdac17dcccbb76a1ef0afc15052c3f13fa3bb0f3f44b385272405d4", + "zh:9e1e18b04f228d671e1653294828021e672dab6635a309e72b2da4ba3b9f07e9", + "zh:a91b69c6df914f8f0504d0f0d25af6a870b79befe6ae11d39a1bd8b879871084", + "zh:bc618ee4f85b8c5db0e1494d207d2a6170ca08dad5ce9844866550a94dd56bea", + "zh:ea85f7e5dbbe768e2e15e0cafacee1c94e319d04c1835db1984a6ce79674c8e4", + "zh:f26e0763dbe6a6b2195c94b44696f2110f7f55433dc142839be16b9697fa5597", + ] +} diff --git a/sources/iac-test/main.tf b/sources/iac-test/main.tf new file mode 100644 index 0000000..1ad822e --- /dev/null +++ b/sources/iac-test/main.tf @@ -0,0 +1,61 @@ +terraform { + required_providers { + proxmox = { + source = "bpg/proxmox" + version = "0.68.0" + } + } +} + +provider "proxmox" { + endpoint = "https://10.0.50.110:8006/" + insecure = true + api_token = trimspace(file("${path.module}/.secrets/api_token")) +} + +resource "proxmox_virtual_environment_vm" "testvm" { + name = "terraform-testvm-1" + node_name = "rbmk2" + + clone { + vm_id = 169 + full = true + datastore_id = "local-lvm" + } + + cpu { + sockets = 1 + cores = 2 + } + + memory { + dedicated = 8192 + } + + network_device { + model = "virtio" + bridge = "vmbr0" + } + + initialization { + datastore_id = "local-lvm" + + user_account { + username = "devops" + keys = [ + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFyVe1ZhUCVs9imt0UmcCIXRAHpoSKFQ7IH/ekEXohZG dzoni-wolkabout" + ] + } + + ip_config { + ipv4 { + address = "10.1.50.125/24" + gateway = "10.1.50.1" + } + } + } + + agent { + enabled = true + } +} diff --git a/sources/multi-vm-iac/.terraform.lock.hcl b/sources/multi-vm-iac/.terraform.lock.hcl new file mode 100644 index 0000000..d81c0d3 --- /dev/null +++ b/sources/multi-vm-iac/.terraform.lock.hcl @@ -0,0 +1,25 @@ +# This file is maintained automatically by "terraform init". +# Manual edits may be lost in future updates. + +provider "registry.terraform.io/bpg/proxmox" { + version = "0.68.0" + constraints = "0.68.0" + hashes = [ + "h1:4Q+bUZoRz7o2ij/oPS3SsAy1D2CDdIMasegk+ll7oho=", + "zh:012f3fce033a7921335576edba0f2d2dad7dcaec2e5ed3b68ced692845131656", + "zh:1853ddbaef049b14e738bf8531a2c8e45d9ac409676a7f7f997d40ae794db783", + "zh:2a284f49f95bfe022f8b5bfed6ae56df5577f590ff26ae12322767f23e3b6c50", + "zh:491a7d5a3cf47fc3016213ca047fcf20288200901f5c0195314c32925fcd36c0", + "zh:4a198ab0b40b02a35955156d9a195c76a22f92d4078195ce94316b793d0d58d4", + "zh:63f0e62c5805b48893f9a106ed11e628f1a3bc3d34360a2bb31a88cfcc2051dd", + "zh:64cdc6a3bdd56e2285a2d65a17d87ee284fcdbbe69246baed4aeaf465a955007", + "zh:6721eaaa4998795c0caed3225aa2bc8ff796a6de86114431194b9770f98e2600", + "zh:79ef8a813d1b3d5ef69f2a00a3160fde9ca65c541db42c998c69db6dea66558f", + "zh:96aa2d4a6cdac17dcccbb76a1ef0afc15052c3f13fa3bb0f3f44b385272405d4", + "zh:9e1e18b04f228d671e1653294828021e672dab6635a309e72b2da4ba3b9f07e9", + "zh:a91b69c6df914f8f0504d0f0d25af6a870b79befe6ae11d39a1bd8b879871084", + "zh:bc618ee4f85b8c5db0e1494d207d2a6170ca08dad5ce9844866550a94dd56bea", + "zh:ea85f7e5dbbe768e2e15e0cafacee1c94e319d04c1835db1984a6ce79674c8e4", + "zh:f26e0763dbe6a6b2195c94b44696f2110f7f55433dc142839be16b9697fa5597", + ] +} diff --git a/sources/multi-vm-iac/README.md b/sources/multi-vm-iac/README.md new file mode 100644 index 0000000..17c8640 --- /dev/null +++ b/sources/multi-vm-iac/README.md @@ -0,0 +1,33 @@ +# Multi VM Terraform setup + +## Priprema okruženja +- `cd ~/multi-vm-iac` +- `rm -rf .terraform terraform.tfstate*` # osveži backend da ne deli state sa starim projektom +- `terraform init -reconfigure` + +## Konfiguracija IP adresa +- `cat <<'EOF' > terraform.tfvars` + ``` + vm_addresses = { + alpha = "10.1.50.XXX/24" + bravo = "10.1.50.YYY/24" + charlie = "10.1.50.ZZZ/24" + delta = "10.1.50.WWW/24" + } + ``` + `EOF` +- Izmeni XXX/YYY/ZZZ/WWW u slobodne adrese pre `apply`. + +## Startovanje pojedinačnih VM-ova +- `terraform plan -target=proxmox_virtual_environment_vm.vm_alpha` +- `terraform apply -target=proxmox_virtual_environment_vm.vm_alpha` +- Ponovi za `vm_bravo`, `vm_charlie`, `vm_delta` po potrebi. + +## Provera i gašenje +- `terraform state list` # pregled aktivnih resursa u ovom projektu +- `terraform destroy -target=proxmox_virtual_environment_vm.vm_alpha` # gasi samo jednu mašinu +- `terraform destroy` # gasi sve instance iz ovog foldera kada završiš + +## Dodatno +- Ako budeš delio state, pređi na remote backend (S3 + DynamoDB lock, Terraform Cloud…) pre proizvodnog korišćenja. +- Za promenu gateway-a koristi varijablu `vm_gateway` u `terraform.tfvars`. diff --git a/sources/multi-vm-iac/main.tf b/sources/multi-vm-iac/main.tf new file mode 100644 index 0000000..98d6a27 --- /dev/null +++ b/sources/multi-vm-iac/main.tf @@ -0,0 +1,218 @@ +terraform { + required_providers { + proxmox = { + source = "bpg/proxmox" + version = "0.68.0" + } + } +} + +provider "proxmox" { + endpoint = "https://10.0.50.110:8006/" + insecure = true + api_token = trimspace(file("${path.module}/.secrets/api_token")) +} + +variable "vm_gateway" { + type = string + description = "Default gateway for all virtual machines." + default = "10.1.50.1" +} + +variable "vm_addresses" { + type = object({ + alpha = string + bravo = string + charlie = string + delta = string + }) + description = "CIDR formatted IPv4 addresses for each virtual machine (e.g. 10.1.50.130/24)." +} + +resource "proxmox_virtual_environment_vm" "vm_alpha" { + name = "terraform-multi-vm-alpha" + node_name = "rbmk2" + + clone { + vm_id = 169 + full = true + datastore_id = "local-lvm" + } + + cpu { + sockets = 1 + cores = 2 + } + + memory { + dedicated = 4096 + } + + network_device { + model = "virtio" + bridge = "vmbr0" + } + + initialization { + datastore_id = "local-lvm" + + user_account { + username = "devops" + keys = [ + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFyVe1ZhUCVs9imt0UmcCIXRAHpoSKFQ7IH/ekEXohZG dzoni-wolkabout" + ] + } + + ip_config { + ipv4 { + address = var.vm_addresses.alpha + gateway = var.vm_gateway + } + } + } + + agent { + enabled = true + } +} + +resource "proxmox_virtual_environment_vm" "vm_bravo" { + name = "terraform-multi-vm-bravo" + node_name = "rbmk2" + + clone { + vm_id = 169 + full = true + datastore_id = "local-lvm" + } + + cpu { + sockets = 1 + cores = 2 + } + + memory { + dedicated = 4096 + } + + network_device { + model = "virtio" + bridge = "vmbr0" + } + + initialization { + datastore_id = "local-lvm" + + user_account { + username = "devops" + keys = [ + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFyVe1ZhUCVs9imt0UmcCIXRAHpoSKFQ7IH/ekEXohZG dzoni-wolkabout" + ] + } + + ip_config { + ipv4 { + address = var.vm_addresses.bravo + gateway = var.vm_gateway + } + } + } + + agent { + enabled = true + } +} + +resource "proxmox_virtual_environment_vm" "vm_charlie" { + name = "terraform-multi-vm-charlie" + node_name = "rbmk2" + + clone { + vm_id = 169 + full = true + datastore_id = "local-lvm" + } + + cpu { + sockets = 1 + cores = 2 + } + + memory { + dedicated = 4096 + } + + network_device { + model = "virtio" + bridge = "vmbr0" + } + + initialization { + datastore_id = "local-lvm" + + user_account { + username = "devops" + keys = [ + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFyVe1ZhUCVs9imt0UmcCIXRAHpoSKFQ7IH/ekEXohZG dzoni-wolkabout" + ] + } + + ip_config { + ipv4 { + address = var.vm_addresses.charlie + gateway = var.vm_gateway + } + } + } + + agent { + enabled = true + } +} + +resource "proxmox_virtual_environment_vm" "vm_delta" { + name = "terraform-multi-vm-delta" + node_name = "rbmk2" + + clone { + vm_id = 169 + full = true + datastore_id = "local-lvm" + } + + cpu { + sockets = 1 + cores = 2 + } + + memory { + dedicated = 4096 + } + + network_device { + model = "virtio" + bridge = "vmbr0" + } + + initialization { + datastore_id = "local-lvm" + + user_account { + username = "devops" + keys = [ + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFyVe1ZhUCVs9imt0UmcCIXRAHpoSKFQ7IH/ekEXohZG dzoni-wolkabout" + ] + } + + ip_config { + ipv4 { + address = var.vm_addresses.delta + gateway = var.vm_gateway + } + } + } + + agent { + enabled = true + } +} diff --git a/terraform/.gitignore b/terraform/.gitignore new file mode 100644 index 0000000..f94faa8 --- /dev/null +++ b/terraform/.gitignore @@ -0,0 +1,8 @@ +.terraform/ +.secrets/ +terraform.tfstate +terraform.tfstate.* +terraform.tfvars +crash.log +crash.*.log + diff --git a/terraform/.terraform.lock.hcl b/terraform/.terraform.lock.hcl new file mode 100644 index 0000000..d81c0d3 --- /dev/null +++ b/terraform/.terraform.lock.hcl @@ -0,0 +1,25 @@ +# This file is maintained automatically by "terraform init". +# Manual edits may be lost in future updates. + +provider "registry.terraform.io/bpg/proxmox" { + version = "0.68.0" + constraints = "0.68.0" + hashes = [ + "h1:4Q+bUZoRz7o2ij/oPS3SsAy1D2CDdIMasegk+ll7oho=", + "zh:012f3fce033a7921335576edba0f2d2dad7dcaec2e5ed3b68ced692845131656", + "zh:1853ddbaef049b14e738bf8531a2c8e45d9ac409676a7f7f997d40ae794db783", + "zh:2a284f49f95bfe022f8b5bfed6ae56df5577f590ff26ae12322767f23e3b6c50", + "zh:491a7d5a3cf47fc3016213ca047fcf20288200901f5c0195314c32925fcd36c0", + "zh:4a198ab0b40b02a35955156d9a195c76a22f92d4078195ce94316b793d0d58d4", + "zh:63f0e62c5805b48893f9a106ed11e628f1a3bc3d34360a2bb31a88cfcc2051dd", + "zh:64cdc6a3bdd56e2285a2d65a17d87ee284fcdbbe69246baed4aeaf465a955007", + "zh:6721eaaa4998795c0caed3225aa2bc8ff796a6de86114431194b9770f98e2600", + "zh:79ef8a813d1b3d5ef69f2a00a3160fde9ca65c541db42c998c69db6dea66558f", + "zh:96aa2d4a6cdac17dcccbb76a1ef0afc15052c3f13fa3bb0f3f44b385272405d4", + "zh:9e1e18b04f228d671e1653294828021e672dab6635a309e72b2da4ba3b9f07e9", + "zh:a91b69c6df914f8f0504d0f0d25af6a870b79befe6ae11d39a1bd8b879871084", + "zh:bc618ee4f85b8c5db0e1494d207d2a6170ca08dad5ce9844866550a94dd56bea", + "zh:ea85f7e5dbbe768e2e15e0cafacee1c94e319d04c1835db1984a6ce79674c8e4", + "zh:f26e0763dbe6a6b2195c94b44696f2110f7f55433dc142839be16b9697fa5597", + ] +} diff --git a/terraform/README.md b/terraform/README.md new file mode 100644 index 0000000..3dd29cb --- /dev/null +++ b/terraform/README.md @@ -0,0 +1,109 @@ +# Wazuh Proxmox Lab (Single VM, reuse VMID/IP) + +Run from: + +`/home/nikola/codex-cli/projects/wazuh-proxmox-iac/terraform` + +Target: +- VMID `104` +- IP `10.1.50.125/24` +- Node `rbmk2` +- OS source: Ubuntu 22.04 cloud-init template +- SSH policy target: user `devops`, port `42315`, key-only auth + +## 0) One-time on Proxmox: Ubuntu 22.04 template + +You need one Ubuntu 22.04 cloud-init template in Proxmox first. +After that, Terraform does the rest. + +Example on Proxmox node (adjust storage/bridge if needed): + +```bash +wget https://cloud-images.ubuntu.com/jammy/current/jammy-server-cloudimg-amd64.img -O /tmp/jammy.img +qm create 9000 --name ubuntu-2204-cloudinit --memory 2048 --cores 2 --net0 virtio,bridge=vmbr0 +qm importdisk 9000 /tmp/jammy.img local-lvm +qm set 9000 --scsihw virtio-scsi-single --scsi0 local-lvm:vm-9000-disk-0 +qm set 9000 --ide2 local-lvm:cloudinit +qm set 9000 --boot c --bootdisk scsi0 +qm set 9000 --serial0 socket --vga serial0 +qm template 9000 +``` + +- pravi Ubuntu 22.04 template VMID `9000` + +## 1) Obrisi postojeci test VM 104 (ako nista ne radi na njemu) + +On Proxmox node: + +```bash +qm stop 104 || true +qm destroy 104 --purge 1 --destroy-unreferenced-disks 1 +``` + +- gasi i brise stari VM 104 + +## 2) Priprema Terraform fajlova + +```bash +cd /home/nikola/codex-cli/projects/wazuh-proxmox-iac/terraform +mkdir -p .secrets +cp terraform.tfvars.example terraform.tfvars +``` + +- ulaz u projekat + vars + secret folder + +```bash +nano terraform.tfvars +``` + +- proveri `vm_id=104`, `vm_ipv4_cidr=10.1.50.125/24`, `proxmox_template_vm_id=9000` + +```bash +nano .secrets/api_token +chmod 600 .secrets/api_token +``` + +- upisi Proxmox API token + +## 3) Podizanje novog Ubuntu VM-a na isto mesto + +```bash +terraform init +terraform fmt -recursive +terraform validate +terraform plan -out tfplan +terraform apply tfplan +terraform output +``` + +- kreira novi VM 104 sa istim IP +- ovaj Terraform ne pokrece Docker/workload automatski; podize clean Ubuntu VM. +- kontrola resursa je kroz `vm_cpu_cores` i `vm_memory_mb` u `terraform.tfvars`. + +## 4) Instalacija Wazuh na novom VM-u + +```bash +chmod +x scripts/company-bootstrap-ubuntu.sh scripts/install-wazuh-aio.sh scripts/verify-wazuh.sh +# ako SSH na 22 nije dostupan, zameni -P22/-p22 sa -P42315/-p42315 +scp -P22 scripts/company-bootstrap-ubuntu.sh devops@10.1.50.125:/tmp/ +ssh devops@10.1.50.125 -p22 "sudo bash /tmp/company-bootstrap-ubuntu.sh devops 42315 \"$(cat ~/.ssh/id_ed25519.pub)\"" +ssh devops@10.1.50.125 -p42315 "echo ssh baseline ok" +scp -P42315 scripts/install-wazuh-aio.sh devops@10.1.50.125:/tmp/ +ssh devops@10.1.50.125 -p42315 "sudo bash /tmp/install-wazuh-aio.sh" +``` + +- primeni company SSH baseline pa instaliraj Wazuh + +## 5) Verifikacija + +```bash +./scripts/verify-wazuh.sh 10.1.50.125 +``` + +- provera dashboard + portovi 1514/1515 + +## Key pravilo (preporuka) + +- Ne bake-uj licni SSH key u template. +- Key ubacuj po VM-u kroz Terraform `vm_ssh_public_key` i/ili bootstrap skriptu. +- Template neka ostane genericki, bez personalnih kljuceva. diff --git a/terraform/main.tf b/terraform/main.tf new file mode 100644 index 0000000..5db8f9e --- /dev/null +++ b/terraform/main.tf @@ -0,0 +1,51 @@ +provider "proxmox" { + endpoint = var.proxmox_endpoint + insecure = var.proxmox_insecure + api_token = trimspace(file(var.proxmox_api_token_file)) +} + +resource "proxmox_virtual_environment_vm" "wazuh" { + name = var.vm_name + vm_id = var.vm_id + node_name = var.proxmox_node_name + + clone { + vm_id = var.proxmox_template_vm_id + full = true + datastore_id = var.proxmox_datastore_id + } + + cpu { + sockets = var.vm_cpu_sockets + cores = var.vm_cpu_cores + } + + memory { + dedicated = var.vm_memory_mb + } + + network_device { + model = "virtio" + bridge = var.proxmox_bridge + } + + initialization { + datastore_id = var.proxmox_datastore_id + + user_account { + username = var.vm_ssh_username + keys = [var.vm_ssh_public_key] + } + + ip_config { + ipv4 { + address = var.vm_ipv4_cidr + gateway = var.vm_gateway + } + } + } + + agent { + enabled = true + } +} diff --git a/terraform/outputs.tf b/terraform/outputs.tf new file mode 100644 index 0000000..a4b3d0b --- /dev/null +++ b/terraform/outputs.tf @@ -0,0 +1,19 @@ +locals { + vm_ip = split("/", var.vm_ipv4_cidr)[0] +} + +output "vm_name" { + value = proxmox_virtual_environment_vm.wazuh.name +} + +output "vm_ip" { + value = local.vm_ip +} + +output "ssh_command" { + value = "ssh ${var.vm_ssh_username}@${local.vm_ip} -p${var.vm_ssh_port}" +} + +output "wazuh_dashboard_url" { + value = "https://${local.vm_ip}" +} diff --git a/terraform/scripts/company-bootstrap-ubuntu.sh b/terraform/scripts/company-bootstrap-ubuntu.sh new file mode 100755 index 0000000..fcd7c77 --- /dev/null +++ b/terraform/scripts/company-bootstrap-ubuntu.sh @@ -0,0 +1,50 @@ +#!/usr/bin/env bash +set -euo pipefail + +if [[ "${EUID}" -ne 0 ]]; then + echo "Run as root (sudo)." >&2 + exit 1 +fi + +SSH_USER="${1:-devops}" +SSH_PORT="${2:-42315}" +SSH_PUBKEY="${3:-}" + +if [[ -z "${SSH_PUBKEY}" ]]; then + echo "Usage: $0 " >&2 + exit 1 +fi + +if ! id -u "${SSH_USER}" >/dev/null 2>&1; then + useradd -m -s /bin/bash "${SSH_USER}" +fi + +usermod -aG sudo "${SSH_USER}" + +install -d -m 700 -o "${SSH_USER}" -g "${SSH_USER}" "/home/${SSH_USER}/.ssh" +touch "/home/${SSH_USER}/.ssh/authorized_keys" +chown "${SSH_USER}:${SSH_USER}" "/home/${SSH_USER}/.ssh/authorized_keys" +chmod 600 "/home/${SSH_USER}/.ssh/authorized_keys" + +if ! grep -Fqx "${SSH_PUBKEY}" "/home/${SSH_USER}/.ssh/authorized_keys"; then + echo "${SSH_PUBKEY}" >>"/home/${SSH_USER}/.ssh/authorized_keys" +fi + +cat >/etc/ssh/sshd_config.d/99-company.conf <&2 + exit 1 +fi + +echo "[1/4] System update and tools" +apt-get update -y +apt-get install -y curl tar + +echo "[2/4] Download Wazuh installer" +cd /root +curl -sSLO https://packages.wazuh.com/4.14/wazuh-install.sh +chmod +x wazuh-install.sh + +echo "[3/4] Install Wazuh all-in-one" +bash ./wazuh-install.sh -a + +echo "[4/4] Installation finished" +echo "Open: https://$(hostname -I | awk '{print $1}')" +echo "Installer output contains generated admin credentials." + diff --git a/terraform/scripts/verify-wazuh.sh b/terraform/scripts/verify-wazuh.sh new file mode 100755 index 0000000..24484a1 --- /dev/null +++ b/terraform/scripts/verify-wazuh.sh @@ -0,0 +1,19 @@ +#!/usr/bin/env bash +set -euo pipefail + +TARGET_IP="${1:-}" + +if [[ -z "${TARGET_IP}" ]]; then + echo "Usage: $0 " >&2 + exit 1 +fi + +echo "[1/3] Dashboard HTTPS check" +curl -kI "https://${TARGET_IP}" | head -n 1 + +echo "[2/3] Enrollment port check" +nc -zv "${TARGET_IP}" 1515 + +echo "[3/3] Agent events port check" +nc -zv "${TARGET_IP}" 1514 + diff --git a/terraform/terraform.tfvars.example b/terraform/terraform.tfvars.example new file mode 100644 index 0000000..a541711 --- /dev/null +++ b/terraform/terraform.tfvars.example @@ -0,0 +1,20 @@ +proxmox_endpoint = "https://10.0.50.110:8006/" +proxmox_insecure = true +proxmox_api_token_file = ".secrets/api_token" +proxmox_node_name = "rbmk2" +# Set this to Ubuntu 22.04 cloud-init template VMID. +proxmox_template_vm_id = 9000 +proxmox_datastore_id = "local-lvm" +proxmox_bridge = "vmbr0" + +vm_name = "terraform-testvm-1" +vm_id = 104 +vm_cpu_sockets = 1 +vm_cpu_cores = 4 +vm_memory_mb = 8192 +vm_ipv4_cidr = "10.1.50.125/24" +vm_gateway = "10.1.50.1" +vm_ssh_username = "devops" +vm_ssh_port = 42315 + +vm_ssh_public_key = "ssh-ed25519 AAAA... your-key-comment" diff --git a/terraform/tfplan b/terraform/tfplan new file mode 100644 index 0000000000000000000000000000000000000000..e6bf7bc34b5777e8e7cde84f1513e46cfdc6d370 GIT binary patch literal 5386 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 LkxaEGxt#qE53(1} literal 0 HcmV?d00001 diff --git a/terraform/tfplan-scale b/terraform/tfplan-scale new file mode 100644 index 0000000000000000000000000000000000000000..4ddaded4c608f285c288abaeb0e1476da94555cf GIT binary patch literal 8443 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 KNYx|$>HQzu841?_ literal 0 HcmV?d00001 diff --git a/terraform/variables.tf b/terraform/variables.tf new file mode 100644 index 0000000..8290263 --- /dev/null +++ b/terraform/variables.tf @@ -0,0 +1,100 @@ +variable "proxmox_endpoint" { + description = "Proxmox API endpoint." + type = string + default = "https://10.0.50.110:8006/" +} + +variable "proxmox_insecure" { + description = "Allow insecure TLS for Proxmox API." + type = bool + default = true +} + +variable "proxmox_api_token_file" { + description = "Path to file containing Proxmox API token." + type = string + default = ".secrets/api_token" +} + +variable "proxmox_node_name" { + description = "Proxmox node where VM will be created." + type = string + default = "rbmk2" +} + +variable "proxmox_template_vm_id" { + description = "Template VM ID used for clone." + type = number + default = 169 +} + +variable "proxmox_datastore_id" { + description = "Datastore used for clone and cloud-init." + type = string + default = "local-lvm" +} + +variable "proxmox_bridge" { + description = "Proxmox bridge name." + type = string + default = "vmbr0" +} + +variable "vm_name" { + description = "Wazuh VM name." + type = string + default = "terraform-testvm-1" +} + +variable "vm_id" { + description = "Proxmox VMID for the Wazuh VM." + type = number + default = 104 +} + +variable "vm_cpu_sockets" { + description = "VM CPU sockets." + type = number + default = 1 +} + +variable "vm_cpu_cores" { + description = "VM CPU cores." + type = number + default = 4 +} + +variable "vm_memory_mb" { + description = "VM memory in MB." + type = number + default = 8192 +} + +variable "vm_ipv4_cidr" { + description = "VM IPv4 address in CIDR format." + type = string + default = "10.1.50.125/24" +} + +variable "vm_gateway" { + description = "VM default gateway." + type = string + default = "10.1.50.1" +} + +variable "vm_ssh_username" { + description = "Cloud-init username for SSH." + type = string + default = "devops" +} + +variable "vm_ssh_port" { + description = "SSH port exposed by company policy." + type = number + default = 42315 +} + +variable "vm_ssh_public_key" { + description = "SSH public key inserted via cloud-init." + type = string +} diff --git a/terraform/versions.tf b/terraform/versions.tf new file mode 100644 index 0000000..30e695a --- /dev/null +++ b/terraform/versions.tf @@ -0,0 +1,11 @@ +terraform { + required_version = ">= 1.5.0" + + required_providers { + proxmox = { + source = "bpg/proxmox" + version = "0.68.0" + } + } +} +