Install/Setup Wazuh 2.0, ELK 5.0, and client deployment

Visualize, analyze and search your host IDS alerts. Elastic Stack is the combination of three popular Open Source projects for log management, known as Elasticsearch, Logstash and Kibana(ELK). Together they provide a real-time and user-friendly console for your OSSEC alerts. OSSEC Wazuh integration with Elastic Stack comes with out-of-the-box dashboards for PCI DSS compliance and CIS benchmarks. You can do forensic and historical analysis of OSSEC alerts and store your data for several years, in a reliable and scalable platform. This post is updating a pervious post of mine using Wazuh 1.0 and version 2.0 of the ELK stack. This post will contain a general setup and configuration for a central logging server.

Install/Setup Wazuh server on CentOS 7 64-bit

Install/Setup NTPd

  1. yum update -y && yum upgrade -y
  2. yum install ntp ntpdate ntp-doc -y
  3. systemctl enable ntpd
  4. systemctl start ntpd
  5. ntpdate pool.ntp.org || true

Install/Setup Wazuh server

  1. cat > /etc/yum.repos.d/wazuh.repo << 'EOF'
    [wazuh_repo]
    gpgcheck=1
    gpgkey=https://packages.wazuh.com/key/GPG-KEY-WAZUH
    enabled=1
    name=CentOS-$releasever - Wazuh
    baseurl=https://packages.wazuh.com/yum/el/$releasever/$basearch
    protect=1
    EOF
  2. yum install wazuh-manager -y

Setup/Configure Syslog input via udp

  1. sed -i '/<\/remote>/a\   \<remote>\n\     \<connection>syslog</connection>\n\     \<allowed-ips><NETWORK IP ADDRESS>/24</allowed-ips>\n\   \</remote>' /var/ossec/etc/ossec.conf
  2. /var/ossec/bin/ossec-control restart

Install Wazuh API

  1. curl –silent –location https://rpm.nodesource.com/setup_6.x | bash –
  2. yum install nodejs -y
  3. yum install wazuh-api -y

Install/Setup Elasticsearch

  1. yum install java -y
  2. rpm –import https://packages.elastic.co/GPG-KEY-elasticsearch
  3. cat > /etc/yum.repos.d/elastic.repo << EOF
    [elastic-5.x]
    name=Elastic repository for 5.x packages
    baseurl=https://artifacts.elastic.co/packages/5.x/yum
    gpgcheck=1
    gpgkey=https://artifacts.elastic.co/GPG-KEY-elasticsearch
    enabled=1
    autorefresh=1
    type=rpm-md
    EOF
  4. yum install elasticsearch -y
  5. systemctl daemon-reload
  6. systemctl enable elasticsearch.service
  7. systemctl start elasticsearch.service
    1. Wait about 30 seconds for Elasticsearch to fully start
  8. curl https://raw.githubusercontent.com/wazuh/wazuh-kibana-app/master/server/startup/integration_files/template_file.json | curl -XPUT 'http://localhost:9200/_template/wazuh' -H 'Content-Type: application/json' -d @-
    1. Command may fail if Elasticsearch hasn’t fully started and listening on port 9200.

Elasticsearch data rotation

  1. cat >/etc/yum.repos.d/curator.repo << 'EOF'
    [curator-5]
    name=CentOS/RHEL 7 repository for Elasticsearch Curator 5.x packages
    baseurl=http://packages.elastic.co/curator/5/centos/7
    gpgcheck=1
    gpgkey=http://packages.elastic.co/GPG-KEY-elasticsearch
    enabled=1
    EOF
  2. yum install elasticsearch-curator -y
  3. mkdir /etc/curator
  4. cat > /etc/curator/config.yml << 'EOF'
    # Remember, leave a key empty if there is no value. None will be a string,
    # not a Python "NoneType"

    client:
      hosts:
        - 127.0.0.1
      port: 9200
      url_prefix:
      use_ssl: False
      certificate:
      client_cert:
      client_key:
      aws_key:
      aws_secret_key:
      aws_region:
      ssl_no_validate: False
      http_auth:
      timeout: 30
      master_only: False
    
    logging:
      loglevel: INFO
      logfile:
      logformat: default
      blacklist: ['elasticsearch']

    EOF

  5. cat > /etc/curator/delete_wazuh.yml << 'EOF'
    # Remember, leave a key empty if there is no value.  None will be a string,
    # not a Python "NoneType"
    #
    # Also remember that all examples have 'disable_action' set to True.  If you
    # want to use this action as a template, be sure to set this to False after
    # copying it.
    actions:
      1:
        action: delete_indices
        description: >-
          Delete indices older than 90 days (based on index name), for logstash-
          prefixed indices. Ignore the error if the filter does not result in an
          actionable list of indices (ignore_empty_list) and exit cleanly.
        options:
          ignore_empty_list: True
          timeout_override:
          continue_if_exception: False
          disable_action: False
        filters:
        - filtertype: pattern
          kind: prefix
          value: wazuh-alerts-
          exclude:
        - filtertype: age
          source: name
          direction: older
          timestring: '%Y.%m.%d'
          unit: days
          unit_count: 90
          exclude:
      2:
        action: delete_indices
        description: >-
          Delete indices older than 90 days (based on index name), for logstash-
          prefixed indices. Ignore the error if the filter does not result in an
          actionable list of indices (ignore_empty_list) and exit cleanly.
        options:
          ignore_empty_list: True
          timeout_override:
          continue_if_exception: False
          disable_action: False
        filters:
        - filtertype: pattern
          kind: prefix
          value: wazuh-monitoring-
          exclude:
        - filtertype: age
          source: name
          direction: older
          timestring: '%Y.%m.%d'
          unit: days
          unit_count: 90
          exclude:

    EOF

  6. echo "@daily /usr/bin/curator --config /etc/curator/config.yml /etc/curator/delete_wazuh.yml" >> /etc/crontab
  7. systemctl enable crond
  8. systemctl start crond

Install/Setup Logstash + OpenSSL

  1. yum install logstash -y
  2. curl -so /etc/logstash/conf.d/01-wazuh.conf https://raw.githubusercontent.com/wazuh/wazuh/2.0/extensions/logstash/01-wazuh.conf
  3. curl -so /etc/logstash/wazuh-elastic5-template.json https://raw.githubusercontent.com/wazuh/wazuh/2.0/extensions/elasticsearch/wazuh-elastic5-template.json
  4. sed -i -e '/## Remote Wazuh Manager - Filebeat input/,+9 s/^/#/' /etc/logstash/conf.d/01-wazuh.conf
    1. Comment out remote Wazuh section
  5. sed -i -e '/## Local Wazuh Manager - JSON file input/,+7 s/#//' /etc/logstash/conf.d/01-wazuh.conf
    1. Uncomment local Wazuh section
  6. openssl req -x509 -batch -nodes -days 3650 -newkey rsa:2048 -keyout /etc/logstash/logstash.key -out /etc/logstash/logstash.cert
  7. cat > /etc/logstash/conf.d/02-beats-input.conf << 'EOF'
    input {
    beats {
    port => 5044
    ssl => true
    ssl_certificate => "/etc/logstash/logstash.cert"
    ssl_key => "/etc/logstash/logstash.key"
    }
    }
    EOF
  8. cat > /etc/logstash/conf.d/30-elasticsearch-output.conf << 'EOF'
    output {
    elasticsearch {
    hosts => ["http://localhost:9200"]
    index => "%{type}-%{[@metadata][beat]}-%{+YYYY.MM.dd}"
    document_type => "%{[@metadata][type]}"
    }
    }
    EOF

    1. These two configs will take in any beats input from Filebeats and create an Elasticsearch index for it.
  9. curl -O "https://geolite.maxmind.com/download/geoip/database/GeoLiteCity.dat.gz"
  10. gzip -d GeoLiteCity.dat.gz && sudo mv GeoLiteCity.dat /etc/logstash/
  11. usermod -a -G ossec logstash
    1. This command is assuming you are running OSSEC/Wazuh and ELK on the same box
  12. systemctl daemon-reload
  13. systemctl enable logstash.service
  14. systemctl start logstash.service

Install/Setup Kibana with Wazuh dashboard

  1. yum install kibana -y
  2. /usr/share/kibana/bin/kibana-plugin install https://packages.wazuh.com/wazuhapp/wazuhapp.zip
    1. This command may take a while to install
  3. systemctl daemon-reload
  4. systemctl enable kibana.service
  5. systemctl start kibana.service

Install/Setup Nginx with OpenSSL

  1. yum -y install epel-release
  2. yum -y install nginx httpd-tools
  3. htpasswd -c /etc/nginx/htpasswdKibana.users kibanaadmin
    1. Enter password for kibana login
  4. cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf.bak
  5. sed -i -e ‘38,87d’ /etc/nginx/nginx.conf
    1. Removes default config settings that we don’t need
  6. mkdir /etc/nginx/ssl
  7. openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/nginx/ssl/nginx.key -out /etc/nginx/ssl/nginx.crt
  8. openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048
  9. cat > /etc/nginx/conf.d/kibana.conf << 'EOF'
    server {
    listen 80 default_server;
    listen [::]:80 default_server;server_name _;
    return 301 https://$host$request_uri;
    }server {
    listen 443 ssl;
    server_name _;root /usr/share/nginx/html;
    index index.html index.htm;ssl_certificate /etc/nginx/ssl/nginx.crt;
    ssl_certificate_key /etc/nginx/ssl/nginx.key;ssl_prefer_server_ciphers on;
    ssl_dhparam /etc/ssl/certs/dhparam.pem;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers HIGH:!aNULL:!MD5;
    ssl_session_timeout 1d;ssl_session_cache shared:SSL:50m;
    ssl_stapling on;
    ssl_stapling_verify on;

    add_header Strict-Transport-Security max-age=15768000;
    auth_basic "Restricted";
    auth_basic_user_file /etc/nginx/htpasswdKibana.users;

    location / {
    proxy_pass http://localhost:5601;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection 'upgrade';
    proxy_set_header Host $host;
    proxy_cache_bypass $http_upgrade;
    }
    }
    EOF

  10. systemctl start nginx
  11. systemctl enable nginx
  12. setsebool -P httpd_can_network_connect 1

Setup Wazuh API

  1. cat > /etc/nginx/conf.d/wazuh-api.conf << 'EOF'
    server {
    listen 55000 ssl;ssl_certificate /etc/nginx/ssl/nginx.crt;
    ssl_certificate_key /etc/nginx/ssl/nginx.key;ssl_prefer_server_ciphers on;
    ssl_dhparam /etc/ssl/certs/dhparam.pem;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers HIGH:!aNULL:!MD5;ssl_session_timeout 1d;
    ssl_session_cache shared:SSL:50m;location / {
    proxy_pass http://127.0.0.1:5000;
    }
    }
    EOF
  2. sed -i 's/config.host = "0.0.0.0";/config.host = "127.0.0.1";/g' /var/ossec/api/configuration/config.js
  3. sed -i 's/config.port = "55000";/config.port = "5000";/g' /var/ossec/api/configuration/config.js
  4. sed -i 's/config.BehindProxyServer = "no";/config.BehindProxyServer = "yes";/g' /var/ossec/api/configuration/config.js
  5. cd /var/ossec/api/configuration/auth
  6. sudo node htpasswd -c user wazuhadmin
  7. systemctl restart wazuh-api
  8. Browse to “http://<ELK/OSSEC server IP addr> and login into Kibana
    1. May need to apply firewall rules below
  9. Select “Wazuh” on the left
  10. Select “Add new API”
    1. Enter “wazuhadmin” for username
    2. Enter password from above
    3. Enter “http://127.0.0.1” for URL
    4. Enter “5000” for port
    5. Select “Save”

Install/Setup FirewallD

  1. yum install firewalld -y
  2. systemctl start firewalld
  3. systemctl enable firewalld
  4. firewall-cmd –zone=public –permanent –add-service=http
  5. firewall-cmd –zone=public –permanent –add-service=https
  6. firewall-cmd –zone=public –permanent –add-port=55000/tcp
  7. firewall-cmd –zone=public –permanent –add-port=1514/udp
  8. firewall-cmd –zone=public –permanent –add-port=514/tcp
  9. firewall-cmd –zone=public –permanent –add-port=514/udp
  10. firewall-cmd –zone=public –permanent –add-service=ssh
  11. firewall-cmd –reload

Windows, and Linux Wazuh agent registration

When our agents are installed, it is necessary for them to communicate with the manager. The communication between an agent and the manager is performed via the OSSEC message protocol, which encrypts messages using a pre-shared key. The process of provisioning an agent authentication key on the manager and distributing it to an agent is called registration.

Generate Wazuh agent authentication key

  1. Login into Wazuh server
  2. /var/ossec/bin/manage_agents
    1. Enter “A” to add an agent
    2. Enter “<agent name preferable hostname>” for agent name
    3. Enter “<IP addr of agent>” for IP address
    4. Except default for agent ID
    5. Enter “y” to confirm
    6. Enter “E” to extract key for agent
    7. Enter “<ID of agent for key>”

Linux deployment

Manual deployment on Ubuntu 16.04 64-bit

Install Wazuh agent on Ubuntu

  1. sudo apt-get install curl apt-transport-https lsb-release -y
  2. curl -s https://packages.wazuh.com/key/GPG-KEY-WAZUH | sudo apt-key add –
  3. CODENAME=$(lsb_release -cs)
  4. echo "deb https://packages.wazuh.com/apt $CODENAME main" \| sudo tee /etc/apt/sources.list.d/wazuh.list
  5. sudo apt-get update -y && sudo apt-get install wazuh-agent -y

Add key to Ubuntu agent

  1. sudo su
  2.  /var/ossec/bin/manage_agents
    1. Enter “I” to import key
    2. Paste key from above
    3. Enter “Y” to confirm adding key
  3. vim /var/ossec/etc/ossec.conf
    1. Replace “MANAGER_IP” between <server-ip></server-ip> with Wazuh IP
    2. save, exit
  4. /var/ossec/bin/ossec-control start

Confirm agent has been registered

  1. Browse to “http://<ELK/Wazuh server IP addr>”and login into Kibana
  2. Select “Wazuh” on the left
  3. Select the “agents” tab at the top
    1. As you can see our “ubuntu” agent was added
    2. localhost.localdomain agent is the actual Wazuh manager running in hybrid mode. Hybrid mode is when the Wazuh manager and wazuh agent run on the same box.

API deployment on Centos 7 Server 64-bit

  1. cat > /etc/yum.repos.d/wazuh.repo <<'EOF'
    [wazuh_repo]
    gpgcheck=1
    gpgkey=https://packages.wazuh.com/key/GPG-KEY-WAZUH
    enabled=1
    name=CentOS-$releasever - Wazuh
    baseurl=https://packages.wazuh.com/yum/el/$releasever/$basearch
    protect=1
    EOF
  2. yum install wazuh-agent -y
  3. wget https://raw.githubusercontent.com/wazuh/wazuh-api/2.0/examples/api-register-agent.sh
  4. sed -i ‘s/API_IP=”10.0.0.1″/API_IP=”<IP addr of Wazuh>”/g’ api-register-agent.sh
  5. sed -i ‘s/PROTOCOL=”http”/PROTOCOL=”https”/g’ api-register-agent.sh
  6. sed -i ‘s/USER=”foo”/USER=”wazuhadmin”/g’ api-register-agent.sh
  7. sed -i ‘s/PASSWORD=”bar”/PASSWORD=”<password of Wazuh api>”/g’ api-register-agent.sh
  8. chmod +x api-register-agent.sh
  9. ./api-register-agent.sh
  10. sed -i ‘s#<server-ip>MANAGER_IP</server-ip>#<server-ip><IP addr of Wazuh></server-ip>#g’ /var/ossec/etc/ossec.conf
  11. /var/ossec/bin/ossec-control restart

Windows 10 deployment

Wazuh manual deployment

  1. Open Powershell as Administrator
  2. Invoke-WebRequest https://packages.wazuh.com/windows/wazuh-winagent-v2.0.1-1.exe -OutFile wazuh_agent.exe
  3. .\wazuh_agent.exe /S
  4. & ‘C:\Program Files (x86)\ossec-agent\win32ui.exe’
    1. Enter “<IP addr of Wazuh>” for Manager IP
    2. Enter “<Generated agent key>” for Authentication key
    3. Enter “Save”
  5. Select “Manage” then “Start”

Wazuh API deployment

  1. Open Powershell prompt as Admin
  2. cd C:\Users\$env:username
  3. Invoke-WebRequest https://packages.wazuh.com/windows/wazuh-winagent-v2.0.1-1.exe -OutFile wazuh_agent.exe
  4. .\wazuh_agent.exe /S
  5. Invoke-WebRequest https://raw.githubusercontent.com/wazuh/wazuh-api/master/examples/api-register-agent.ps1 -OutFile wazuh-api-register-agent.ps1
  6. Set-ExecutionPolicy RemoteSigned
    1. Need administration privileges for this
  7. (Get-Content wazuh-api-register-agent.ps1).replace('$username = "foo"', '$username = "wazuhadmin"') | Set-Content wazuh-api-register-agent.ps1
  8. (Get-Content wazuh-api-register-agent.ps1).replace('$password = "bar"', '$password = ""') | Set-Content wazuh-api-register-agent.ps1
  9. (Get-Content wazuh-api-register-agent.ps1).replace('$base_url = "http://:55000"
    ', '$base_url = "https://:55000"') | Set-Content wazuh-api-register-agent.ps1
  10. (Get-Content wazuh-api-register-agent.ps1).replace('', '') | Set-Content wazuh-api-register-agent.ps1
  11. REG ADD “HKCU\SOFTWARE\Microsoft\Internet Explorer\PhishingFilter” /v EnabledV9 /t REG_DWORD /d 0 /f
    1. This will DISABLE SmartScreen filter on Internet Explorer, what I’m lazy
  12. .\wazuh-api-register-agent.ps1

Setup/Configure Active Response

Linux blocking brute force attempts

  • In this example, a command with the name “firewall-drop” is configured to use the “firewall-drop.sh” script using the data element “scrip”. The Active response is configured to initiate the “firewall-block” command on all systems when a rule in either the “authentificaiton_failed” or “authentification_failures” rule group fires. This is a Stateful response with a timeout of 700 seconds. The repeated offenders parameter increases the timeout period for each subsequent offence by a specific IP address.
  1. cp /var/ossec/etc/ossec.conf /var/ossec/etc/ossec.conf.bak
  2. vim /var/ossec/etc/ossec.conf

    <active-response>
    <!--- Linux block srcip on ALL machines for multiple failed authentication attempts--->
    <command>firewall-block</command>
    <location>all</location>
    <rules_group>authentication_failed,authentication_failures</rules_group>
    <timeout>700</timeout>
    <repeated_offenders>30,60,120</repeated_offenders>
    </active-response>
  3. /var/ossec/bin/ossec-control restart
    1. This should push out the new config to all agents

Windows blocking anything above a threat level

  • In this example, a command with the name “win_rout-null” is configured to use the “route-null.cmd” script using the data element “srcip”. The Active response is configured to initiate the “win_rout-null” command on the local host when the rule has a higher alert level than 7. This is a Stateful response with a timeout set at 900 seconds.
  1. vim /var/ossec/etc/ossec.conf

    <active-response>
    <!--- Windows block srcip on local machine when rule level is greater than 8-->
    <command>win_route‐null</command>
    <location>local</location>
    <level>8</level>
    <timeout>900</timeout>
    </active-response>
  2. /var/ossec/bin/ossec-control restart

Install/Setup Alerting via Slack

Setup/Configure Slack notifications

  1. /var/ossec/bin/ossec-control enable integrator
  2. /var/ossec/bin/ossec-control restart
  3. Add to/var/ossec/etc/ossec.conf:
    slack
    https://

Resources/Sources

2 thoughts on “Install/Setup Wazuh 2.0, ELK 5.0, and client deployment

  1. Amine says:

    when configuring Syslog in ossec.conf, i get this error Error reading XML file ‘/etc/ossec.conf’: (line 0).
    Thank you

Leave a Reply

Your email address will not be published. Required fields are marked *