From 1f6298e1bef7f2c6a6a5c8166a698c982e0d8533 Mon Sep 17 00:00:00 2001 From: Jose Luis Date: Thu, 16 Mar 2017 18:09:32 -0400 Subject: [PATCH] first commit --- README.md | 118 +++- ansible-role-elk/README.md | 27 + ansible-role-elk/defaults/main.yml | 9 + ansible-role-elk/handlers/main.yml | 9 + ansible-role-elk/meta/main.yml | 21 + ansible-role-elk/tasks/RedHat.yml | 40 ++ ansible-role-elk/tasks/main.yml | 65 ++ ansible-role-elk/templates/01-wazuh.conf.j2 | 45 ++ .../templates/elasticsearch.yml.j2 | 89 +++ ansible-role-elk/templates/jvm.options.j2 | 108 +++ ansible-role-elk/templates/kibana.yml.j2 | 100 +++ .../templates/wazuh-elastic5-template.json.j2 | 620 ++++++++++++++++++ ansible-role-elk/tests/requirements.yml | 2 + ansible-role-elk/tests/test.yml | 15 + ansible-role-filebeat/README.md | 74 +++ ansible-role-filebeat/defaults/main.yml | 29 + ansible-role-filebeat/handlers/main.yml | 3 + ansible-role-filebeat/meta/main.yml | 26 + ansible-role-filebeat/tasks/config.yml | 26 + ansible-role-filebeat/tasks/main.yml | 18 + ansible-role-filebeat/tasks/setup-Debian.yml | 14 + ansible-role-filebeat/tasks/setup-RedHat.yml | 11 + ansible-role-filebeat/templates/beats.repo.j2 | 6 + .../templates/filebeat.yml.j2 | 150 +++++ ansible-role-filebeat/tests/requirements.yml | 4 + ansible-role-filebeat/tests/test.yml | 20 + ansible-wazuh-agent/README.md | 48 ++ ansible-wazuh-agent/defaults/main.yml | 6 + ansible-wazuh-agent/handlers/main.yml | 7 + ansible-wazuh-agent/meta/main.yml | 47 ++ ansible-wazuh-agent/tasks/Debian.yml | 32 + ansible-wazuh-agent/tasks/RedHat.yml | 23 + ansible-wazuh-agent/tasks/main.yml | 41 ++ .../var-ossec-etc-ossec-agent.conf.j2 | 53 ++ ansible-wazuh-agent/vars/main.yml | 2 + ansible-wazuh-server/.gitignore | 1 + ansible-wazuh-server/.kitchen.yml | 21 + ansible-wazuh-server/CHANGELOG.md | 31 + ansible-wazuh-server/README.md | 188 ++++++ ansible-wazuh-server/defaults/main.yml | 6 + ansible-wazuh-server/handlers/main.yml | 7 + ansible-wazuh-server/meta/main.yml | 23 + ansible-wazuh-server/molecule.yml | 85 +++ ansible-wazuh-server/playbook.retry | 1 + ansible-wazuh-server/playbook.yml | 3 + ansible-wazuh-server/tasks/Debian.yml | 49 ++ ansible-wazuh-server/tasks/RedHat.yml | 63 ++ ansible-wazuh-server/tasks/main.yml | 117 ++++ .../templates/ossec-authd-init.service | 104 +++ .../templates/ossec-authd.service | 8 + .../var-ossec-etc-ossec-server.conf.j2 | 212 ++++++ .../var-ossec-etc-shared-agent.conf.j2 | 42 ++ .../var-ossec-rules-local_rules.xml.j2 | 57 ++ ansible-wazuh-server/vars/main.yml | 110 ++++ elk.yml | 3 + vars.yml | 110 ++++ wazuh-agent.retry | 1 + wazuh-agent.yml | 3 + wazuh-manager.yml | 4 + 59 files changed, 3155 insertions(+), 2 deletions(-) create mode 100644 ansible-role-elk/README.md create mode 100644 ansible-role-elk/defaults/main.yml create mode 100644 ansible-role-elk/handlers/main.yml create mode 100644 ansible-role-elk/meta/main.yml create mode 100644 ansible-role-elk/tasks/RedHat.yml create mode 100644 ansible-role-elk/tasks/main.yml create mode 100644 ansible-role-elk/templates/01-wazuh.conf.j2 create mode 100644 ansible-role-elk/templates/elasticsearch.yml.j2 create mode 100644 ansible-role-elk/templates/jvm.options.j2 create mode 100644 ansible-role-elk/templates/kibana.yml.j2 create mode 100644 ansible-role-elk/templates/wazuh-elastic5-template.json.j2 create mode 100644 ansible-role-elk/tests/requirements.yml create mode 100644 ansible-role-elk/tests/test.yml create mode 100644 ansible-role-filebeat/README.md create mode 100644 ansible-role-filebeat/defaults/main.yml create mode 100644 ansible-role-filebeat/handlers/main.yml create mode 100644 ansible-role-filebeat/meta/main.yml create mode 100644 ansible-role-filebeat/tasks/config.yml create mode 100644 ansible-role-filebeat/tasks/main.yml create mode 100644 ansible-role-filebeat/tasks/setup-Debian.yml create mode 100644 ansible-role-filebeat/tasks/setup-RedHat.yml create mode 100644 ansible-role-filebeat/templates/beats.repo.j2 create mode 100644 ansible-role-filebeat/templates/filebeat.yml.j2 create mode 100644 ansible-role-filebeat/tests/requirements.yml create mode 100644 ansible-role-filebeat/tests/test.yml create mode 100644 ansible-wazuh-agent/README.md create mode 100644 ansible-wazuh-agent/defaults/main.yml create mode 100644 ansible-wazuh-agent/handlers/main.yml create mode 100644 ansible-wazuh-agent/meta/main.yml create mode 100644 ansible-wazuh-agent/tasks/Debian.yml create mode 100644 ansible-wazuh-agent/tasks/RedHat.yml create mode 100644 ansible-wazuh-agent/tasks/main.yml create mode 100644 ansible-wazuh-agent/templates/var-ossec-etc-ossec-agent.conf.j2 create mode 100644 ansible-wazuh-agent/vars/main.yml create mode 100644 ansible-wazuh-server/.gitignore create mode 100644 ansible-wazuh-server/.kitchen.yml create mode 100644 ansible-wazuh-server/CHANGELOG.md create mode 100644 ansible-wazuh-server/README.md create mode 100644 ansible-wazuh-server/defaults/main.yml create mode 100644 ansible-wazuh-server/handlers/main.yml create mode 100644 ansible-wazuh-server/meta/main.yml create mode 100644 ansible-wazuh-server/molecule.yml create mode 100644 ansible-wazuh-server/playbook.retry create mode 100644 ansible-wazuh-server/playbook.yml create mode 100644 ansible-wazuh-server/tasks/Debian.yml create mode 100644 ansible-wazuh-server/tasks/RedHat.yml create mode 100644 ansible-wazuh-server/tasks/main.yml create mode 100644 ansible-wazuh-server/templates/ossec-authd-init.service create mode 100644 ansible-wazuh-server/templates/ossec-authd.service create mode 100644 ansible-wazuh-server/templates/var-ossec-etc-ossec-server.conf.j2 create mode 100644 ansible-wazuh-server/templates/var-ossec-etc-shared-agent.conf.j2 create mode 100644 ansible-wazuh-server/templates/var-ossec-rules-local_rules.xml.j2 create mode 100644 ansible-wazuh-server/vars/main.yml create mode 100644 elk.yml create mode 100644 vars.yml create mode 100644 wazuh-agent.retry create mode 100644 wazuh-agent.yml create mode 100644 wazuh-manager.yml diff --git a/README.md b/README.md index a01595eb..816ffaac 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,116 @@ -# wazuh-ansible -Wazuh Ansible playbook +## Install Ansible (server) + +``` +Debian +sudo apt-get install ansible + +CentOS +sudo yum install ansible (EPEL) +``` + +## Generate keys + +If you do not already have an SSH key pair that you would like to use for Ansible administration, we can create one now on your Ansible, locate in OSSEC Manager host and run: + +``` +$ ssh-keygen +``` + +Choose ~/.ssh/id_rsa_ansible as output. + +Enable ssh-agent and register de key: + +``` +$ eval "$(ssh-agent -s)" +$ ssh-add ~/.ssh/id_rsa_ansible +``` + +Copy ~/.ssh/id_rsa_ansible.pub content into the .ssh/authorized_keys host where you want to deploy OSSEC Agents in. + + +## Configuring Ansible Hosts + +Open the file with root privileges: + +``` +$ sudo nano /etc/ansible/hosts +``` + +Add ossec hosts: + +``` +[wazuh-manager] +10.0.0.51 + +[wazuh-agent] +10.0.0.123 +10.0.0.122 +10.0.0.121 + +[elk] +10.0.0.124 +``` + +## Install roles/playbooks + +``` +cd ~ +git clone https://github.com/wazuh/ossec-playbook/ +cp -pr ossec-playbook/* /etc/ansible/roles/ +``` + + +## Run the playbook + +Create in your home o preferred folder the file agent.yml with the content: + +``` +- hosts: all:!ossec-manager + roles: + - { role: ansible-wazuh-agent, ossec_server_ip: 10.0.0.51 } +``` + +and other file with wazuh-manager.yml with the content: + +``` +- hosts: wazuh-manager + roles: + - role: ansible-wazuh-server + - role: ansible-role-filebeat +``` + +Run the playbook for a manager + +``` +$ ansible-playbook wazuh-manager.yml -e"@vars.yml" +``` + +Run the playbbok for an agent: + + +``` +$ ansible-playbook wazuh-agent.yml -e"@vars.yml" +``` + + +## Example Playbook + +``` + - hosts: wazuh-agents + roles: + - ansible-wazuh-agent + - hots: wazuh-manager + - ansible-wazuh-manager + - ansible-role-filebeat + - hosts: elk + - ansible-role-elk + +``` + +### Created by + +Github: https://github.com/dj-wasabi/ansible-ossec-server + +mail: ikben [ at ] werner-dijkerman . nl + +Modificated by Wazuh diff --git a/ansible-role-elk/README.md b/ansible-role-elk/README.md new file mode 100644 index 00000000..f4e4143f --- /dev/null +++ b/ansible-role-elk/README.md @@ -0,0 +1,27 @@ +# Ansible Role: Elasticsearch + + +An Ansible Role that installs Elasticsearch, Logstash, Kibana and WazuhAPP on RedHat/CentOS. + +## Requirements + +Requires at least Java 8 (Java 8+ preferred). + +## Role Variables +Available variables are listed below, along with default values (see `defaults/main.yml`): + + elasticsearch_network_host: localhost + +Network host to listen for incoming connections on. By default we only listen on the localhost interface. Change this to the IP address to listen on a specific interface, or `0.0.0.0` to listen on all interfaces. + + elasticsearch_http_port: 9200 + +Whether to allow inline scripting against ElasticSearch. You should read the following link as there are possible security implications for enabling these options: [Enable Dynamic Scripting](https://www.elastic.co/guide/en/elasticsearch/reference/current/modules-scripting.html#enable-dynamic-scripting). Available options include: `true`, `false`, and `sandbox`. + +## License + +MIT / BSD + +## Author Information + +This role was created in 2014 by [Jeff Geerling](https://www.jeffgeerling.com/), author of [Ansible for DevOps](https://www.ansiblefordevops.com/). diff --git a/ansible-role-elk/defaults/main.yml b/ansible-role-elk/defaults/main.yml new file mode 100644 index 00000000..9ad375fd --- /dev/null +++ b/ansible-role-elk/defaults/main.yml @@ -0,0 +1,9 @@ +--- +elasticsearch_cluster_name: wazuh +elasticsearch_node_name: node-1 +elasticsearch_http_port: 9200 +elasticsearch_network_host: localhost +elasticsearch_jvm_xms: 1g + + +kibana_server_host: "0.0.0.0" diff --git a/ansible-role-elk/handlers/main.yml b/ansible-role-elk/handlers/main.yml new file mode 100644 index 00000000..1b2400b8 --- /dev/null +++ b/ansible-role-elk/handlers/main.yml @@ -0,0 +1,9 @@ +--- +- name: restart elasticsearch + service: name=elasticsearch state=restarted + +- name: restart logstash + service: name=logstash state=restarted + +- name: restart kibana + service: name=kibana state=restarted diff --git a/ansible-role-elk/meta/main.yml b/ansible-role-elk/meta/main.yml new file mode 100644 index 00000000..073595dd --- /dev/null +++ b/ansible-role-elk/meta/main.yml @@ -0,0 +1,21 @@ +--- +galaxy_info: + author: geerlingguy + description: Elasticsearch for Linux. + company: "Midwestern Mac, LLC" + license: "license (BSD, MIT)" + min_ansible_version: 1.8 + platforms: + - name: EL + versions: + - all + - name: Debian + versions: + - all + - name: Ubuntu + versions: + - all + galaxy_tags: + - web + - system + - monitoring diff --git a/ansible-role-elk/tasks/RedHat.yml b/ansible-role-elk/tasks/RedHat.yml new file mode 100644 index 00000000..51910946 --- /dev/null +++ b/ansible-role-elk/tasks/RedHat.yml @@ -0,0 +1,40 @@ +--- +- name: download Java RPM + shell: + "curl -L -H 'Cookie:oraclelicense=accept-securebackup-cookie' -o /tmp/jdk-8-linux-x64.rpm http://download.oracle.com/otn-pub/java/jdk/8u111-b14/jdk-8u111-linux-x64.rpm" + args: + creates: "/tmp/jdk-8-linux-x64.rpm" + register: oracle_java_task_rpm_download + become: yes + tags: + - installation + +- name: install RPM + action: "yum name=/tmp/jdk-8-linux-x64.rpm state=present" + when: not oracle_java_task_rpm_download|skipped + become: yes + tags: + - installation + +- name: Add Elasticsearch GPG key. + rpm_key: + key: https://artifacts.elastic.co/GPG-KEY-elasticsearch + state: present + +- name: RedHat | Install ELK repo + yum_repository: + name: elk_repo + description: Elastic repository for 5.x packages + baseurl: https://artifacts.elastic.co/packages/5.x/yum + gpgkey: https://artifacts.elastic.co/GPG-KEY-elasticsearch + gpgcheck: yes + +- name: RedHat | Install ELK + yum: pkg={{ item }} + state=present + with_items: + - logstash-5.2.2 + - elasticsearch-5.2.2 + - kibana-5.2.2 + tags: + - init diff --git a/ansible-role-elk/tasks/main.yml b/ansible-role-elk/tasks/main.yml new file mode 100644 index 00000000..d83bc17c --- /dev/null +++ b/ansible-role-elk/tasks/main.yml @@ -0,0 +1,65 @@ +--- +- include: RedHat.yml + when: ansible_os_family == 'RedHat' + +- name: Configure Elasticsearch. + template: + src: elasticsearch.yml.j2 + dest: /etc/elasticsearch/elasticsearch.yml + owner: root + group: elasticsearch + mode: 0660 + notify: restart elasticsearch + +- name: Configure Elasticsearch JVM memmory. + template: + src: jvm.options.j2 + dest: /etc/elasticsearch/jvm.options + owner: root + group: elasticsearch + mode: 0660 + notify: restart elasticsearch + +- name: Start Elasticsearch. + service: name=elasticsearch state=started enabled=yes + +- name: Make sure Elasticsearch is running before proceeding. + wait_for: host={{ elasticsearch_network_host }} port={{ elasticsearch_http_port }} delay=3 timeout=300 + +- name: Logstash configuration + template: + src: 01-wazuh.conf.j2 + dest: /etc/logstash/conf.d/01-wazuh.conf + owner: root + group: root + notify: restart logstash + +- name: Logstash template + template: + src: wazuh-elastic5-template.json.j2 + dest: /etc/logstash/wazuh-elastic5-template.json + owner: root + group: root + notify: restart logstash + +- name: Kibana configuration + template: + src: kibana.yml.j2 + dest: /etc/kibana/kibana.yml + owner: root + group: root + mode: 0664 + notify: restart kibana + +- name: Install Wazuh-APP (can take a while) + shell: if ! /usr/share/kibana/bin/kibana-plugin list | grep wazuh; then /usr/share/kibana/bin/kibana-plugin install https://packages.wazuh.com/wazuhapp/wazuhapp-2.0_5.2.2.zip; fi; + +- name: Ensure Logstash, Kibana and Elasticsearch started and enabled + service: + name: "{{ item }}" + enabled: yes + state: started + with_items: + - logstash + - elasticsearch + - kibana diff --git a/ansible-role-elk/templates/01-wazuh.conf.j2 b/ansible-role-elk/templates/01-wazuh.conf.j2 new file mode 100644 index 00000000..3bc0b0af --- /dev/null +++ b/ansible-role-elk/templates/01-wazuh.conf.j2 @@ -0,0 +1,45 @@ +# {{ ansible_managed }} +# Wazuh - Logstash configuration file +## Remote Wazuh Manager - Filebeat input +input { + beats { + port => 5000 + codec => "json" +# ssl => true +# ssl_certificate => "/etc/logstash/logstash.crt" +# ssl_key => "/etc/logstash/logstash.key" + } +} +## Local Wazuh Manager - JSON file input +#input { +# file { +# type => "wazuh-alerts" +# path => "/var/ossec/logs/alerts/alerts.json" +# codec => "json" +# } +#} +filter { + geoip { + source => "srcip" + target => "GeoLocation" + fields => ["city_name", "continent_code", "country_code2", "country_name", "region_name", "location"] + } + date { + match => ["timestamp", "ISO8601"] + target => "@timestamp" + } + mutate { + remove_field => [ "timestamp", "beat", "fields", "input_type", "tags", "count", "@version", "log", "offset", "type"] + } +} +output { + #stdout { codec => rubydebug } + elasticsearch { + hosts => ["localhost:9200"] + index => "wazuh-alerts-%{+YYYY.MM.dd}" + document_type => "wazuh" + template => "/etc/logstash/wazuh-elastic5-template.json" + template_name => "wazuh" + template_overwrite => true + } +} diff --git a/ansible-role-elk/templates/elasticsearch.yml.j2 b/ansible-role-elk/templates/elasticsearch.yml.j2 new file mode 100644 index 00000000..0939da3a --- /dev/null +++ b/ansible-role-elk/templates/elasticsearch.yml.j2 @@ -0,0 +1,89 @@ +# {{ ansible_managed }} +# ======================== Elasticsearch Configuration ========================= +# +# NOTE: Elasticsearch comes with reasonable defaults for most settings. +# Before you set out to tweak and tune the configuration, make sure you +# understand what are you trying to accomplish and the consequences. +# +# The primary way of configuring a node is via this file. This template lists +# the most important settings you may want to configure for a production cluster. +# +# Please consult the documentation for further information on configuration options: +# https://www.elastic.co/guide/en/elasticsearch/reference/index.html +# +# ---------------------------------- Cluster ----------------------------------- +# +# Use a descriptive name for your cluster: +# +cluster.name: {{ elasticsearch_cluster_name }} +# +# ------------------------------------ Node ------------------------------------ +# +# Use a descriptive name for the node: +# +node.name: {{ elasticsearch_node_name }} +# +# Add custom attributes to the node: +# +#node.attr.rack: r1 +# +# ----------------------------------- Paths ------------------------------------ +# +# Path to directory where to store the data (separate multiple locations by comma): +# +#path.data: /path/to/data +# +# Path to log files: +# +#path.logs: /path/to/logs +# +# ----------------------------------- Memory ----------------------------------- +# +# Lock the memory on startup: +# +#bootstrap.memory_lock: true +# +# Make sure that the heap size is set to about half the memory available +# on the system and that the owner of the process is allowed to use this +# limit. +# +# Elasticsearch performs poorly when the system is swapping the memory. +# +# ---------------------------------- Network ----------------------------------- +# +# Set the bind address to a specific IP (IPv4 or IPv6): +# +#network.host: 192.168.0.1 +# +# Set a custom port for HTTP: +# +#http.port: 9200 +# +# For more information, consult the network module documentation. +# +# --------------------------------- Discovery ---------------------------------- +# +# Pass an initial list of hosts to perform discovery when new node is started: +# The default list of hosts is ["127.0.0.1", "[::1]"] +# +#discovery.zen.ping.unicast.hosts: ["host1", "host2"] +# +# Prevent the "split brain" by configuring the majority of nodes (total number of master-eligible nodes / 2 + 1): +# +#discovery.zen.minimum_master_nodes: 3 +# +# For more information, consult the zen discovery module documentation. +# +# ---------------------------------- Gateway ----------------------------------- +# +# Block initial recovery after a full cluster restart until N nodes are started: +# +#gateway.recover_after_nodes: 3 +# +# For more information, consult the gateway module documentation. +# +# ---------------------------------- Various ----------------------------------- +# +# Require explicit names when deleting indices: +# +#action.destructive_requires_name: true diff --git a/ansible-role-elk/templates/jvm.options.j2 b/ansible-role-elk/templates/jvm.options.j2 new file mode 100644 index 00000000..1eed34ef --- /dev/null +++ b/ansible-role-elk/templates/jvm.options.j2 @@ -0,0 +1,108 @@ +# {{ ansible_managed }} +## JVM configuration + +################################################################ +## IMPORTANT: JVM heap size +################################################################ +## +## You should always set the min and max JVM heap +## size to the same value. For example, to set +## the heap to 4 GB, set: +## +## -Xms4g +## -Xmx4g +## +## See https://www.elastic.co/guide/en/elasticsearch/reference/current/heap-size.html +## for more information +## +################################################################ + +# Xms represents the initial size of total heap space +# Xmx represents the maximum size of total heap space + +-Xms{{ elasticsearch_jvm_xms }} +-Xmx{{ elasticsearch_jvm_xms }} + +################################################################ +## Expert settings +################################################################ +## +## All settings below this section are considered +## expert settings. Don't tamper with them unless +## you understand what you are doing +## +################################################################ + +## GC configuration +-XX:+UseConcMarkSweepGC +-XX:CMSInitiatingOccupancyFraction=75 +-XX:+UseCMSInitiatingOccupancyOnly + +## optimizations + +# disable calls to System#gc +-XX:+DisableExplicitGC + +# pre-touch memory pages used by the JVM during initialization +-XX:+AlwaysPreTouch + +## basic + +# force the server VM (remove on 32-bit client JVMs) +-server + +# explicitly set the stack size (reduce to 320k on 32-bit client JVMs) +-Xss1m + +# set to headless, just in case +-Djava.awt.headless=true + +# ensure UTF-8 encoding by default (e.g. filenames) +-Dfile.encoding=UTF-8 + +# use our provided JNA always versus the system one +-Djna.nosys=true + +# use old-style file permissions on JDK9 +-Djdk.io.permissionsUseCanonicalPath=true + +# flags to configure Netty +-Dio.netty.noUnsafe=true +-Dio.netty.noKeySetOptimization=true +-Dio.netty.recycler.maxCapacityPerThread=0 + +# log4j 2 +-Dlog4j.shutdownHookEnabled=false +-Dlog4j2.disable.jmx=true +-Dlog4j.skipJansi=true + +## heap dumps + +# generate a heap dump when an allocation from the Java heap fails +# heap dumps are created in the working directory of the JVM +-XX:+HeapDumpOnOutOfMemoryError + +# specify an alternative path for heap dumps +# ensure the directory exists and has sufficient space +#-XX:HeapDumpPath=${heap.dump.path} + +## GC logging + +#-XX:+PrintGCDetails +#-XX:+PrintGCTimeStamps +#-XX:+PrintGCDateStamps +#-XX:+PrintClassHistogram +#-XX:+PrintTenuringDistribution +#-XX:+PrintGCApplicationStoppedTime + +# log GC status to a file with time stamps +# ensure the directory exists +#-Xloggc:${loggc} + +# Elasticsearch 5.0.0 will throw an exception on unquoted field names in JSON. +# If documents were already indexed with unquoted fields in a previous version +# of Elasticsearch, some operations may throw errors. +# +# WARNING: This option will be removed in Elasticsearch 6.0.0 and is provided +# only for migration purposes. +#-Delasticsearch.json.allow_unquoted_field_names=true diff --git a/ansible-role-elk/templates/kibana.yml.j2 b/ansible-role-elk/templates/kibana.yml.j2 new file mode 100644 index 00000000..90cf2e84 --- /dev/null +++ b/ansible-role-elk/templates/kibana.yml.j2 @@ -0,0 +1,100 @@ +# {{ ansible_managed }} +# Kibana is served by a back end server. This setting specifies the port to use. +#server.port: 5601 + +# Specifies the address to which the Kibana server will bind. IP addresses and host names are both valid values. +# The default is 'localhost', which usually means remote machines will not be able to connect. +# To allow connections from remote users, set this parameter to a non-loopback address. +server.host: {{ kibana_server_host }} + +# Enables you to specify a path to mount Kibana at if you are running behind a proxy. This only affects +# the URLs generated by Kibana, your proxy is expected to remove the basePath value before forwarding requests +# to Kibana. This setting cannot end in a slash. +#server.basePath: "" + +# The maximum payload size in bytes for incoming server requests. +#server.maxPayloadBytes: 1048576 + +# The Kibana server's name. This is used for display purposes. +#server.name: "your-hostname" + +# The URL of the Elasticsearch instance to use for all your queries. +#elasticsearch.url: "http://localhost:9200" + +# When this setting's value is true Kibana uses the hostname specified in the server.host +# setting. When the value of this setting is false, Kibana uses the hostname of the host +# that connects to this Kibana instance. +#elasticsearch.preserveHost: true + +# Kibana uses an index in Elasticsearch to store saved searches, visualizations and +# dashboards. Kibana creates a new index if the index doesn't already exist. +#kibana.index: ".kibana" + +# The default application to load. +#kibana.defaultAppId: "discover" + +# If your Elasticsearch is protected with basic authentication, these settings provide +# the username and password that the Kibana server uses to perform maintenance on the Kibana +# index at startup. Your Kibana users still need to authenticate with Elasticsearch, which +# is proxied through the Kibana server. +#elasticsearch.username: "user" +#elasticsearch.password: "pass" + +# Paths to the PEM-format SSL certificate and SSL key files, respectively. These +# files enable SSL for outgoing requests from the Kibana server to the browser. +#server.ssl.cert: /path/to/your/server.crt +#server.ssl.key: /path/to/your/server.key + +# Optional settings that provide the paths to the PEM-format SSL certificate and key files. +# These files validate that your Elasticsearch backend uses the same key files. +#elasticsearch.ssl.cert: /path/to/your/client.crt +#elasticsearch.ssl.key: /path/to/your/client.key + +# Optional setting that enables you to specify a path to the PEM file for the certificate +# authority for your Elasticsearch instance. +#elasticsearch.ssl.ca: /path/to/your/CA.pem + +# To disregard the validity of SSL certificates, change this setting's value to false. +#elasticsearch.ssl.verify: true + +# Time in milliseconds to wait for Elasticsearch to respond to pings. Defaults to the value of +# the elasticsearch.requestTimeout setting. +#elasticsearch.pingTimeout: 1500 + +# Time in milliseconds to wait for responses from the back end or Elasticsearch. This value +# must be a positive integer. +#elasticsearch.requestTimeout: 30000 + +# List of Kibana client-side headers to send to Elasticsearch. To send *no* client-side +# headers, set this value to [] (an empty list). +#elasticsearch.requestHeadersWhitelist: [ authorization ] + +# Header names and values that are sent to Elasticsearch. Any custom headers cannot be overwritten +# by client-side headers, regardless of the elasticsearch.requestHeadersWhitelist configuration. +#elasticsearch.customHeaders: {} + +# Time in milliseconds for Elasticsearch to wait for responses from shards. Set to 0 to disable. +#elasticsearch.shardTimeout: 0 + +# Time in milliseconds to wait for Elasticsearch at Kibana startup before retrying. +#elasticsearch.startupTimeout: 5000 + +# Specifies the path where Kibana creates the process ID file. +#pid.file: /var/run/kibana.pid + +# Enables you specify a file where Kibana stores log output. +#logging.dest: stdout + +# Set the value of this setting to true to suppress all logging output. +#logging.silent: false + +# Set the value of this setting to true to suppress all logging output other than error messages. +#logging.quiet: false + +# Set the value of this setting to true to log all events, including system usage information +# and all requests. +#logging.verbose: false + +# Set the interval in milliseconds to sample system and process performance +# metrics. Minimum is 100ms. Defaults to 5000. +#ops.interval: 5000 diff --git a/ansible-role-elk/templates/wazuh-elastic5-template.json.j2 b/ansible-role-elk/templates/wazuh-elastic5-template.json.j2 new file mode 100644 index 00000000..2ec715f2 --- /dev/null +++ b/ansible-role-elk/templates/wazuh-elastic5-template.json.j2 @@ -0,0 +1,620 @@ +{ + "order": 0, + "template": "wazuh*", + "settings": { + "index.refresh_interval": "5s" + }, + "mappings": { + "wazuh": { + "dynamic_templates": [ + { + "string_as_keyword": { + "match_mapping_type": "string", + "mapping": { + "type": "keyword", + "doc_values": "true" + } + } + } + ], + "properties": { + "@timestamp": { + "type": "date", + "format": "dateOptionalTime" + }, + "@version": { + "type": "text" + }, + "agent": { + "properties": { + "ip": { + "type": "keyword", + "doc_values": "true" + }, + "id": { + "type": "keyword", + "doc_values": "true" + }, + "name": { + "type": "keyword", + "doc_values": "true" + } + } + }, + "manager": { + "properties": { + "name": { + "type": "keyword", + "doc_values": "true" + } + } + }, + "dstuser": { + "type": "keyword", + "doc_values": "true" + }, + "AlertsFile": { + "type": "keyword", + "doc_values": "true" + }, + "full_log": { + "type": "text" + }, + "previous_log": { + "type": "text" + }, + "GeoLocation": { + "properties": { + "area_code": { + "type": "long" + }, + "city_name": { + "type": "keyword", + "doc_values": "true" + }, + "continent_code": { + "type": "text" + }, + "coordinates": { + "type": "double" + }, + "country_code2": { + "type": "text" + }, + "country_code3": { + "type": "text" + }, + "country_name": { + "type": "keyword", + "doc_values": "true" + }, + "dma_code": { + "type": "long" + }, + "ip": { + "type": "keyword", + "doc_values": "true" + }, + "latitude": { + "type": "double" + }, + "location": { + "type": "geo_point" + }, + "longitude": { + "type": "double" + }, + "postal_code": { + "type": "keyword" + }, + "real_region_name": { + "type": "keyword", + "doc_values": "true" + }, + "region_name": { + "type": "keyword", + "doc_values": "true" + }, + "timezone": { + "type": "text" + } + } + }, + "host": { + "type": "keyword", + "doc_values": "true" + }, + "syscheck": { + "properties": { + "path": { + "type": "keyword", + "doc_values": "true" + }, + "sha1_before": { + "type": "keyword", + "doc_values": "true" + }, + "sha1_after": { + "type": "keyword", + "doc_values": "true" + }, + "uid_before": { + "type": "keyword", + "doc_values": "true" + }, + "uid_after": { + "type": "keyword", + "doc_values": "true" + }, + "gid_before": { + "type": "keyword", + "doc_values": "true" + }, + "gid_after": { + "type": "keyword", + "doc_values": "true" + }, + "perm_before": { + "type": "keyword", + "doc_values": "true" + }, + "perm_after": { + "type": "keyword", + "doc_values": "true" + }, + "md5_after": { + "type": "keyword", + "doc_values": "true" + }, + "md5_before": { + "type": "keyword", + "doc_values": "true" + }, + "gname_after": { + "type": "keyword", + "doc_values": "true" + }, + "gname_before": { + "type": "keyword", + "doc_values": "true" + }, + "inode_after": { + "type": "keyword", + "doc_values": "true" + }, + "inode_before": { + "type": "keyword", + "doc_values": "true" + }, + "mtime_after": { + "type": "date", + "format": "dateOptionalTime", + "doc_values": "true" + }, + "mtime_before": { + "type": "date", + "format": "dateOptionalTime", + "doc_values": "true" + }, + "uname_after": { + "type": "keyword", + "doc_values": "true" + }, + "uname_before": { + "type": "keyword", + "doc_values": "true" + }, + "size_before": { + "type": "long", + "doc_values": "true" + }, + "size_after": { + "type": "long", + "doc_values": "true" + }, + "diff": { + "type": "keyword", + "doc_values": "true" + }, + "event": { + "type": "keyword", + "doc_values": "true" + } + } + }, + "location": { + "type": "keyword", + "doc_values": "true" + }, + "message": { + "type": "text" + }, + "offset": { + "type": "keyword" + }, + "rule": { + "properties": { + "description": { + "type": "keyword", + "doc_values": "true" + }, + "groups": { + "type": "keyword", + "doc_values": "true" + }, + "level": { + "type": "long", + "doc_values": "true" + }, + "id": { + "type": "keyword", + "doc_values": "true" + }, + "cve": { + "type": "keyword", + "doc_values": "true" + }, + "info": { + "type": "keyword", + "doc_values": "true" + }, + "frequency": { + "type": "long", + "doc_values": "true" + }, + "firedtimes": { + "type": "long", + "doc_values": "true" + }, + "cis": { + "type": "keyword", + "doc_values": "true" + }, + "pci_dss": { + "type": "keyword", + "doc_values": "true" + } + } + }, + "decoder": { + "properties": { + "parent": { + "type": "keyword", + "doc_values": "true" + }, + "name": { + "type": "keyword", + "doc_values": "true" + }, + "ftscomment": { + "type": "keyword", + "doc_values": "true" + }, + "fts": { + "type": "long", + "doc_values": "true" + }, + "accumulate": { + "type": "long", + "doc_values": "true" + } + } + }, + "srcip": { + "type": "keyword", + "doc_values": "true" + }, + "protocol": { + "type": "keyword", + "doc_values": "true" + }, + "action": { + "type": "keyword", + "doc_values": "true" + }, + "dstip": { + "type": "keyword", + "doc_values": "true" + }, + "dstport": { + "type": "keyword", + "doc_values": "true" + }, + "srcuser": { + "type": "keyword", + "doc_values": "true" + }, + "program_name": { + "type": "keyword", + "doc_values": "true" + }, + "id": { + "type": "keyword", + "doc_values": "true" + }, + "status": { + "type": "keyword", + "doc_values": "true" + }, + "command": { + "type": "keyword", + "doc_values": "true" + }, + "url": { + "type": "keyword", + "doc_values": "true" + }, + "data": { + "type": "keyword", + "doc_values": "true" + }, + "system_name": { + "type": "keyword", + "doc_values": "true" + }, + "type": { + "type": "text" + }, + "title": { + "type": "keyword", + "doc_values": "true" + }, + "oscap": { + "properties": { + "check.title": { + "type": "keyword", + "doc_values": "true" + }, + "check.id": { + "type": "keyword", + "doc_values": "true" + }, + "check.result": { + "type": "keyword", + "doc_values": "true" + }, + "check.severity": { + "type": "keyword", + "doc_values": "true" + }, + "check.description": { + "type": "text" + }, + "check.rationale": { + "type": "text" + }, + "check.references": { + "type": "text" + }, + "check.identifiers": { + "type": "text" + }, + "check.oval.id": { + "type": "keyword", + "doc_values": "true" + }, + "scan.id": { + "type": "keyword", + "doc_values": "true" + }, + "scan.content": { + "type": "keyword", + "doc_values": "true" + }, + "scan.benchmark.id": { + "type": "keyword", + "doc_values": "true" + }, + "scan.profile.title": { + "type": "keyword", + "doc_values": "true" + }, + "scan.profile.id": { + "type": "keyword", + "doc_values": "true" + }, + "scan.score": { + "type": "double", + "doc_values": "true" + }, + "scan.return_code": { + "type": "long", + "doc_values": "true" + } + } + }, + "audit": { + "properties": { + "type": { + "type": "keyword", + "doc_values": "true" + }, + "id": { + "type": "keyword", + "doc_values": "true" + }, + "syscall": { + "type": "keyword", + "doc_values": "true" + }, + "exit": { + "type": "keyword", + "doc_values": "true" + }, + "ppid": { + "type": "keyword", + "doc_values": "true" + }, + "pid": { + "type": "keyword", + "doc_values": "true" + }, + "auid": { + "type": "keyword", + "doc_values": "true" + }, + "uid": { + "type": "keyword", + "doc_values": "true" + }, + "gid": { + "type": "keyword", + "doc_values": "true" + }, + "euid": { + "type": "keyword", + "doc_values": "true" + }, + "suid": { + "type": "keyword", + "doc_values": "true" + }, + "fsuid": { + "type": "keyword", + "doc_values": "true" + }, + "egid": { + "type": "keyword", + "doc_values": "true" + }, + "sgid": { + "type": "keyword", + "doc_values": "true" + }, + "fsgid": { + "type": "keyword", + "doc_values": "true" + }, + "tty": { + "type": "keyword", + "doc_values": "true" + }, + "session": { + "type": "keyword", + "doc_values": "true" + }, + "command": { + "type": "keyword", + "doc_values": "true" + }, + "exe": { + "type": "keyword", + "doc_values": "true" + }, + "key": { + "type": "keyword", + "doc_values": "true" + }, + "cwd": { + "type": "keyword", + "doc_values": "true" + }, + "directory.name": { + "type": "keyword", + "doc_values": "true" + }, + "directory.inode": { + "type": "keyword", + "doc_values": "true" + }, + "directory.mode": { + "type": "keyword", + "doc_values": "true" + }, + "file.name": { + "type": "keyword", + "doc_values": "true" + }, + "file.inode": { + "type": "keyword", + "doc_values": "true" + }, + "file.mode": { + "type": "keyword", + "doc_values": "true" + }, + "acct": { + "type": "keyword", + "doc_values": "true" + }, + "dev": { + "type": "keyword", + "doc_values": "true" + }, + "enforcing": { + "type": "keyword", + "doc_values": "true" + }, + "list": { + "type": "keyword", + "doc_values": "true" + }, + "old-auid": { + "type": "keyword", + "doc_values": "true" + }, + "old-ses": { + "type": "keyword", + "doc_values": "true" + }, + "old_enforcing": { + "type": "keyword", + "doc_values": "true" + }, + "old_prom": { + "type": "keyword", + "doc_values": "true" + }, + "op": { + "type": "keyword", + "doc_values": "true" + }, + "prom": { + "type": "keyword", + "doc_values": "true" + }, + "res": { + "type": "keyword", + "doc_values": "true" + }, + "srcip": { + "type": "keyword", + "doc_values": "true" + }, + "subj": { + "type": "keyword", + "doc_values": "true" + }, + "success": { + "type": "keyword", + "doc_values": "true" + } + } + } + } + }, + "agent": { + "properties": { + "@timestamp": { + "type": "date", + "format": "dateOptionalTime" + }, + "status": { + "type": "keyword" + }, + "ip": { + "type": "keyword" + }, + "host": { + "type": "keyword" + }, + "name": { + "type": "keyword" + }, + "id": { + "type": "keyword" + } + } + } + } +} diff --git a/ansible-role-elk/tests/requirements.yml b/ansible-role-elk/tests/requirements.yml new file mode 100644 index 00000000..8fbe7cb6 --- /dev/null +++ b/ansible-role-elk/tests/requirements.yml @@ -0,0 +1,2 @@ +--- +- src: geerlingguy.java diff --git a/ansible-role-elk/tests/test.yml b/ansible-role-elk/tests/test.yml new file mode 100644 index 00000000..7e775aea --- /dev/null +++ b/ansible-role-elk/tests/test.yml @@ -0,0 +1,15 @@ +--- +- hosts: all + + pre_tasks: + - name: Update apt cache. + apt: update_cache=yes cache_valid_time=600 + when: ansible_os_family == 'Debian' + changed_when: false + + - name: Ensure build dependencies are installed. + package: name=curl state=present + + roles: + - geerlingguy.java + - role_under_test diff --git a/ansible-role-filebeat/README.md b/ansible-role-filebeat/README.md new file mode 100644 index 00000000..1eccacb8 --- /dev/null +++ b/ansible-role-filebeat/README.md @@ -0,0 +1,74 @@ +# Ansible Role: Filebeat for ELK Stack + +An Ansible Role that installs [Filebeat](https://www.elastic.co/products/beats/filebeat) on RedHat/CentOS or Debian/Ubuntu. + +## Requirements + +None. + +## Role Variables + +Available variables are listed below, along with default values (see `defaults/main.yml`): + + filebeat_create_config: true + +Whether to create the Filebeat configuration file and handle the copying of SSL key and cert for filebeat. If you prefer to create a configuration file yourself you can set this to `false`. + + filebeat_prospectors: + - input_type: log + paths: + - "/var/log/*.log" + +Prospectors that will be listed in the `prospectors` section of the Filebeat configuration. Read through the [Filebeat Prospectors configuration guide](https://www.elastic.co/guide/en/beats/filebeat/current/configuration-filebeat-options.html) for more options. + + filebeat_output_elasticsearch_enabled: false + filebeat_output_elasticsearch_hosts: + - "localhost:9200" + +Whether to enable Elasticsearch output, and which hosts to send output to. + + filebeat_output_logstash_enabled: true + filebeat_output_logstash_hosts: + - "localhost:5000" + +Whether to enable Logstash output, and which hosts to send output to. + + filebeat_enable_logging: false + filebeat_log_level: warning + filebeat_log_dir: /var/log/filebeat + filebeat_log_filename: filebeat.log + +Filebeat logging. + + filebeat_ssl_dir: /etc/pki/logstash + +The path where certificates and keyfiles will be stored. + + filebeat_ssl_certificate_file: "" + filebeat_ssl_key_file: "" + +Local paths to the SSL certificate and key files, which will be copied into the `filebeat_ssl_dir`. + +For utmost security, you should use your own valid certificate and keyfile, and update the `filebeat_ssl_*` variables in your playbook to use your certificate. + +To generate a self-signed certificate/key pair, you can use use the command: + + $ sudo openssl req -x509 -batch -nodes -days 3650 -newkey rsa:2048 -keyout filebeat.key -out filebeat.crt + +Note that filebeat and logstash may not work correctly with self-signed certificates unless you also have the full chain of trust (including the Certificate Authority for your self-signed cert) added on your server. See: https://github.com/elastic/logstash/issues/4926#issuecomment-203936891 + + filebeat_ssl_insecure: "false" + +Set this to `"true"` to allow the use of self-signed certificates (when a CA isn't available). + +## Dependencies + +None. + +## License + +MIT / BSD + +## Author Information + +This role was created in 2016 by [Jeff Geerling](https://www.jeffgeerling.com/), author of [Ansible for DevOps](https://www.ansiblefordevops.com/). diff --git a/ansible-role-filebeat/defaults/main.yml b/ansible-role-filebeat/defaults/main.yml new file mode 100644 index 00000000..5e9f7f50 --- /dev/null +++ b/ansible-role-filebeat/defaults/main.yml @@ -0,0 +1,29 @@ +--- +filebeat_create_config: true + +filebeat_prospectors: + - input_type: log + paths: + - "/var/ossec/logs/alerts/alerts.json" + document_type: json + json.message_key: log + json.keys_under_root: true + json.overwrite_keys: true + +filebeat_output_elasticsearch_enabled: false +filebeat_output_elasticsearch_hosts: + - "localhost:9200" + +filebeat_output_logstash_enabled: true +filebeat_output_logstash_hosts: + - "192.168.33.172:5000" + +filebeat_enable_logging: true +filebeat_log_level: debug +filebeat_log_dir: /var/log/mybeat +filebeat_log_filename: mybeat.log + +filebeat_ssl_dir: /etc/pki/logstash +filebeat_ssl_certificate_file: "" +filebeat_ssl_key_file: "" +filebeat_ssl_insecure: "false" diff --git a/ansible-role-filebeat/handlers/main.yml b/ansible-role-filebeat/handlers/main.yml new file mode 100644 index 00000000..96e15a22 --- /dev/null +++ b/ansible-role-filebeat/handlers/main.yml @@ -0,0 +1,3 @@ +--- +- name: restart filebeat + service: name=filebeat state=restarted diff --git a/ansible-role-filebeat/meta/main.yml b/ansible-role-filebeat/meta/main.yml new file mode 100644 index 00000000..5ac2a409 --- /dev/null +++ b/ansible-role-filebeat/meta/main.yml @@ -0,0 +1,26 @@ +--- +dependencies: [] + +galaxy_info: + author: geerlingguy + description: Filebeat for Linux. + company: "Midwestern Mac, LLC" + license: "license (BSD, MIT)" + min_ansible_version: 2.0 + platforms: + - name: EL + versions: + - 6 + - 7 + - name: Debian + versions: + - jessie + - name: Ubuntu + versions: + - precise + - trusty + - xenial + galaxy_tags: + - web + - system + - monitoring diff --git a/ansible-role-filebeat/tasks/config.yml b/ansible-role-filebeat/tasks/config.yml new file mode 100644 index 00000000..71a1672f --- /dev/null +++ b/ansible-role-filebeat/tasks/config.yml @@ -0,0 +1,26 @@ +--- +- name: Copy Filebeat configuration. + template: + src: filebeat.yml.j2 + dest: "/etc/filebeat/filebeat.yml" + owner: root + group: root + mode: 0644 + notify: restart filebeat + +- name: Ensure Filebeat SSL key pair directory exists. + file: + path: "{{ filebeat_ssl_dir }}" + state: directory + when: filebeat_ssl_key_file + +- name: Copy SSL key and cert for filebeat. + copy: + src: "{{ item }}" + dest: "{{ filebeat_ssl_dir }}/{{ item | basename }}" + mode: 0644 + with_items: + - "{{ filebeat_ssl_key_file }}" + - "{{ filebeat_ssl_certificate_file }}" + notify: restart filebeat + when: filebeat_ssl_key_file and filebeat_ssl_certificate_file \ No newline at end of file diff --git a/ansible-role-filebeat/tasks/main.yml b/ansible-role-filebeat/tasks/main.yml new file mode 100644 index 00000000..e6886b46 --- /dev/null +++ b/ansible-role-filebeat/tasks/main.yml @@ -0,0 +1,18 @@ +--- +- include: setup-RedHat.yml + when: ansible_os_family == 'RedHat' + +- include: setup-Debian.yml + when: ansible_os_family == 'Debian' + +- name: Install Filebeat. + package: name=filebeat state=present + +- include: config.yml + when: filebeat_create_config + +- name: Ensure Filebeat is started and enabled at boot. + service: + name: filebeat + state: started + enabled: yes diff --git a/ansible-role-filebeat/tasks/setup-Debian.yml b/ansible-role-filebeat/tasks/setup-Debian.yml new file mode 100644 index 00000000..2bd71fa5 --- /dev/null +++ b/ansible-role-filebeat/tasks/setup-Debian.yml @@ -0,0 +1,14 @@ +--- +- name: Ensure depdency is installed (Ubuntu). + apt: name=apt-transport-https state=present + +- name: Add Elasticsearch apt key. + apt_key: + url: https://packages.elastic.co/GPG-KEY-elasticsearch + state: present + +- name: Add Filebeat repository. + apt_repository: + repo: 'deb https://packages.elastic.co/beats/apt stable main' + state: present + update_cache: yes diff --git a/ansible-role-filebeat/tasks/setup-RedHat.yml b/ansible-role-filebeat/tasks/setup-RedHat.yml new file mode 100644 index 00000000..abdb7c01 --- /dev/null +++ b/ansible-role-filebeat/tasks/setup-RedHat.yml @@ -0,0 +1,11 @@ +--- +- name: Add Elasticsearch GPG key. + rpm_key: + key: https://packages.elastic.co/GPG-KEY-elasticsearch + state: present + +- name: Add Filebeat repository. + template: + src: beats.repo.j2 + dest: /etc/yum.repos.d/beats.repo + mode: 0644 diff --git a/ansible-role-filebeat/templates/beats.repo.j2 b/ansible-role-filebeat/templates/beats.repo.j2 new file mode 100644 index 00000000..86f84507 --- /dev/null +++ b/ansible-role-filebeat/templates/beats.repo.j2 @@ -0,0 +1,6 @@ +[beats] +name=Elastic Beats Repository +baseurl=https://packages.elastic.co/beats/yum/el/$basearch +enabled=1 +gpgkey=https://packages.elastic.co/GPG-KEY-elasticsearch +gpgcheck=1 diff --git a/ansible-role-filebeat/templates/filebeat.yml.j2 b/ansible-role-filebeat/templates/filebeat.yml.j2 new file mode 100644 index 00000000..dc4cac82 --- /dev/null +++ b/ansible-role-filebeat/templates/filebeat.yml.j2 @@ -0,0 +1,150 @@ +filebeat: + # List of prospectors to fetch data. + prospectors: + {{ filebeat_prospectors | to_json }} + +# Configure what outputs to use when sending the data collected by the beat. +# Multiple outputs may be used. +output: + +{% if filebeat_output_elasticsearch_enabled %} + ### Elasticsearch as output + elasticsearch: + # Array of hosts to connect to. + hosts: {{ filebeat_output_elasticsearch_hosts | to_json }} + + # Optional protocol and basic auth credentials. These are deprecated. + #protocol: "https" + #username: "admin" + #password: "s3cr3t" + + # Number of workers per Elasticsearch host. + #worker: 1 + + # Optional index name. The default is "filebeat" and generates + # [filebeat-]YYYY.MM.DD keys. + #index: "filebeat" + + # Optional HTTP Path + #path: "/elasticsearch" + + # Proxy server URL + # proxy_url: http://proxy:3128 + + # The number of times a particular Elasticsearch index operation is attempted. If + # the indexing operation doesn't succeed after this many retries, the events are + # dropped. The default is 3. + #max_retries: 3 + + # The maximum number of events to bulk in a single Elasticsearch bulk API index request. + # The default is 50. + #bulk_max_size: 50 + + # Configure http request timeout before failing an request to Elasticsearch. + #timeout: 90 + + # The number of seconds to wait for new events between two bulk API index requests. + # If `bulk_max_size` is reached before this interval expires, addition bulk index + # requests are made. + #flush_interval: 1 + + # Boolean that sets if the topology is kept in Elasticsearch. The default is + # false. This option makes sense only for Packetbeat. + #save_topology: false + + # The time to live in seconds for the topology information that is stored in + # Elasticsearch. The default is 15 seconds. + #topology_expire: 15 + +{% if filebeat_ssl_certificate_file and filebeat_ssl_key_file %} + # tls configuration. By default is off. + tls: + # List of root certificates for HTTPS server verifications + #certificate_authorities: ["/etc/pki/root/ca.pem"] + + # Certificate for TLS client authentication + certificate: "{{ filebeat_ssl_dir }}/{{ filebeat_ssl_certificate_file | basename }}" + + # Client Certificate Key + certificate_key: "{{ filebeat_ssl_dir }}/{{ filebeat_ssl_key_file | basename}}" + + # Controls whether the client verifies server certificates and host name. + # If insecure is set to true, all server host names and certificates will be + # accepted. In this mode TLS based connections are susceptible to + # man-in-the-middle attacks. Use only for testing. + insecure: {{ filebeat_ssl_insecure }} + + # Configure cipher suites to be used for TLS connections + #cipher_suites: [] + + # Configure curve types for ECDHE based cipher suites + #curve_types: [] + + # Configure minimum TLS version allowed for connection to logstash + #min_version: 1.0 + + # Configure maximum TLS version allowed for connection to logstash + #max_version: 1.2 +{% endif %} +{% endif %} + +{% if filebeat_output_logstash_enabled %} + ### Logstash as output + logstash: + # The Logstash hosts + hosts: {{ filebeat_output_logstash_hosts | to_json }} + + # Number of workers per Logstash host. + #worker: 1 + + # Optional load balance the events between the Logstash hosts + #loadbalance: true + + # Optional index name. The default index name depends on the each beat. + # For Packetbeat, the default is set to packetbeat, for Topbeat + # top topbeat and for Filebeat to filebeat. + #index: filebeat + +{% if filebeat_ssl_certificate_file and filebeat_ssl_key_file %} + # Optional TLS. By default is off. + tls: + # List of root certificates for HTTPS server verifications + #certificate_authorities: ["/etc/pki/root/ca.pem"] + + # Certificate for TLS client authentication + certificate: "{{ filebeat_ssl_dir }}/{{ filebeat_ssl_certificate_file | basename }}" + + # Client Certificate Key + certificate_key: "{{ filebeat_ssl_dir }}/{{ filebeat_ssl_key_file | basename}}" + + # Controls whether the client verifies server certificates and host name. + # If insecure is set to true, all server host names and certificates will be + # accepted. In this mode TLS based connections are susceptible to + # man-in-the-middle attacks. Use only for testing. + #insecure: true + insecure: {{ filebeat_ssl_insecure }} + + # Configure cipher suites to be used for TLS connections + #cipher_suites: [] + + # Configure curve types for ECDHE based cipher suites + #curve_types: [] +{% endif %} + +{% if filebeat_enable_logging %} +logging: + ### Filebeat log + level: {{ filebeat_log_level }} + + # Enable file rotation with default configuration + to_files: true + + # Do not log to syslog + to_syslog: false + + files: + path: {{ filebeat_log_dir }} + name: {{ filebeat_log_filename }} + keepfiles: 7 +{% endif %} +{% endif %} diff --git a/ansible-role-filebeat/tests/requirements.yml b/ansible-role-filebeat/tests/requirements.yml new file mode 100644 index 00000000..141fecdb --- /dev/null +++ b/ansible-role-filebeat/tests/requirements.yml @@ -0,0 +1,4 @@ +--- +- src: geerlingguy.java +- src: geerlingguy.elasticsearch +- src: geerlingguy.logstash diff --git a/ansible-role-filebeat/tests/test.yml b/ansible-role-filebeat/tests/test.yml new file mode 100644 index 00000000..6981d75b --- /dev/null +++ b/ansible-role-filebeat/tests/test.yml @@ -0,0 +1,20 @@ +--- +- hosts: all + + pre_tasks: + - name: Update apt cache. + apt: update_cache=yes cache_valid_time=600 + when: ansible_os_family == 'Debian' + + - name: Install test dependencies (RedHat). + package: name=which state=present + when: ansible_os_family == 'RedHat' + + - name: Install test dependencies. + package: name=curl state=present + + roles: + - geerlingguy.java + - geerlingguy.elasticsearch + - geerlingguy.logstash + - role_under_test diff --git a/ansible-wazuh-agent/README.md b/ansible-wazuh-agent/README.md new file mode 100644 index 00000000..415a6e3f --- /dev/null +++ b/ansible-wazuh-agent/README.md @@ -0,0 +1,48 @@ +ansible-ossec-agent +========= + +This role will install and configure an ossec-agent on the server. When there there is an parameter `ossec_server_name` configured, it will delagate an action for automatically authenticate the agent. + +Requirements +------------ + +This role will work on: + * Red Hat + * Debian + +So, you'll need one of those operating systems.. :-) + +Role Variables +-------------- + +This role needs 1 parameters: +* `ossec_server_ip`: This is the ip address of the server running the ossec-server. + + +Dependencies +------------ + +No dependencies. + +Example Playbook +---------------- + +The following is an example how this role can be used: + + - hosts: all:!wazuh-manager + roles: + - { role: ansible-ossec-agent, ossec_server_ip: 192.168.1.1 } + +License +------- + +GPLv3 + +Author Information +------------------ + +Github: https://github.com/dj-wasabi/ansible-ossec-agent + +mail: ikben [ at ] werner-dijkerman . nl + +Modified by Wazuh diff --git a/ansible-wazuh-agent/defaults/main.yml b/ansible-wazuh-agent/defaults/main.yml new file mode 100644 index 00000000..ec137f2a --- /dev/null +++ b/ansible-wazuh-agent/defaults/main.yml @@ -0,0 +1,6 @@ +--- +# defaults file for ossec-agent + +ossec_server_ip: 127.0.0.1 +ossec_server_name: "" +ossec_managed_server: true diff --git a/ansible-wazuh-agent/handlers/main.yml b/ansible-wazuh-agent/handlers/main.yml new file mode 100644 index 00000000..6039b620 --- /dev/null +++ b/ansible-wazuh-agent/handlers/main.yml @@ -0,0 +1,7 @@ +--- +# handlers file for ossec-agent + +- name: restart wazuh-agent + service: name=wazuh-agent + state=restarted + enabled=yes diff --git a/ansible-wazuh-agent/meta/main.yml b/ansible-wazuh-agent/meta/main.yml new file mode 100644 index 00000000..cb11a41c --- /dev/null +++ b/ansible-wazuh-agent/meta/main.yml @@ -0,0 +1,47 @@ +--- +galaxy_info: + author: Werner Dijkerman + description: INstalling and maintaining the ossec-agent. + company: myCompany.Dotcom + license: license (GPLv3) + min_ansible_version: 1.4 + platforms: + - name: EL + versions: + - 5 + - 6 + - 7 + - name: Fedora + versions: + - all + #- name: opensuse + # versions: + # - all + # - 12.1 + # - 12.2 + # - 12.3 + # - 13.1 + # - 13.2 + #- name: Ubuntu + # versions: + # - all + # - lucid + # - maverick + # - natty + # - oneiric + # - precise + # - quantal + # - raring + # - saucy + # - trusty + - name: Debian + versions: + - all + categories: + - monitoring +dependencies: [] + # List your role dependencies here, one per line. Only + # dependencies available via galaxy should be listed here. + # Be sure to remove the '[]' above if you add dependencies + # to this list. + diff --git a/ansible-wazuh-agent/tasks/Debian.yml b/ansible-wazuh-agent/tasks/Debian.yml new file mode 100644 index 00000000..56ce748b --- /dev/null +++ b/ansible-wazuh-agent/tasks/Debian.yml @@ -0,0 +1,32 @@ +--- +- name: Debian/Ubuntu | Installing repository key + apt_key: url=https://packages.wazuh.com/key/GPG-KEY-WAZUH + +- name: Debian/Ubuntu | Install apt-transport-https + apt: pkg=apt-transport-https + state=present + update_cache=yes + cache_valid_time=3600 + +- name: Debian/Ubuntu | Installing Wazuh repository key + apt_key: url=https://packages.wazuh.com/key/GPG-KEY-WAZUH + +- name: Add Wazuh epositories. + apt_repository: + repo: deb https://packages.wazuh.com/apt {{ ansible_distribution_release }} main + state: present + register: wazuh_repo + +- name: Update apt cache if repo was added. + apt: update_cache=yes + when: wazuh_repo.changed + +- name: Debian/Ubuntu | Install wazuh-agent + apt: pkg={{ item }} + state=present + update_cache=yes + cache_valid_time=3600 + with_items: + - wazuh-agent + tags: + - init diff --git a/ansible-wazuh-agent/tasks/RedHat.yml b/ansible-wazuh-agent/tasks/RedHat.yml new file mode 100644 index 00000000..80e8a177 --- /dev/null +++ b/ansible-wazuh-agent/tasks/RedHat.yml @@ -0,0 +1,23 @@ +--- +# Tasks specific for RedHat systems + +- name: RedHat | Set some facts + set_fact: + ansible_distribution: centos + when: ansible_distribution == "RedHat" + +- name: RedHat | Install Wazuh repo + yum_repository: + name: wazuh_repo + description: CentOS-$releasever - Wazuh + baseurl: https://packages.wazuh.com/yum/el/$releasever/$basearch + gpgkey: https://packages.wazuh.com/key/GPG-KEY-WAZUH + gpgcheck: yes + +- name: RedHat | Install Wazuh Agent + yum: pkg={{ item }} + state=present + with_items: + - wazuh-agent + tags: + - init diff --git a/ansible-wazuh-agent/tasks/main.yml b/ansible-wazuh-agent/tasks/main.yml new file mode 100644 index 00000000..2c96ca86 --- /dev/null +++ b/ansible-wazuh-agent/tasks/main.yml @@ -0,0 +1,41 @@ +--- +# tasks file for ossec-agent + +- name: "Install the correct repository" + include: "RedHat.yml" + when: ansible_os_family == "RedHat" + +- name: Install the correct repository + include: "Debian.yml" + when: ansible_os_family == "Debian" + +- name: "Check if client.keys exists" + stat: path=/var/ossec/etc/client.keys + register: check_keys + tags: + - config + +- name: "Register client" + shell: /var/ossec/bin/agent-auth -m {{ ossec_server_ip }} -p 1515 + when: ossec_server_ip and check_keys.stat.size == 0 + tags: + - config + +- name: "Installing the ossec.conf" + template: src=var-ossec-etc-ossec-agent.conf.j2 + dest=/var/ossec/etc/ossec.conf + owner=root + group=root + mode=0644 + notify: restart wazuh-agent + tags: + - init + - config + +- name: Ensure Wazuh Manager service is started and enabled + service: + name: "{{ item }}" + enabled: yes + state: started + with_items: + - wazuh-agent diff --git a/ansible-wazuh-agent/templates/var-ossec-etc-ossec-agent.conf.j2 b/ansible-wazuh-agent/templates/var-ossec-etc-ossec-agent.conf.j2 new file mode 100644 index 00000000..9dd9ef37 --- /dev/null +++ b/ansible-wazuh-agent/templates/var-ossec-etc-ossec-agent.conf.j2 @@ -0,0 +1,53 @@ + + + + + {{ ossec_server_ip }} + {% if ossec_profile is defined %} + {{ ossec_profile }} + {% endif %} + + + {% if ansible_distribution == 'Ubuntu' and ansible_distribution_release == 'xenial' %} + + 1800 + 1d + yes + + + xccdf_org.ssgproject.content_profile_common + + + {% elif ansible_distribution == 'CentOS' %} + + 1800 + 1d + yes + + {% if ansible_distribution_major_version == '7' %} + + {% elif ansible_distribution_major_version == '6' %} + + {% endif %} + xccdf_org.ssgproject.content_profile_pci-dss + xccdf_org.ssgproject.content_profile_common + + +{% elif ansible_distribution == 'RedHat' %} + + 1800 + 1d + yes + + {% if ansible_distribution_major_version == '7' %} + + {% elif ansible_distribution_major_version == '6' %} + + {% endif %} + xccdf_org.ssgproject.content_profile_pci-dss + xccdf_org.ssgproject.content_profile_common + + +{% endif %} + + diff --git a/ansible-wazuh-agent/vars/main.yml b/ansible-wazuh-agent/vars/main.yml new file mode 100644 index 00000000..285e8384 --- /dev/null +++ b/ansible-wazuh-agent/vars/main.yml @@ -0,0 +1,2 @@ +--- +# vars file for ossec-agent diff --git a/ansible-wazuh-server/.gitignore b/ansible-wazuh-server/.gitignore new file mode 100644 index 00000000..a8a9013c --- /dev/null +++ b/ansible-wazuh-server/.gitignore @@ -0,0 +1 @@ +./.kitchen diff --git a/ansible-wazuh-server/.kitchen.yml b/ansible-wazuh-server/.kitchen.yml new file mode 100644 index 00000000..8d73eb67 --- /dev/null +++ b/ansible-wazuh-server/.kitchen.yml @@ -0,0 +1,21 @@ +--- +driver: + name: vagrant + provision_command: sed -i '/tsflags=nodocs/d' /etc/yum.conf + +provisioner: + name: ansible_playbook + ansible_yum_repo: "http://mirror.logol.ru/epel/6/x86_64/epel-release-6-8.noarch.rpm" + hosts: localhost + require_chef_for_busser: false + require_ruby_for_busser: true + +platforms: + - name: centos-7.2 + - name: ubuntu-14.04 + +verifier: + ruby_bindir: '/usr/bin' + +suites: + - name: default diff --git a/ansible-wazuh-server/CHANGELOG.md b/ansible-wazuh-server/CHANGELOG.md new file mode 100644 index 00000000..897c05b4 --- /dev/null +++ b/ansible-wazuh-server/CHANGELOG.md @@ -0,0 +1,31 @@ +#ansible-ossec-server Release + +Below an overview of all changes in the releases. + +Version (Release date) + +0.2.0 (2017-02-14) + + * Added molecule testing + * do not look for specific key ID. It appears that OSSEC released a new… #3 (By pull request: recunius (Thanks!)) + * Updates #4 (By pull request: recunius (Thanks!)) + * allow providing own local_rules.xml template with var ossec_server_… #5 (By pull request: recunius (Thanks!)) + * Update CIS filename to CentOS & Redhat 7 #6 (By pull request: jlruizmlg (Thanks!)) + * add ossec authd as service #7 (By pull request: jlruizmlg (Thanks!)) + * Fix the permissions in the wazuh-authd in upstart system. #8 (By pull request: jlruizmlg (Thanks!)) + * Remove ssl files and add task to generate them + Fix script init task #10 (By pull request: aarnaud (Thanks!)) + +0.1.0 (2015-11-16) + + * Fixes for CentOS/EL7 #1 (By pull request: andskli (Thanks!)) + * Updates to support Ubuntu and also adds more configuration options #2 (By pull request: recunius (Thanks!)) + * Added kitchen test and serverspec tests + +0.0.2 (2014-12-11) + + * Added possibilty to use other mail settings + * Reworked module for better setup. Updated readme + +0.0.1 (2014-12-04) + + * Initial creation diff --git a/ansible-wazuh-server/README.md b/ansible-wazuh-server/README.md new file mode 100644 index 00000000..fbec5d19 --- /dev/null +++ b/ansible-wazuh-server/README.md @@ -0,0 +1,188 @@ +Role Name +========= + +This role will install the Wazuh server on a host. + +Requirements +------------ + +This role will work on: + * Red Hat + * Debian + +So, you'll need one of those operating systems.. :-) + +Role Variables +-------------- + +This role has some variables which you can or need to override. +``` +ossec_server_config: [] +ossec_agent_configs: [] +``` + +###Example setup + +Edit the vars file for the host which runs the ossec-server: +### host_vars/ossec-server +``` +ossec_server_config: + mail_to: + - me@example.com + mail_smtp_server: localhost + mail_from: ossec@example.com + frequency_check: 43200 + syscheck_scan_on_start: 'yes' + ignore_files: + - /etc/mtab + - /etc/mnttab + - /etc/hosts.deny + - /etc/mail/statistics + - /etc/random-seed + - /etc/random.seed + - /etc/adjtime + - /etc/httpd/logs + - /etc/utmpx + - /etc/wtmpx + - /etc/cups/certs + - /etc/dumpdates + - /etc/svc/volatile + no_diff: + - /etc/ssl/private.key + directories: + - check_all: 'yes' + dirs: /etc,/usr/bin,/usr/sbin + - check_all: 'yes' + dirs: /bin,/sbin + localfiles: + - format: 'syslog' + location: '/var/log/messages' + - format: 'syslog' + location: '/var/log/secure' + - format: 'command' + command: 'df -P' + frequency: '360' + - format: 'full_command' + command: 'netstat -tln | grep -v 127.0.0.1 | sort' + frequency: '360' + - format: 'full_command' + command: 'last -n 20' + frequency: '360' + globals: + - '127.0.0.1' + - '192.168.2.1' + connection: + - type: 'secure' + port: '1514' + protocol: 'udp' + log_level: 1 + email_level: 12 + commands: + - name: 'disable-account' + executable: 'disable-account.sh' + expect: 'user' + timeout_allowed: 'yes' + - name: 'restart-ossec' + executable: 'restart-ossec.sh' + expect: '' + timeout_allowed: 'no' + - name: 'firewall-drop' + executable: 'firewall-drop.sh' + expect: 'srcip' + timeout_allowed: 'yes' + - name: 'host-deny' + executable: 'host-deny.sh' + expect: 'srcip' + timeout_allowed: 'yes' + - name: 'route-null' + executable: 'route-null.sh' + expect: 'srcip' + timeout_allowed: 'yes' + - name: 'win_route-null' + executable: 'route-null.cmd' + expect: 'srcip' + timeout_allowed: 'yes' + active_responses: + - command: 'host-deny' + location: 'local' + level: 6 + timeout: 600 + +ossec_agent_configs: + - type: os + type_value: linux + frequency_check: 79200 + ignore_files: + - /etc/mtab + - /etc/mnttab + - /etc/hosts.deny + - /etc/mail/statistics + - /etc/svc/volatile + directories: + - check_all: yes + dirs: /etc,/usr/bin,/usr/sbin + - check_all: yes + dirs: /bin,/sbin + localfiles: + - format: 'syslog' + location: '/var/log/messages' + - format: 'syslog' + location: '/var/log/secure' + - format: 'syslog' + location: '/var/log/maillog' + - format: 'apache' + location: '/var/log/httpd/error_log' + - format: 'apache' + location: '/var/log/httpd/access_log' + - format: 'apache' + location: '/var/ossec/logs/active-responses.log' +``` + +####ossec_server_config: +At first, there is the server configuration. Change it for your needs, as this default setup won't do any good for you. (You don't have access to use the mail.example.com mailhost. :-)) + + +####ossec_agent_configs: +http://ossec-docs.readthedocs.org/en/latest/manual/agent/agent-configuration.html + +There are 3 "types": + * os + * name + * profile + +In the above setup, the type is os. And this configuration is for the "linux" os. You can have several types configured in the host_vars file, so you can create all kind of different configs. + +You can find here some more information about the ossec shared agent configuration: http://ossec-docs.readthedocs.org/en/latest/manual/syscheck/ + +#### <_role_>/vars/main.yml +nil + +Dependencies +------------ + +No dependencies. + +Example Playbook +---------------- + +Including an example of how to use your role (for instance, with variables passed in as parameters) is always nice for users too: + + - hosts: ossec-server.example.com + roles: + - { role: dj-wasabi.ossec-server } + +License +------- + +GPLv3 + +Author Information +------------------ + +Please send suggestion or pull requests to make this role better. + +Github: https://github.com/dj-wasabi/ansible-ossec-server + +mail: ikben [ at ] werner-dijkerman . nl + +Modificated by **Wazuh** diff --git a/ansible-wazuh-server/defaults/main.yml b/ansible-wazuh-server/defaults/main.yml new file mode 100644 index 00000000..427b14ad --- /dev/null +++ b/ansible-wazuh-server/defaults/main.yml @@ -0,0 +1,6 @@ +--- +# defaults file for ossec-server +# +ossec_server_config: [] +ossec_agent_configs: [] +ossec_server_fqdn: "ossec-server" diff --git a/ansible-wazuh-server/handlers/main.yml b/ansible-wazuh-server/handlers/main.yml new file mode 100644 index 00000000..066730f3 --- /dev/null +++ b/ansible-wazuh-server/handlers/main.yml @@ -0,0 +1,7 @@ +--- +# handlers file for wazuh-manager + +- name: restart wazuh-manager + service: name=wazuh-manager + state=restarted + enabled=yes diff --git a/ansible-wazuh-server/meta/main.yml b/ansible-wazuh-server/meta/main.yml new file mode 100644 index 00000000..3c03eb1e --- /dev/null +++ b/ansible-wazuh-server/meta/main.yml @@ -0,0 +1,23 @@ +--- +galaxy_info: + author: Werner Dijkerman + description: Installing and maintaining the ossec-server. + company: myCompany.Dotcom + license: license (GPLv3) + min_ansible_version: 1.4 + platforms: + - name: EL + versions: + - all + - name: Fedora + versions: + - all + - name: Ubuntu + versions: + - all + - name: Debian + versions: + - all + categories: + - monitoring +dependencies: [] diff --git a/ansible-wazuh-server/molecule.yml b/ansible-wazuh-server/molecule.yml new file mode 100644 index 00000000..daf30bad --- /dev/null +++ b/ansible-wazuh-server/molecule.yml @@ -0,0 +1,85 @@ +--- +dependency: + name: galaxy +driver: + name: docker + +ansible: + group_vars: + ossec: + ossec_server_config: + mail_to: + - me@example.com + mail_smtp_server: localhost + mail_from: ossec@example.com + frequency_check: 72000 + ignore_files: + - /etc/mtab + - /etc/mnttab + - /etc/hosts.deny + directories: + - check_all: 'yes' + dirs: /etc,/usr/bin,/usr/sbin + - check_all: 'yes' + dirs: /bin,/sbin + localfiles: + - format: 'syslog' + location: '/var/log/messages' + - format: 'syslog' + location: '/var/log/secure' + globals: + - '127.0.0.1' + - '192.168.2.1' + connection: 'secure' + log_level: 1 + email_level: 7 + commands: + - name: 'host-deny' + executable: 'host-deny.sh' + expect: 'srcip' + timeout_allowed: 'yes' + active_responses: + - command: 'host-deny' + location: 'local' + level: 6 + timeout: 600 + localfiles: + - format: 'syslog' + location: '/var/log/messages' + ossec_agent_configs: + - type: os + type_value: linux + frequency_check: 79200 + ignore_files: + - /etc/mtab + - /etc/mnttab + localfiles: + - format: 'syslog' + location: '/var/log/messages' + directories: + - check_all: yes + dirs: /etc,/usr/bin,/usr/sbin + +docker: + containers: + - name: ansible-ossec-server-centos + ansible_groups: + - ossec + image: milcom/centos7-systemd + image_version: latest + privileged: True + - name: ansible-ossec-server-debian + ansible_groups: + - ossec + image: maint/debian-systemd + image_version: latest + privileged: True +# - name: ansible-ossec-server-ubuntu +# ansible_groups: +# - ossec +# image: rastasheep/ubuntu-sshd +# image_version: 16.04 +# privileged: True + +verifier: + name: testinfra diff --git a/ansible-wazuh-server/playbook.retry b/ansible-wazuh-server/playbook.retry new file mode 100644 index 00000000..ebf72921 --- /dev/null +++ b/ansible-wazuh-server/playbook.retry @@ -0,0 +1 @@ +192.168.212.138 diff --git a/ansible-wazuh-server/playbook.yml b/ansible-wazuh-server/playbook.yml new file mode 100644 index 00000000..fca1c018 --- /dev/null +++ b/ansible-wazuh-server/playbook.yml @@ -0,0 +1,3 @@ +- hosts: ossec-manager + roles: + - role: ansible-ossec-server diff --git a/ansible-wazuh-server/tasks/Debian.yml b/ansible-wazuh-server/tasks/Debian.yml new file mode 100644 index 00000000..d32fb813 --- /dev/null +++ b/ansible-wazuh-server/tasks/Debian.yml @@ -0,0 +1,49 @@ +--- +- name: Debian/Ubuntu | Install apt-transport-https + apt: pkg=apt-transport-https + state=present + update_cache=yes + cache_valid_time=3600 + +- name: Debian/Ubuntu | Installing Wazuh repository key + apt_key: url=https://packages.wazuh.com/key/GPG-KEY-WAZUH + +- name: Add Wazuh epositories. + apt_repository: + repo: deb https://packages.wazuh.com/apt {{ ansible_distribution_release }} main + state: present + register: wazuh_repo + +- name: Debian/Ubuntu | Installing NodeJS repository key + apt_key: url=https://deb.nodesource.com/gpgkey/nodesource.gpg.key + +- name: Add NodeSource repositories for Node.js. + apt_repository: + repo: "{{ item }}" + state: present + with_items: + - deb https://deb.nodesource.com/node_6.x {{ ansible_distribution_release }} main + - deb-src https://deb.nodesource.com/node_6.x {{ ansible_distribution_release }} main + register: node_repo + +- name: Update apt cache if repo was added. + apt: update_cache=yes + when: + - node_repo.changed + - wazuh_repo.changed + +- name: Debian/Ubuntu | Install wazuh-manager + apt: pkg={{ item }} + state=present + update_cache=yes + cache_valid_time=3600 + with_items: + - wazuh-manager + - wazuh-api + tags: + - init + +- name: Set Distribution CIS filename for Debian/Ubuntu + set_fact: + cis_distribution_filename: cis_debian_linux_rcl.txt + when: ansible_os_family == "Debian" diff --git a/ansible-wazuh-server/tasks/RedHat.yml b/ansible-wazuh-server/tasks/RedHat.yml new file mode 100644 index 00000000..efa0496c --- /dev/null +++ b/ansible-wazuh-server/tasks/RedHat.yml @@ -0,0 +1,63 @@ +--- +# Tasks specific for RedHat systems + +- name: RedHat | Set some facts + set_fact: + ansible_distribution: centos + when: ansible_distribution == "RedHat" + +- name: RedHat | Install Wazuh repo + yum_repository: + name: NodeJS + description: NodeJS-$releasever + baseurl: https://rpm.nodesource.com/pub_6.x/el/$releasever/x86_64 + gpgkey: https://rpm.nodesource.com/pub/el/NODESOURCE-GPG-SIGNING-KEY-EL + gpgcheck: yes + +- name: RedHat | Install NodeJS repo + yum_repository: + name: wazuh_repo + description: CentOS-$releasever - Wazuh + baseurl: https://packages.wazuh.com/yum/el/$releasever/$basearch + gpgkey: https://packages.wazuh.com/key/GPG-KEY-WAZUH + gpgcheck: yes + +- name: RedHat | Install epel repo + yum: name=https://dl.fedoraproject.org/pub/epel/epel-release-latest-{{ansible_distribution_major_version}}.noarch.rpm state=present + +- name: RedHat | Install Wazuh Manager and Wazuh Api + yum: pkg={{ item }} + state=present + with_items: + - wazuh-manager + - wazuh-api + tags: + - init + +- name: RedHat | Install openscap + yum: pkg=openscap-scanner + state=present + when: ansible_os_family == "RedHat" and ansible_distribution_major_version >= 6 + tags: + - init + +- name: Set Distribution CIS filename for RHEL5 + set_fact: + cis_distribution_filename: cis_rhel5_linux_rcl.txt + when: ansible_os_family == "RedHat" and ansible_distribution_major_version == "5" + +- name: Set Distribution CIS filename for RHEL6 + set_fact: + cis_distribution_filename: cis_rhel6_linux_rcl.txt + when: ansible_os_family == "RedHat" and ansible_distribution_major_version == "6" + +- name: Set Distribution CIS filename for RHEL7 + set_fact: + cis_distribution_filename: cis_rhel7_linux_rcl.txt + when: ansible_os_family == "RedHat" and ansible_distribution_major_version == "7" + +- name: Set ossec deploy facts for RedHat + set_fact: + ossec_server_config_filename: ossec-server.conf + ossec_init_name: wazuh-manager + when: ansible_os_family == "RedHat" diff --git a/ansible-wazuh-server/tasks/main.yml b/ansible-wazuh-server/tasks/main.yml new file mode 100644 index 00000000..00791964 --- /dev/null +++ b/ansible-wazuh-server/tasks/main.yml @@ -0,0 +1,117 @@ +--- +# tasks file for ossec-server + +- name: Install the correct repository + include: "RedHat.yml" + when: ansible_os_family == "RedHat" + +- name: Install the correct repository + include: "Debian.yml" + when: ansible_os_family == "Debian" + + +- name: Generate SSL files + command: "openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:1825 -keyout sslmanager.key -out sslmanager.cert -subj /CN={{ossec_server_fqdn}}/" + args: + creates: sslmanager.cert + chdir: /var/ossec/etc/ + tags: + - config + +- name: Configure the shared-agent.conf + template: src=var-ossec-etc-shared-agent.conf.j2 + dest=/var/ossec/etc/shared/agent.conf + owner=ossec + group=ossec + mode=0644 + notify: restart wazuh-manager + tags: + - init + - config + +- name: Installing custom local_rules.xml + template: + src: "{{ playbook_dir }}/{{ ossec_server_config.local_rules_template }}" + dest: /var/ossec/rules/local_rules.xml + owner: root + group: root + mode: 0644 + when: ossec_server_config.local_rules_template is defined + notify: restart wazuh-manager + tags: + - init + - config + - rules + +- name: Installing the local_rules.xml (default local_rules.xml) + template: src=var-ossec-rules-local_rules.xml.j2 + dest=/var/ossec/etc/rules/local_rules.xml + owner=root + group=root + mode=0644 + when: ossec_server_config.local_rules_template is not defined + notify: restart wazuh-manager + tags: + - init + - config + - rules + +- name: Check if client-syslog is enabled + shell: "/var/ossec/bin/ossec-control status | grep -c 'ossec-csyslogd is running' | xargs echo" + register: csyslog_running + changed_when: False + +- name: Enable client-syslog if not running and ossec_server_config.syslog_outputs is given + command: /var/ossec/bin/ossec-control enable client-syslog + when: csyslog_running.stdout == '0' and ossec_server_config.syslog_outputs is defined + +- name: Start client-syslog if not running and ossec_server_config.syslog_outputs is given + command: /var/ossec/bin/ossec-control start client-syslog + when: csyslog_running.stdout == '0' and ossec_server_config.syslog_outputs is defined + +- name: Set ossec deploy facts for Debian + set_fact: + ossec_server_config_filename: ossec.conf + ossec_init_name: ossec + when: ansible_os_family == "Debian" + +- name: Configure ossec.conf + template: src=var-ossec-etc-ossec-server.conf.j2 + dest=/var/ossec/etc/ossec.conf + owner=root + group=root + mode=0644 + notify: restart wazuh-manager + tags: + - init + - config + +- name: Write ossec-authd init file + template: src=ossec-authd-init.service + dest=/etc/init.d/ossec-authd + owner=root + group=root + mode=0755 + when: ansible_service_mgr == "upstart" and ansible_os_family != "CoreOS" + tags: + - init + - config + +- name: Write ossec-authd systemd file + template: + src: ossec-authd.service + dest: /lib/systemd/system/ossec-authd.service + when: ansible_service_mgr == "systemd" and ansible_os_family != "CoreOS" + tags: + - init + - config + +- name: Ensure Wazuh Manager, wazuh api and ossec-authd service is started and enabled + service: + name: "{{ item }}" + enabled: yes + state: started + with_items: + - wazuh-manager + - wazuh-api + - ossec-authd diff --git a/ansible-wazuh-server/templates/ossec-authd-init.service b/ansible-wazuh-server/templates/ossec-authd-init.service new file mode 100644 index 00000000..5feeb506 --- /dev/null +++ b/ansible-wazuh-server/templates/ossec-authd-init.service @@ -0,0 +1,104 @@ +#!/bin/sh +# +# ossec-authd Start the OSSEC-HIDS Authentication Daemon +# +# chkconfig: 2345 99 01 +# description: Provides key signing for OSSEC Clients +# processname: ossec-authd +# config: /var/ossec/etc/ossec.conf +# pidfile: /var/run/ossec-authd.pid +### BEGIN INIT INFO +# Provides: ossec-authd +# Default-Start: 2 3 4 5 +# Default-Stop: 0 1 6 +# Short-Description: Authentication Daemon for OSSEC-HIDS. +# Description: Provides key signing for OSSEC Clients +### END INIT INFO + +# Author: Brad Lhotsky +NAME=ossec-authd +HOME=/var/ossec +DAEMON=/var/ossec/bin/ossec-authd +DAEMON_ARGS="-p 1515 2>&1 >> /var/ossec/logs/ossec-authd.log &" +PIDDIR=/var/ossec/var/run +SCRIPTNAME=/etc/init.d/ossec-authd + +if [ ! -e $HOME/etc/sslmanager.key ] + then + echo "Creating ossec-authd key and cert" + openssl genrsa -out $HOME/etc/sslmanager.key 4096 + openssl req -new -x509 -key $HOME/etc/sslmanager.key\ + -out $HOME/etc/sslmanager.cert -days 3650\ + -subj /CN=fqdn/ +fi + +. /etc/rc.d/init.d/functions + +getpid() { + for filename in $PIDDIR/${NAME}*.pid; do + pidfile=$(basename $filename) + pid=$(echo $pidfile |cut -d\- -f 3 |cut -d\. -f 1) + kill -0 $pid &> /dev/null + RETVAL=$? + if [ $RETVAL -eq 0 ]; then + PIDFILE=$filename + PID=$pid + else + rm -f $filename + fi; + done; +} + +start() { + echo -n $"Starting $NAME: " + daemon $DAEMON $DAEMON_ARGS + retval=$? + if [ $retval -eq 0 ]; then + echo_success + echo + else + echo_failure + echo + fi + return $retval +} + +stop() { + echo -n $"Stopping $NAME: " + getpid + killproc -p $PIDFILE $NAME + retval=$? + echo + return $retval +} + +restart() { + stop + start +} + +case "$1" in + start) + start + ;; + stop) + stop + ;; + status) + getpid + if [ -z $PIDFILE ]; then + status $NAME + else + status -p $PIDFILE $NAME + fi; + ;; + restart) + restart + ;; + *) + echo "Usage: $0 {start|stop|status}" + exit 2 + ;; +esac + +exit $? diff --git a/ansible-wazuh-server/templates/ossec-authd.service b/ansible-wazuh-server/templates/ossec-authd.service new file mode 100644 index 00000000..ba488148 --- /dev/null +++ b/ansible-wazuh-server/templates/ossec-authd.service @@ -0,0 +1,8 @@ +[Unit] +Description=Wazuh authd + +[Service] +EnvironmentFile=/etc/ossec-init.conf +Environment=DIRECTORY=/var/ossec + +ExecStart=/usr/bin/env ${DIRECTORY}/bin/ossec-authd -p 1515 diff --git a/ansible-wazuh-server/templates/var-ossec-etc-ossec-server.conf.j2 b/ansible-wazuh-server/templates/var-ossec-etc-ossec-server.conf.j2 new file mode 100644 index 00000000..59ee7862 --- /dev/null +++ b/ansible-wazuh-server/templates/var-ossec-etc-ossec-server.conf.j2 @@ -0,0 +1,212 @@ + + + + + yes + yes + {% if ossec_server_config.email_notification is not defined or ossec_server_config.email_notification | lower == "yes" %} + yes +{% for to in ossec_server_config.mail_to %} + {{ to }} +{% endfor %} + {{ ossec_server_config.mail_smtp_server }} + {{ ossec_server_config.mail_from }} + {% else %} + no + {% endif %} + + +{% if ossec_server_config.extra_emails is defined %} +{% for mail in ossec_server_config.extra_emails %} + + {{ mail.mail_to }} + {% if mail.format is defined %} + {{ mail.format }} + {% endif %} + {% if mail.level is defined %} + {{ mail.level }} + {% endif %} + {% if mail.event_location is defined %} + {{ mail.event_location }} + {% endif %} + {% if mail.group is defined %} + {{ mail.group }} + {% endif %} + {% if mail.do_not_delay is defined and mail.do_not_delay == true %} + + {% endif %} + {% if mail.do_not_group is defined and mail.do_not_group == true %} + + {% endif %} + {% if mail.rule_id is defined %} + {{ mail.rule_id }} + {% endif %} + +{% endfor %} +{% endif %} + + + {{ ossec_server_config.log_level }} + {{ ossec_server_config.email_level }} + + + +{% for connection in ossec_server_config.connection %} + {{ connection.type }} + {{ connection.port }} + {{ connection.protocol }} +{% endfor %} + + + + no + yes + yes + yes + yes + yes + yes + yes + yes + + + 43200 + + /var/ossec/etc/shared/rootkit_files.txt + /var/ossec/etc/shared/rootkit_trojans.txt + /var/ossec/etc/shared/system_audit_rcl.txt + /var/ossec/etc/shared/{{ cis_distribution_filename }} + + yes + + + + + {{ ossec_server_config.frequency_check }} + {{ ossec_server_config.syscheck_scan_on_start }} + + +{% for directory in ossec_server_config.directories %} + {{ directory.dirs }} +{% endfor %} + + + {% for ignore_file in ossec_server_config.ignore_files %} + {{ ignore_file }} + {% endfor %} + + + {% for no_diff in ossec_server_config.no_diff %} + {{ no_diff }} + {% endfor %} + + + {% if ansible_distribution == 'Ubuntu' and ansible_distribution_release == 'xenial' %} + + 1800 + 1d + yes + + + xccdf_org.ssgproject.content_profile_common + + + {% elif ansible_distribution == 'CentOS' %} + + 1800 + 1d + yes + + {% if ansible_distribution_major_version == '7' %} + + {% elif ansible_distribution_major_version == '6' %} + + {% endif %} + xccdf_org.ssgproject.content_profile_pci-dss + xccdf_org.ssgproject.content_profile_common + + +{% elif ansible_distribution == 'RedHat' %} + + 1800 + 1d + yes + + {% if ansible_distribution_major_version == '7' %} + + {% elif ansible_distribution_major_version == '6' %} + + {% endif %} + xccdf_org.ssgproject.content_profile_pci-dss + xccdf_org.ssgproject.content_profile_common + + +{% endif %} + + + +{% for white_list in ossec_server_config.globals %} + {{ white_list }} +{% endfor %} + + + {% for command in ossec_server_config.commands %} + + {{ command.name }} + {{ command.executable }} + {{ command.expect }} + {{ command.timeout_allowed }} + + {% endfor %} + + + + + ruleset/decoders + ruleset/rules + 0215-policy_rules.xml + etc/lists/audit-keys + + + etc/decoders + etc/rules + + + +{% for response in ossec_server_config.active_responses %} + + {{ response.command }} + {{ response.location }} + {{ response.level }} + {{ response.timeout }} + +{% endfor %} + + +{% for localfile in ossec_server_config.localfiles %} + + {{ localfile.format }} + {% if localfile.format == 'command' or localfile.format == 'full_command' %} + {{ localfile.command }} + {{ localfile.frequency }} + {% else %} + {{ localfile.location }} + {% endif %} + +{% endfor %} + +{% if ossec_server_config.syslog_outputs is defined %} +{% for syslog_output in ossec_server_config.syslog_outputs %} + + {{ syslog_output.server }} + {{ syslog_output.port }} + {{ syslog_output.format }} + +{% endfor %} +{% endif %} + + diff --git a/ansible-wazuh-server/templates/var-ossec-etc-shared-agent.conf.j2 b/ansible-wazuh-server/templates/var-ossec-etc-shared-agent.conf.j2 new file mode 100644 index 00000000..ac5a4d65 --- /dev/null +++ b/ansible-wazuh-server/templates/var-ossec-etc-shared-agent.conf.j2 @@ -0,0 +1,42 @@ +{% for item in ossec_agent_configs %} + + + +{% for directory in item.directories %} + {{ directory.dirs }} +{% endfor %} + + {{ item.frequency_check }} + {% for ignore_file in item.ignore_files %} + {{ ignore_file }} + {% endfor %} + + + +{% for localfile in item.localfiles %} + + {{ localfile.format }} + {% if localfile.command is defined %} + {{ localfile.command }} + {% else %} + {{ localfile.location }} + {% endif %} + +{% endfor %} + + + /var/ossec/etc/shared/rootkit_files.txt + /var/ossec/etc/shared/rootkit_trojans.txt + /var/ossec/etc/shared/system_audit_rcl.txt + {% if item.cis_distribution_filename is defined %} + /var/ossec/etc/shared/{{ item.cis_distribution_filename }} + {% else %} + {# none specified so install all #} + /var/ossec/etc/shared/cis_debian_linux_rcl.txt + /var/ossec/etc/shared/cis_rhel_linux_rcl.txt + /var/ossec/etc/shared/cis_rhel5_linux_rcl.txt + {% endif %} + + + +{% endfor %} diff --git a/ansible-wazuh-server/templates/var-ossec-rules-local_rules.xml.j2 b/ansible-wazuh-server/templates/var-ossec-rules-local_rules.xml.j2 new file mode 100644 index 00000000..572edd9e --- /dev/null +++ b/ansible-wazuh-server/templates/var-ossec-rules-local_rules.xml.j2 @@ -0,0 +1,57 @@ + + + + + + + + + + 5711 + 1.1.1.1 + Example of rule that will ignore sshd + failed logins from IP 1.1.1.1. + + + + + + + + + + + + + + diff --git a/ansible-wazuh-server/vars/main.yml b/ansible-wazuh-server/vars/main.yml new file mode 100644 index 00000000..c9b7c2b1 --- /dev/null +++ b/ansible-wazuh-server/vars/main.yml @@ -0,0 +1,110 @@ +ossec_server_config: + mail_to: + - me@example.com + mail_smtp_server: localhost + mail_from: ossec@example.com + frequency_check: 43200 + syscheck_scan_on_start: 'yes' + ignore_files: + - /etc/mtab + - /etc/mnttab + - /etc/hosts.deny + - /etc/mail/statistics + - /etc/random-seed + - /etc/random.seed + - /etc/adjtime + - /etc/httpd/logs + - /etc/utmpx + - /etc/wtmpx + - /etc/cups/certs + - /etc/dumpdates + - /etc/svc/volatile + no_diff: + - /etc/ssl/private.key + directories: + - check_all: 'yes' + dirs: /etc,/usr/bin,/usr/sbin + - check_all: 'yes' + dirs: /bin,/sbin + localfiles: + - format: 'syslog' + location: '/var/log/messages' + - format: 'syslog' + location: '/var/log/secure' + - format: 'command' + command: 'df -P' + frequency: '360' + - format: 'full_command' + command: 'netstat -tln | grep -v 127.0.0.1 | sort' + frequency: '360' + - format: 'full_command' + command: 'last -n 20' + frequency: '360' + globals: + - '127.0.0.1' + - '192.168.2.1' + connection: + - type: 'secure' + port: '1514' + protocol: 'udp' + log_level: 1 + email_level: 12 + commands: + - name: 'disable-account' + executable: 'disable-account.sh' + expect: 'user' + timeout_allowed: 'yes' + - name: 'restart-ossec' + executable: 'restart-ossec.sh' + expect: '' + timeout_allowed: 'no' + - name: 'firewall-drop' + executable: 'firewall-drop.sh' + expect: 'srcip' + timeout_allowed: 'yes' + - name: 'host-deny' + executable: 'host-deny.sh' + expect: 'srcip' + timeout_allowed: 'yes' + - name: 'route-null' + executable: 'route-null.sh' + expect: 'srcip' + timeout_allowed: 'yes' + - name: 'win_route-null' + executable: 'route-null.cmd' + expect: 'srcip' + timeout_allowed: 'yes' + active_responses: + - command: 'host-deny' + location: 'local' + level: 6 + timeout: 600 + +ossec_agent_configs: + - type: os + type_value: linux + frequency_check: 79200 + ignore_files: + - /etc/mtab + - /etc/mnttab + - /etc/hosts.deny + - /etc/mail/statistics + - /etc/svc/volatile + directories: + - check_all: yes + dirs: /etc,/usr/bin,/usr/sbin + - check_all: yes + dirs: /bin,/sbin + localfiles: + - format: 'syslog' + location: '/var/log/messages' + - format: 'syslog' + location: '/var/log/secure' + - format: 'syslog' + location: '/var/log/maillog' + - format: 'apache' + location: '/var/log/httpd/error_log' + - format: 'apache' + location: '/var/log/httpd/access_log' + - format: 'apache' + location: '/var/ossec/logs/active-responses.log' diff --git a/elk.yml b/elk.yml new file mode 100644 index 00000000..ba2bfbb6 --- /dev/null +++ b/elk.yml @@ -0,0 +1,3 @@ +- hosts: elk + roles: + - role: ansible-role-elk diff --git a/vars.yml b/vars.yml new file mode 100644 index 00000000..c9b7c2b1 --- /dev/null +++ b/vars.yml @@ -0,0 +1,110 @@ +ossec_server_config: + mail_to: + - me@example.com + mail_smtp_server: localhost + mail_from: ossec@example.com + frequency_check: 43200 + syscheck_scan_on_start: 'yes' + ignore_files: + - /etc/mtab + - /etc/mnttab + - /etc/hosts.deny + - /etc/mail/statistics + - /etc/random-seed + - /etc/random.seed + - /etc/adjtime + - /etc/httpd/logs + - /etc/utmpx + - /etc/wtmpx + - /etc/cups/certs + - /etc/dumpdates + - /etc/svc/volatile + no_diff: + - /etc/ssl/private.key + directories: + - check_all: 'yes' + dirs: /etc,/usr/bin,/usr/sbin + - check_all: 'yes' + dirs: /bin,/sbin + localfiles: + - format: 'syslog' + location: '/var/log/messages' + - format: 'syslog' + location: '/var/log/secure' + - format: 'command' + command: 'df -P' + frequency: '360' + - format: 'full_command' + command: 'netstat -tln | grep -v 127.0.0.1 | sort' + frequency: '360' + - format: 'full_command' + command: 'last -n 20' + frequency: '360' + globals: + - '127.0.0.1' + - '192.168.2.1' + connection: + - type: 'secure' + port: '1514' + protocol: 'udp' + log_level: 1 + email_level: 12 + commands: + - name: 'disable-account' + executable: 'disable-account.sh' + expect: 'user' + timeout_allowed: 'yes' + - name: 'restart-ossec' + executable: 'restart-ossec.sh' + expect: '' + timeout_allowed: 'no' + - name: 'firewall-drop' + executable: 'firewall-drop.sh' + expect: 'srcip' + timeout_allowed: 'yes' + - name: 'host-deny' + executable: 'host-deny.sh' + expect: 'srcip' + timeout_allowed: 'yes' + - name: 'route-null' + executable: 'route-null.sh' + expect: 'srcip' + timeout_allowed: 'yes' + - name: 'win_route-null' + executable: 'route-null.cmd' + expect: 'srcip' + timeout_allowed: 'yes' + active_responses: + - command: 'host-deny' + location: 'local' + level: 6 + timeout: 600 + +ossec_agent_configs: + - type: os + type_value: linux + frequency_check: 79200 + ignore_files: + - /etc/mtab + - /etc/mnttab + - /etc/hosts.deny + - /etc/mail/statistics + - /etc/svc/volatile + directories: + - check_all: yes + dirs: /etc,/usr/bin,/usr/sbin + - check_all: yes + dirs: /bin,/sbin + localfiles: + - format: 'syslog' + location: '/var/log/messages' + - format: 'syslog' + location: '/var/log/secure' + - format: 'syslog' + location: '/var/log/maillog' + - format: 'apache' + location: '/var/log/httpd/error_log' + - format: 'apache' + location: '/var/log/httpd/access_log' + - format: 'apache' + location: '/var/ossec/logs/active-responses.log' diff --git a/wazuh-agent.retry b/wazuh-agent.retry new file mode 100644 index 00000000..885577a5 --- /dev/null +++ b/wazuh-agent.retry @@ -0,0 +1 @@ +192.168.33.166 diff --git a/wazuh-agent.yml b/wazuh-agent.yml new file mode 100644 index 00000000..e2ab4aae --- /dev/null +++ b/wazuh-agent.yml @@ -0,0 +1,3 @@ +- hosts: all:!wazuh-manager + roles: + - { role: ansible-wazuh-agent, ossec_server_ip: 192.168.33.170 } diff --git a/wazuh-manager.yml b/wazuh-manager.yml new file mode 100644 index 00000000..cb37fab0 --- /dev/null +++ b/wazuh-manager.yml @@ -0,0 +1,4 @@ +- hosts: wazuh-manager + roles: + - role: ansible-wazuh-server + - role: ansible-role-filebeat