Compare commits
3 Commits
d36098c6aa
...
695b7b017e
| Author | SHA1 | Date | |
|---|---|---|---|
| 695b7b017e | |||
| 3e7939b682 | |||
| 170146efb1 |
@@ -1,10 +0,0 @@
|
|||||||
{
|
|
||||||
"sessionID": "ses_f9c7a2a4bffeGbArqDu2FhIlC5",
|
|
||||||
"updatedAt": "2026-09-02T19:11:53.267Z",
|
|
||||||
"sources": {
|
|
||||||
"background-task": {
|
|
||||||
"state": "idle",
|
|
||||||
"updatedAt": "2026-09-02T19:11:53.267Z"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
{
|
|
||||||
"sessionID": "ses_f9c868146ffeKpqM2tbofhzWO3",
|
|
||||||
"updatedAt": "2026-09-02T19:03:22.170Z",
|
|
||||||
"sources": {
|
|
||||||
"background-task": {
|
|
||||||
"state": "idle",
|
|
||||||
"updatedAt": "2026-09-02T19:03:22.170Z"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -4,430 +4,19 @@
|
|||||||
vars_files:
|
vars_files:
|
||||||
- ./vars.yml
|
- ./vars.yml
|
||||||
tasks:
|
tasks:
|
||||||
- name: Update Packages
|
- name: Pull images
|
||||||
ansible.builtin.dnf:
|
|
||||||
update_cache: yes
|
|
||||||
|
|
||||||
- name: Install Packages
|
|
||||||
ansible.builtin.dnf:
|
|
||||||
name:
|
|
||||||
- vim
|
|
||||||
- podman
|
|
||||||
- fail2ban
|
|
||||||
- python3-libdnf5
|
|
||||||
state: present
|
|
||||||
|
|
||||||
- name: Create directories
|
|
||||||
file:
|
|
||||||
path: "{{ item }}"
|
|
||||||
state: directory
|
|
||||||
mode: '0755'
|
|
||||||
loop: "{{ directories }}"
|
|
||||||
|
|
||||||
- name: Create Jellyfin directories
|
|
||||||
file:
|
|
||||||
path: "{{ item }}"
|
|
||||||
state: directory
|
|
||||||
mode: '0777'
|
|
||||||
loop: "{{ directories_jellyfin }}"
|
|
||||||
|
|
||||||
- name: Create internal podman network
|
|
||||||
containers.podman.podman_network:
|
|
||||||
name: npm_internal
|
|
||||||
ip_range: 10.10.0.128/25
|
|
||||||
subnet: 10.10.0.0/24
|
|
||||||
gateway: 10.10.0.1
|
|
||||||
state: present
|
|
||||||
|
|
||||||
- name: Ensure WireGuard kernel module is loaded
|
|
||||||
ansible.builtin.modprobe:
|
|
||||||
name: wireguard
|
|
||||||
state: present
|
|
||||||
|
|
||||||
- name: Persist WireGuard kernel module across reboots
|
|
||||||
ansible.builtin.copy:
|
|
||||||
dest: /etc/modules-load.d/wg-easy.conf
|
|
||||||
content: |
|
|
||||||
wireguard
|
|
||||||
nft_masq
|
|
||||||
mode: '0644'
|
|
||||||
|
|
||||||
- name: Enable IP forwarding on host
|
|
||||||
ansible.posix.sysctl:
|
|
||||||
name: net.ipv4.ip_forward
|
|
||||||
value: '1'
|
|
||||||
sysctl_set: true
|
|
||||||
state: present
|
|
||||||
|
|
||||||
- name: Enable source valid mark on host
|
|
||||||
ansible.posix.sysctl:
|
|
||||||
name: net.ipv4.conf.all.src_valid_mark
|
|
||||||
value: '1'
|
|
||||||
sysctl_set: true
|
|
||||||
state: present
|
|
||||||
reload: true
|
|
||||||
|
|
||||||
- name: Raise vm.max_map_count for Wazuh indexer
|
|
||||||
ansible.posix.sysctl:
|
|
||||||
name: vm.max_map_count
|
|
||||||
value: '262144'
|
|
||||||
sysctl_set: true
|
|
||||||
state: present
|
|
||||||
reload: true
|
|
||||||
|
|
||||||
- name: pull images
|
|
||||||
containers.podman.podman_image:
|
containers.podman.podman_image:
|
||||||
name: "{{ item }}"
|
name: "{{ item }}"
|
||||||
loop: "{{ images }}"
|
loop: "{{ images }}"
|
||||||
|
|
||||||
- name: Deploy Nginx Proxy Manager
|
roles:
|
||||||
containers.podman.podman_container:
|
- packages
|
||||||
image: "docker.io/jc21/nginx-proxy-manager:latest"
|
- directories
|
||||||
name: npm
|
- sysctl
|
||||||
restart_policy: always
|
- network
|
||||||
recreate: true
|
- wireguard
|
||||||
state: started
|
- npm
|
||||||
ports:
|
- gitea
|
||||||
- "80:80"
|
- jellyfin
|
||||||
- "81:81"
|
- wazuh
|
||||||
- "443:443"
|
|
||||||
volumes:
|
|
||||||
- "/opt/apps/npm:/data:z"
|
|
||||||
- "/opt/apps/letsencrypt:/etc/letsencrypt:z"
|
|
||||||
network:
|
|
||||||
- npm_internal
|
|
||||||
ip: '10.10.0.19'
|
|
||||||
|
|
||||||
|
|
||||||
- name: Deploy Gitea
|
|
||||||
containers.podman.podman_container:
|
|
||||||
image: docker.gitea.com/gitea:nightly
|
|
||||||
name: gitea
|
|
||||||
env:
|
|
||||||
USER_UID: 1000
|
|
||||||
USER_GID: 1000
|
|
||||||
restart_policy: always
|
|
||||||
recreate: true
|
|
||||||
state: started
|
|
||||||
volumes:
|
|
||||||
- /opt/apps/gitea:/data:z
|
|
||||||
- /usr/share/zoneinfo/America/Denver:/etc/timezone:ro
|
|
||||||
- /etc/localtime:/etc/localtime:ro
|
|
||||||
network:
|
|
||||||
- npm_internal
|
|
||||||
ip: '10.10.0.25'
|
|
||||||
ports:
|
|
||||||
# - "3000:3000"
|
|
||||||
- "222:22"
|
|
||||||
|
|
||||||
- name: Deploy Jellyfin
|
|
||||||
containers.podman.podman_container:
|
|
||||||
image: lscr.io/linuxserver/jellyfin:latest
|
|
||||||
name: jellyfin
|
|
||||||
env:
|
|
||||||
USER_UID: 1000
|
|
||||||
USER_GID: 1000
|
|
||||||
JELLYFIN_PublishedServerUrl: http://jellyfin.boxswapper.io
|
|
||||||
restart_policy: always
|
|
||||||
recreate: true
|
|
||||||
state: started
|
|
||||||
volumes:
|
|
||||||
- /opt/apps/jellyfin/config:/config:z
|
|
||||||
- /opt/apps/jellyfin/tvseries:/data/tvshows:z
|
|
||||||
- /opt/apps/jellyfin/movies:/data/movies:z
|
|
||||||
- /usr/share/zoneinfo/America/Denver:/etc/timezone:ro
|
|
||||||
- /etc/localtime:/etc/localtime:ro
|
|
||||||
network:
|
|
||||||
- npm_internal
|
|
||||||
ip: '10.10.0.30'
|
|
||||||
# ports:
|
|
||||||
# - 8096:8096
|
|
||||||
# - 8920:8920 #optional
|
|
||||||
# - 7359:7359/udp #optional
|
|
||||||
# - 1900:1900/udp #optional
|
|
||||||
|
|
||||||
# WireGuard Easy VPN (v15) — UI at 10.10.0.36:51821 on npm_internal, fronted by NPM
|
|
||||||
# (vpn.boxswapper.io -> http://10.10.0.36:51821). Login: admin / wireguard_ui_password from vars.yml.
|
|
||||||
# v15 init is ONE-TIME: the INIT_* envs below are consumed only when /etc/wireguard/wg-easy.db is ABSENT.
|
|
||||||
# Force a re-init (wipes clients + server keys): podman rm -f wg-easy && rm -rf /opt/apps/wireguard, then re-run.
|
|
||||||
# NAT from VPN clients to LAN/apps (10.10.1.0/24 -> 10.10.0.0/24) uses NFTABLES hooks —
|
|
||||||
# wg-easy's iptables-legacy hooks cannot init the nat table inside a podman netns
|
|
||||||
# ("Table does not exist"), which makes wg-quick up fail and every client API call
|
|
||||||
# 500 with "Unable to access interface". scripts/patch-wg-hooks.py rewrites the hooks
|
|
||||||
# to nft rules and the tasks below restart wg-easy to apply them. See the official
|
|
||||||
# wg-easy "Podman + nftables" tutorial.
|
|
||||||
# EXTERNAL ACCESS: router MUST forward UDP 51820 -> 192.168.0.98. Test from LTE,
|
|
||||||
# not your LAN — NAT hairpin breaks public-IP handshakes from inside the network.
|
|
||||||
- name: Deploy WireGuard Easy (wg-easy)
|
|
||||||
containers.podman.podman_container:
|
|
||||||
name: wg-easy
|
|
||||||
image: "{{ wireguard_image }}"
|
|
||||||
restart_policy: always
|
|
||||||
recreate: true
|
|
||||||
state: started
|
|
||||||
env:
|
|
||||||
INIT_ENABLED: "true"
|
|
||||||
INIT_USERNAME: "{{ wireguard_ui_username }}"
|
|
||||||
INIT_PASSWORD: "{{ wireguard_ui_password }}"
|
|
||||||
INIT_HOST: "{{ wireguard_host }}"
|
|
||||||
INIT_PORT: "{{ wireguard_port }}"
|
|
||||||
INIT_DNS: "{{ wireguard_default_dns }}"
|
|
||||||
INIT_IPV4_CIDR: "{{ wireguard_cidr }}"
|
|
||||||
INIT_IPV6_CIDR: "{{ wireguard_ipv6_cidr }}"
|
|
||||||
INIT_ALLOWED_IPS: "{{ wireguard_allowed_ips }}"
|
|
||||||
PORT: "{{ wireguard_ui_port }}"
|
|
||||||
INSECURE: "true"
|
|
||||||
DISABLE_VERSION_CHECK: "true"
|
|
||||||
ports:
|
|
||||||
- "{{ wireguard_port }}:{{ wireguard_port }}/udp"
|
|
||||||
- "{{ wireguard_ui_port }}:{{ wireguard_ui_port }}/tcp"
|
|
||||||
volumes:
|
|
||||||
- "/opt/apps/wireguard:/etc/wireguard:z"
|
|
||||||
- "/lib/modules:/lib/modules:ro"
|
|
||||||
cap_add:
|
|
||||||
- NET_ADMIN
|
|
||||||
- SYS_MODULE
|
|
||||||
- NET_RAW
|
|
||||||
sysctl:
|
|
||||||
net.ipv4.ip_forward: "1"
|
|
||||||
net.ipv4.conf.all.src_valid_mark: "1"
|
|
||||||
net.ipv6.conf.all.disable_ipv6: "0"
|
|
||||||
net.ipv6.conf.all.forwarding: "1"
|
|
||||||
net.ipv6.conf.default.forwarding: "1"
|
|
||||||
network:
|
|
||||||
- npm_internal
|
|
||||||
ip: '{{ wireguard_ip }}'
|
|
||||||
|
|
||||||
- name: Copy wg-easy hook repair script
|
|
||||||
ansible.builtin.copy:
|
|
||||||
src: ./scripts/patch-wg-hooks.py
|
|
||||||
dest: /opt/apps/wireguard/patch-wg-hooks.py
|
|
||||||
owner: root
|
|
||||||
group: root
|
|
||||||
mode: '0755'
|
|
||||||
|
|
||||||
- name: Replace iptables hooks with nftables (iptables-legacy broken in podman)
|
|
||||||
ansible.builtin.command: python3 /opt/apps/wireguard/patch-wg-hooks.py
|
|
||||||
register: wg_hooks_patch
|
|
||||||
changed_when: "'patched hooks' in wg_hooks_patch.stdout"
|
|
||||||
|
|
||||||
- name: Restart wg-easy to apply nft hooks
|
|
||||||
ansible.builtin.command: podman restart wg-easy
|
|
||||||
when: "'patched hooks' in wg_hooks_patch.stdout"
|
|
||||||
|
|
||||||
- name: Wait for WireGuard Easy web UI
|
|
||||||
ansible.builtin.wait_for:
|
|
||||||
host: '{{ wireguard_ip }}'
|
|
||||||
port: '{{ wireguard_ui_port }}'
|
|
||||||
delay: 5
|
|
||||||
timeout: 120
|
|
||||||
|
|
||||||
# Wazuh SIEM (single-node: indexer + manager + dashboard) on npm_internal
|
|
||||||
# Dashboard is NOT exposed on host ports — NPM proxies wazuh.boxswapper.io to https://10.10.0.40:5601
|
|
||||||
# DNS record must be grey-cloud (Cloudflare 523 lesson from vpn.boxswapper.io), cert via NPM
|
|
||||||
# Config is copied from ./wazuh-docker/config before first deploy
|
|
||||||
- name: Copy Wazuh config files to host
|
|
||||||
ansible.builtin.copy:
|
|
||||||
src: ./wazuh-docker/config/
|
|
||||||
dest: /opt/apps/wazuh/config/
|
|
||||||
owner: root
|
|
||||||
group: root
|
|
||||||
mode: preserve
|
|
||||||
force: true
|
|
||||||
|
|
||||||
- name: Check for stale Wazuh certificate residue
|
|
||||||
ansible.builtin.stat:
|
|
||||||
path: /opt/apps/wazuh/config/wazuh_indexer_ssl_certs/root-ca.pem
|
|
||||||
register: wazuh_cert_residue
|
|
||||||
|
|
||||||
- name: Remove stale Wazuh certificate directories
|
|
||||||
ansible.builtin.file:
|
|
||||||
path: /opt/apps/wazuh/config/wazuh_indexer_ssl_certs
|
|
||||||
state: absent
|
|
||||||
when: wazuh_cert_residue.stat.exists and wazuh_cert_residue.stat.isdir
|
|
||||||
|
|
||||||
- name: Recreate Wazuh certificates directory
|
|
||||||
ansible.builtin.file:
|
|
||||||
path: /opt/apps/wazuh/config/wazuh_indexer_ssl_certs
|
|
||||||
state: directory
|
|
||||||
mode: '0755'
|
|
||||||
owner: root
|
|
||||||
group: root
|
|
||||||
|
|
||||||
- name: Generate Wazuh certificates
|
|
||||||
ansible.builtin.command: podman run --rm -e CERT_TOOL_VERSION=4.14 -v /opt/apps/wazuh/config/certs.yml:/config/certs.yml:z -v /opt/apps/wazuh/config/wazuh_indexer_ssl_certs/:/certificates:z docker.io/wazuh/wazuh-certs-generator:0.0.3
|
|
||||||
args:
|
|
||||||
creates: /opt/apps/wazuh/config/wazuh_indexer_ssl_certs/root-ca.pem
|
|
||||||
|
|
||||||
- name: Copy root CA as manager root CA
|
|
||||||
ansible.builtin.copy:
|
|
||||||
src: /opt/apps/wazuh/config/wazuh_indexer_ssl_certs/root-ca.pem
|
|
||||||
dest: /opt/apps/wazuh/config/wazuh_indexer_ssl_certs/root-ca-manager.pem
|
|
||||||
remote_src: true
|
|
||||||
force: false
|
|
||||||
|
|
||||||
- name: Deploy Wazuh indexer
|
|
||||||
containers.podman.podman_container:
|
|
||||||
name: wazuh.indexer
|
|
||||||
image: "docker.io/wazuh/wazuh-indexer:{{ wazuh_version }}"
|
|
||||||
hostname: wazuh.indexer
|
|
||||||
restart_policy: always
|
|
||||||
recreate: true
|
|
||||||
state: started
|
|
||||||
env:
|
|
||||||
OPENSEARCH_JAVA_OPTS: "-Xms1g -Xmx1g"
|
|
||||||
ulimit:
|
|
||||||
- "memlock=-1:-1"
|
|
||||||
- "nofile=65536:65536"
|
|
||||||
volumes:
|
|
||||||
- "wazuh-indexer-data:/var/lib/wazuh-indexer"
|
|
||||||
- "/opt/apps/wazuh/config/wazuh_indexer_ssl_certs/root-ca.pem:/usr/share/wazuh-indexer/config/certs/root-ca.pem:z"
|
|
||||||
- "/opt/apps/wazuh/config/wazuh_indexer_ssl_certs/wazuh.indexer-key.pem:/usr/share/wazuh-indexer/config/certs/wazuh.indexer.key:z"
|
|
||||||
- "/opt/apps/wazuh/config/wazuh_indexer_ssl_certs/wazuh.indexer.pem:/usr/share/wazuh-indexer/config/certs/wazuh.indexer.pem:z"
|
|
||||||
- "/opt/apps/wazuh/config/wazuh_indexer_ssl_certs/admin.pem:/usr/share/wazuh-indexer/config/certs/admin.pem:z"
|
|
||||||
- "/opt/apps/wazuh/config/wazuh_indexer_ssl_certs/admin-key.pem:/usr/share/wazuh-indexer/config/certs/admin-key.pem:z"
|
|
||||||
- "/opt/apps/wazuh/config/wazuh_indexer/wazuh.indexer.yml:/usr/share/wazuh-indexer/config/opensearch.yml:z"
|
|
||||||
- "/opt/apps/wazuh/config/wazuh_indexer/internal_users.yml:/usr/share/wazuh-indexer/config/opensearch-security/internal_users.yml:z"
|
|
||||||
network:
|
|
||||||
- npm_internal
|
|
||||||
ip: '{{ wazuh_indexer_ip }}'
|
|
||||||
|
|
||||||
- name: Wait for Wazuh indexer to be ready
|
|
||||||
ansible.builtin.wait_for:
|
|
||||||
host: '{{ wazuh_indexer_ip }}'
|
|
||||||
port: 9200
|
|
||||||
delay: 10
|
|
||||||
timeout: 300
|
|
||||||
|
|
||||||
- name: Deploy Wazuh manager
|
|
||||||
containers.podman.podman_container:
|
|
||||||
name: wazuh.manager
|
|
||||||
image: "docker.io/wazuh/wazuh-manager:{{ wazuh_version }}"
|
|
||||||
hostname: wazuh.manager
|
|
||||||
restart_policy: always
|
|
||||||
recreate: true
|
|
||||||
state: started
|
|
||||||
env:
|
|
||||||
INDEXER_URL: "https://wazuh.indexer:9200"
|
|
||||||
INDEXER_USERNAME: "admin"
|
|
||||||
INDEXER_PASSWORD: "*WD*oW9m6iKf4hDovy7BbMmhLxC9D?Tv"
|
|
||||||
FILEBEAT_SSL_VERIFICATION_MODE: "full"
|
|
||||||
SSL_CERTIFICATE_AUTHORITIES: "/etc/ssl/root-ca.pem"
|
|
||||||
SSL_CERTIFICATE: "/etc/ssl/filebeat.pem"
|
|
||||||
SSL_KEY: "/etc/ssl/filebeat.key"
|
|
||||||
API_USERNAME: "wazuh-wui"
|
|
||||||
API_PASSWORD: "MyS3cr37P450r.*-"
|
|
||||||
ulimit:
|
|
||||||
- "memlock=-1:-1"
|
|
||||||
- "nofile=655360:655360"
|
|
||||||
ports:
|
|
||||||
- "1514:1514"
|
|
||||||
- "1515:1515"
|
|
||||||
- "514:514/udp"
|
|
||||||
- "55000:55000"
|
|
||||||
volumes:
|
|
||||||
- "wazuh_api_configuration:/var/ossec/api/configuration"
|
|
||||||
- "wazuh_etc:/var/ossec/etc"
|
|
||||||
- "wazuh_logs:/var/ossec/logs"
|
|
||||||
- "wazuh_queue:/var/ossec/queue"
|
|
||||||
- "wazuh_var_multigroups:/var/ossec/var/multigroups"
|
|
||||||
- "wazuh_integrations:/var/ossec/integrations"
|
|
||||||
- "wazuh_agentless:/var/ossec/agentless"
|
|
||||||
- "wazuh_active_response:/var/ossec/active-response/bin"
|
|
||||||
- "wazuh_wodles:/var/ossec/wodles"
|
|
||||||
- "filebeat_etc:/etc/filebeat"
|
|
||||||
- "filebeat_var:/var/lib/filebeat"
|
|
||||||
- "/opt/apps/wazuh/config/wazuh_indexer_ssl_certs/root-ca-manager.pem:/etc/ssl/root-ca.pem:z"
|
|
||||||
- "/opt/apps/wazuh/config/wazuh_indexer_ssl_certs/wazuh.manager.pem:/etc/ssl/filebeat.pem:z"
|
|
||||||
- "/opt/apps/wazuh/config/wazuh_indexer_ssl_certs/wazuh.manager-key.pem:/etc/ssl/filebeat.key:z"
|
|
||||||
- "/opt/apps/wazuh/config/wazuh_cluster/wazuh_manager.conf:/wazuh-config-mount/etc/ossec.conf:z"
|
|
||||||
network:
|
|
||||||
- npm_internal
|
|
||||||
ip: '{{ wazuh_manager_ip }}'
|
|
||||||
|
|
||||||
- name: Deploy Wazuh dashboard
|
|
||||||
containers.podman.podman_container:
|
|
||||||
name: wazuh.dashboard
|
|
||||||
image: "docker.io/wazuh/wazuh-dashboard:{{ wazuh_version }}"
|
|
||||||
hostname: wazuh.dashboard
|
|
||||||
restart_policy: always
|
|
||||||
recreate: true
|
|
||||||
state: started
|
|
||||||
env:
|
|
||||||
INDEXER_USERNAME: "admin"
|
|
||||||
INDEXER_PASSWORD: "*WD*oW9m6iKf4hDovy7BbMmhLxC9D?Tv"
|
|
||||||
WAZUH_API_URL: "https://wazuh.manager"
|
|
||||||
DASHBOARD_USERNAME: "kibanaserver"
|
|
||||||
DASHBOARD_PASSWORD: "kibanaserver"
|
|
||||||
API_USERNAME: "wazuh-wui"
|
|
||||||
API_PASSWORD: "MyS3cr37P450r.*-"
|
|
||||||
volumes:
|
|
||||||
- "/opt/apps/wazuh/config/wazuh_indexer_ssl_certs/wazuh.dashboard.pem:/usr/share/wazuh-dashboard/certs/wazuh-dashboard.pem:z"
|
|
||||||
- "/opt/apps/wazuh/config/wazuh_indexer_ssl_certs/wazuh.dashboard-key.pem:/usr/share/wazuh-dashboard/certs/wazuh-dashboard-key.pem:z"
|
|
||||||
- "/opt/apps/wazuh/config/wazuh_indexer_ssl_certs/root-ca.pem:/usr/share/wazuh-dashboard/certs/root-ca.pem:z"
|
|
||||||
- "/opt/apps/wazuh/config/wazuh_dashboard/opensearch_dashboards.yml:/usr/share/wazuh-dashboard/config/opensearch_dashboards.yml:z"
|
|
||||||
- "/opt/apps/wazuh/config/wazuh_dashboard/wazuh.yml:/usr/share/wazuh-dashboard/data/wazuh/config/wazuh.yml:z"
|
|
||||||
- "wazuh-dashboard-config:/usr/share/wazuh-dashboard/data/wazuh/config"
|
|
||||||
- "wazuh-dashboard-custom:/usr/share/wazuh-dashboard/plugins/wazuh/public/assets/custom"
|
|
||||||
network:
|
|
||||||
- npm_internal
|
|
||||||
ip: '{{ wazuh_dashboard_ip }}'
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#----N8N deployment, no GPU avail for deployment ------#
|
|
||||||
|
|
||||||
# - name: Deploy n8n
|
|
||||||
# containers.podman.podman_container:
|
|
||||||
# image: docker.n8n.io/n8nio/n8n
|
|
||||||
# name: n8n
|
|
||||||
# env:
|
|
||||||
# N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS: true
|
|
||||||
# N8N_RUNNERS_ENABLED: true
|
|
||||||
# restart_policy: always
|
|
||||||
# recreate: true
|
|
||||||
# state: started
|
|
||||||
# volumes:
|
|
||||||
# - /opt/apps/n8n/data:/home/node/.n8n:z
|
|
||||||
# - /opt/apps/n8n/files:/files:z
|
|
||||||
# - /usr/share/zoneinfo/America/Denver:/etc/timezone:ro
|
|
||||||
# - /etc/localtime:/etc/localtime:ro
|
|
||||||
|
|
||||||
# network:
|
|
||||||
# - npm_internal
|
|
||||||
# ip: '10.10.0.35'
|
|
||||||
# # ports:
|
|
||||||
# # - 5678:5678
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
14
roles/directories/tasks/main.yml
Normal file
14
roles/directories/tasks/main.yml
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
---
|
||||||
|
- name: Create directories
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "{{ item }}"
|
||||||
|
state: directory
|
||||||
|
mode: '0755'
|
||||||
|
loop: "{{ directories }}"
|
||||||
|
|
||||||
|
- name: Create Jellyfin directories
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "{{ item }}"
|
||||||
|
state: directory
|
||||||
|
mode: '0777'
|
||||||
|
loop: "{{ directories_jellyfin }}"
|
||||||
20
roles/gitea/tasks/main.yml
Normal file
20
roles/gitea/tasks/main.yml
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
---
|
||||||
|
- name: Deploy Gitea
|
||||||
|
containers.podman.podman_container:
|
||||||
|
image: docker.gitea.com/gitea:nightly
|
||||||
|
name: gitea
|
||||||
|
env:
|
||||||
|
USER_UID: 1000
|
||||||
|
USER_GID: 1000
|
||||||
|
restart_policy: always
|
||||||
|
recreate: true
|
||||||
|
state: started
|
||||||
|
volumes:
|
||||||
|
- /opt/apps/gitea:/data:z
|
||||||
|
- /usr/share/zoneinfo/America/Denver:/etc/timezone:ro
|
||||||
|
- /etc/localtime:/etc/localtime:ro
|
||||||
|
network:
|
||||||
|
- npm_internal
|
||||||
|
ip: '10.10.0.25'
|
||||||
|
ports:
|
||||||
|
- "222:22"
|
||||||
21
roles/jellyfin/tasks/main.yml
Normal file
21
roles/jellyfin/tasks/main.yml
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
---
|
||||||
|
- name: Deploy Jellyfin
|
||||||
|
containers.podman.podman_container:
|
||||||
|
image: lscr.io/linuxserver/jellyfin:latest
|
||||||
|
name: jellyfin
|
||||||
|
env:
|
||||||
|
USER_UID: 1000
|
||||||
|
USER_GID: 1000
|
||||||
|
JELLYFIN_PublishedServerUrl: http://jellyfin.boxswapper.io
|
||||||
|
restart_policy: always
|
||||||
|
recreate: true
|
||||||
|
state: started
|
||||||
|
volumes:
|
||||||
|
- /opt/apps/jellyfin/config:/config:z
|
||||||
|
- /opt/apps/jellyfin/tvseries:/data/tvshows:z
|
||||||
|
- /opt/apps/jellyfin/movies:/data/movies:z
|
||||||
|
- /usr/share/zoneinfo/America/Denver:/etc/timezone:ro
|
||||||
|
- /etc/localtime:/etc/localtime:ro
|
||||||
|
network:
|
||||||
|
- npm_internal
|
||||||
|
ip: '10.10.0.30'
|
||||||
8
roles/network/tasks/main.yml
Normal file
8
roles/network/tasks/main.yml
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
---
|
||||||
|
- name: Create internal podman network
|
||||||
|
containers.podman.podman_network:
|
||||||
|
name: npm_internal
|
||||||
|
ip_range: 10.10.0.128/25
|
||||||
|
subnet: 10.10.0.0/24
|
||||||
|
gateway: 10.10.0.1
|
||||||
|
state: present
|
||||||
18
roles/npm/tasks/main.yml
Normal file
18
roles/npm/tasks/main.yml
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
---
|
||||||
|
- name: Deploy Nginx Proxy Manager
|
||||||
|
containers.podman.podman_container:
|
||||||
|
image: "docker.io/jc21/nginx-proxy-manager:latest"
|
||||||
|
name: npm
|
||||||
|
restart_policy: always
|
||||||
|
recreate: true
|
||||||
|
state: started
|
||||||
|
ports:
|
||||||
|
- "80:80"
|
||||||
|
- "81:81"
|
||||||
|
- "443:443"
|
||||||
|
volumes:
|
||||||
|
- "/opt/apps/npm:/data:z"
|
||||||
|
- "/opt/apps/letsencrypt:/etc/letsencrypt:z"
|
||||||
|
network:
|
||||||
|
- npm_internal
|
||||||
|
ip: '10.10.0.19'
|
||||||
45
roles/packages/tasks/main.yml
Normal file
45
roles/packages/tasks/main.yml
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
---
|
||||||
|
- name: Update Packages
|
||||||
|
ansible.builtin.dnf:
|
||||||
|
update_cache: yes
|
||||||
|
|
||||||
|
- name: Apply security updates
|
||||||
|
ansible.builtin.dnf:
|
||||||
|
name: "*"
|
||||||
|
state: latest
|
||||||
|
security: yes
|
||||||
|
update_cache: yes
|
||||||
|
|
||||||
|
- name: Install Packages
|
||||||
|
ansible.builtin.dnf:
|
||||||
|
name:
|
||||||
|
- vim
|
||||||
|
- podman
|
||||||
|
- fail2ban
|
||||||
|
- python3-libdnf5
|
||||||
|
state: present
|
||||||
|
|
||||||
|
- name: Copy Wazuh agent RPM to host
|
||||||
|
ansible.builtin.copy:
|
||||||
|
src: "{{ playbook_dir }}/{{ wazuh_agent_rpm }}"
|
||||||
|
dest: "/tmp/{{ wazuh_agent_rpm }}"
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: '0644'
|
||||||
|
|
||||||
|
- name: Install Wazuh agent RPM
|
||||||
|
ansible.builtin.dnf:
|
||||||
|
name: "/tmp/{{ wazuh_agent_rpm }}"
|
||||||
|
state: present
|
||||||
|
|
||||||
|
- name: Point Wazuh agent at Wazuh manager
|
||||||
|
ansible.builtin.replace:
|
||||||
|
path: /var/ossec/etc/ossec.conf
|
||||||
|
regexp: '<address>MANAGER_IP</address>'
|
||||||
|
replace: '<address>{{ wazuh_server_address }}</address>'
|
||||||
|
|
||||||
|
- name: Enable and start Wazuh agent
|
||||||
|
ansible.builtin.systemd:
|
||||||
|
name: wazuh-agent
|
||||||
|
enabled: true
|
||||||
|
state: started
|
||||||
23
roles/sysctl/tasks/main.yml
Normal file
23
roles/sysctl/tasks/main.yml
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
---
|
||||||
|
- name: Enable IP forwarding on host
|
||||||
|
ansible.posix.sysctl:
|
||||||
|
name: net.ipv4.ip_forward
|
||||||
|
value: '1'
|
||||||
|
sysctl_set: true
|
||||||
|
state: present
|
||||||
|
|
||||||
|
- name: Enable source valid mark on host
|
||||||
|
ansible.posix.sysctl:
|
||||||
|
name: net.ipv4.conf.all.src_valid_mark
|
||||||
|
value: '1'
|
||||||
|
sysctl_set: true
|
||||||
|
state: present
|
||||||
|
reload: true
|
||||||
|
|
||||||
|
- name: Raise vm.max_map_count for Wazuh indexer
|
||||||
|
ansible.posix.sysctl:
|
||||||
|
name: vm.max_map_count
|
||||||
|
value: '262144'
|
||||||
|
sysctl_set: true
|
||||||
|
state: present
|
||||||
|
reload: true
|
||||||
157
roles/wazuh/tasks/main.yml
Normal file
157
roles/wazuh/tasks/main.yml
Normal file
@@ -0,0 +1,157 @@
|
|||||||
|
---
|
||||||
|
# Wazuh SIEM (single-node: indexer + manager + dashboard) on npm_internal
|
||||||
|
# Dashboard is NOT exposed on host ports — NPM proxies wazuh.boxswapper.io to https://10.10.0.40:5601
|
||||||
|
# DNS record must be grey-cloud (Cloudflare 523 lesson from vpn.boxswapper.io), cert via NPM
|
||||||
|
# Config is copied from ./wazuh-docker/config before first deploy
|
||||||
|
|
||||||
|
- name: Copy Wazuh config files to host
|
||||||
|
ansible.builtin.copy:
|
||||||
|
src: ./wazuh-docker/config/
|
||||||
|
dest: /opt/apps/wazuh/config/
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: preserve
|
||||||
|
force: true
|
||||||
|
|
||||||
|
- name: Check for stale Wazuh certificate residue
|
||||||
|
ansible.builtin.stat:
|
||||||
|
path: /opt/apps/wazuh/config/wazuh_indexer_ssl_certs/root-ca.pem
|
||||||
|
register: wazuh_cert_residue
|
||||||
|
|
||||||
|
- name: Remove stale Wazuh certificate directories
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: /opt/apps/wazuh/config/wazuh_indexer_ssl_certs
|
||||||
|
state: absent
|
||||||
|
when: wazuh_cert_residue.stat.exists and wazuh_cert_residue.stat.isdir
|
||||||
|
|
||||||
|
- name: Recreate Wazuh certificates directory
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: /opt/apps/wazuh/config/wazuh_indexer_ssl_certs
|
||||||
|
state: directory
|
||||||
|
mode: '0755'
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
|
||||||
|
- name: Generate Wazuh certificates
|
||||||
|
ansible.builtin.command: >
|
||||||
|
podman run --rm
|
||||||
|
-e CERT_TOOL_VERSION=4.14
|
||||||
|
-v /opt/apps/wazuh/config/certs.yml:/config/certs.yml:z
|
||||||
|
-v /opt/apps/wazuh/config/wazuh_indexer_ssl_certs/:/certificates:z
|
||||||
|
docker.io/wazuh/wazuh-certs-generator:0.0.3
|
||||||
|
args:
|
||||||
|
creates: /opt/apps/wazuh/config/wazuh_indexer_ssl_certs/root-ca.pem
|
||||||
|
|
||||||
|
- name: Copy root CA as manager root CA
|
||||||
|
ansible.builtin.copy:
|
||||||
|
src: /opt/apps/wazuh/config/wazuh_indexer_ssl_certs/root-ca.pem
|
||||||
|
dest: /opt/apps/wazuh/config/wazuh_indexer_ssl_certs/root-ca-manager.pem
|
||||||
|
remote_src: true
|
||||||
|
force: false
|
||||||
|
|
||||||
|
- name: Deploy Wazuh indexer
|
||||||
|
containers.podman.podman_container:
|
||||||
|
name: wazuh.indexer
|
||||||
|
image: "docker.io/wazuh/wazuh-indexer:{{ wazuh_version }}"
|
||||||
|
hostname: wazuh.indexer
|
||||||
|
restart_policy: always
|
||||||
|
recreate: true
|
||||||
|
state: started
|
||||||
|
env:
|
||||||
|
OPENSEARCH_JAVA_OPTS: "-Xms1g -Xmx1g"
|
||||||
|
ulimit:
|
||||||
|
- "memlock=-1:-1"
|
||||||
|
- "nofile=65536:65536"
|
||||||
|
volumes:
|
||||||
|
- "wazuh-indexer-data:/var/lib/wazuh-indexer"
|
||||||
|
- "/opt/apps/wazuh/config/wazuh_indexer_ssl_certs/root-ca.pem:/usr/share/wazuh-indexer/config/certs/root-ca.pem:z"
|
||||||
|
- "/opt/apps/wazuh/config/wazuh_indexer_ssl_certs/wazuh.indexer-key.pem:/usr/share/wazuh-indexer/config/certs/wazuh.indexer.key:z"
|
||||||
|
- "/opt/apps/wazuh/config/wazuh_indexer_ssl_certs/wazuh.indexer.pem:/usr/share/wazuh-indexer/config/certs/wazuh.indexer.pem:z"
|
||||||
|
- "/opt/apps/wazuh/config/wazuh_indexer_ssl_certs/admin.pem:/usr/share/wazuh-indexer/config/certs/admin.pem:z"
|
||||||
|
- "/opt/apps/wazuh/config/wazuh_indexer_ssl_certs/admin-key.pem:/usr/share/wazuh-indexer/config/certs/admin-key.pem:z"
|
||||||
|
- "/opt/apps/wazuh/config/wazuh_indexer/wazuh.indexer.yml:/usr/share/wazuh-indexer/config/opensearch.yml:z"
|
||||||
|
- "/opt/apps/wazuh/config/wazuh_indexer/internal_users.yml:/usr/share/wazuh-indexer/config/opensearch-security/internal_users.yml:z"
|
||||||
|
network:
|
||||||
|
- npm_internal
|
||||||
|
ip: '{{ wazuh_indexer_ip }}'
|
||||||
|
|
||||||
|
- name: Wait for Wazuh indexer to be ready
|
||||||
|
ansible.builtin.wait_for:
|
||||||
|
host: '{{ wazuh_indexer_ip }}'
|
||||||
|
port: 9200
|
||||||
|
delay: 10
|
||||||
|
timeout: 300
|
||||||
|
|
||||||
|
- name: Deploy Wazuh manager
|
||||||
|
containers.podman.podman_container:
|
||||||
|
name: wazuh.manager
|
||||||
|
image: "docker.io/wazuh/wazuh-manager:{{ wazuh_version }}"
|
||||||
|
hostname: wazuh.manager
|
||||||
|
restart_policy: always
|
||||||
|
recreate: true
|
||||||
|
state: started
|
||||||
|
env:
|
||||||
|
INDEXER_URL: "https://wazuh.indexer:9200"
|
||||||
|
INDEXER_USERNAME: "admin"
|
||||||
|
INDEXER_PASSWORD: "*WD*oW9m6iKf4hDovy7BbMmhLxC9D?Tv"
|
||||||
|
FILEBEAT_SSL_VERIFICATION_MODE: "full"
|
||||||
|
SSL_CERTIFICATE_AUTHORITIES: "/etc/ssl/root-ca.pem"
|
||||||
|
SSL_CERTIFICATE: "/etc/ssl/filebeat.pem"
|
||||||
|
SSL_KEY: "/etc/ssl/filebeat.key"
|
||||||
|
API_USERNAME: "wazuh-wui"
|
||||||
|
API_PASSWORD: "MyS3cr37P450r.*-"
|
||||||
|
ulimit:
|
||||||
|
- "memlock=-1:-1"
|
||||||
|
- "nofile=655360:655360"
|
||||||
|
ports:
|
||||||
|
- "1514:1514"
|
||||||
|
- "1515:1515"
|
||||||
|
- "514:514/udp"
|
||||||
|
- "55000:55000"
|
||||||
|
volumes:
|
||||||
|
- "wazuh_api_configuration:/var/ossec/api/configuration"
|
||||||
|
- "wazuh_etc:/var/ossec/etc"
|
||||||
|
- "wazuh_logs:/var/ossec/logs"
|
||||||
|
- "wazuh_queue:/var/ossec/queue"
|
||||||
|
- "wazuh_var_multigroups:/var/ossec/var/multigroups"
|
||||||
|
- "wazuh_integrations:/var/ossec/integrations"
|
||||||
|
- "wazuh_agentless:/var/ossec/agentless"
|
||||||
|
- "wazuh_active_response:/var/ossec/active-response/bin"
|
||||||
|
- "wazuh_wodles:/var/ossec/wodles"
|
||||||
|
- "filebeat_etc:/etc/filebeat"
|
||||||
|
- "filebeat_var:/var/lib/filebeat"
|
||||||
|
- "/opt/apps/wazuh/config/wazuh_indexer_ssl_certs/root-ca-manager.pem:/etc/ssl/root-ca.pem:z"
|
||||||
|
- "/opt/apps/wazuh/config/wazuh_indexer_ssl_certs/wazuh.manager.pem:/etc/ssl/filebeat.pem:z"
|
||||||
|
- "/opt/apps/wazuh/config/wazuh_indexer_ssl_certs/wazuh.manager-key.pem:/etc/ssl/filebeat.key:z"
|
||||||
|
- "/opt/apps/wazuh/config/wazuh_cluster/wazuh_manager.conf:/wazuh-config-mount/etc/ossec.conf:z"
|
||||||
|
network:
|
||||||
|
- npm_internal
|
||||||
|
ip: '{{ wazuh_manager_ip }}'
|
||||||
|
|
||||||
|
- name: Deploy Wazuh dashboard
|
||||||
|
containers.podman.podman_container:
|
||||||
|
name: wazuh.dashboard
|
||||||
|
image: "docker.io/wazuh/wazuh-dashboard:{{ wazuh_version }}"
|
||||||
|
hostname: wazuh.dashboard
|
||||||
|
restart_policy: always
|
||||||
|
recreate: true
|
||||||
|
state: started
|
||||||
|
env:
|
||||||
|
INDEXER_USERNAME: "admin"
|
||||||
|
INDEXER_PASSWORD: "*WD*oW9m6iKf4hDovy7BbMmhLxC9D?Tv"
|
||||||
|
WAZUH_API_URL: "https://wazuh.manager"
|
||||||
|
DASHBOARD_USERNAME: "kibanaserver"
|
||||||
|
DASHBOARD_PASSWORD: "kibanaserver"
|
||||||
|
API_USERNAME: "wazuh-wui"
|
||||||
|
API_PASSWORD: "MyS3cr37P450r.*-"
|
||||||
|
volumes:
|
||||||
|
- "/opt/apps/wazuh/config/wazuh_indexer_ssl_certs/wazuh.dashboard.pem:/usr/share/wazuh-dashboard/certs/wazuh-dashboard.pem:z"
|
||||||
|
- "/opt/apps/wazuh/config/wazuh_indexer_ssl_certs/wazuh.dashboard-key.pem:/usr/share/wazuh-dashboard/certs/wazuh-dashboard-key.pem:z"
|
||||||
|
- "/opt/apps/wazuh/config/wazuh_indexer_ssl_certs/root-ca.pem:/usr/share/wazuh-dashboard/certs/root-ca.pem:z"
|
||||||
|
- "/opt/apps/wazuh/config/wazuh_dashboard/opensearch_dashboards.yml:/usr/share/wazuh-dashboard/config/opensearch_dashboards.yml:z"
|
||||||
|
- "/opt/apps/wazuh/config/wazuh_dashboard/wazuh.yml:/usr/share/wazuh-dashboard/data/wazuh/config/wazuh.yml:z"
|
||||||
|
- "wazuh-dashboard-config:/usr/share/wazuh-dashboard/data/wazuh/config"
|
||||||
|
- "wazuh-dashboard-custom:/usr/share/wazuh-dashboard/plugins/wazuh/public/assets/custom"
|
||||||
|
network:
|
||||||
|
- npm_internal
|
||||||
|
ip: '{{ wazuh_dashboard_ip }}'
|
||||||
89
roles/wireguard/tasks/main.yml
Normal file
89
roles/wireguard/tasks/main.yml
Normal file
@@ -0,0 +1,89 @@
|
|||||||
|
---
|
||||||
|
- name: Ensure WireGuard kernel module is loaded
|
||||||
|
ansible.builtin.modprobe:
|
||||||
|
name: wireguard
|
||||||
|
state: present
|
||||||
|
|
||||||
|
- name: Persist WireGuard kernel module across reboots
|
||||||
|
ansible.builtin.copy:
|
||||||
|
dest: /etc/modules-load.d/wg-easy.conf
|
||||||
|
content: |
|
||||||
|
wireguard
|
||||||
|
nft_masq
|
||||||
|
mode: '0644'
|
||||||
|
|
||||||
|
# WireGuard Easy VPN (v15) — UI at 10.10.0.36:51821 on npm_internal, fronted by NPM
|
||||||
|
# (vpn.boxswapper.io -> http://10.10.0.36:51821). Login: admin / wireguard_ui_password from vars.yml.
|
||||||
|
# v15 init is ONE-TIME: the INIT_* envs below are consumed only when /etc/wireguard/wg-easy.db is ABSENT.
|
||||||
|
# Force a re-init (wipes clients + server keys): podman rm -f wg-easy && rm -rf /opt/apps/wireguard, then re-run.
|
||||||
|
# NAT from VPN clients to LAN/apps (10.10.1.0/24 -> 10.10.0.0/24) uses NFTABLES hooks —
|
||||||
|
# wg-easy's iptables-legacy hooks cannot init the nat table inside a podman netns
|
||||||
|
# ("Table does not exist"), which makes wg-quick up fail and every client API call
|
||||||
|
# 500 with "Unable to access interface". scripts/patch-wg-hooks.py rewrites the hooks
|
||||||
|
# to nft rules and the tasks below restart wg-easy to apply them. See the official
|
||||||
|
# wg-easy "Podman + nftables" tutorial.
|
||||||
|
# EXTERNAL ACCESS: router MUST forward UDP 51820 -> 192.168.0.98. Test from LTE,
|
||||||
|
# not your LAN — NAT hairpin breaks public-IP handshakes from inside the network.
|
||||||
|
- name: Deploy WireGuard Easy (wg-easy)
|
||||||
|
containers.podman.podman_container:
|
||||||
|
name: wg-easy
|
||||||
|
image: "{{ wireguard_image }}"
|
||||||
|
restart_policy: always
|
||||||
|
recreate: true
|
||||||
|
state: started
|
||||||
|
env:
|
||||||
|
INIT_ENABLED: "true"
|
||||||
|
INIT_USERNAME: "{{ wireguard_ui_username }}"
|
||||||
|
INIT_PASSWORD: "{{ wireguard_ui_password }}"
|
||||||
|
INIT_HOST: "{{ wireguard_host }}"
|
||||||
|
INIT_PORT: "{{ wireguard_port }}"
|
||||||
|
INIT_DNS: "{{ wireguard_default_dns }}"
|
||||||
|
INIT_IPV4_CIDR: "{{ wireguard_cidr }}"
|
||||||
|
INIT_IPV6_CIDR: "{{ wireguard_ipv6_cidr }}"
|
||||||
|
INIT_ALLOWED_IPS: "{{ wireguard_allowed_ips }}"
|
||||||
|
PORT: "{{ wireguard_ui_port }}"
|
||||||
|
INSECURE: "true"
|
||||||
|
DISABLE_VERSION_CHECK: "true"
|
||||||
|
ports:
|
||||||
|
- "{{ wireguard_port }}:{{ wireguard_port }}/udp"
|
||||||
|
- "{{ wireguard_ui_port }}:{{ wireguard_ui_port }}/tcp"
|
||||||
|
volumes:
|
||||||
|
- "/opt/apps/wireguard:/etc/wireguard:z"
|
||||||
|
- "/lib/modules:/lib/modules:ro"
|
||||||
|
cap_add:
|
||||||
|
- NET_ADMIN
|
||||||
|
- SYS_MODULE
|
||||||
|
- NET_RAW
|
||||||
|
sysctl:
|
||||||
|
net.ipv4.ip_forward: "1"
|
||||||
|
net.ipv4.conf.all.src_valid_mark: "1"
|
||||||
|
net.ipv6.conf.all.disable_ipv6: "0"
|
||||||
|
net.ipv6.conf.all.forwarding: "1"
|
||||||
|
net.ipv6.conf.default.forwarding: "1"
|
||||||
|
network:
|
||||||
|
- npm_internal
|
||||||
|
ip: '{{ wireguard_ip }}'
|
||||||
|
|
||||||
|
- name: Copy wg-easy hook repair script
|
||||||
|
ansible.builtin.copy:
|
||||||
|
src: ./scripts/patch-wg-hooks.py
|
||||||
|
dest: /opt/apps/wireguard/patch-wg-hooks.py
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: '0755'
|
||||||
|
|
||||||
|
- name: Replace iptables hooks with nftables (iptables-legacy broken in podman)
|
||||||
|
ansible.builtin.command: python3 /opt/apps/wireguard/patch-wg-hooks.py
|
||||||
|
register: wg_hooks_patch
|
||||||
|
changed_when: "'patched hooks' in wg_hooks_patch.stdout"
|
||||||
|
|
||||||
|
- name: Restart wg-easy to apply nft hooks
|
||||||
|
ansible.builtin.command: podman restart wg-easy
|
||||||
|
when: "'patched hooks' in wg_hooks_patch.stdout"
|
||||||
|
|
||||||
|
- name: Wait for WireGuard Easy web UI
|
||||||
|
ansible.builtin.wait_for:
|
||||||
|
host: '{{ wireguard_ip }}'
|
||||||
|
port: '{{ wireguard_ui_port }}'
|
||||||
|
delay: 5
|
||||||
|
timeout: 120
|
||||||
5
vars.yml
5
vars.yml
@@ -62,3 +62,8 @@ wazuh_dashboard_ip: 10.10.0.40
|
|||||||
wazuh_manager_ip: 10.10.0.41
|
wazuh_manager_ip: 10.10.0.41
|
||||||
wazuh_indexer_ip: 10.10.0.42
|
wazuh_indexer_ip: 10.10.0.42
|
||||||
|
|
||||||
|
## Wazuh agent (installed on this host by packages role)
|
||||||
|
## Server address the agent reports to (manager reachable on ports 1514/1515 via router forwarding)
|
||||||
|
wazuh_agent_rpm: wazuh-agent-4.14.1-1.x86_64.rpm
|
||||||
|
wazuh_server_address: wazuh.boxswapper.io
|
||||||
|
|
||||||
|
|||||||
@@ -1,24 +0,0 @@
|
|||||||
# Deploy Wazuh Docker in single node configuration
|
|
||||||
|
|
||||||
This deployment is defined in the `docker-compose.yml` file with one Wazuh manager containers, one Wazuh indexer containers, and one Wazuh dashboard container. It can be deployed by following these steps:
|
|
||||||
|
|
||||||
1) Increase max_map_count on your host (Linux). This command must be run with root permissions:
|
|
||||||
```
|
|
||||||
$ sysctl -w vm.max_map_count=262144
|
|
||||||
```
|
|
||||||
2) Run the certificate creation script:
|
|
||||||
```
|
|
||||||
$ docker compose -f generate-indexer-certs.yml run --rm generator
|
|
||||||
```
|
|
||||||
3) Start the environment with docker compose:
|
|
||||||
|
|
||||||
- In the foregroud:
|
|
||||||
```
|
|
||||||
$ docker compose up
|
|
||||||
```
|
|
||||||
- In the background:
|
|
||||||
```
|
|
||||||
$ docker compose up -d
|
|
||||||
```
|
|
||||||
|
|
||||||
The environment takes about 1 minute to get up (depending on your Docker host) for the first time since Wazuh Indexer must be started for the first time and the indexes and index patterns must be generated.
|
|
||||||
@@ -1,109 +0,0 @@
|
|||||||
# Wazuh App Copyright (C) 2017, Wazuh Inc. (License GPLv2)
|
|
||||||
services:
|
|
||||||
wazuh.manager:
|
|
||||||
image: wazuh/wazuh-manager:5.0.0
|
|
||||||
hostname: wazuh.manager
|
|
||||||
restart: always
|
|
||||||
ulimits:
|
|
||||||
memlock:
|
|
||||||
soft: -1
|
|
||||||
hard: -1
|
|
||||||
nofile:
|
|
||||||
soft: 655360
|
|
||||||
hard: 655360
|
|
||||||
ports:
|
|
||||||
- "1514:1514"
|
|
||||||
- "1515:1515"
|
|
||||||
- "514:514/udp"
|
|
||||||
- "55000:55000"
|
|
||||||
environment:
|
|
||||||
- INDEXER_URL=https://wazuh.indexer:9200
|
|
||||||
- INDEXER_USERNAME=admin
|
|
||||||
- INDEXER_PASSWORD=*WD*oW9m6iKf4hDovy7BbMmhLxC9D?Tv
|
|
||||||
- FILEBEAT_SSL_VERIFICATION_MODE=full
|
|
||||||
- SSL_CERTIFICATE_AUTHORITIES=/etc/ssl/root-ca.pem
|
|
||||||
- SSL_CERTIFICATE=/etc/ssl/filebeat.pem
|
|
||||||
- SSL_KEY=/etc/ssl/filebeat.key
|
|
||||||
- API_USERNAME=wazuh-wui
|
|
||||||
- API_PASSWORD=MyS3cr37P450r.*-
|
|
||||||
volumes:
|
|
||||||
- wazuh_api_configuration:/var/ossec/api/configuration
|
|
||||||
- wazuh_etc:/var/ossec/etc
|
|
||||||
- wazuh_logs:/var/ossec/logs
|
|
||||||
- wazuh_queue:/var/ossec/queue
|
|
||||||
- wazuh_var_multigroups:/var/ossec/var/multigroups
|
|
||||||
- wazuh_active_response:/var/ossec/active-response/bin
|
|
||||||
- wazuh_wodles:/var/ossec/wodles
|
|
||||||
- filebeat_etc:/etc/filebeat
|
|
||||||
- filebeat_var:/var/lib/filebeat
|
|
||||||
- ./config/wazuh_indexer_ssl_certs/root-ca-manager.pem:/etc/ssl/root-ca.pem
|
|
||||||
- ./config/wazuh_indexer_ssl_certs/wazuh.manager.pem:/etc/ssl/filebeat.pem
|
|
||||||
- ./config/wazuh_indexer_ssl_certs/wazuh.manager-key.pem:/etc/ssl/filebeat.key
|
|
||||||
- ./config/wazuh_cluster/wazuh_manager.conf:/wazuh-config-mount/etc/ossec.conf
|
|
||||||
|
|
||||||
wazuh.indexer:
|
|
||||||
image: wazuh/wazuh-indexer:5.0.0
|
|
||||||
hostname: wazuh.indexer
|
|
||||||
restart: always
|
|
||||||
ports:
|
|
||||||
- "9200:9200"
|
|
||||||
environment:
|
|
||||||
- "OPENSEARCH_JAVA_OPTS=-Xms1g -Xmx1g"
|
|
||||||
ulimits:
|
|
||||||
memlock:
|
|
||||||
soft: -1
|
|
||||||
hard: -1
|
|
||||||
nofile:
|
|
||||||
soft: 65536
|
|
||||||
hard: 65536
|
|
||||||
volumes:
|
|
||||||
- wazuh-indexer-data:/var/lib/wazuh-indexer
|
|
||||||
- ./config/wazuh_indexer_ssl_certs/root-ca.pem:/usr/share/wazuh-indexer/config/certs/root-ca.pem
|
|
||||||
- ./config/wazuh_indexer_ssl_certs/wazuh.indexer-key.pem:/usr/share/wazuh-indexer/config/certs/wazuh.indexer.key
|
|
||||||
- ./config/wazuh_indexer_ssl_certs/wazuh.indexer.pem:/usr/share/wazuh-indexer/config/certs/wazuh.indexer.pem
|
|
||||||
- ./config/wazuh_indexer_ssl_certs/admin.pem:/usr/share/wazuh-indexer/config/certs/admin.pem
|
|
||||||
- ./config/wazuh_indexer_ssl_certs/admin-key.pem:/usr/share/wazuh-indexer/config/certs/admin-key.pem
|
|
||||||
- ./config/wazuh_indexer/wazuh.indexer.yml:/usr/share/wazuh-indexer/config/opensearch.yml
|
|
||||||
- ./config/wazuh_indexer/internal_users.yml:/usr/share/wazuh-indexer/config/opensearch-security/internal_users.yml
|
|
||||||
|
|
||||||
wazuh.dashboard:
|
|
||||||
image: wazuh/wazuh-dashboard:5.0.0
|
|
||||||
hostname: wazuh.dashboard
|
|
||||||
restart: always
|
|
||||||
ports:
|
|
||||||
- 443:5601
|
|
||||||
environment:
|
|
||||||
- INDEXER_USERNAME=admin
|
|
||||||
- INDEXER_PASSWORD=SecretPassword
|
|
||||||
- WAZUH_API_URL=https://wazuh.manager
|
|
||||||
- DASHBOARD_USERNAME=kibanaserver
|
|
||||||
- DASHBOARD_PASSWORD=kibanaserver
|
|
||||||
- API_USERNAME=wazuh-wui
|
|
||||||
- API_PASSWORD=MyS3cr37P450r.*-
|
|
||||||
volumes:
|
|
||||||
- ./config/wazuh_indexer_ssl_certs/wazuh.dashboard.pem:/usr/share/wazuh-dashboard/certs/wazuh-dashboard.pem
|
|
||||||
- ./config/wazuh_indexer_ssl_certs/wazuh.dashboard-key.pem:/usr/share/wazuh-dashboard/certs/wazuh-dashboard-key.pem
|
|
||||||
- ./config/wazuh_indexer_ssl_certs/root-ca.pem:/usr/share/wazuh-dashboard/certs/root-ca.pem
|
|
||||||
- ./config/wazuh_dashboard/opensearch_dashboards.yml:/usr/share/wazuh-dashboard/config/opensearch_dashboards.yml
|
|
||||||
- ./config/wazuh_dashboard/wazuh.yml:/usr/share/wazuh-dashboard/data/wazuh/config/wazuh.yml
|
|
||||||
- wazuh-dashboard-config:/usr/share/wazuh-dashboard/data/wazuh/config
|
|
||||||
- wazuh-dashboard-custom:/usr/share/wazuh-dashboard/plugins/wazuh/public/assets/custom
|
|
||||||
depends_on:
|
|
||||||
- wazuh.indexer
|
|
||||||
links:
|
|
||||||
- wazuh.indexer:wazuh.indexer
|
|
||||||
- wazuh.manager:wazuh.manager
|
|
||||||
|
|
||||||
volumes:
|
|
||||||
wazuh_api_configuration:
|
|
||||||
wazuh_etc:
|
|
||||||
wazuh_logs:
|
|
||||||
wazuh_queue:
|
|
||||||
wazuh_var_multigroups:
|
|
||||||
wazuh_active_response:
|
|
||||||
wazuh_wodles:
|
|
||||||
filebeat_etc:
|
|
||||||
filebeat_var:
|
|
||||||
wazuh-indexer-data:
|
|
||||||
wazuh-dashboard-config:
|
|
||||||
wazuh-dashboard-custom:
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
# Wazuh App Copyright (C) 2017, Wazuh Inc. (License GPLv2)
|
|
||||||
services:
|
|
||||||
generator:
|
|
||||||
image: wazuh/wazuh-certs-generator:0.0.3
|
|
||||||
hostname: wazuh-certs-generator
|
|
||||||
environment:
|
|
||||||
- CERT_TOOL_VERSION=4.14
|
|
||||||
volumes:
|
|
||||||
- ./config/wazuh_indexer_ssl_certs/:/certificates/
|
|
||||||
- ./config/certs.yml:/config/certs.yml
|
|
||||||
Reference in New Issue
Block a user