<commit_before>---
- hosts: all
  vars:
    rock_debug: "{{ lookup('env', 'DEBUG') }}"
    http_proxy: "{{ lookup('env','http_proxy') }}"
    https_proxy: "{{ lookup('env', 'https_proxy') }}"
  tasks:
  - name: Get default settings
    include_vars: files/rocknsm_config.dist.yml
  - name: Apply override settings, if available
    include_vars: /etc/rocknsm/config.yml
    ignore_errors: true
    failed_when: false
  - name: Debug variables
    include: debug.yml
    when: rock_debug is defined and rock_debug

    ######################################################
    ################# Data Directory #####################
    ######################################################
    ###############
    ##### NOTE ####
    ###############
    # You will want to remount this to your "good" storage after the build.
    # This is just to make sure all the paths in the configs are proper.
    ###############  - file:
  - name: Create ROCK data dir
    file:
      path: "{{ rock_data_dir }}"
      mode: 0755
      owner: "{{ rock_data_user }}"
      group: "{{ rock_data_group }}"
      state: directory
    when: false

    ######################################################
    ######### Configure the monitoring interface #########
    ######################################################
  - name: Set monitor interface config
    template:
      src: templates/ifcfg-monif.j2
      dest: /etc/sysconfig/network-scripts/ifcfg-{{ item }}
      mode: 0644
      owner: root
      group: root
      force: yes
    with_items: "{{ rock_monifs }}"

  - name: Configure local ifup script
    template:
      src: templates/ifup-local.j2
      dest: /sbin/ifup-local
      mode: 0755
      owner: root
      group: root
      force: yes
    notify: configure monitor interfaces

    #######################################################
    #################### Disable IPv6 #####################
    #######################################################

  - name: Disable IPv6 for all interfaces
    sysctl:
      name: net.ipv6.conf.all.disable_ipv6
      value: 1l
      sysctl_file: "{{ rock_sysctl_file }}"

  - name: Disable IPv6 for default interfaces
    sysctl:
      name: net.ipv6.conf.default.disable_ipv6
      value: 1
      sysctl_file: "{{ rock_sysctl_file }}"

  - name: Disable IPv6 in SSHD
    lineinfile:
      dest: /etc/ssh/sshd_config
      regexp: AddressFamily
      line: AddressFamily inet
    notify:
    - sshd restart

  - name: Remove localhost6 from hosts file
    lineinfile:
      dest: /etc/hosts
      regexp: localhost6
      state: absent

    #######################################################
    #################### DNS Changes ######################
    #######################################################
  - name: Set hostname in hosts file
    lineinfile:
      dest: /etc/hosts
      insertafter: 127.0.0.1
      line: 127.0.0.2  {{ rock_fqdn }}  {{ rock_hostname }}

  - name: Set system hostname
    hostname:
      name: "{{ rock_fqdn }}"

    #######################################################
    ################## Setup Yum Repos ####################
    #######################################################
  - name: Setup EPEL repo
    yum_repository:
      name: epel
      description: EPEL YUM repo
      baseurl: "{{ epel_baseurl }}"
      gpgkey:  "{{ epel_gpgurl }}"
      gpgcheck: yes
    when: rock_online_install

  - name: Setup ELrepo Kernel repo
    yum_repository:
      name: elrepo-kernel
      description: ELrepo Kernel YUM repo
      baseurl: "{{ elrepo_baseurl }}"
      gpgkey:  "{{ elrepo_gpgurl }}"
      gpgcheck: yes
    when: rock_online_install

  - name: Setup Elastic repo
    yum_repository:
      name: elastic-5.x
      description: Elastic Stack repository for 5.x
      baseurl: "{{ elastic_baseurl }}"
      gpgkey:  "{{ elastic_gpgurl }}"
      gpgcheck: no
    when: rock_online_install

  - name: Setup ROCK NSM repo
    yum_repository:
      name: rocknsm
      description: ROCK NSM repository for devel
      baseurl: "{{ rocknsm_baseurl }}"
      gpgkey:  "{{ rocknsm_gpgurl }}"
      gpgcheck: no
      cost: 750
    when: rock_online_install

  - name: Setup local offline repo
    yum_repository:
      name: rocknsm-local
      description: ROCKNSM Local Repository
      baseurl: "{{ rocknsm_local_baseurl }}"
      gpgcheck: no
      cost: 500
    when: not rock_online_install

    #######################################################
    ############# Install/Remove Packages #################
    #######################################################
  - name: Configure packages
    yum:
      name: "{{ item.pkg }}"
      state: "{{ item.state }}"
    when: (item.test) or (item.test is undefined)
    with_items:
      - { pkg: "{{ rocknsm_package_list }}", state: installed }
      - { pkg: elasticsearch, test: "{{with_elasticsearch}}", state: installed }
      - { pkg: logstash, test: "{{with_logstash}}", state: installed }
      - { pkg: kibana, test: "{{with_kibana}}", state: installed }
      - { pkg: nginx, test: "{{with_nginx}}", state: installed }
      - { pkg: bro, test: "{{with_bro}}", state: installed }
      - { pkg: bro-plugin-af_packet, test: "{{with_bro}}", state: installed }
      - { pkg: bro-plugin-kafka, test: "{{(with_bro and with_kafka)}}", state: installed }
      - { pkg: stenographer, test: "{{with_stenographer}}", state: installed }
      - { pkg: suricata, test: "{{with_suricata}}", state: installed }
      - { pkg: snort, test: "{{with_snort}}", state: installed }
      - { pkg: daq, test: "{{with_snort}}", state: installed }
      - { pkg: zookeeper, test: "{{with_zookeeper}}", state: installed }
      - { pkg: kafka, test: "{{with_kafka}}", state: installed }
      - { pkg: kafkacat, test: "{{with_kafka}}", state: installed }
      - { pkg: fsfserver, test: "{{with_fsfserver}}", state: installed }
      - { pkg: chrony, state: installed }
      - { pkg: firewalld, state: installed }
      - { pkg: postfix, state: absent }

  - name: Ensure cache directory exists
    file:
      dest: "{{ rock_cache_dir }}"
      state: directory
      mode: 0755

  - name: Download Pulled Pork
    get_url:
      url: "{{ pulledpork_url }}"
      dest: "{{ rock_cache_dir }}/{{ pulledpork_filename }}"
      mode: 0644
    when: rock_online_install

  - name: Install Pulled Pork
    unarchive:
      src: "{{ rock_cache_dir }}/{{ pulledpork_filename }}"
      dest: /opt
      owner: root
      group: root
      creates: "/opt/pulledpork-{{ pulledpork_release }}"
      remote_src: yes
    when: "{{ with_pulledpork }}"

    ######################################################
    ################### Configure Time ###################
    ######################################################
  - name: Enable and start chrony
    service:
      name: chronyd
      enabled: yes
      state: started

  - name: Set system timezone
    command: /usr/bin/timedatectl set-timezone UTC
    when: ansible_date_time.tz != "UTC"

  - name: Check if RTC set to UTC
    shell: timedatectl | awk '/RTC in local/ { print $5 }'
    changed_when: false
    register: chrony_local_utc

  - name: Set system hardware clock to UTC
    command: /usr/bin/timedatectl set-local-rtc no
    when: chrony_local_utc == 'yes'

    #######################################################
    ################ Configure firewall ###################
    #######################################################

  - name: Enable and start firewalld
    service:
      name: firewalld
      enabled: yes
      state: started

  - name: Configure firewalld
    firewalld:
      port: "{{ item[1].port }}"
      source: "{{ item[0] }}"
      permanent: yes
      state: enabled
      immediate: yes
    when: (item[1].test is undefined) or item[1].test
    with_nested:
      - "{{ rock_mgmt_nets }}"
      -
        - { port: "22/tcp" }
        - { port: "80/tcp",  test: "{{ with_kibana }}" }

    ######################################################
    ############## Configure GeoIP Databases #############
    ######################################################
  - name: Configure GeoIP Update
    copy: src=files/GeoIP.conf dest=/etc/GeoIP.conf

    # There's an issue w/ geoipupdate when env is empty
  - name: Update GeoIP
    shell: >
      if [ "x$HTTP_PROXY" == "x" ]; then
          unset HTTP_PROXY;
      fi
      if [ "x$http_proxy" == "x" ]; then
          unset http_proxy;
      fi
      if [ "x$HTTPS_PROXY" == "x" ]; then
          unset HTTPS_PROXY;
      fi
      if [ "x$https_proxy" == "x" ]; then
          unset https_proxy;
      fi
      /usr/bin/geoipupdate
    args:
      creates: /usr/share/GeoIP/GeoLiteASNum.dat
    register: result
    failed_when: (result.rc != 0) and (result.rc != 1)

  - name: Create GeoIP symlinks
    file:
      src: "/usr/share/GeoIP/{{ item.src }}"
      dest: "/usr/share/GeoIP/{{ item.dest }}"
      force: yes
      state: link
    with_items:
      - { src: 'GeoLiteCity.dat', dest: 'GeoIPCity.dat' }
      - { src: 'GeoLiteCountry.dat', dest: 'GeoIPCountry.dat' }
      - { src: 'GeoLiteASNum.dat', dest: 'GeoIPASNum.dat' }
      - { src: 'GeoLiteCityv6.dat', dest: 'GeoIPCityv6.dat' }

    #######################################################
    ###################### Setup Bro  #####################
    #######################################################
  - name: Create bro group
    group:
      name: "{{ bro_group }}"
      state: present
      system: yes
    when: with_bro

  - name: Create bro user and group
    user:
      name: "{{ bro_user }}"
      comment: "bro service account"
      createhome: no
      group: "{{ bro_group }}"
      home: /opt/bro
      shell: /sbin/nologin
      system: yes
      state: present
    when: with_bro

  - name: Create Bro directories
    file:
      path: "{{ item }}"
      mode: 0755
      owner: "{{ bro_user }}"
      group: "{{ bro_group }}"
      state: directory
    with_items:
      - "{{ bro_data_dir }}"
      - "{{ bro_data_dir }}/logs"
      - "{{ bro_data_dir }}/spool"
    when: with_bro

  - name: Create symlinks for wandering analysts
    file:
      dest: "/opt/bro/{{ item }}"
      src:  "{{ bro_data_dir }}/{{ item }}"
      state: link
      force: yes
    with_items:
      - logs
    when: with_bro

  - name: Create Bro node.cfg
    template:
      src: templates/bro-node.cfg.j2
      dest: /opt/bro/etc/node.cfg
      mode: 0644
      owner: root
      group: root
    when: with_bro

  - name: Create broctl.cfg
    template:
      src: templates/bro-broctl.cfg.j2
      dest: /opt/bro/etc/broctl.cfg
      mode: 0644
      owner: root
      group: root
  - name: Create bro networks.cfg
    copy:
      src: files/bro-networks.cfg
      dest: /opt/bro/etc/networks.cfg
      mode: 0644
      owner: root
      group: root

  - name: Add bro custom scripts dir
    file:
      path: /opt/bro/share/bro/site/scripts
      owner: root
      group: root
      mode: 0755
      state: directory

  - name: Set permissions on broctl scripts dir
    file:
      path: /opt/bro/share/broctl/scripts
      owner: "{{ bro_user }}"
      group: "{{ bro_user }}"
      mode: 0755
      state: directory

  - name: Add README to scripts dir
    copy:
      src: files/bro-scripts-readme.txt
      dest: /opt/bro/share/bro/site/scripts/README.txt
      mode: 0644
      owner: root
      group: root

  - name: Checkout ROCK Bro scripts
    git:
      repo: "{{ bro_rockscripts_repo }}"
      dest: /opt/bro/share/bro/site/scripts/rock
      version: "{{ bro_rockscripts_branch }}"
    when: rock_online_install

  - name: Deploy offline ROCK Bro scripts
    unarchive:
      src: "{{ rock_cache_dir }}/{{ bro_rockscripts_filename }}"
      dest: /opt/bro/share/bro/site/scripts/
      owner: root
      group: root
      creates: "/opt/bro/share/bro/site/scripts/rock-scripts-{{ bro_rockscripts_branch | replace ('/', '-') }}"
      remote_src: yes
    when: not rock_online_install

  - name: Symlink offline ROCK bro scripts
    file:
      src: "/opt/bro/share/bro/site/scripts/rock-scripts-{{ bro_rockscripts_branch | replace ('/', '-') }}"
      dest: "/opt/bro/share/bro/site/scripts/rock"
      state: link
      force: yes
    when: not rock_online_install

  - name: Update owner for ROCK NSM Bro scripts
    file:
      path: /opt/bro/share/bro/site/scripts/rock
      owner: "{{ bro_user }}"
      group: "{{ bro_group }}"
      state: directory
      recurse: yes
      follow: yes
    tags:
      - bro_scripts

  - name: Add ROCK scripts to local.bro
    lineinfile:
      dest: /opt/bro/share/bro/site/local.bro
      line: "@load scripts/rock # ROCK NSM customizations"
      state: present

  - name: Add AF_PACKET workaround to local.bro
    lineinfile:
      dest: /opt/bro/share/bro/site/local.bro
      line: "@load scripts/rock/plugins/afpacket"
      state: present
    when: with_bro

  - name: Enable Bro Kafka output to local.bro
    lineinfile:
      dest: /opt/bro/share/bro/site/local.bro
      line: "@load scripts/rock/plugins/kafka"
      state: present
    when: with_bro and with_kafka

  - name: Add bro to path and aliases
    copy:
      src: files/profile.d-bro.sh
      dest: /etc/profile.d/bro.sh
      mode: 0644
      owner: root
      group: root

  - name: Set bro capabilities
    capabilities:
      path: /opt/bro/bin/bro
      capability: "{{ item }}"
      state: present
    with_items:
      - "cap_net_raw+eip"
      - "cap_net_admin+eip"

  - name: Set capstats capabilities
    capabilities:
      path: /opt/bro/bin/capstats
      capability: "{{ item }}"
      state: present
    with_items:
      - "cap_net_raw+eip"
      - "cap_net_admin+eip"

  - name: Set broctl cron
    cron:
      name: "broctl maintenance"
      minute: "*/5"
      cron_file: rocknsm_broctl
      user: "{{ bro_user }}"
      job: "/opt/bro/bin/broctl cron >/dev/null 2>&1"

  - name: Install broctl service file
    template:
      src: templates/broctl.service.j2
      dest: /etc/systemd/system/broctl.service
      owner: root
      group: root
      mode: 0644
    notify: reload systemd

  - name: Initialize bro scripts for workers
    command: /opt/bro/bin/broctl install
    args:
      creates: "{{ bro_data_dir }}/spool/broctl-config.sh"
    become: yes
    become_user: "{{ bro_user }}"

  - name: Enable and start broctl
    service: name=broctl enabled=yes state=started

    ######################################################
    ################# Setup Stenographer #################
    ######################################################

  - name: Set stenographer config
    template:
      src: templates/stenographer-config.j2
      dest: "/etc/stenographer/config.{{ item.1 }}"
    with_indexed_items: "{{ rock_monifs }}"
    when: with_stenographer

  - name: Create Stenographer directories
    file:
      path: "{{ stenographer_data_dir }}/{{ item[0] }}/{{ item[1] }}"
      mode: 0755
      owner: "{{ stenographer_user }}"
      group: "{{ stenographer_group }}"
      state: directory
    with_nested:
      - "{{ rock_monifs }}"
      - [ 'index', 'packets' ]
    when: with_stenographer

  - name: Install stenographer service files
    copy:
      src: "files/{{ item }}"
      dest: "/etc/systemd/system/{{ item }}"
      mode: 0644
      owner: root
      group: root
    with_items:
      - stenographer.service
      - stenographer@.service
    when: with_stenographer

  - name: Generate stenographer keys
    command: >
      /usr/bin/stenokeys.sh {{ stenographer_user }} {{ stenographer_group }}
    args:
      creates: /etc/stenographer/certs/client_key.pem
    when: with_stenographer

  - name: Set Stenographer disabled by default
    service: name=stenographer enabled=no state=stopped
    when: with_stenographer

    ######################################################
    ################## Setup Suricata ####################
    ######################################################

  - name: Create Suricata directories
    file:
      path: "{{ suricata_data_dir }}/"
      mode: 0755
      owner: "{{ suricata_user }}"
      group: "{{ suricata_group }}"
      state: directory
    when: with_suricata

  - name: Set suricata capabilities
    capabilities:
      path: /usr/sbin/suricata
      capability: "{{ item }}"
      state: present
    with_items:
      - "cap_net_raw+eip"
      - "cap_net_admin+eip"
      - "cap_ipc_lock+eip"
    when: with_suricata

  - name: Remove suricata sysconfig file
    file:
      path: /etc/sysconfig/suricata
      state: absent
    when: with_suricata

  - name: Install suricata service files
    copy:
      src: "files/suricata.service"
      dest: "/etc/systemd/system/suricata.service"
      mode: 0644
      owner: root
      group: root
    when: with_suricata

  - name: Install suricata overrides
    template:
      src: templates/suricata_overrides.yaml.j2
      dest: /etc/suricata/rocknsm-overrides.yaml
      mode: 0644
      owner: "{{ suricata_user }}"
      group: root
    when: with_suricata

  - name: Create IP reputation config dir
    file:
      path: /etc/suricata/rules/iplists
      state: directory
      owner: root
      group: root
      mode: 0755
    when: with_suricata

  - name: Set suricata overrides include in main config
    lineinfile:
      dest: /etc/suricata/suricata.yaml
      line: "include: rocknsm-overrides.yaml"
      state: present
    when: with_suricata

  - name: Enable and start suricata
    service: name="suricata" enabled=yes state=started
    when: with_suricata

  - name: Configure logrotate for suricata logs
    copy:
      src: files/logrotate-suricata.conf
      dest: /etc/logrotate.d/suricata.conf
      mode: 0644
      owner: root
      group: root
    when: with_suricata

    ######################################################
    ################# Setup PulledPork  ##################
    ######################################################
  - name: Create pulledpork directory symlink
    file:
      src: "/opt/pulledpork-{{ pulledpork_release }}"
      dest: "/opt/pulledpork"
      state: link
      force: yes
    when: with_pulledpork

  - name: Set pulledpork executable
    file:
      path: /opt/pulledpork/pulledpork.pl
      mode: 0755
      owner: root
      group: root
    when: with_pulledpork

  - name: Create pulledpork config dir
    file:
      path: /etc/pulledpork
      mode: 0755
      owner: root
      group: root
      state: directory
    when: with_pulledpork

  - name: Configure pulledpork
    template:
      src: templates/pulledpork.conf.j2
      dest: /etc/pulledpork/pulledpork.conf
      owner: root
      group: root
      mode: 0644
    when: with_pulledpork

  - name: Check stats of rules files
    stat:
      path: "{{ pulledpork_engine_basepath }}/rules/pulledpork.rules"
    register: rules_file
    when: with_pulledpork

  - name: Create initial pulledpork rules-related files
    file:
      path: "{{ pulledpork_engine_basepath }}/rules/pulledpork.rules"
      owner: root
      group: root
      mode: 0644
      state: touch
    when: not rules_file.stat.exists and with_pulledpork

  - name: Schedule pulledpork to run daily
    cron:
      name: "pulledpork update"
      cron_file: rocknsm_pulledpork
      user: root
      hour: "12"
      minute: "0"
      job: /opt/pulledpork/pulledpork.pl
        -c /etc/pulledpork/pulledpork.conf
        -l > /var/log/pulledpork.log 2>&1;
        {{ "/usr/bin/systemctl kill -s USR2 suricata;" if with_suricata else None }}
        {{ "/usr/bin/systemctl restart snortd;" if with_snort else None }}
    when: with_pulledpork

    ######################################################
    ################### Setup Zookeeper ##################
    ######################################################
  - name: Install zookeeper service file
    copy:
      src: files/zookeeper.service
      dest: /etc/systemd/system/zookeeper.service
      mode: 0644
      owner: root
      group: root
    when: with_zookeeper

  - name: Enable and start zookeeper
    service: name=zookeeper state=started enabled=yes
    when: with_zookeeper

    ######################################################
    ##################### Setup Kafka ####################
    ######################################################

  - name: Create Kafka data dir
    file:
      path: "{{ kafka_data_dir }}"
      mode: 0755
      owner: "{{ kafka_user }}"
      group: "{{ kafka_group }}"
      state: directory
    when: with_kafka

  - name: Set kafka retention
    lineinfile:
      dest: "{{ kafka_config_path }}"
      regexp: "log.retention.hours="
      line:  "log.retention.hours=1"
      state: present
    when: with_kafka

  - name: Set kafka data dir
    lineinfile:
      dest: "{{ kafka_config_path }}"
      regexp: "log.dirs="
      line: "log.dirs={{ kafka_data_dir }}"
    when: with_kafka

  - name: Enable and start kafka
    service: name=kafka state=started enabled=yes
    when: with_kafka

    ######################################################
    ################# Setup Elasticsearch ################
    ######################################################
  - name: Create Elasticsearch directory
    file:
      path: "{{ es_data_dir }}"
      mode: 0755
      owner: "{{ es_user }}"
      group: "{{ es_group }}"
      state: directory
    when: with_elasticsearch

  - name: Setup elasticsearch config
    template:
      src: templates/elasticsearch.yml.j2
      dest: /etc/elasticsearch/elasticsearch.yml
      owner: root
      group: "{{ es_group }}"
      mode: 0640
    when: with_elasticsearch

  - name: Create elasticsearch systemd override dir
    file:
      path: /etc/systemd/system/elasticsearch.service.d
      owner: root
      group: root
      mode: 0755
      state: directory
    when: with_elasticsearch

  - name: Enable elasticsearch memlock in service override
    copy:
      content: "{{ es_memlock_override }}"
      dest: /etc/systemd/system/elasticsearch.service.d/override.conf
      mode: 0644
      owner: root
      group: root
    when: with_elasticsearch

  - name: Setup elasticsearch data dir in sysconfig
    lineinfile:
      dest: /etc/sysconfig/elasticsearch
      regexp: "DATA_DIR="
      line: "DATA_DIR={{ es_data_dir }}"
    when: with_elasticsearch

  - name: Setup elasticsearch jvm options
    template:
      src: templates/es-jvm.options.j2
      dest: /etc/elasticsearch/jvm.options
      mode: 0640
      owner: root
      group: "{{ es_group }}"
    when: with_elasticsearch

  - name: Install ROCK Elasticsearch cleanup script
    copy:
      src: files/es_cleanup.sh
      dest: /usr/local/bin/es_cleanup.sh
      mode: 0755
      owner: root
      group: root
    when: with_elasticsearch

  - name: Set elasticsearch cleanup cron job
    cron:
      name: "ES maintenance"
      cron_file: rocknsm_es_maintenance
      hour: 0
      minute: 1
      user: root
      job: /usr/local/bin/es_cleanup.sh > /dev/null 2>&1
    when: with_elasticsearch

  - name: Enable and start Elasticsearch
    service: name=elasticsearch state=started enabled=yes
    when: with_elasticsearch

  - name: Wait for Elasticsearch to become ready
    wait_for: host=localhost port=9200

  - name: Check for Bro mapping templates
    uri:
      method: "GET"
      url: http://localhost:9200/_template/bro_index
    failed_when: False
    register: bro_mapping

  - name: Load Bro Elasticsearch mapping templates
    uri:
      method: PUT
      url: http://localhost:9200/_template/bro_index
      body: "{{ lookup('file', 'files/es-bro-mappings.json')}}"
      body_format: json
    when: bro_mapping.status == 404

    ######################################################
    ################### Setup Logstash ###################
    ######################################################

  - name: Install Bro-Kafka configuration for Logstash
    copy:
      src: files/logstash-kafka-bro.conf
      dest: /etc/logstash/conf.d/kafka-bro.conf
      mode: 0640
      owner: "{{ logstash_user }}"
      group: "{{ logstash_group }}"
    when: with_logstash and with_bro and with_kafka

  - name: Configure Logstash to pickup suricata events
    copy:
      src: "files/logstash-suricata-es.conf"
      dest: "/etc/logstash/conf.d/suricata-es.conf"
      mode: 0644
      owner: root
      group: root
    when: with_logstash and with_suricata

  - name: Configure Logstash to pickup the FSF scan.log
    copy:
      src: "files/logstash-fsf-es.conf"
      dest: "/etc/logstash/conf.d/fsf-es.conf"
      mode: 0644
      owner: root
      group: root
    when: with_logstash and with_fsfserver

  - name: Enable and start Logstash
    service: name=logstash state=started enabled=yes
    when: with_logstash

    ######################################################
    ################### Setup Kibana #####################
    ######################################################

  - name: Enable and start Kibana
    service: name=kibana state=started enabled=yes
    when: "{{ with_kibana }}"

  - name: Download ROCK Dashboards
    get_url:
      url: "{{ rock_dashboards_url }}"
      dest: "{{ rock_cache_dir }}/{{ rock_dashboards_filename }}"
      mode: 0644
    when: "{{ with_kibana and rock_online_install }}"

  - name: Extract ROCK Dashboards
    unarchive:
      src: "{{ rock_cache_dir }}/{{ rock_dashboards_filename }}"
      dest: /opt/rocknsm
      owner: root
      group: root
      creates: "/opt/rocknsm/rock-dashboards-{{ rock_dashboards_branch }}"
      remote_src: yes
    when: "{{ with_kibana }}"

  - name: Query Kibana package info
    yum:
      list: kibana
    register: kibana_pkg
    when: "{{ with_kibana }}"

  - name: Store installed kibana pkg info
    set_fact:
      kibana_info: "{{ kibana_pkg.results | selectattr('repo', 'match', 'installed') | first }}"
    when: "{{ with_kibana }}"

  - name: Check current Kibana config
    uri:
      method: "GET"
      url: "{{ es_url }}/.kibana/config/{{ kibana_info.version }}/_source"
      return_content: true
    register: kibana_cfg
    changed_when: false
    until: kibana_cfg.status == 200
    retries: 10
    delay: 3
    when: "{{ with_kibana }}"

  - name: Store Kibana config dict
    set_fact:
      kibana_config: "{{ kibana_cfg.json }}"
    when: "{{ with_kibana }}"

  - name: Configure Kibana templates
    uri:
      method: PUT
      url: http://localhost:9200/_template/kibana-config
      body: >
        { "order" : 0, "template" : ".kibana",
          "settings" :
            { "index.number_of_replicas" : "0",
              "index.number_of_shards" : "1" },
          "mappings" : { }, "aliases" : { } }
      status_code: 200,201
    when: "{{ with_kibana }}"

  - name: Push Kibana dashboard config
    command: >
      /opt/rocknsm/rock-dashboards-{{ rock_dashboards_branch }}/load.sh
        -url {{ es_url }}
    args:
      chdir: /opt/rocknsm/rock-dashboards-{{ rock_dashboards_branch }}/
    when: "{{ with_kibana and (kibana_config.rock_config is undefined or kibana_config.rock_config != rock_dashboards_version) }}"

  - name: Store default Kibana index to Bro
    set_fact:
      kibana_config: "{{ kibana_config | combine({'defaultIndex': 'bro-*' })}}"
    when: "{{ with_kibana and with_bro }}"

  - name: Store default Kibana index to Suricata
    set_fact:
      kibana_config: "{{ kibana_config | combine({'defaultIndex': 'suricata-*' })}}"
    when: "{{ with_kibana and with_suricata and not with_bro }}"

  - name: Update Kibana config dict w/ rock_config version
    set_fact:
      kibana_config: "{{ kibana_config | combine({'rock_config': rock_dashboards_version }) }}"
    when: "{{ with_kibana }}"

  - name: Push Kibana settings for index and rock_version
    uri:
      method: PUT
      url: "{{ es_url }}/.kibana/config/{{ kibana_info.version }}"
      body: "{{ kibana_config }}"
      body_format: "json"
      status_code: 200,201
    when: "{{ with_kibana }}"

    ######################################################
    ################### Setup nginx ######################
    ######################################################

  - name: Install ROCK nginx configuration
    template:
      src: templates/nginx-rock.conf.j2
      dest: /etc/nginx/conf.d/rock.conf
      mode: 0644
      owner: root
      group: root
    when: with_nginx and with_kibana

  - name: Install nginx base configuration
    copy:
      src: files/nginx.conf
      dest: /etc/nginx/nginx.conf
      mode: 0644
      owner: root
      group: root
    when: with_nginx

  - name: Enable nginx to perform proxy connect
    seboolean: name=httpd_can_network_connect state=yes persistent=yes
    when: with_nginx and with_kibana

  - name: Enable and start nginx
    service: name=nginx state=started enabled=yes
    when: with_nginx

    #######################################################
    ######################## FSF ##########################
    #######################################################
    
  - name: Configure logrotate for FSF logs
    copy:
      src: files/logrotate-fsf.conf
      dest: /etc/logrotate.d/fsf.conf
      mode: 0644
      owner: root
      group: root
    when: with_fsfserver

  - name: Enable and start FSF
    service: name=fsf state=started enabled=yes
    when: with_fsfserver

    ######################################################
    ############### Setup ROCKNSM Scripts ################
    ######################################################

  - name: Install rock start script
    copy:
      src: files/rock_start
      dest: /usr/local/bin/rock_start
      mode: 0700<commit_msg>Create data directory for FSF w/ 0755 perms<commit_after>---
- hosts: all
  vars:
    rock_debug: "{{ lookup('env', 'DEBUG') }}"
    http_proxy: "{{ lookup('env','http_proxy') }}"
    https_proxy: "{{ lookup('env', 'https_proxy') }}"
  tasks:
  - name: Get default settings
    include_vars: files/rocknsm_config.dist.yml
  - name: Apply override settings, if available
    include_vars: /etc/rocknsm/config.yml
    ignore_errors: true
    failed_when: false
  - name: Debug variables
    include: debug.yml
    when: rock_debug is defined and rock_debug

    ######################################################
    ################# Data Directory #####################
    ######################################################
    ###############
    ##### NOTE ####
    ###############
    # You will want to remount this to your "good" storage after the build.
    # This is just to make sure all the paths in the configs are proper.
    ###############  - file:
  - name: Create ROCK data dir
    file:
      path: "{{ rock_data_dir }}"
      mode: 0755
      owner: "{{ rock_data_user }}"
      group: "{{ rock_data_group }}"
      state: directory
    when: false

    ######################################################
    ######### Configure the monitoring interface #########
    ######################################################
  - name: Set monitor interface config
    template:
      src: templates/ifcfg-monif.j2
      dest: /etc/sysconfig/network-scripts/ifcfg-{{ item }}
      mode: 0644
      owner: root
      group: root
      force: yes
    with_items: "{{ rock_monifs }}"

  - name: Configure local ifup script
    template:
      src: templates/ifup-local.j2
      dest: /sbin/ifup-local
      mode: 0755
      owner: root
      group: root
      force: yes
    notify: configure monitor interfaces

    #######################################################
    #################### Disable IPv6 #####################
    #######################################################

  - name: Disable IPv6 for all interfaces
    sysctl:
      name: net.ipv6.conf.all.disable_ipv6
      value: 1l
      sysctl_file: "{{ rock_sysctl_file }}"

  - name: Disable IPv6 for default interfaces
    sysctl:
      name: net.ipv6.conf.default.disable_ipv6
      value: 1
      sysctl_file: "{{ rock_sysctl_file }}"

  - name: Disable IPv6 in SSHD
    lineinfile:
      dest: /etc/ssh/sshd_config
      regexp: AddressFamily
      line: AddressFamily inet
    notify:
    - sshd restart

  - name: Remove localhost6 from hosts file
    lineinfile:
      dest: /etc/hosts
      regexp: localhost6
      state: absent

    #######################################################
    #################### DNS Changes ######################
    #######################################################
  - name: Set hostname in hosts file
    lineinfile:
      dest: /etc/hosts
      insertafter: 127.0.0.1
      line: 127.0.0.2  {{ rock_fqdn }}  {{ rock_hostname }}

  - name: Set system hostname
    hostname:
      name: "{{ rock_fqdn }}"

    #######################################################
    ################## Setup Yum Repos ####################
    #######################################################
  - name: Setup EPEL repo
    yum_repository:
      name: epel
      description: EPEL YUM repo
      baseurl: "{{ epel_baseurl }}"
      gpgkey:  "{{ epel_gpgurl }}"
      gpgcheck: yes
    when: rock_online_install

  - name: Setup ELrepo Kernel repo
    yum_repository:
      name: elrepo-kernel
      description: ELrepo Kernel YUM repo
      baseurl: "{{ elrepo_baseurl }}"
      gpgkey:  "{{ elrepo_gpgurl }}"
      gpgcheck: yes
    when: rock_online_install

  - name: Setup Elastic repo
    yum_repository:
      name: elastic-5.x
      description: Elastic Stack repository for 5.x
      baseurl: "{{ elastic_baseurl }}"
      gpgkey:  "{{ elastic_gpgurl }}"
      gpgcheck: no
    when: rock_online_install

  - name: Setup ROCK NSM repo
    yum_repository:
      name: rocknsm
      description: ROCK NSM repository for devel
      baseurl: "{{ rocknsm_baseurl }}"
      gpgkey:  "{{ rocknsm_gpgurl }}"
      gpgcheck: no
      cost: 750
    when: rock_online_install

  - name: Setup local offline repo
    yum_repository:
      name: rocknsm-local
      description: ROCKNSM Local Repository
      baseurl: "{{ rocknsm_local_baseurl }}"
      gpgcheck: no
      cost: 500
    when: not rock_online_install

    #######################################################
    ############# Install/Remove Packages #################
    #######################################################
  - name: Configure packages
    yum:
      name: "{{ item.pkg }}"
      state: "{{ item.state }}"
    when: (item.test) or (item.test is undefined)
    with_items:
      - { pkg: "{{ rocknsm_package_list }}", state: installed }
      - { pkg: elasticsearch, test: "{{with_elasticsearch}}", state: installed }
      - { pkg: logstash, test: "{{with_logstash}}", state: installed }
      - { pkg: kibana, test: "{{with_kibana}}", state: installed }
      - { pkg: nginx, test: "{{with_nginx}}", state: installed }
      - { pkg: bro, test: "{{with_bro}}", state: installed }
      - { pkg: bro-plugin-af_packet, test: "{{with_bro}}", state: installed }
      - { pkg: bro-plugin-kafka, test: "{{(with_bro and with_kafka)}}", state: installed }
      - { pkg: stenographer, test: "{{with_stenographer}}", state: installed }
      - { pkg: suricata, test: "{{with_suricata}}", state: installed }
      - { pkg: snort, test: "{{with_snort}}", state: installed }
      - { pkg: daq, test: "{{with_snort}}", state: installed }
      - { pkg: zookeeper, test: "{{with_zookeeper}}", state: installed }
      - { pkg: kafka, test: "{{with_kafka}}", state: installed }
      - { pkg: kafkacat, test: "{{with_kafka}}", state: installed }
      - { pkg: fsfserver, test: "{{with_fsfserver}}", state: installed }
      - { pkg: chrony, state: installed }
      - { pkg: firewalld, state: installed }
      - { pkg: postfix, state: absent }

  - name: Ensure cache directory exists
    file:
      dest: "{{ rock_cache_dir }}"
      state: directory
      mode: 0755

  - name: Download Pulled Pork
    get_url:
      url: "{{ pulledpork_url }}"
      dest: "{{ rock_cache_dir }}/{{ pulledpork_filename }}"
      mode: 0644
    when: rock_online_install

  - name: Install Pulled Pork
    unarchive:
      src: "{{ rock_cache_dir }}/{{ pulledpork_filename }}"
      dest: /opt
      owner: root
      group: root
      creates: "/opt/pulledpork-{{ pulledpork_release }}"
      remote_src: yes
    when: "{{ with_pulledpork }}"

    ######################################################
    ################### Configure Time ###################
    ######################################################
  - name: Enable and start chrony
    service:
      name: chronyd
      enabled: yes
      state: started

  - name: Set system timezone
    command: /usr/bin/timedatectl set-timezone UTC
    when: ansible_date_time.tz != "UTC"

  - name: Check if RTC set to UTC
    shell: timedatectl | awk '/RTC in local/ { print $5 }'
    changed_when: false
    register: chrony_local_utc

  - name: Set system hardware clock to UTC
    command: /usr/bin/timedatectl set-local-rtc no
    when: chrony_local_utc == 'yes'

    #######################################################
    ################ Configure firewall ###################
    #######################################################

  - name: Enable and start firewalld
    service:
      name: firewalld
      enabled: yes
      state: started

  - name: Configure firewalld
    firewalld:
      port: "{{ item[1].port }}"
      source: "{{ item[0] }}"
      permanent: yes
      state: enabled
      immediate: yes
    when: (item[1].test is undefined) or item[1].test
    with_nested:
      - "{{ rock_mgmt_nets }}"
      -
        - { port: "22/tcp" }
        - { port: "80/tcp",  test: "{{ with_kibana }}" }

    ######################################################
    ############## Configure GeoIP Databases #############
    ######################################################
  - name: Configure GeoIP Update
    copy: src=files/GeoIP.conf dest=/etc/GeoIP.conf

    # There's an issue w/ geoipupdate when env is empty
  - name: Update GeoIP
    shell: >
      if [ "x$HTTP_PROXY" == "x" ]; then
          unset HTTP_PROXY;
      fi
      if [ "x$http_proxy" == "x" ]; then
          unset http_proxy;
      fi
      if [ "x$HTTPS_PROXY" == "x" ]; then
          unset HTTPS_PROXY;
      fi
      if [ "x$https_proxy" == "x" ]; then
          unset https_proxy;
      fi
      /usr/bin/geoipupdate
    args:
      creates: /usr/share/GeoIP/GeoLiteASNum.dat
    register: result
    failed_when: (result.rc != 0) and (result.rc != 1)

  - name: Create GeoIP symlinks
    file:
      src: "/usr/share/GeoIP/{{ item.src }}"
      dest: "/usr/share/GeoIP/{{ item.dest }}"
      force: yes
      state: link
    with_items:
      - { src: 'GeoLiteCity.dat', dest: 'GeoIPCity.dat' }
      - { src: 'GeoLiteCountry.dat', dest: 'GeoIPCountry.dat' }
      - { src: 'GeoLiteASNum.dat', dest: 'GeoIPASNum.dat' }
      - { src: 'GeoLiteCityv6.dat', dest: 'GeoIPCityv6.dat' }

    #######################################################
    ###################### Setup Bro  #####################
    #######################################################
  - name: Create bro group
    group:
      name: "{{ bro_group }}"
      state: present
      system: yes
    when: with_bro

  - name: Create bro user and group
    user:
      name: "{{ bro_user }}"
      comment: "bro service account"
      createhome: no
      group: "{{ bro_group }}"
      home: /opt/bro
      shell: /sbin/nologin
      system: yes
      state: present
    when: with_bro

  - name: Create Bro directories
    file:
      path: "{{ item }}"
      mode: 0755
      owner: "{{ bro_user }}"
      group: "{{ bro_group }}"
      state: directory
    with_items:
      - "{{ bro_data_dir }}"
      - "{{ bro_data_dir }}/logs"
      - "{{ bro_data_dir }}/spool"
    when: with_bro

  - name: Create symlinks for wandering analysts
    file:
      dest: "/opt/bro/{{ item }}"
      src:  "{{ bro_data_dir }}/{{ item }}"
      state: link
      force: yes
    with_items:
      - logs
    when: with_bro

  - name: Create Bro node.cfg
    template:
      src: templates/bro-node.cfg.j2
      dest: /opt/bro/etc/node.cfg
      mode: 0644
      owner: root
      group: root
    when: with_bro

  - name: Create broctl.cfg
    template:
      src: templates/bro-broctl.cfg.j2
      dest: /opt/bro/etc/broctl.cfg
      mode: 0644
      owner: root
      group: root
  - name: Create bro networks.cfg
    copy:
      src: files/bro-networks.cfg
      dest: /opt/bro/etc/networks.cfg
      mode: 0644
      owner: root
      group: root

  - name: Add bro custom scripts dir
    file:
      path: /opt/bro/share/bro/site/scripts
      owner: root
      group: root
      mode: 0755
      state: directory

  - name: Set permissions on broctl scripts dir
    file:
      path: /opt/bro/share/broctl/scripts
      owner: "{{ bro_user }}"
      group: "{{ bro_user }}"
      mode: 0755
      state: directory

  - name: Add README to scripts dir
    copy:
      src: files/bro-scripts-readme.txt
      dest: /opt/bro/share/bro/site/scripts/README.txt
      mode: 0644
      owner: root
      group: root

  - name: Checkout ROCK Bro scripts
    git:
      repo: "{{ bro_rockscripts_repo }}"
      dest: /opt/bro/share/bro/site/scripts/rock
      version: "{{ bro_rockscripts_branch }}"
    when: rock_online_install

  - name: Deploy offline ROCK Bro scripts
    unarchive:
      src: "{{ rock_cache_dir }}/{{ bro_rockscripts_filename }}"
      dest: /opt/bro/share/bro/site/scripts/
      owner: root
      group: root
      creates: "/opt/bro/share/bro/site/scripts/rock-scripts-{{ bro_rockscripts_branch | replace ('/', '-') }}"
      remote_src: yes
    when: not rock_online_install

  - name: Symlink offline ROCK bro scripts
    file:
      src: "/opt/bro/share/bro/site/scripts/rock-scripts-{{ bro_rockscripts_branch | replace ('/', '-') }}"
      dest: "/opt/bro/share/bro/site/scripts/rock"
      state: link
      force: yes
    when: not rock_online_install

  - name: Update owner for ROCK NSM Bro scripts
    file:
      path: /opt/bro/share/bro/site/scripts/rock
      owner: "{{ bro_user }}"
      group: "{{ bro_group }}"
      state: directory
      recurse: yes
      follow: yes
    tags:
      - bro_scripts

  - name: Add ROCK scripts to local.bro
    lineinfile:
      dest: /opt/bro/share/bro/site/local.bro
      line: "@load scripts/rock # ROCK NSM customizations"
      state: present

  - name: Add AF_PACKET workaround to local.bro
    lineinfile:
      dest: /opt/bro/share/bro/site/local.bro
      line: "@load scripts/rock/plugins/afpacket"
      state: present
    when: with_bro

  - name: Enable Bro Kafka output to local.bro
    lineinfile:
      dest: /opt/bro/share/bro/site/local.bro
      line: "@load scripts/rock/plugins/kafka"
      state: present
    when: with_bro and with_kafka

  - name: Add bro to path and aliases
    copy:
      src: files/profile.d-bro.sh
      dest: /etc/profile.d/bro.sh
      mode: 0644
      owner: root
      group: root

  - name: Set bro capabilities
    capabilities:
      path: /opt/bro/bin/bro
      capability: "{{ item }}"
      state: present
    with_items:
      - "cap_net_raw+eip"
      - "cap_net_admin+eip"

  - name: Set capstats capabilities
    capabilities:
      path: /opt/bro/bin/capstats
      capability: "{{ item }}"
      state: present
    with_items:
      - "cap_net_raw+eip"
      - "cap_net_admin+eip"

  - name: Set broctl cron
    cron:
      name: "broctl maintenance"
      minute: "*/5"
      cron_file: rocknsm_broctl
      user: "{{ bro_user }}"
      job: "/opt/bro/bin/broctl cron >/dev/null 2>&1"

  - name: Install broctl service file
    template:
      src: templates/broctl.service.j2
      dest: /etc/systemd/system/broctl.service
      owner: root
      group: root
      mode: 0644
    notify: reload systemd

  - name: Initialize bro scripts for workers
    command: /opt/bro/bin/broctl install
    args:
      creates: "{{ bro_data_dir }}/spool/broctl-config.sh"
    become: yes
    become_user: "{{ bro_user }}"

  - name: Enable and start broctl
    service: name=broctl enabled=yes state=started

    ######################################################
    ################# Setup Stenographer #################
    ######################################################

  - name: Set stenographer config
    template:
      src: templates/stenographer-config.j2
      dest: "/etc/stenographer/config.{{ item.1 }}"
    with_indexed_items: "{{ rock_monifs }}"
    when: with_stenographer

  - name: Create Stenographer directories
    file:
      path: "{{ stenographer_data_dir }}/{{ item[0] }}/{{ item[1] }}"
      mode: 0755
      owner: "{{ stenographer_user }}"
      group: "{{ stenographer_group }}"
      state: directory
    with_nested:
      - "{{ rock_monifs }}"
      - [ 'index', 'packets' ]
    when: with_stenographer

  - name: Install stenographer service files
    copy:
      src: "files/{{ item }}"
      dest: "/etc/systemd/system/{{ item }}"
      mode: 0644
      owner: root
      group: root
    with_items:
      - stenographer.service
      - stenographer@.service
    when: with_stenographer

  - name: Generate stenographer keys
    command: >
      /usr/bin/stenokeys.sh {{ stenographer_user }} {{ stenographer_group }}
    args:
      creates: /etc/stenographer/certs/client_key.pem
    when: with_stenographer

  - name: Set Stenographer disabled by default
    service: name=stenographer enabled=no state=stopped
    when: with_stenographer

    ######################################################
    ################## Setup Suricata ####################
    ######################################################

  - name: Create Suricata directories
    file:
      path: "{{ suricata_data_dir }}/"
      mode: 0755
      owner: "{{ suricata_user }}"
      group: "{{ suricata_group }}"
      state: directory
    when: with_suricata

  - name: Set suricata capabilities
    capabilities:
      path: /usr/sbin/suricata
      capability: "{{ item }}"
      state: present
    with_items:
      - "cap_net_raw+eip"
      - "cap_net_admin+eip"
      - "cap_ipc_lock+eip"
    when: with_suricata

  - name: Remove suricata sysconfig file
    file:
      path: /etc/sysconfig/suricata
      state: absent
    when: with_suricata

  - name: Install suricata service files
    copy:
      src: "files/suricata.service"
      dest: "/etc/systemd/system/suricata.service"
      mode: 0644
      owner: root
      group: root
    when: with_suricata

  - name: Install suricata overrides
    template:
      src: templates/suricata_overrides.yaml.j2
      dest: /etc/suricata/rocknsm-overrides.yaml
      mode: 0644
      owner: "{{ suricata_user }}"
      group: root
    when: with_suricata

  - name: Create IP reputation config dir
    file:
      path: /etc/suricata/rules/iplists
      state: directory
      owner: root
      group: root
      mode: 0755
    when: with_suricata

  - name: Set suricata overrides include in main config
    lineinfile:
      dest: /etc/suricata/suricata.yaml
      line: "include: rocknsm-overrides.yaml"
      state: present
    when: with_suricata

  - name: Enable and start suricata
    service: name="suricata" enabled=yes state=started
    when: with_suricata

  - name: Configure logrotate for suricata logs
    copy:
      src: files/logrotate-suricata.conf
      dest: /etc/logrotate.d/suricata.conf
      mode: 0644
      owner: root
      group: root
    when: with_suricata

    ######################################################
    ################# Setup PulledPork  ##################
    ######################################################
  - name: Create pulledpork directory symlink
    file:
      src: "/opt/pulledpork-{{ pulledpork_release }}"
      dest: "/opt/pulledpork"
      state: link
      force: yes
    when: with_pulledpork

  - name: Set pulledpork executable
    file:
      path: /opt/pulledpork/pulledpork.pl
      mode: 0755
      owner: root
      group: root
    when: with_pulledpork

  - name: Create pulledpork config dir
    file:
      path: /etc/pulledpork
      mode: 0755
      owner: root
      group: root
      state: directory
    when: with_pulledpork

  - name: Configure pulledpork
    template:
      src: templates/pulledpork.conf.j2
      dest: /etc/pulledpork/pulledpork.conf
      owner: root
      group: root
      mode: 0644
    when: with_pulledpork

  - name: Check stats of rules files
    stat:
      path: "{{ pulledpork_engine_basepath }}/rules/pulledpork.rules"
    register: rules_file
    when: with_pulledpork

  - name: Create initial pulledpork rules-related files
    file:
      path: "{{ pulledpork_engine_basepath }}/rules/pulledpork.rules"
      owner: root
      group: root
      mode: 0644
      state: touch
    when: not rules_file.stat.exists and with_pulledpork

  - name: Schedule pulledpork to run daily
    cron:
      name: "pulledpork update"
      cron_file: rocknsm_pulledpork
      user: root
      hour: "12"
      minute: "0"
      job: /opt/pulledpork/pulledpork.pl
        -c /etc/pulledpork/pulledpork.conf
        -l > /var/log/pulledpork.log 2>&1;
        {{ "/usr/bin/systemctl kill -s USR2 suricata;" if with_suricata else None }}
        {{ "/usr/bin/systemctl restart snortd;" if with_snort else None }}
    when: with_pulledpork

    #######################################################
    ######################## FSF ##########################
    #######################################################

  - name: Create FSF data dir
    file:
      path: "{{ fsf_data_dir }}"
      mode: 0755
      owner: "{{ fsf_user }}"
      group: "{{ fsf_group }}"
      state: directory
    when: with_fsfserver

  - name: Configure logrotate for FSF logs
    copy:
      src: files/logrotate-fsf.conf
      dest: /etc/logrotate.d/fsf.conf
      mode: 0644
      owner: root
      group: root
    when: with_fsfserver

  - name: Enable and start FSF
    service: name=fsf state=started enabled=yes
    when: with_fsfserver and enable_fsfserver

    ######################################################
    ################### Setup Zookeeper ##################
    ######################################################
  - name: Install zookeeper service file
    copy:
      src: files/zookeeper.service
      dest: /etc/systemd/system/zookeeper.service
      mode: 0644
      owner: root
      group: root
    when: with_zookeeper

  - name: Enable and start zookeeper
    service: name=zookeeper state=started enabled=yes
    when: with_zookeeper

    ######################################################
    ##################### Setup Kafka ####################
    ######################################################

  - name: Create Kafka data dir
    file:
      path: "{{ kafka_data_dir }}"
      mode: 0755
      owner: "{{ kafka_user }}"
      group: "{{ kafka_group }}"
      state: directory
    when: with_kafka

  - name: Set kafka retention
    lineinfile:
      dest: "{{ kafka_config_path }}"
      regexp: "log.retention.hours="
      line:  "log.retention.hours=1"
      state: present
    when: with_kafka

  - name: Set kafka data dir
    lineinfile:
      dest: "{{ kafka_config_path }}"
      regexp: "log.dirs="
      line: "log.dirs={{ kafka_data_dir }}"
    when: with_kafka

  - name: Enable and start kafka
    service: name=kafka state=started enabled=yes
    when: with_kafka

    ######################################################
    ################# Setup Elasticsearch ################
    ######################################################
  - name: Create Elasticsearch directory
    file:
      path: "{{ es_data_dir }}"
      mode: 0755
      owner: "{{ es_user }}"
      group: "{{ es_group }}"
      state: directory
    when: with_elasticsearch

  - name: Setup elasticsearch config
    template:
      src: templates/elasticsearch.yml.j2
      dest: /etc/elasticsearch/elasticsearch.yml
      owner: root
      group: "{{ es_group }}"
      mode: 0640
    when: with_elasticsearch

  - name: Create elasticsearch systemd override dir
    file:
      path: /etc/systemd/system/elasticsearch.service.d
      owner: root
      group: root
      mode: 0755
      state: directory
    when: with_elasticsearch

  - name: Enable elasticsearch memlock in service override
    copy:
      content: "{{ es_memlock_override }}"
      dest: /etc/systemd/system/elasticsearch.service.d/override.conf
      mode: 0644
      owner: root
      group: root
    when: with_elasticsearch

  - name: Setup elasticsearch data dir in sysconfig
    lineinfile:
      dest: /etc/sysconfig/elasticsearch
      regexp: "DATA_DIR="
      line: "DATA_DIR={{ es_data_dir }}"
    when: with_elasticsearch

  - name: Setup elasticsearch jvm options
    template:
      src: templates/es-jvm.options.j2
      dest: /etc/elasticsearch/jvm.options
      mode: 0640
      owner: root
      group: "{{ es_group }}"
    when: with_elasticsearch

  - name: Install ROCK Elasticsearch cleanup script
    copy:
      src: files/es_cleanup.sh
      dest: /usr/local/bin/es_cleanup.sh
      mode: 0755
      owner: root
      group: root
    when: with_elasticsearch

  - name: Set elasticsearch cleanup cron job
    cron:
      name: "ES maintenance"
      cron_file: rocknsm_es_maintenance
      hour: 0
      minute: 1
      user: root
      job: /usr/local/bin/es_cleanup.sh > /dev/null 2>&1
    when: with_elasticsearch

  - name: Enable and start Elasticsearch
    service: name=elasticsearch state=started enabled=yes
    when: with_elasticsearch

  - name: Wait for Elasticsearch to become ready
    wait_for: host=localhost port=9200

  - name: Check for Bro mapping templates
    uri:
      method: "GET"
      url: http://localhost:9200/_template/bro_index
    failed_when: False
    register: bro_mapping

  - name: Load Bro Elasticsearch mapping templates
    uri:
      method: PUT
      url: http://localhost:9200/_template/bro_index
      body: "{{ lookup('file', 'files/es-bro-mappings.json')}}"
      body_format: json
    when: bro_mapping.status == 404

    ######################################################
    ################### Setup Logstash ###################
    ######################################################

  - name: Install Bro-Kafka configuration for Logstash
    copy:
      src: files/logstash-kafka-bro.conf
      dest: /etc/logstash/conf.d/kafka-bro.conf
      mode: 0640
      owner: "{{ logstash_user }}"
      group: "{{ logstash_group }}"
    when: with_logstash and with_bro and with_kafka

  - name: Configure Logstash to pickup suricata events
    copy:
      src: "files/logstash-suricata-es.conf"
      dest: "/etc/logstash/conf.d/suricata-es.conf"
      mode: 0644
      owner: root
      group: root
    when: with_logstash and with_suricata

  - name: Configure Logstash to pickup the FSF scan.log
    copy:
      src: "files/logstash-fsf-es.conf"
      dest: "/etc/logstash/conf.d/fsf-es.conf"
      mode: 0644
      owner: root
      group: root
    when: with_logstash and with_fsfserver

  - name: Enable and start Logstash
    service: name=logstash state=started enabled=yes
    when: with_logstash

    ######################################################
    ################### Setup Kibana #####################
    ######################################################

  - name: Enable and start Kibana
    service: name=kibana state=started enabled=yes
    when: "{{ with_kibana }}"

  - name: Download ROCK Dashboards
    get_url:
      url: "{{ rock_dashboards_url }}"
      dest: "{{ rock_cache_dir }}/{{ rock_dashboards_filename }}"
      mode: 0644
    when: "{{ with_kibana and rock_online_install }}"

  - name: Extract ROCK Dashboards
    unarchive:
      src: "{{ rock_cache_dir }}/{{ rock_dashboards_filename }}"
      dest: /opt/rocknsm
      owner: root
      group: root
      creates: "/opt/rocknsm/rock-dashboards-{{ rock_dashboards_branch }}"
      remote_src: yes
    when: "{{ with_kibana }}"

  - name: Query Kibana package info
    yum:
      list: kibana
    register: kibana_pkg
    when: "{{ with_kibana }}"

  - name: Store installed kibana pkg info
    set_fact:
      kibana_info: "{{ kibana_pkg.results | selectattr('repo', 'match', 'installed') | first }}"
    when: "{{ with_kibana }}"

  - name: Check current Kibana config
    uri:
      method: "GET"
      url: "{{ es_url }}/.kibana/config/{{ kibana_info.version }}/_source"
      return_content: true
    register: kibana_cfg
    changed_when: false
    until: kibana_cfg.status == 200
    retries: 10
    delay: 3
    when: "{{ with_kibana }}"

  - name: Store Kibana config dict
    set_fact:
      kibana_config: "{{ kibana_cfg.json }}"
    when: "{{ with_kibana }}"

  - name: Configure Kibana templates
    uri:
      method: PUT
      url: http://localhost:9200/_template/kibana-config
      body: >
        { "order" : 0, "template" : ".kibana",
          "settings" :
            { "index.number_of_replicas" : "0",
              "index.number_of_shards" : "1" },
          "mappings" : { }, "aliases" : { } }
      status_code: 200,201
    when: "{{ with_kibana }}"

  - name: Push Kibana dashboard config
    command: >
      /opt/rocknsm/rock-dashboards-{{ rock_dashboards_branch }}/load.sh
        -url {{ es_url }}
    args:
      chdir: /opt/rocknsm/rock-dashboards-{{ rock_dashboards_branch }}/
    when: "{{ with_kibana and (kibana_config.rock_config is undefined or kibana_config.rock_config != rock_dashboards_version) }}"

  - name: Store default Kibana index to Bro
    set_fact:
      kibana_config: "{{ kibana_config | combine({'defaultIndex': 'bro-*' })}}"
    when: "{{ with_kibana and with_bro }}"

  - name: Store default Kibana index to Suricata
    set_fact:
      kibana_config: "{{ kibana_config | combine({'defaultIndex': 'suricata-*' })}}"
    when: "{{ with_kibana and with_suricata and not with_bro }}"

  - name: Update Kibana config dict w/ rock_config version
    set_fact:
      kibana_config: "{{ kibana_config | combine({'rock_config': rock_dashboards_version }) }}"
    when: "{{ with_kibana }}"

  - name: Push Kibana settings for index and rock_version
    uri:
      method: PUT
      url: "{{ es_url }}/.kibana/config/{{ kibana_info.version }}"
      body: "{{ kibana_config }}"
      body_format: "json"
      status_code: 200,201
    when: "{{ with_kibana }}"

    ######################################################
    ################### Setup nginx ######################
    ######################################################

  - name: Install ROCK nginx configuration
    template:
      src: templates/nginx-rock.conf.j2
      dest: /etc/nginx/conf.d/rock.conf
      mode: 0644
      owner: root
      group: root
    when: with_nginx and with_kibana

  - name: Install nginx base configuration
    copy:
      src: files/nginx.conf
      dest: /etc/nginx/nginx.conf
      mode: 0644
      owner: root
      group: root
    when: with_nginx

  - name: Enable nginx to perform proxy connect
    seboolean: name=httpd_can_network_connect state=yes persistent=yes
    when: with_nginx and with_kibana

  - name: Enable and start nginx
    service: name=nginx state=started enabled=yes
    when: with_nginx

    ######################################################
    ############### Setup ROCKNSM Scripts ################
    ######################################################

  - name: Install rock start script
    copy:
      src: files/rock_start
      dest: /usr/local/bin/rock_start
      mode: 0700
{'fraction_non_alphanumeric': 0.20347910690621174, 'fraction_numerical': 0.009427473873148474, 'mean_word_length': 2.7022730095640295, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 23, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 4, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7271978', 'n_tokens_mistral': 19310, 'n_tokens_neox': 18423, 'n_words': 4502}