diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..86c25cb --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,10 @@ +# Change Log +All notable changes to this project will be documented in this file. + +## [v4.1.1] + +### Added + +- All-in-one and distributred unattended installation ([@sergiogp98](https://github.com/sergiogp98)) [PR#82](https://github.com/wazuh/wazuh-cloudformation/pull/82) +- Update to [Wazuh v4.1.1](https://github.com/wazuh/wazuh/blob/v4.1.1/CHANGELOG.md#v411) + diff --git a/README.md b/README.md index 32ccb1d..1ac26b2 100644 --- a/README.md +++ b/README.md @@ -27,3 +27,42 @@ This repository contains CloudFormation templates and provision scripts to deplo * Kibana server seats behind an internet facing load balancer, that optionally loads an SSL Certificate for HTTPS * A Splunk Indexer instance with a Splunk app for Wazuh installed on it. * Six Wazuh agents installed on different operating systems: Red Hat 7, CentOS 7, Ubuntu, Debian, Amazon Linux and Windows. + +## Unattendend all-in-one + +* Install scipt following [Wazuh unattended all-in-one installation](https://documentation.wazuh.com/current/installation-guide/open-distro/all-in-one-deployment/unattended-installation.html) +* Resources: + - WazuhAIO: EC2 instance + - SecurityGroup: EC2 Security Group. It enables the following ports: + - 443 ( HTTPS) -> 0.0.0.0 + - 22 (SSH) -> 0.0.0.0 + +## Unattended distributed +* Install scipt following [Wazuh unattended distributed installation](https://documentation.wazuh.com/current/installation-guide/open-distro/distributed-deployment/unattended/index.html) +* Reosurces: + - WazuhVPC: EC2 VPC + - SubnetWazuh: EC2 Subnet over WazuhVPC + - SubnetElasticsearch: EC2 Subnet over WazuhVPC + - InternetGateway: EC2 InternetGateway between WazuhVPC and public network + - GatewayToInternet: EC2 VPCGatewayAttachment attached to WazuhVPC + - PublicRouteTable: EC2 RouteTable for WazuhVPC + - PublicRoute: EC2 Route of PublicRouteTable with a specific destination CIDR + - SubnetWazuhPublicRouteTable: EC2 SubnetRouteTableAssociation attached to SubnetWazuh + - SubnetElasticPublicRouteTable: EC2 SubnetRouteTableAssociation attached to SubnetElasticsearch + - WazuhSecurityGroup: EC2 SecurityGroup over WazuhVPC. It enables the following ports and protocols: + - 22 (SSH) -> 0.0.0.0 + - ICMP -> 0.0.0.0 + - 1514-1516 (Wazuh manager) -> WazuhVPC + - 55000 (Wazuh API) -> WazuhVPC + - ElasticSecurityGroup: EC2 SecurityGroup over WazuhVPC. It enables the following ports and protocols: + - 22 (SSH) -> 0.0.0.0 + - ICMP -> 0.0.0.0 + - 443 (HTTPS) -> 0.0.0.0 + - 9200-9400 (Wazuh manager) -> WazuhVPC + - 5000 (wazuh manager) -> WazuhVPC + - Elastic1: EC2 Instance Elasticsearch initial node (with Kibana) + - Elastic2: EC2 Instance Elasticsearch node + - Elastic3: EC2 Instance Elasticsearch node + - WazuhMaster: EC2 Instance Wazuh master node + - WazuhWorker: EC2 Instance Wazuh worker node + diff --git a/all-in-one/README.md b/all-in-one/README.md new file mode 100644 index 0000000..963d8a4 --- /dev/null +++ b/all-in-one/README.md @@ -0,0 +1,13 @@ +# Wazuh for Amazon AWS Cloudformation + +[![Slack](https://img.shields.io/badge/slack-join-blue.svg)](https://goo.gl/forms/M2AoZC4b2R9A9Zy12) +[![Email](https://img.shields.io/badge/email-join-blue.svg)](https://groups.google.com/forum/#!forum/wazuh) +[![Documentation](https://img.shields.io/badge/docs-view-green.svg)](https://documentation.wazuh.com) +[![Web](https://img.shields.io/badge/web-view-green.svg)](https://wazuh.com) + +The all-in-one environment has the following structure: + +* One EC2 instance where all components will be installed on +* Follow the [all-in-one unattended](https://documentation.wazuh.com/current/installation-guide/open-distro/all-in-one-deployment/unattended-installation.html) installation method +* Components: Elasticsearch node, Wazuh server set to one master node and a Kibana +node diff --git a/all-in-one/unattended/template.yml b/all-in-one/unattended/template.yml new file mode 100644 index 0000000..ff4930c --- /dev/null +++ b/all-in-one/unattended/template.yml @@ -0,0 +1,123 @@ +AWSTemplateFormatVersion: 2010-09-09 +Description: Provides an unattended all-in-one Wazuh installation +Parameters: + InstanceType: + AllowedValues: + - t2.small + - t2.medium + - t2.large + - t2.xlarge + ConstraintDescription: must be a valid EC2 instance type. + Default: t2.large + Description: EC2 instance type + Type: String + KeyName: + ConstraintDescription: Can contain only ASCII characters. + Description: Name of an existing EC2 KeyPair to enable SSH access to the instance + Type: AWS::EC2::KeyPair::KeyName + SSHLocation: + AllowedPattern: (\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})/(\d{1,2}) + ConstraintDescription: Must be a valid IP CIDR range of the form x.x.x.x/x + Default: 0.0.0.0/0 + Description: The IP address range that can be used to SSH to the EC2 instances + MaxLength: '18' + MinLength: '9' + Type: String + WazuhVersion: + AllowedValues: + - "v4.0.1" + - "v4.0.2" + - "v4.0.3" + - "v4.0.4" + - "v4.1.0" + - "v4.1.1" + Description: Wazuh version + Default: "v4.1.1" + Type: String + LogFile: + Description: Log file path to keep track of actions + Type: String + Default: /var/log/wazuh-cloudformation.log +Mappings: + AWSInstanceType2Arch: + t2.large: + Arch: HVM64 + t2.medium: + Arch: HVM64 + t2.micro: + Arch: HVM64 + t2.xlarge: + Arch: HVM64 + t2.small: + Arch: HVM64 + + AWSRegionArch2AMI: + us-east-1: + HVM64: ami-0c6b1d09930fac512 + HVMCENTOS7: ami-02eac2c0129f6376b + HVMUBUNTU64: ami-024a64a6685d05041 + HVMREDHAT7: ami-6871a115 + HVMDEBIAN: ami-0357081a1383dc76b + HVMWINDOWS: ami-0a9ca0496f746e6e0 + us-east-2: + HVM64: ami-0ebbf2179e615c338 + HVMCENTOS7: ami-0f2b4fc905b0bd1f1 + HVMUBUNTU64: ami-097ebb39620d8d54b + HVMREDHAT7: ami-03291866 + HVMDEBIAN: ami-09c10a66337c79669 + HVMWINDOWS: ami-0087a83ed4a60d1e9 + us-west-1: + HVM64: ami-015954d5e5548d13b + HVMUBUNTU64: ami-040dfc3ebf1bfc4f6 + HVMCENTOS7: ami-074e2d6769f445be5 + HVMREDHAT7: ami-18726478 + HVMDEBIAN: ami-0adbaf2e0ce044437 + HVMWINDOWS: ami-05bf35c67c02cd868 + us-west-2: + HVM64: ami-0cb72367e98845d43 + HVMUBUNTU64: ami-0196ce5c34425a906 + HVMCENTOS7: ami-01ed306a12b7d1c96 + HVMREDHAT7: ami-28e07e50 + HVMDEBIAN: ami-05a3ef6744aa96514 + HVMWINDOWS: ami-04ad37d2932b886c0 + +Resources: + WazuhAIO: + Properties: + ImageId: + Fn::FindInMap: + - AWSRegionArch2AMI + - Ref: AWS::Region + - Fn::FindInMap: + - AWSInstanceType2Arch + - Ref: InstanceType + - Arch + InstanceType: + Ref: InstanceType + KeyName: + Ref: KeyName + SecurityGroups: + - Ref: SecurityGroup + UserData: + Fn::Base64: !Sub | + #!/bin/bash + echo "Downloading script..." > ${LogFile} + curl -so ~/all-in-one-installation.sh https://raw.githubusercontent.com/wazuh/wazuh-documentation/${WazuhVersion}/resources/open-distro/unattended-installation/all-in-one-installation.sh + echo "Installing script..." > ${LogFile} + bash ~/all-in-one-installation.sh > ${LogFile} + Type: AWS::EC2::Instance + + SecurityGroup: + Properties: + GroupDescription: Enable HTTPS access via port 443 + SecurityGroupIngress: + - CidrIp: 0.0.0.0/0 + FromPort: '443' + IpProtocol: tcp + ToPort: '443' + - CidrIp: + Ref: SSHLocation + FromPort: '22' + IpProtocol: tcp + ToPort: '22' + Type: AWS::EC2::SecurityGroup diff --git a/distributed/README.MD b/distributed/README.MD new file mode 100644 index 0000000..8587518 --- /dev/null +++ b/distributed/README.MD @@ -0,0 +1,14 @@ +# Wazuh for Amazon AWS Cloudformation + +[![Slack](https://img.shields.io/badge/slack-join-blue.svg)](https://goo.gl/forms/M2AoZC4b2R9A9Zy12) +[![Email](https://img.shields.io/badge/email-join-blue.svg)](https://groups.google.com/forum/#!forum/wazuh) +[![Documentation](https://img.shields.io/badge/docs-view-green.svg)](https://documentation.wazuh.com) +[![Web](https://img.shields.io/badge/web-view-green.svg)](https://wazuh.com) + +The distributed environment has the following structure: + +* A VPC with two subnets, one for Wazuh servers, and another for Elastic Stack +* Wazuh managers cluster with two nodes, a master and a worker +* Elasticsearch cluster with 3 data nodes +* Kibana nodes installed among Elasticsearch initial node +* Follow the [distributed unattended](https://documentation.wazuh.com/current/installation-guide/open-distro/distributed-deployment/unattended/index.html) installation method diff --git a/distributed/unattended/scripts/check_certs.sh b/distributed/unattended/scripts/check_certs.sh new file mode 100644 index 0000000..e360dd5 --- /dev/null +++ b/distributed/unattended/scripts/check_certs.sh @@ -0,0 +1,20 @@ +#!/bin/bash + +CERTS_FILE={{src}}/certs.tar +find=0 +while [ $find -eq 0 ] +do + if [[ -f "{{dst}}/certs.tar" ]] + then + find=1 + echo "Cert files already in /root" + elif [[ -f "$CERTS_FILE" ]] + then + find=1 + echo "Cert files found. Moving them to {{dst}}..." + mv $CERTS_FILE {{dst}} + else + echo "Cert files not found. Sleeping 60 seconds..." + sleep 60 + fi +done diff --git a/distributed/unattended/scripts/check_ports.sh b/distributed/unattended/scripts/check_ports.sh new file mode 100644 index 0000000..fac6afb --- /dev/null +++ b/distributed/unattended/scripts/check_ports.sh @@ -0,0 +1,21 @@ +#!/bin/bash + +USER=$1 +IP=$2 +PORT=$3 + +open=0 +while [ $open -eq 0 ] +do + ssh -i ~/.ssh/ssh.key $USER@$IP "sudo netstat -tulnp" | grep $PORT &> /dev/null + if [[ $? -eq 0 ]] # Open + then + open=1 + echo "Port $PORT open in $IP" + else # Close + echo "Port $PORT close in $IP. Sleeping 60 seconds..." + sleep 60 + fi +done + + diff --git a/distributed/unattended/scripts/initialize_kibana.sh b/distributed/unattended/scripts/initialize_kibana.sh new file mode 100755 index 0000000..d8a296f --- /dev/null +++ b/distributed/unattended/scripts/initialize_kibana.sh @@ -0,0 +1,15 @@ +#!/bin/bash + +echo "Linking 443 port to Kibana socket..." +setcap 'cap_net_bind_service=+ep' /usr/share/kibana/node/bin/node +echo "Starting kibana service..." +systemctl daemon-reload +systemctl enable kibana.service +systemctl restart kibana.service +echo "Initializing Kibana (this may take a while)" +until [[ "$(curl -XGET https://{{kibana_ip}}/status -I -uadmin:admin -k -s --max-time 300 | grep "200 OK")" ]]; do + sleep 10 +done +conf="$(awk '{sub("url: https://localhost", "url: https://{{wazuh_master_ip}}")}1' /usr/share/kibana/data/wazuh/config/wazuh.yml)" +echo "${conf}" > /usr/share/kibana/data/wazuh/config/wazuh.yml +echo "You can access the web interface https://{{kibana_ip}}. The credentials are admin:admin" diff --git a/distributed/unattended/scripts/update_ossec_conf.sh b/distributed/unattended/scripts/update_ossec_conf.sh new file mode 100644 index 0000000..73f70f3 --- /dev/null +++ b/distributed/unattended/scripts/update_ossec_conf.sh @@ -0,0 +1,6 @@ +#!/bin/bash + +logger -s "Updating {{ossec_conf}}..." 2>> {{log_file}} +cat ~/cluster.conf | logger -s 2>> {{log_file}} +sed -i '//,/<\/cluster>/d' {{ossec_conf}} +cat ~/cluster.conf >> {{ossec_conf}} diff --git a/distributed/unattended/template.yml b/distributed/unattended/template.yml new file mode 100644 index 0000000..6fe3ab1 --- /dev/null +++ b/distributed/unattended/template.yml @@ -0,0 +1,959 @@ +AWSTemplateFormatVersion: 2010-09-09 +Description: Provides an unattended distributed Wazuh installation +Parameters: + ## AWS + AvailabilityZone: + Description: Select an availability zone for the VPC + Type: 'List' + InstanceType: + AllowedValues: + - t2.small + - t2.medium + - t2.large + - t2.xlarge + ConstraintDescription: must be a valid EC2 instance type. + Default: t2.large + Description: EC2 instance type + Type: String + KeyName: + ConstraintDescription: Can contain only ASCII characters. + Description: Name of an existing EC2 KeyPair to enable SSH access to the instance + Type: AWS::EC2::KeyPair::KeyName + SSHLocation: + AllowedPattern: (\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})/(\d{1,2}) + ConstraintDescription: Must be a valid IP CIDR range of the form x.x.x.x/x + Default: 0.0.0.0/0 + Description: The IP address range that can be used to SSH to the EC2 instances + MaxLength: '18' + MinLength: '9' + Type: String + Ec2User: + AllowedValues: + - ec2-user + Default: ec2-user + Description: Username in EC2 instance + Type: String + SshKey: + Description: AWS Cloudformation Stack SSH Private Key. Do not copy "BEGIN RSA PRIVATE KEY" and "END RSA PRIVATE KEY" lines + Type: String + NoEcho: 'True' + + # Log + LogFile: + Description: Log file path to keep track of actions + Type: String + Default: /var/log/wazuh-cloudformation.log + + ## Version + WazuhVersion: + AllowedValues: + - "v4.0.1" + - "v4.0.2" + - "v4.0.3" + - "v4.0.4" + - "v4.1.0" + - "v4.1.1" + Description: Wazuh version + Default: "v4.1.1" + Type: String + + # WazuhCluster + WazuhClusterKey: + Description: Key that will be used to encrypt communication between Wazuh cluster nodes. Run "openssl rand -hex 16" + Type: String + NoEcho: 'True' + MinLength: '32' + MaxLength: '32' + +Mappings: + Node2NameAndIP: + MasterNode: + Name: master-node + IP: 10.0.0.100 + WorkerNode: + Name: worker-node + IP: 10.0.0.200 + Elastic1: + Name: elastic-node-1 + IP: 10.0.1.101 + Elastic2: + Name: elastic-node-2 + IP: 10.0.1.102 + Elastic3: + Name: elastic-node-3 + IP: 10.0.1.103 + + AWSInstanceType2Arch: + t2.large: + Arch: HVM64 + t2.medium: + Arch: HVM64 + t2.micro: + Arch: HVM64 + t2.xlarge: + Arch: HVM64 + t2.small: + Arch: HVM64 + + AWSRegionArch2AMI: + us-east-1: + HVM64: ami-0c6b1d09930fac512 + HVMCENTOS7: ami-02eac2c0129f6376b + HVMUBUNTU64: ami-024a64a6685d05041 + HVMREDHAT7: ami-6871a115 + HVMDEBIAN: ami-0357081a1383dc76b + HVMWINDOWS: ami-0a9ca0496f746e6e0 + us-east-2: + HVM64: ami-0ebbf2179e615c338 + HVMCENTOS7: ami-0f2b4fc905b0bd1f1 + HVMUBUNTU64: ami-097ebb39620d8d54b + HVMREDHAT7: ami-03291866 + HVMDEBIAN: ami-09c10a66337c79669 + HVMWINDOWS: ami-0087a83ed4a60d1e9 + us-west-1: + HVM64: ami-015954d5e5548d13b + HVMUBUNTU64: ami-040dfc3ebf1bfc4f6 + HVMCENTOS7: ami-074e2d6769f445be5 + HVMREDHAT7: ami-18726478 + HVMDEBIAN: ami-0adbaf2e0ce044437 + HVMWINDOWS: ami-05bf35c67c02cd868 + us-west-2: + HVM64: ami-0cb72367e98845d43 + HVMUBUNTU64: ami-0196ce5c34425a906 + HVMCENTOS7: ami-01ed306a12b7d1c96 + HVMREDHAT7: ami-28e07e50 + HVMDEBIAN: ami-05a3ef6744aa96514 + HVMWINDOWS: ami-04ad37d2932b886c0 + + Subnet2CIDR: + WazuhVpc: + CIDR: 10.0.0.0/16 + SubnetWazuh: + CIDR: 10.0.0.0/24 + SubnetElasticsearch: + CIDR: 10.0.1.0/24 + +Resources: + # Network resources + WazuhVpc: + Type: 'AWS::EC2::VPC' + Properties: + CidrBlock: !FindInMap + - Subnet2CIDR + - WazuhVpc + - CIDR + EnableDnsSupport: 'true' + EnableDnsHostnames: 'true' + Tags: + - Key: Application + Value: !Ref 'AWS::StackId' + - Key: Name + Value: !Ref 'AWS::StackName' + + SubnetWazuh: + Type: 'AWS::EC2::Subnet' + Properties: + VpcId: !Ref WazuhVpc + AvailabilityZone: !Select [ "0", !Ref AvailabilityZone ] + CidrBlock: !FindInMap + - Subnet2CIDR + - SubnetWazuh + - CIDR + Tags: + - Key: Application + Value: !Ref 'AWS::StackId' + - Key: Name + Value: !Sub '${AWS::StackName}-SubnetWazuh' + + SubnetElasticsearch: + Type: 'AWS::EC2::Subnet' + Properties: + VpcId: !Ref WazuhVpc + AvailabilityZone: !Select [ "0", !Ref AvailabilityZone ] + CidrBlock: !FindInMap + - Subnet2CIDR + - SubnetElasticsearch + - CIDR + Tags: + - Key: Application + Value: !Ref 'AWS::StackId' + - Key: Name + Value: !Sub '${AWS::StackName}-SubnetElasticsearch' + + # Internet access and routing + InternetGateway: + Type: 'AWS::EC2::InternetGateway' + Properties: + Tags: + - Key: Application + Value: !Ref 'AWS::StackId' + - Key: Name + Value: !Sub '${AWS::StackName}-InternetGateway' + + GatewayToInternet: + Type: 'AWS::EC2::VPCGatewayAttachment' + Properties: + VpcId: !Ref WazuhVpc + InternetGatewayId: !Ref InternetGateway + + PublicRouteTable: + Type: 'AWS::EC2::RouteTable' + Properties: + VpcId: !Ref WazuhVpc + Tags: + - Key: Application + Value: !Ref 'AWS::StackId' + - Key: Name + Value: !Sub '${AWS::StackName}-PublicRouteTable' + + PublicRoute: + Type: 'AWS::EC2::Route' + DependsOn: GatewayToInternet + Properties: + RouteTableId: !Ref PublicRouteTable + DestinationCidrBlock: 0.0.0.0/0 + GatewayId: !Ref InternetGateway + + SubnetWazuhPublicRouteTable: + Type: 'AWS::EC2::SubnetRouteTableAssociation' + Properties: + SubnetId: !Ref SubnetWazuh + RouteTableId: !Ref PublicRouteTable + + SubnetElasticPublicRouteTable: + Type: 'AWS::EC2::SubnetRouteTableAssociation' + Properties: + SubnetId: !Ref SubnetElasticsearch + RouteTableId: !Ref PublicRouteTable + + # Security groups + WazuhSecurityGroup: + Type: 'AWS::EC2::SecurityGroup' + Properties: + GroupDescription: Wazuh security group + VpcId: !Ref WazuhVpc + SecurityGroupIngress: + - IpProtocol: tcp + FromPort: 22 + ToPort: 22 + CidrIp: 0.0.0.0/0 + - IpProtocol: icmp + FromPort: -1 + ToPort: -1 + CidrIp: 0.0.0.0/0 + - IpProtocol: tcp + FromPort: 1514 + ToPort: 1516 + CidrIp: !FindInMap + - Subnet2CIDR + - WazuhVpc + - CIDR + - IpProtocol: tcp + FromPort: 55000 + ToPort: 55000 + CidrIp: !FindInMap + - Subnet2CIDR + - WazuhVpc + - CIDR + Tags: + - Key: Name + Value: !Sub '${AWS::StackName}-WazuhSecurityGroup' + + ElasticSecurityGroup: + Type: 'AWS::EC2::SecurityGroup' + Properties: + GroupDescription: Elasticsearch security group + VpcId: !Ref WazuhVpc + SecurityGroupIngress: + - IpProtocol: tcp + FromPort: 22 + ToPort: 22 + CidrIp: 0.0.0.0/0 + - IpProtocol: icmp + FromPort: -1 + ToPort: -1 + CidrIp: 0.0.0.0/0 + - IpProtocol: tcp + FromPort: 443 + ToPort: 443 + CidrIp: 0.0.0.0/0 + - IpProtocol: tcp + FromPort: 9200 + ToPort: 9400 + CidrIp: !FindInMap + - Subnet2CIDR + - WazuhVpc + - CIDR + - IpProtocol: tcp + FromPort: 5000 + ToPort: 5000 + CidrIp: !FindInMap + - Subnet2CIDR + - WazuhVpc + - CIDR + Tags: + - Key: Name + Value: !Sub '${AWS::StackName}-ElasticSecurityGroup' + + # Instances + Elastic1: + Type: AWS::EC2::Instance + Metadata: + 'AWS::CloudFormation::Init': + configSets: + Elastic1InstallationSet: + - SshConfig + - DownloadFile + - ConfigFile + - InstallElastic + DeployAndCheck: + - ScpAndNetstat + Cluster: + - SecurityAdmin + KibanaInstallationSet: + - InstallKibana + SshConfig: + files: + /tmp/ssh.key: + content: !Sub | + -----BEGIN RSA PRIVATE KEY----- + ${SshKey} + -----END RSA PRIVATE KEY----- + mode: '000600' + owner: root + group: root + commands: + write-log: + command: "logger -s \"Creating ssh.key in ~/.ssh... \" 2>> $LogFile" + env: + LogFile: !Ref LogFile + move-ssh-key: + command: + "mv /tmp/ssh.key ~/.ssh" + DownloadFile: + commands: + write-log: + command: "logger -s \"Downloading elastic-stack-installation.sh... \" 2>> $LogFile" + env: + LogFile: !Ref LogFile + download-elk-installation-script: + command: "curl -so ~/elastic-stack-installation.sh https://raw.githubusercontent.com/wazuh/wazuh-documentation/$WazuhVersion/resources/open-distro/unattended-installation/distributed/elastic-stack-installation.sh" + env: + WazuhVersion: !Ref WazuhVersion + cwd: "~" + ConfigFile: + commands: + write-log: + command: "logger -s \"Creating custom config.yml... \" 2>> $LogFile" + env: + LogFile: !Ref LogFile + files: + /root/config.yml: + source: !Sub >- + https://raw.githubusercontent.com/wazuh/wazuh-cloudformation/feature-unattended-installation/distributed/unattended/templates/config_cluster.yml + mode: '000700' + owner: root + group: root + context: + cluster_name: "elastic_cluster" + master_node_1: !FindInMap [Node2NameAndIP, Elastic1, Name] + master_node_2: !FindInMap [Node2NameAndIP, Elastic2, Name] + master_node_3: !FindInMap [Node2NameAndIP, Elastic3, Name] + elasticsearch_ip_node1: !FindInMap [Node2NameAndIP, Elastic1, IP] + elasticsearch_ip_node2: !FindInMap [Node2NameAndIP, Elastic2, IP] + elasticsearch_ip_node3: !FindInMap [Node2NameAndIP, Elastic3, IP] + wazuh_master_name: !FindInMap [Node2NameAndIP, MasterNode, Name] + wazuh_worker_name: !FindInMap [Node2NameAndIP, WorkerNode, Name] + kibana_ip: !FindInMap [Node2NameAndIP, Elastic1, IP] + wazuh_master_server_IP: !FindInMap [Node2NameAndIP, MasterNode, IP] + InstallElastic: + commands: + install-elastic: + command: + "bash ~/elastic-stack-installation.sh -d -e -c -n $NodeName | logger -s 2>> $LogFile" + env: + NodeName: !FindInMap [Node2NameAndIP, Elastic1, Name] + LogFile: !Ref LogFile + cwd: "~" + ignoreErrors: "true" + ScpAndNetstat: + files: + /root/check_ports.sh: + source: !Sub >- + https://raw.githubusercontent.com/wazuh/wazuh-cloudformation/feature-unattended-installation/distributed/unattended/scripts/check_ports.sh + mode: '000700' + owner: root + group: root + commands: + run-commands: + command: + "logger -s \"Copying files to all nodes...\" 2>> $LogFile && \ + scp -i ~/.ssh/ssh.key -o StrictHostKeyChecking=no ~/certs.tar $Ec2User@$Elastic2IP:~/certs.tar && \ + scp -i ~/.ssh/ssh.key -o StrictHostKeyChecking=no ~/certs.tar $Ec2User@$Elastic3IP:~/certs.tar && \ + scp -i ~/.ssh/ssh.key -o StrictHostKeyChecking=no ~/certs.tar $Ec2User@$WazuhMasterIP:~/certs.tar && \ + scp -i ~/.ssh/ssh.key -o StrictHostKeyChecking=no ~/certs.tar $Ec2User@$WazuhWorkerIP:~/certs.tar && \ + bash ~/check_ports.sh $Ec2User $Elastic2IP 9200 | logger -s 2>> $LogFile && \ + bash ~/check_ports.sh $Ec2User $Elastic3IP 9200 | logger -s 2>> $LogFile && \ + bash ~/check_ports.sh $Ec2User $WazuhMasterIP 1514 | logger -s 2>> $LogFile && \ + bash ~/check_ports.sh $Ec2User $WazuhWorkerIP 1514 | logger -s 2>> $LogFile" + env: + LogFile: !Ref LogFile + Ec2User: !Ref Ec2User + Elastic2IP: !FindInMap [Node2NameAndIP, Elastic2, IP] + Elastic3IP: !FindInMap [Node2NameAndIP, Elastic3, IP] + WazuhMasterIP: !FindInMap [Node2NameAndIP, MasterNode, IP] + WazuhWorkerIP: !FindInMap [Node2NameAndIP, WorkerNode, IP] + SecurityAdmin: + commands: + run-script: + command: + "/usr/share/elasticsearch/plugins/opendistro_security/tools/securityadmin.sh \ + -cd /usr/share/elasticsearch/plugins/opendistro_security/securityconfig/ \ + -icl \ + -nhnv \ + -cacert /etc/elasticsearch/certs/root-ca.pem \ + -cert /etc/elasticsearch/certs/admin.pem \ + -key /etc/elasticsearch/certs/admin.key \ + -h $ElasticIP | logger -s 2>> $LogFile" + env: + ElasticIP: !FindInMap [Node2NameAndIP, Elastic1, IP] + LogFile: !Ref LogFile + InstallKibana: + files: + /root/initialize_kibana.sh: + source: !Sub >- + https://raw.githubusercontent.com/wazuh/wazuh-cloudformation/feature-unattended-installation/distributed/unattended/scripts/initialize_kibana.sh + mode: '000700' + owner: root + group: root + context: + kibana_ip: !FindInMap [Node2NameAndIP, Elastic1, IP] + wazuh_master_ip: !FindInMap [Node2NameAndIP, MasterNode, IP] + commands: + comment-initializeKibana: + command: "sed -i 's/initializeKibana kip/#initializeKibana kip/' ~/elastic-stack-installation.sh" + ignoreErrors: "true" + install-kibana: + command: "bash ~/elastic-stack-installation.sh -d -k -n $NodeName | logger -s 2>> $LogFile" + env: + NodeName: !FindInMap [Node2NameAndIP, Elastic1, Name] + LogFile: !Ref LogFile + ignoreErrors: "true" + initializeKibana: + command: "bash ~/initialize_kibana.sh | logger -s 2>> $LogFile" + env: + LogFile: !Ref LogFile + Properties: + ImageId: + Fn::FindInMap: + - AWSRegionArch2AMI + - Ref: AWS::Region + - Fn::FindInMap: + - AWSInstanceType2Arch + - Ref: InstanceType + - Arch + InstanceType: + Ref: InstanceType + KeyName: + Ref: KeyName + NetworkInterfaces: + - AssociatePublicIpAddress: "true" + DeviceIndex: "0" + GroupSet: + - Ref: "ElasticSecurityGroup" + SubnetId: + Ref: "SubnetElasticsearch" + PrivateIpAddress: !FindInMap [Node2NameAndIP, Elastic1, IP] + Tags: + - Key: Name + Value: Elastic1 + UserData: + Fn::Base64: !Sub | + Content-Type: multipart/mixed; boundary="//" + MIME-Version: 1.0 + + --// + Content-Type: text/cloud-config; charset="us-ascii" + MIME-Version: 1.0 + Content-Transfer-Encoding: 7bit + Content-Disposition: attachment; filename="cloud-config.txt" + + #cloud-config + cloud_final_modules: + - [scripts-user, always] + + --// + Content-Type: text/x-shellscript; charset="us-ascii" + MIME-Version: 1.0 + Content-Transfer-Encoding: 7bit + Content-Disposition: attachment; filename="userdata.txt" + + #!/bin/bash -xe + /opt/aws/bin/cfn-init --stack ${AWS::StackName} --resource Elastic1 --configsets Elastic1InstallationSet,DeployAndCheck,Cluster,KibanaInstallationSet --region ${AWS::Region} + /opt/aws/bin/cfn-signal -e $? --stack ${AWS::StackName} --resource Elastic1 --region ${AWS::Region} + --// + DependsOn: GatewayToInternet + + Elastic2: + Type: AWS::EC2::Instance + Metadata: + 'AWS::CloudFormation::Init': + configSets: + Elastic2InstallationSet: + - DownloadFile + - CheckCerts + - InstallElastic + DownloadFile: + commands: + write-log: + command: "logger -s \"Downloading elastic-stack-installation.sh... \" 2>> $LogFile" + env: + LogFile: !Ref LogFile + download-elk-installation-script: + command: "curl -so ~/elastic-stack-installation.sh https://raw.githubusercontent.com/wazuh/wazuh-documentation/$WazuhVersion/resources/open-distro/unattended-installation/distributed/elastic-stack-installation.sh" + env: + WazuhVersion: !Ref WazuhVersion + cwd: "~" + CheckCerts: + files: + /root/check_certs.sh: + source: !Sub >- + https://raw.githubusercontent.com/wazuh/wazuh-cloudformation/feature-unattended-installation/distributed/unattended/scripts/check_certs.sh + mode: '000700' + owner: root + group: root + context: + src: !Sub /home/${Ec2User} + dst: /root + log_file: !Ref LogFile + commands: + move_files: + command: "bash ~/check_certs.sh | logger -s 2>> $LogFile" + env: + LogFile: !Ref LogFile + InstallElastic: + commands: + install-elastic: + command: "bash ~/elastic-stack-installation.sh -e -n $NodeName | logger -s 2>> $LogFile" + env: + NodeName: !FindInMap [Node2NameAndIP, Elastic2, Name] + LogFile: !Ref LogFile + cwd: "~" + ignoreErrors: "true" + Properties: + ImageId: + Fn::FindInMap: + - AWSRegionArch2AMI + - Ref: AWS::Region + - Fn::FindInMap: + - AWSInstanceType2Arch + - Ref: InstanceType + - Arch + InstanceType: + Ref: InstanceType + KeyName: + Ref: KeyName + NetworkInterfaces: + - AssociatePublicIpAddress: "true" + DeviceIndex: "0" + GroupSet: + - Ref: "ElasticSecurityGroup" + SubnetId: + Ref: "SubnetElasticsearch" + PrivateIpAddress: !FindInMap [Node2NameAndIP, Elastic2, IP] + Tags: + - Key: Name + Value: Elastic2 + UserData: + Fn::Base64: !Sub | + Content-Type: multipart/mixed; boundary="//" + MIME-Version: 1.0 + + --// + Content-Type: text/cloud-config; charset="us-ascii" + MIME-Version: 1.0 + Content-Transfer-Encoding: 7bit + Content-Disposition: attachment; filename="cloud-config.txt" + + #cloud-config + cloud_final_modules: + - [scripts-user, always] + + --// + Content-Type: text/x-shellscript; charset="us-ascii" + MIME-Version: 1.0 + Content-Transfer-Encoding: 7bit + Content-Disposition: attachment; filename="userdata.txt" + + #!/bin/bash -xe + /opt/aws/bin/cfn-init --stack ${AWS::StackName} --resource Elastic2 --configsets Elastic2InstallationSet --region ${AWS::Region} + /opt/aws/bin/cfn-signal -e $? --stack ${AWS::StackName} --resource Elastic2 --region ${AWS::Region} + --// + DependsOn: GatewayToInternet + + Elastic3: + Type: AWS::EC2::Instance + Metadata: + 'AWS::CloudFormation::Init': + configSets: + Elastic3InstallationSet: + - DownloadFile + - CheckCerts + - InstallElastic + DownloadFile: + commands: + write-log: + command: "logger -s \"Downloading elastic-stack-installation.sh... \" 2>> $LogFile" + env: + LogFile: !Ref LogFile + download-elk-installation-script: + command: "curl -so ~/elastic-stack-installation.sh https://raw.githubusercontent.com/wazuh/wazuh-documentation/$WazuhVersion/resources/open-distro/unattended-installation/distributed/elastic-stack-installation.sh" + env: + WazuhVersion: !Ref WazuhVersion + cwd: "~" + CheckCerts: + files: + /root/check_certs.sh: + source: !Sub >- + https://raw.githubusercontent.com/wazuh/wazuh-cloudformation/feature-unattended-installation/distributed/unattended/scripts/check_certs.sh + mode: '000700' + owner: root + group: root + context: + src: !Sub /home/${Ec2User} + dst: /root + commands: + move_files: + command: "bash ~/check_certs.sh | logger -s 2>> $LogFile" + env: + LogFile: !Ref LogFile + InstallElastic: + commands: + install-elastic: + command: "bash ~/elastic-stack-installation.sh -e -n $NodeName | logger -s 2>> $LogFile" + env: + NodeName: !FindInMap [Node2NameAndIP, Elastic3, Name] + LogFile: !Ref LogFile + cwd: "~" + ignoreErrors: "true" + Properties: + ImageId: + Fn::FindInMap: + - AWSRegionArch2AMI + - Ref: AWS::Region + - Fn::FindInMap: + - AWSInstanceType2Arch + - Ref: InstanceType + - Arch + InstanceType: + Ref: InstanceType + KeyName: + Ref: KeyName + NetworkInterfaces: + - AssociatePublicIpAddress: "true" + DeviceIndex: "0" + GroupSet: + - Ref: "ElasticSecurityGroup" + SubnetId: + Ref: "SubnetElasticsearch" + PrivateIpAddress: !FindInMap [Node2NameAndIP, Elastic3, IP] + Tags: + - Key: Name + Value: Elastic3 + UserData: + Fn::Base64: !Sub | + Content-Type: multipart/mixed; boundary="//" + MIME-Version: 1.0 + + --// + Content-Type: text/cloud-config; charset="us-ascii" + MIME-Version: 1.0 + Content-Transfer-Encoding: 7bit + Content-Disposition: attachment; filename="cloud-config.txt" + + #cloud-config + cloud_final_modules: + - [scripts-user, always] + + --// + Content-Type: text/x-shellscript; charset="us-ascii" + MIME-Version: 1.0 + Content-Transfer-Encoding: 7bit + Content-Disposition: attachment; filename="userdata.txt" + + #!/bin/bash -xe + /opt/aws/bin/cfn-init --stack ${AWS::StackName} --resource Elastic3 --configsets Elastic3InstallationSet --region ${AWS::Region} + /opt/aws/bin/cfn-signal -e $? --stack ${AWS::StackName} --resource Elastic3 --region ${AWS::Region} + --// + DependsOn: GatewayToInternet + + WazuhMaster: + Type: AWS::EC2::Instance + Metadata: + 'AWS::CloudFormation::Init': + configSets: + WazuhMasterInstallationSet: + - DownloadFile + - CheckCerts + - InstallWazuh + - ConfigureMaster + DownloadFile: + commands: + write-log: + command: "logger -s \"Downloading wazuh-server-installation.sh... \" 2>> $LogFile" + env: + LogFile: !Ref LogFile + download-elk-installation-script: + command: "curl -so ~/wazuh-server-installation.sh https://raw.githubusercontent.com/wazuh/wazuh-documentation/$WazuhVersion/resources/open-distro/unattended-installation/distributed/wazuh-server-installation.sh" + env: + WazuhVersion: !Ref WazuhVersion + cwd: "~" + CheckCerts: + files: + /root/check_certs.sh: + source: !Sub >- + https://raw.githubusercontent.com/wazuh/wazuh-cloudformation/feature-unattended-installation/distributed/unattended/scripts/check_certs.sh + mode: '000700' + owner: root + group: root + context: + src: !Sub /home/${Ec2User} + dst: /root + commands: + move_files: + command: "bash ~/check_certs.sh | logger -s 2>> $LogFile" + env: + LogFile: !Ref LogFile + InstallWazuh: + commands: + install-wazuh: + command: "bash ~/wazuh-server-installation.sh -n $NodeName >> $LogFile" + env: + NodeName: !FindInMap [Node2NameAndIP, MasterNode, Name] + LogFile: !Ref LogFile + cwd: "~" + ignoreErrors: "true" + ConfigureMaster: + files: + /root/cluster.conf: + source: !Sub >- + https://raw.githubusercontent.com/wazuh/wazuh-cloudformation/feature-unattended-installation/distributed/unattended/templates/cluster.conf + mode: '000700' + owner: root + group: root + context: + cluster_name: 'wazuh_cluster' + node_name: !FindInMap [Node2NameAndIP, MasterNode, Name] + node_type: 'master' + key: !Ref WazuhClusterKey + port: '1516' + bind_addr: '0.0.0.0' + ip: !FindInMap [Node2NameAndIP, MasterNode, IP] + hidden: 'no' + disabled: 'no' + /root/update_ossec_conf.sh: + source: !Sub >- + https://raw.githubusercontent.com/wazuh/wazuh-cloudformation/feature-unattended-installation/distributed/unattended/scripts/update_ossec_conf.sh + mode: '000700' + owner: root + group: root + context: + ossec_conf: '/var/ossec/etc/ossec.conf' + log_file: !Ref LogFile + commands: + edit-ossec-conf: + command: + "bash ~/update_ossec_conf.sh" + restart-manager: + command: + "logger -s \"Restarting manager...\" 2>> $LogFile && \ + systemctl restart wazuh-manager" + env: + LogFile: !Ref LogFile + Properties: + ImageId: + Fn::FindInMap: + - AWSRegionArch2AMI + - Ref: AWS::Region + - Fn::FindInMap: + - AWSInstanceType2Arch + - Ref: InstanceType + - Arch + InstanceType: + Ref: InstanceType + KeyName: + Ref: KeyName + NetworkInterfaces: + - AssociatePublicIpAddress: "true" + DeviceIndex: "0" + GroupSet: + - Ref: "WazuhSecurityGroup" + SubnetId: + Ref: "SubnetWazuh" + PrivateIpAddress: !FindInMap [Node2NameAndIP, MasterNode, IP] + Tags: + - Key: Name + Value: WazuhMaster + UserData: + Fn::Base64: !Sub | + Content-Type: multipart/mixed; boundary="//" + MIME-Version: 1.0 + + --// + Content-Type: text/cloud-config; charset="us-ascii" + MIME-Version: 1.0 + Content-Transfer-Encoding: 7bit + Content-Disposition: attachment; filename="cloud-config.txt" + + #cloud-config + cloud_final_modules: + - [scripts-user, always] + + --// + Content-Type: text/x-shellscript; charset="us-ascii" + MIME-Version: 1.0 + Content-Transfer-Encoding: 7bit + Content-Disposition: attachment; filename="userdata.txt" + + #!/bin/bash -xe + /opt/aws/bin/cfn-init --stack ${AWS::StackName} --resource WazuhMaster --configsets WazuhMasterInstallationSet --region ${AWS::Region} + /opt/aws/bin/cfn-signal -e $? --stack ${AWS::StackName} --resource WazuhMaster --region ${AWS::Region} + + --// + DependsOn: GatewayToInternet + + WazuhWorker: + Type: AWS::EC2::Instance + Metadata: + 'AWS::CloudFormation::Init': + configSets: + WazuhWorkerInstallationSet: + - DownloadFile + - CheckCerts + - InstallWazuh + - ConfigureWorker + DownloadFile: + commands: + write-log: + command: "logger -s \"Downloading wazuh-server-installation.sh... \" 2>> $LogFile" + env: + LogFile: !Ref LogFile + download-elk-installation-script: + command: "curl -so ~/wazuh-server-installation.sh https://raw.githubusercontent.com/wazuh/wazuh-documentation/$WazuhVersion/resources/open-distro/unattended-installation/distributed/wazuh-server-installation.sh" + env: + WazuhVersion: !Ref WazuhVersion + cwd: "~" + CheckCerts: + files: + /root/check_certs.sh: + source: !Sub >- + https://raw.githubusercontent.com/wazuh/wazuh-cloudformation/feature-unattended-installation/distributed/unattended/scripts/check_certs.sh + mode: '000700' + owner: root + group: root + context: + src: !Sub /home/${Ec2User} + dst: /root + log_file: !Ref LogFile + commands: + move_files: + command: "bash ~/check_certs.sh | logger -s 2>> $LogFile" + env: + LogFile: !Ref LogFile + InstallWazuh: + commands: + install-wazuh: + command: "bash ~/wazuh-server-installation.sh -n $NodeName | logger -s 2>> $LogFile" + env: + NodeName: !FindInMap [Node2NameAndIP, WorkerNode, Name] + LogFile: !Ref LogFile + cwd: "~" + ignoreErrors: "true" + ConfigureWorker: + files: + /root/cluster.conf: + source: !Sub >- + https://raw.githubusercontent.com/wazuh/wazuh-cloudformation/feature-unattended-installation/distributed/unattended/templates/cluster.conf + mode: '000700' + owner: root + group: root + context: + cluster_name: 'wazuh_cluster' + node_name: !FindInMap [Node2NameAndIP, WorkerNode, Name] + node_type: 'worker' + key: !Ref WazuhClusterKey + port: '1516' + bind_addr: '0.0.0.0' + ip: !FindInMap [Node2NameAndIP, MasterNode, IP] + hidden: 'no' + disabled: 'no' + /root/update_ossec_conf.sh: + source: !Sub >- + https://raw.githubusercontent.com/wazuh/wazuh-cloudformation/feature-unattended-installation/distributed/unattended/scripts/update_ossec_conf.sh + mode: '000700' + owner: root + group: root + context: + ossec_conf: '/var/ossec/etc/ossec.conf' + log_file: !Ref LogFile + commands: + edit-ossec-conf: + command: + "bash ~/update_ossec_conf.sh" + restart-manager: + command: + "logger -s \"Restarting manager...\" 2>> $LogFile && \ + systemctl restart wazuh-manager" + env: + LogFile: !Ref LogFile + Properties: + ImageId: + Fn::FindInMap: + - AWSRegionArch2AMI + - Ref: AWS::Region + - Fn::FindInMap: + - AWSInstanceType2Arch + - Ref: InstanceType + - Arch + InstanceType: + Ref: InstanceType + KeyName: + Ref: KeyName + NetworkInterfaces: + - AssociatePublicIpAddress: "true" + DeviceIndex: "0" + GroupSet: + - Ref: "WazuhSecurityGroup" + SubnetId: + Ref: "SubnetWazuh" + PrivateIpAddress: !FindInMap [Node2NameAndIP, WorkerNode, IP] + Tags: + - Key: Name + Value: WazuhWorker + UserData: + Fn::Base64: !Sub | + Content-Type: multipart/mixed; boundary="//" + MIME-Version: 1.0 + + --// + Content-Type: text/cloud-config; charset="us-ascii" + MIME-Version: 1.0 + Content-Transfer-Encoding: 7bit + Content-Disposition: attachment; filename="cloud-config.txt" + + #cloud-config + cloud_final_modules: + - [scripts-user, always] + + --// + Content-Type: text/x-shellscript; charset="us-ascii" + MIME-Version: 1.0 + Content-Transfer-Encoding: 7bit + Content-Disposition: attachment; filename="userdata.txt" + + #!/bin/bash -xe + /opt/aws/bin/cfn-init --stack ${AWS::StackName} --resource WazuhWorker --configsets WazuhWorkerInstallationSet --region ${AWS::Region} + /opt/aws/bin/cfn-signal -e $? --stack ${AWS::StackName} --resource WazuhWorker --region ${AWS::Region} + --// + DependsOn: GatewayToInternet + diff --git a/distributed/unattended/templates/cluster.conf b/distributed/unattended/templates/cluster.conf new file mode 100644 index 0000000..52c0008 --- /dev/null +++ b/distributed/unattended/templates/cluster.conf @@ -0,0 +1,15 @@ + + + {{cluster_name}} + {{node_name}} + {{node_type}} + {{key}} + {{port}} + {{bind_addr}} + + {{ip}} + + {{hidden}} + {{disabled}} + + diff --git a/distributed/unattended/templates/config_cluster.yml b/distributed/unattended/templates/config_cluster.yml new file mode 100644 index 0000000..def0312 --- /dev/null +++ b/distributed/unattended/templates/config_cluster.yml @@ -0,0 +1,33 @@ +## Multi-node configuration + +## Elasticsearch configuration + +cluster.name: {{cluster_name}} + +cluster.initial_master_nodes: + - {{master_node_1}} + - {{master_node_2}} + - {{master_node_3}} + +discovery.seed_hosts: + - {{elasticsearch_ip_node1}} + - {{elasticsearch_ip_node2}} + - {{elasticsearch_ip_node3}} + +## Certificates creation + +# Clients certificates +clients: + - name: admin + dn: CN=admin,OU=Docu,O=Wazuh,L=California,C=US + admin: true + - name: {{wazuh_master_name}} + dn: CN={{wazuh_master_name}},OU=Docu,O=Wazuh,L=California,C=US + - name: {{wazuh_worker_name}} + dn: CN={{wazuh_worker_name}},OU=Docu,O=Wazuh,L=California,C=US + +# Kibana-instance +- {{kibana_ip}} + +# Wazuh-master-configuration +- {{wazuh_master_server_IP}}