From 81ee333b07a55ac3f5e1e83fb67e153e0a6aba9c Mon Sep 17 00:00:00 2001 From: Josh Brower Date: Tue, 24 Jan 2023 13:36:30 -0500 Subject: [PATCH 01/20] Initial support - Elastic Fleet Node --- pillar/top.sls | 6 +++ salt/allowed_states.map.jinja | 9 +++++ salt/elastic-fleet/init.sls | 15 +------- salt/firewall/assigned_hostgroups.map.yaml | 45 ++++++++++++++++++++++ salt/firewall/hostgroups/fleet | 0 salt/top.sls | 10 +++++ setup/so-setup | 14 ++++++- setup/so-whiptail | 2 +- 8 files changed, 86 insertions(+), 15 deletions(-) create mode 100644 salt/firewall/hostgroups/fleet diff --git a/pillar/top.sls b/pillar/top.sls index 074a0a9d4..7c34bbe85 100644 --- a/pillar/top.sls +++ b/pillar/top.sls @@ -184,6 +184,12 @@ base: - minions.{{ grains.id }} - minions.adv_{{ grains.id }} + '*_fleet': + - backup.soc_backup + - backup.adv_backup + - minions.{{ grains.id }} + - minions.adv_{{ grains.id }} + '*_workstation': - minions.{{ grains.id }} - minions.adv_{{ grains.id }} diff --git a/salt/allowed_states.map.jinja b/salt/allowed_states.map.jinja index 2f6cc60a0..a91796a4a 100644 --- a/salt/allowed_states.map.jinja +++ b/salt/allowed_states.map.jinja @@ -197,6 +197,15 @@ 'tcpreplay', 'docker_clean' ], + 'so-fleet': [ + 'ssl', + 'telegraf', + 'firewall', + 'healthcheck', + 'schedule', + 'elastic-fleet', + 'docker_clean' + ], 'so-receiver': [ 'ssl', 'telegraf', diff --git a/salt/elastic-fleet/init.sls b/salt/elastic-fleet/init.sls index 1460fda38..4062cff46 100644 --- a/salt/elastic-fleet/init.sls +++ b/salt/elastic-fleet/init.sls @@ -1,15 +1,12 @@ # Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one # or more contributor license agreements. Licensed under the Elastic License 2.0; you may not use # this file except in compliance with the Elastic License 2.0. -{% from 'allowed_states.map.jinja' import allowed_states %} -{% if sls in allowed_states %} {% from 'vars/globals.map.jinja' import GLOBALS %} {% from 'docker/docker.map.jinja' import DOCKER %} # These values are generated during node install and stored in minion pillar -{% set SERVICETOKEN = salt['pillar.get']('elasticfleet:server:es_token','') %} +{% set SERVICETOKEN = salt['pillar.get']('elasticfleet:server:es_token','AAEAAWVsYXN0aWMvZmxlZXQtc2VydmVyL3Rva2VuLTE2NzQzMzE3MTE4MDE6MGRHZDBnd2xRZDJBX0hLVjd2TnJBdw') %} {% set FLEETSERVERPOLICY = salt['pillar.get']('elasticfleet:server:server_policy','so-manager') %} -{% set FLEETURL = salt['pillar.get']('elasticfleet:server:url') %} # Add EA Group elasticsagentgroup: @@ -62,7 +59,7 @@ so-elastic-fleet: - /opt/so/conf/elastic-fleet/state:/usr/share/elastic-agent/state:rw - environment: - FLEET_SERVER_ENABLE=true - - FLEET_URL=https://{{ FLEETURL }}:8220 + - FLEET_URL=https://{{ GLOBALS.node_ip }}:8220 - FLEET_SERVER_ELASTICSEARCH_HOST=https://{{ GLOBALS.manager_ip }}:9200 - FLEET_SERVER_SERVICE_TOKEN={{ SERVICETOKEN }} - FLEET_SERVER_POLICY_ID={{ FLEETSERVERPOLICY }} @@ -76,11 +73,3 @@ append_so-elastic-fleet_so-status.conf: file.append: - name: /opt/so/conf/so-status/so-status.conf - text: so-elastic-fleet - -{% else %} - -{{sls}}_state_not_allowed: - test.fail_without_changes: - - name: {{sls}}_state_not_allowed - -{% endif %} diff --git a/salt/firewall/assigned_hostgroups.map.yaml b/salt/firewall/assigned_hostgroups.map.yaml index e91859743..4c300a496 100644 --- a/salt/firewall/assigned_hostgroups.map.yaml +++ b/salt/firewall/assigned_hostgroups.map.yaml @@ -65,6 +65,41 @@ role: localhost: portgroups: - {{ portgroups.all }} + fleet: + chain: + DOCKER-USER: + hostgroups: + sensors: + portgroups: + - {{ portgroups.elastic_agent_control }} + - {{ portgroups.elastic_agent_data }} + elastic_agent_endpoint: + portgroups: + - {{ portgroups.elastic_agent_control }} + - {{ portgroups.elastic_agent_data }} + INPUT: + hostgroups: + anywhere: + portgroups: + - {{ portgroups.ssh }} + dockernet: + portgroups: + - {{ portgroups.all }} + localhost: + portgroups: + - {{ portgroups.all }} + standalone: + portgroups: + - {{ portgroups.salt_manager }} + sensors: + portgroups: + - {{ portgroups.salt_manager }} + searchnodes: + portgroups: + - {{ portgroups.salt_manager }} + heavynodes: + portgroups: + - {{ portgroups.salt_manager }} manager: chain: DOCKER-USER: @@ -85,6 +120,8 @@ role: portgroups: - {{ portgroups.beats_5044 }} - {{ portgroups.beats_5644 }} + - {{ portgroups.elastic_agent_control }} + - {{ portgroups.elastic_agent_data }} searchnodes: portgroups: - {{ portgroups.redis }} @@ -110,6 +147,10 @@ role: elasticsearch_rest: portgroups: - {{ portgroups.elasticsearch_rest }} + elastic_agent_endpoint: + portgroups: + - {{ portgroups.elastic_agent_control }} + - {{ portgroups.elastic_agent_data }} endgame: portgroups: - {{ portgroups.endgame }} @@ -144,6 +185,8 @@ role: portgroups: - {{ portgroups.beats_5044 }} - {{ portgroups.beats_5644 }} + - {{ portgroups.elastic_agent_control }} + - {{ portgroups.elastic_agent_data }} searchnodes: portgroups: - {{ portgroups.redis }} @@ -220,6 +263,8 @@ role: - {{ portgroups.yum }} - {{ portgroups.beats_5044 }} - {{ portgroups.beats_5644 }} + - {{ portgroups.elastic_agent_control }} + - {{ portgroups.elastic_agent_data }} searchnodes: portgroups: - {{ portgroups.docker_registry }} diff --git a/salt/firewall/hostgroups/fleet b/salt/firewall/hostgroups/fleet new file mode 100644 index 000000000..e69de29bb diff --git a/salt/top.sls b/salt/top.sls index e29d3b081..54b1fefd9 100644 --- a/salt/top.sls +++ b/salt/top.sls @@ -376,6 +376,16 @@ base: {%- endif %} - idh + '*_fleet and G@saltversion:{{saltversion}}': + - match: compound + - ssl + - sensoroni + - telegraf + - firewall + - elastic-fleet + - schedule + - docker_clean + 'J@workstation:gui:enabled:^[Tt][Rr][Uu][Ee]$ and ( G@saltversion:{{saltversion}} and G@os:CentOS )': - match: compound - workstation diff --git a/setup/so-setup b/setup/so-setup index 2b0abedc8..1583e4b66 100755 --- a/setup/so-setup +++ b/setup/so-setup @@ -408,7 +408,19 @@ if ! [[ -f $install_opt_file ]]; then whiptail_sensor_nics set_minion_info whiptail_end_settings - + + elif [[ $is_fleet ]]; then + check_requirements "fleet" + networking_needful + check_network_manager_conf + set_network_dev_status_list + collect_mngr_hostname + add_mngr_ip_to_hosts + check_manager_connection + detect_cloud + set_minion_info + whiptail_end_settings + elif [[ $is_searchnode ]]; then check_requirements "elasticsearch" networking_needful diff --git a/setup/so-whiptail b/setup/so-whiptail index a03c85645..5cc1d0c6f 100755 --- a/setup/so-whiptail +++ b/setup/so-whiptail @@ -548,7 +548,7 @@ whiptail_install_type_dist_existing() { install_type=$(whiptail --title "$whiptail_title" --radiolist "$node_msg" 19 58 6 \ "SENSOR" "Create a forward only sensor " ON \ "SEARCHNODE" "Add a search node with parsing " OFF \ - "FLEET" "Dedicated Fleet Osquery Node " OFF \ + "FLEET" "Dedicated Elastic Fleet Node " OFF \ "HEAVYNODE" "Sensor + Search Node " OFF \ "IDH" "Intrusion Detection Honeypot Node " OFF \ "RECEIVER" "Receiver Node " OFF \ From 29aa6dceed924f4413e1988ac687d5a405a84f07 Mon Sep 17 00:00:00 2001 From: Josh Brower Date: Fri, 27 Jan 2023 07:49:21 -0500 Subject: [PATCH 02/20] Add logstash --- pillar/logstash/fleet.sls | 6 ++++++ pillar/top.sls | 2 ++ salt/allowed_states.map.jinja | 1 + salt/common/tools/sbin/so-minion | 23 ++++++++++++++++++++++ salt/firewall/assigned_hostgroups.map.yaml | 3 +++ salt/logstash/init.sls | 2 +- salt/ssl/init.sls | 2 +- salt/top.sls | 1 + salt/vars/fleet.map.jinja | 1 + 9 files changed, 39 insertions(+), 2 deletions(-) create mode 100644 pillar/logstash/fleet.sls create mode 100644 salt/vars/fleet.map.jinja diff --git a/pillar/logstash/fleet.sls b/pillar/logstash/fleet.sls new file mode 100644 index 000000000..15641f935 --- /dev/null +++ b/pillar/logstash/fleet.sls @@ -0,0 +1,6 @@ +logstash: + pipelines: + fleet: + config: + - so/0012_input_elastic_agent.conf + - so/9805_output_elastic_agent.conf.jinja \ No newline at end of file diff --git a/pillar/top.sls b/pillar/top.sls index 7c34bbe85..e0cac069f 100644 --- a/pillar/top.sls +++ b/pillar/top.sls @@ -185,6 +185,8 @@ base: - minions.adv_{{ grains.id }} '*_fleet': + - soc_global + - adv_global - backup.soc_backup - backup.adv_backup - minions.{{ grains.id }} diff --git a/salt/allowed_states.map.jinja b/salt/allowed_states.map.jinja index a91796a4a..c502c7b3e 100644 --- a/salt/allowed_states.map.jinja +++ b/salt/allowed_states.map.jinja @@ -201,6 +201,7 @@ 'ssl', 'telegraf', 'firewall', + 'logstash', 'healthcheck', 'schedule', 'elastic-fleet', diff --git a/salt/common/tools/sbin/so-minion b/salt/common/tools/sbin/so-minion index bde47991f..f0b0c4ffe 100755 --- a/salt/common/tools/sbin/so-minion +++ b/salt/common/tools/sbin/so-minion @@ -119,6 +119,25 @@ function add_elastic_to_minion() { " " >> $PILLARFILE } +# Add Elastic Fleet Server settings to the minion file +function add_fleet_to_minion() { + + # Create ES Token for Fleet server (Curl to Kibana API) + # TODO: Add error handling + ESTOKEN=$(curl -K /opt/so/conf/elasticsearch/curl.config -L -X POST "localhost:5601/api/fleet/service_tokens" -H 'kbn-xsrf: true' -H 'Content-Type: application/json' | jq -r .value) + + # Create Logstash Certs + + + # Write out settings to minion file + printf '%s\n'\ + "logstash_settings:"\ + " lsheap: '500m'"\ + "fleet-server:"\ + " ES-Token: '$ESTOKEN'"\ + " " >> $PILLARFILE +} + # Analyst Workstation function add_analyst_to_minion() { printf '%s\n'\ @@ -170,6 +189,10 @@ function createEVAL() { add_sensor_to_minion } +function createFLEET() { + add_fleet_to_minion +} + function createIDHNODE() { echo "Nothing custom needed for IDH nodes" } diff --git a/salt/firewall/assigned_hostgroups.map.yaml b/salt/firewall/assigned_hostgroups.map.yaml index 4c300a496..9014f7a3b 100644 --- a/salt/firewall/assigned_hostgroups.map.yaml +++ b/salt/firewall/assigned_hostgroups.map.yaml @@ -255,6 +255,9 @@ role: - {{ portgroups.elastic_agent_data }} - {{ portgroups.endgame }} - {{ portgroups.strelka_frontend }} + fleet: + portgroups: + - {{ portgroups.elasticsearch_rest }} sensors: portgroups: - {{ portgroups.docker_registry }} diff --git a/salt/logstash/init.sls b/salt/logstash/init.sls index 05b184239..fee8b5496 100644 --- a/salt/logstash/init.sls +++ b/salt/logstash/init.sls @@ -22,7 +22,7 @@ include: - ssl - {% if GLOBALS.role not in ['so-receiver'] %} + {% if GLOBALS.role not in ['so-receiver','so-fleet'] %} - elasticsearch {% endif %} diff --git a/salt/ssl/init.sls b/salt/ssl/init.sls index 855a4a3ea..36f622b8d 100644 --- a/salt/ssl/init.sls +++ b/salt/ssl/init.sls @@ -152,7 +152,7 @@ rediskeyperms: - group: 939 {% endif %} -{% if grains['role'] in ['so-manager', 'so-eval', 'so-managersearch', 'so-standalone', 'so-import', 'so-heavynode'] %} +{% if grains['role'] in ['so-manager', 'so-eval', 'so-managersearch', 'so-standalone', 'so-import', 'so-heavynode', 'so-fleet'] %} etc_elasticfleet_key: x509.private_key_managed: - name: /etc/pki/elasticfleet.key diff --git a/salt/top.sls b/salt/top.sls index 54b1fefd9..09f1435ad 100644 --- a/salt/top.sls +++ b/salt/top.sls @@ -382,6 +382,7 @@ base: - sensoroni - telegraf - firewall + - logstash - elastic-fleet - schedule - docker_clean diff --git a/salt/vars/fleet.map.jinja b/salt/vars/fleet.map.jinja new file mode 100644 index 000000000..964f69663 --- /dev/null +++ b/salt/vars/fleet.map.jinja @@ -0,0 +1 @@ +{% set ROLE_GLOBALS = {} %} From 17af095e145df21fa42311b5c1fe89385dcf42d4 Mon Sep 17 00:00:00 2001 From: Josh Brower Date: Fri, 27 Jan 2023 11:28:54 -0500 Subject: [PATCH 03/20] Fix firewall --- salt/elastic-fleet/init.sls | 2 +- salt/firewall/map.jinja | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/salt/elastic-fleet/init.sls b/salt/elastic-fleet/init.sls index 4062cff46..957c2f50d 100644 --- a/salt/elastic-fleet/init.sls +++ b/salt/elastic-fleet/init.sls @@ -5,7 +5,7 @@ {% from 'docker/docker.map.jinja' import DOCKER %} # These values are generated during node install and stored in minion pillar -{% set SERVICETOKEN = salt['pillar.get']('elasticfleet:server:es_token','AAEAAWVsYXN0aWMvZmxlZXQtc2VydmVyL3Rva2VuLTE2NzQzMzE3MTE4MDE6MGRHZDBnd2xRZDJBX0hLVjd2TnJBdw') %} +{% set SERVICETOKEN = salt['pillar.get']('elasticfleet:server:es_token','') %} {% set FLEETSERVERPOLICY = salt['pillar.get']('elasticfleet:server:server_policy','so-manager') %} # Add EA Group diff --git a/salt/firewall/map.jinja b/salt/firewall/map.jinja index 1ec3271c4..d9761e291 100644 --- a/salt/firewall/map.jinja +++ b/salt/firewall/map.jinja @@ -19,6 +19,7 @@ 'analyst', 'analyst_workstations', 'eval', + 'fleet', 'heavynodes', 'idh', 'manager', From 18a54b86f491d509877eea80911c29bcec50f4f2 Mon Sep 17 00:00:00 2001 From: Josh Brower Date: Tue, 31 Jan 2023 14:57:39 -0500 Subject: [PATCH 04/20] More fixes --- pillar/logstash/fleet.sls | 2 +- pillar/logstash/init.sls | 1 + pillar/logstash/manager.sls | 6 +++--- pillar/top.sls | 4 ++++ salt/common/tools/sbin/so-minion | 5 +++-- salt/docker/defaults.yaml | 1 + salt/firewall/assigned_hostgroups.map.yaml | 3 +++ salt/firewall/ports/ports.yaml | 3 +++ salt/logstash/init.sls | 4 ++++ salt/logstash/map.jinja | 2 +- .../config/so/0013_input_lumberjack_fleet.conf | 13 +++++++++++++ .../so/9806_output_lumberjack_fleet.conf.jinja | 10 ++++++++++ 12 files changed, 47 insertions(+), 7 deletions(-) create mode 100644 salt/logstash/pipelines/config/so/0013_input_lumberjack_fleet.conf create mode 100644 salt/logstash/pipelines/config/so/9806_output_lumberjack_fleet.conf.jinja diff --git a/pillar/logstash/fleet.sls b/pillar/logstash/fleet.sls index 15641f935..fb70e7f0d 100644 --- a/pillar/logstash/fleet.sls +++ b/pillar/logstash/fleet.sls @@ -3,4 +3,4 @@ logstash: fleet: config: - so/0012_input_elastic_agent.conf - - so/9805_output_elastic_agent.conf.jinja \ No newline at end of file + - so/9806_output_lumberjack_fleet.conf.jinja \ No newline at end of file diff --git a/pillar/logstash/init.sls b/pillar/logstash/init.sls index 7ad31cf9b..b94ae2c44 100644 --- a/pillar/logstash/init.sls +++ b/pillar/logstash/init.sls @@ -4,6 +4,7 @@ logstash: - 0.0.0.0:3765:3765 - 0.0.0.0:5044:5044 - 0.0.0.0:5055:5055 + - 0.0.0.0:5056:5056 - 0.0.0.0:5644:5644 - 0.0.0.0:6050:6050 - 0.0.0.0:6051:6051 diff --git a/pillar/logstash/manager.sls b/pillar/logstash/manager.sls index 41a2197fd..cee8eec02 100644 --- a/pillar/logstash/manager.sls +++ b/pillar/logstash/manager.sls @@ -3,6 +3,6 @@ logstash: manager: config: - so/0011_input_endgame.conf - - so/0012_input_elastic_agent.conf - - so/9999_output_redis.conf.jinja - + - so/0012_input_elastic_agent.conf + - so/0013_input_lumberjack_fleet.conf + - so/9999_output_redis.conf.jinja \ No newline at end of file diff --git a/pillar/top.sls b/pillar/top.sls index 96e0b7a53..1fb8c4e7d 100644 --- a/pillar/top.sls +++ b/pillar/top.sls @@ -204,6 +204,10 @@ base: - adv_global - backup.soc_backup - backup.adv_backup + - logstash + - logstash.fleet + - logstash.soc_logstash + - logstash.adv_logstash - minions.{{ grains.id }} - minions.adv_{{ grains.id }} diff --git a/salt/common/tools/sbin/so-minion b/salt/common/tools/sbin/so-minion index cce5e2a64..1c9aff028 100755 --- a/salt/common/tools/sbin/so-minion +++ b/salt/common/tools/sbin/so-minion @@ -131,8 +131,9 @@ function add_fleet_to_minion() { # Write out settings to minion file printf '%s\n'\ - "fleet-server:"\ - " ES-Token: '$ESTOKEN'"\ + "elasticfleet:"\ + " server:"\ + " es_token: '$ESTOKEN'"\ " " >> $PILLARFILE } diff --git a/salt/docker/defaults.yaml b/salt/docker/defaults.yaml index e2ec07d32..24a9d80a6 100644 --- a/salt/docker/defaults.yaml +++ b/salt/docker/defaults.yaml @@ -48,6 +48,7 @@ docker: - 0.0.0.0:3765:3765 - 0.0.0.0:5044:5044 - 0.0.0.0:5055:5055 + - 0.0.0.0:5056:5056 - 0.0.0.0:5644:5644 - 0.0.0.0:6050:6050 - 0.0.0.0:6051:6051 diff --git a/salt/firewall/assigned_hostgroups.map.yaml b/salt/firewall/assigned_hostgroups.map.yaml index 82f183b3a..8d8d12035 100644 --- a/salt/firewall/assigned_hostgroups.map.yaml +++ b/salt/firewall/assigned_hostgroups.map.yaml @@ -249,6 +249,7 @@ role: - {{ portgroups.yum }} - {{ portgroups.beats_5044 }} - {{ portgroups.beats_5644 }} + - {{ portgroups.beats_5056 }} - {{ portgroups.redis }} - {{ portgroups.elasticsearch_node }} - {{ portgroups.elastic_agent_control }} @@ -258,6 +259,7 @@ role: fleet: portgroups: - {{ portgroups.elasticsearch_rest }} + - {{ portgroups.beats_5056 }} sensors: portgroups: - {{ portgroups.docker_registry }} @@ -266,6 +268,7 @@ role: - {{ portgroups.yum }} - {{ portgroups.beats_5044 }} - {{ portgroups.beats_5644 }} + - {{ portgroups.beats_5056 }} - {{ portgroups.elastic_agent_control }} - {{ portgroups.elastic_agent_data }} searchnodes: diff --git a/salt/firewall/ports/ports.yaml b/salt/firewall/ports/ports.yaml index d26b373cb..3f2407214 100644 --- a/salt/firewall/ports/ports.yaml +++ b/salt/firewall/ports/ports.yaml @@ -17,6 +17,9 @@ firewall: beats_5066: tcp: - 5066 + beats_5056: + tcp: + - 5056 docker_registry: tcp: - 5000 diff --git a/salt/logstash/init.sls b/salt/logstash/init.sls index fee8b5496..7720d3182 100644 --- a/salt/logstash/init.sls +++ b/salt/logstash/init.sls @@ -164,6 +164,10 @@ so-logstash: - /etc/pki/filebeat.crt:/usr/share/logstash/filebeat.crt:ro - /etc/pki/filebeat.p8:/usr/share/logstash/filebeat.key:ro {% endif %} + {% if GLOBALS.role in ['so-fleet'] %} + - /etc/pki/elasticfleet.crt:/usr/share/logstash/filebeat.crt:ro + - /etc/pki/elasticfleet02.p8:/usr/share/logstash/filebeat.key:ro + {% endif %} {% if GLOBALS.role in ['so-manager', 'so-helix', 'so-managersearch', 'so-standalone', 'so-import'] %} - /etc/pki/ca.crt:/usr/share/filebeat/ca.crt:ro {% else %} diff --git a/salt/logstash/map.jinja b/salt/logstash/map.jinja index 035e36d86..a70ab19d6 100644 --- a/salt/logstash/map.jinja +++ b/salt/logstash/map.jinja @@ -1,6 +1,6 @@ {% from 'vars/globals.map.jinja' import GLOBALS %} {% set REDIS_NODES = [] %} -{% if GLOBALS.role in ['so-searchnode', 'so-standalone', 'so-managersearch'] %} +{% if GLOBALS.role in ['so-searchnode', 'so-standalone', 'so-managersearch','so-fleet'] %} {% set node_data = salt['pillar.get']('logstash:nodes') %} {% for node_type, node_details in node_data.items() | sort %} {% if node_type in ['manager', 'managersearch', 'standalone', 'receiver' ] %} diff --git a/salt/logstash/pipelines/config/so/0013_input_lumberjack_fleet.conf b/salt/logstash/pipelines/config/so/0013_input_lumberjack_fleet.conf new file mode 100644 index 000000000..894ecddb2 --- /dev/null +++ b/salt/logstash/pipelines/config/so/0013_input_lumberjack_fleet.conf @@ -0,0 +1,13 @@ +input { + http { + additional_codecs => { "application/json" => "json_lines" } + port => 5056 + tags => [ "elastic-agent" ] + ssl => true + ssl_certificate_authorities => ["/usr/share/filebeat/ca.crt"] + ssl_certificate => "/usr/share/logstash/filebeat.crt" + ssl_key => "/usr/share/logstash/filebeat.key" + ssl_verify_mode => "peer" + ecs_compatibility => v8 + } +} \ No newline at end of file diff --git a/salt/logstash/pipelines/config/so/9806_output_lumberjack_fleet.conf.jinja b/salt/logstash/pipelines/config/so/9806_output_lumberjack_fleet.conf.jinja new file mode 100644 index 000000000..c4bd28fe9 --- /dev/null +++ b/salt/logstash/pipelines/config/so/9806_output_lumberjack_fleet.conf.jinja @@ -0,0 +1,10 @@ +output { + http { + url => 'https://{{ GLOBALS.manager }}:5056' + http_method => post + retry_non_idempotent => true + format => json_batch + http_compression => true + ecs_compatibility => v8 + } +} \ No newline at end of file From b8d8a5fd6b49fd11dc07113c189202dda983c250 Mon Sep 17 00:00:00 2001 From: Josh Brower Date: Tue, 31 Jan 2023 17:02:41 -0500 Subject: [PATCH 05/20] Remove default outputs --- salt/common/tools/sbin/so-elastic-fleet-setup | 2 +- .../pipelines/config/so/9806_output_lumberjack_fleet.conf.jinja | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/salt/common/tools/sbin/so-elastic-fleet-setup b/salt/common/tools/sbin/so-elastic-fleet-setup index c945aeec3..04b922694 100755 --- a/salt/common/tools/sbin/so-elastic-fleet-setup +++ b/salt/common/tools/sbin/so-elastic-fleet-setup @@ -42,7 +42,7 @@ JSON_STRING=$( jq -n \ --arg LOGSTASHCRT "$LOGSTASHCRT" \ --arg LOGSTASHKEY "$LOGSTASHKEY" \ --arg LOGSTASHCA "$LOGSTASHCA" \ - '{"name":"so-manager_logstash","id":"so-manager_logstash","type":"logstash","hosts":["{{ GLOBALS.manager_ip }}:5055"],"is_default":true,"is_default_monitoring":true,"config_yaml":"","ssl":{"certificate": $LOGSTASHCRT,"key": $LOGSTASHKEY,"certificate_authorities":[ $LOGSTASHCA ]}}' + '{"name":"so-manager_logstash","id":"so-manager_logstash","type":"logstash","hosts":["{{ GLOBALS.manager_ip }}:5055"],config_yaml":"","ssl":{"certificate": $LOGSTASHCRT,"key": $LOGSTASHKEY,"certificate_authorities":[ $LOGSTASHCA ]}}' ) # Add SO-Manager Logstash Ouput diff --git a/salt/logstash/pipelines/config/so/9806_output_lumberjack_fleet.conf.jinja b/salt/logstash/pipelines/config/so/9806_output_lumberjack_fleet.conf.jinja index c4bd28fe9..eec2bd74f 100644 --- a/salt/logstash/pipelines/config/so/9806_output_lumberjack_fleet.conf.jinja +++ b/salt/logstash/pipelines/config/so/9806_output_lumberjack_fleet.conf.jinja @@ -1,6 +1,7 @@ output { http { url => 'https://{{ GLOBALS.manager }}:5056' + cacert => ["/usr/share/filebeat/ca.crt"] http_method => post retry_non_idempotent => true format => json_batch From 967a0807ad748bbd6f89f8792d5bdf53671aee80 Mon Sep 17 00:00:00 2001 From: Josh Brower Date: Wed, 1 Feb 2023 09:16:34 -0500 Subject: [PATCH 06/20] Fix typo --- salt/common/tools/sbin/so-elastic-fleet-setup | 2 +- salt/kibana/init.sls | 6 ------ 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/salt/common/tools/sbin/so-elastic-fleet-setup b/salt/common/tools/sbin/so-elastic-fleet-setup index 04b922694..ddb60e817 100755 --- a/salt/common/tools/sbin/so-elastic-fleet-setup +++ b/salt/common/tools/sbin/so-elastic-fleet-setup @@ -42,7 +42,7 @@ JSON_STRING=$( jq -n \ --arg LOGSTASHCRT "$LOGSTASHCRT" \ --arg LOGSTASHKEY "$LOGSTASHKEY" \ --arg LOGSTASHCA "$LOGSTASHCA" \ - '{"name":"so-manager_logstash","id":"so-manager_logstash","type":"logstash","hosts":["{{ GLOBALS.manager_ip }}:5055"],config_yaml":"","ssl":{"certificate": $LOGSTASHCRT,"key": $LOGSTASHKEY,"certificate_authorities":[ $LOGSTASHCA ]}}' + '{"name":"so-manager_logstash","id":"so-manager_logstash","type":"logstash","hosts":["{{ GLOBALS.manager_ip }}:5055"],"config_yaml":"","ssl":{"certificate": $LOGSTASHCRT,"key": $LOGSTASHKEY,"certificate_authorities":[ $LOGSTASHCA ]}}' ) # Add SO-Manager Logstash Ouput diff --git a/salt/kibana/init.sls b/salt/kibana/init.sls index 4ac0af025..c4222b0a3 100644 --- a/salt/kibana/init.sls +++ b/salt/kibana/init.sls @@ -106,12 +106,6 @@ append_so-kibana_so-status.conf: - name: /opt/so/conf/so-status/so-status.conf - text: so-kibana -osquery_hunt_link: - cmd.script: - - source: salt://kibana/files/live_query_fixup.sh - - cwd: /root - - template: jinja - {% else %} {{sls}}_state_not_allowed: From 1c1b079058bfbf3c599552c9b0400d0ac432655f Mon Sep 17 00:00:00 2001 From: Josh Brower Date: Wed, 1 Feb 2023 15:42:05 -0500 Subject: [PATCH 07/20] Change default output --- salt/common/tools/sbin/so-elastic-fleet-setup | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/salt/common/tools/sbin/so-elastic-fleet-setup b/salt/common/tools/sbin/so-elastic-fleet-setup index ddb60e817..c516b43c3 100755 --- a/salt/common/tools/sbin/so-elastic-fleet-setup +++ b/salt/common/tools/sbin/so-elastic-fleet-setup @@ -24,8 +24,7 @@ mkdir -p /opt/so/conf/elastic-fleet/certs cp /etc/ssl/certs/intca.crt /opt/so/conf/elastic-fleet/certs cp /etc/pki/elasticfleet* /opt/so/conf/elastic-fleet/certs -{% if grains.role == 'so-import' %} -# Add SO-Manager Elasticsearch Ouput +# Add Local Elasticsearch Ouput for Fleet Server ESCACRT=$(openssl x509 -in /opt/so/conf/elastic-fleet/certs/intca.crt) JSON_STRING=$( jq -n \ --arg ESCACRT "$ESCACRT" \ @@ -33,7 +32,6 @@ JSON_STRING=$( jq -n \ curl -K /opt/so/conf/elasticsearch/curl.config -L -X POST "localhost:5601/api/fleet/outputs" -H 'kbn-xsrf: true' -H 'Content-Type: application/json' -d "$JSON_STRING" printf "\n\n" -{% else %} # Create Logstash Output payload LOGSTASHCRT=$(openssl x509 -in /opt/so/conf/elastic-fleet/certs/elasticfleet.crt) LOGSTASHKEY=$(openssl rsa -in /opt/so/conf/elastic-fleet/certs/elasticfleet.key) From e4b10aa28c511bc173e90478703da289ae05b80c Mon Sep 17 00:00:00 2001 From: Josh Brower Date: Wed, 1 Feb 2023 15:47:26 -0500 Subject: [PATCH 08/20] Remove endif --- salt/common/tools/sbin/so-elastic-fleet-setup | 1 - 1 file changed, 1 deletion(-) diff --git a/salt/common/tools/sbin/so-elastic-fleet-setup b/salt/common/tools/sbin/so-elastic-fleet-setup index c516b43c3..0525d2499 100755 --- a/salt/common/tools/sbin/so-elastic-fleet-setup +++ b/salt/common/tools/sbin/so-elastic-fleet-setup @@ -46,7 +46,6 @@ JSON_STRING=$( jq -n \ # Add SO-Manager Logstash Ouput curl -K /opt/so/conf/elasticsearch/curl.config -L -X POST "localhost:5601/api/fleet/outputs" -H 'kbn-xsrf: true' -H 'Content-Type: application/json' -d "$JSON_STRING" printf "\n\n" -{%- endif %} # Add Elastic Fleet Integrations From 035451cdb8098b5c7627544caec5af639157a946 Mon Sep 17 00:00:00 2001 From: Josh Brower Date: Mon, 3 Apr 2023 07:30:25 -0400 Subject: [PATCH 09/20] Cleanup conflict leftovers --- salt/common/tools/sbin/so-minion | 5 ----- 1 file changed, 5 deletions(-) diff --git a/salt/common/tools/sbin/so-minion b/salt/common/tools/sbin/so-minion index e37644ac6..0fa642c83 100755 --- a/salt/common/tools/sbin/so-minion +++ b/salt/common/tools/sbin/so-minion @@ -238,11 +238,6 @@ function createFLEET() { add_logstash_to_minion } -function createFLEET() { - add_fleet_to_minion - add_logstash_to_minion -} - function createIDH() { add_idh_to_minion } From c2d4e870c8f0c31528a204a44442ed638e973f33 Mon Sep 17 00:00:00 2001 From: Josh Brower Date: Mon, 3 Apr 2023 16:50:34 -0400 Subject: [PATCH 10/20] Fixup Elastic Fleet --- salt/allowed_states.map.jinja | 2 +- salt/common/tools/sbin/so-elastic-fleet-setup | 7 +++---- salt/elasticfleet/init.sls | 3 --- salt/top.sls | 2 +- 4 files changed, 5 insertions(+), 9 deletions(-) diff --git a/salt/allowed_states.map.jinja b/salt/allowed_states.map.jinja index f0dcdd7b1..9f652e389 100644 --- a/salt/allowed_states.map.jinja +++ b/salt/allowed_states.map.jinja @@ -198,7 +198,7 @@ 'logstash', 'healthcheck', 'schedule', - 'elastic-fleet', + 'elasticfleet', 'docker_clean' ], 'so-receiver': [ diff --git a/salt/common/tools/sbin/so-elastic-fleet-setup b/salt/common/tools/sbin/so-elastic-fleet-setup index 6848aa432..c9c9ecf5c 100755 --- a/salt/common/tools/sbin/so-elastic-fleet-setup +++ b/salt/common/tools/sbin/so-elastic-fleet-setup @@ -24,7 +24,6 @@ mkdir -p /opt/so/conf/elastic-fleet/certs cp /etc/ssl/certs/intca.crt /opt/so/conf/elastic-fleet/certs cp /etc/pki/elasticfleet* /opt/so/conf/elastic-fleet/certs -{% if grains.role in ['so-import', 'so-eval'] %} # Add SO-Manager Elasticsearch Ouput ESCACRT=$(openssl x509 -in /opt/so/conf/elastic-fleet/certs/intca.crt) JSON_STRING=$( jq -n \ @@ -33,7 +32,7 @@ JSON_STRING=$( jq -n \ curl -K /opt/so/conf/elasticsearch/curl.config -L -X POST "localhost:5601/api/fleet/outputs" -H 'kbn-xsrf: true' -H 'Content-Type: application/json' -d "$JSON_STRING" printf "\n\n" -{% else %} +{% if grains.role not in ['so-import', 'so-eval'] %} # Create Logstash Output payload LOGSTASHCRT=$(openssl x509 -in /opt/so/conf/elastic-fleet/certs/elasticfleet.crt) LOGSTASHKEY=$(openssl rsa -in /opt/so/conf/elastic-fleet/certs/elasticfleet.key) @@ -42,13 +41,13 @@ JSON_STRING=$( jq -n \ --arg LOGSTASHCRT "$LOGSTASHCRT" \ --arg LOGSTASHKEY "$LOGSTASHKEY" \ --arg LOGSTASHCA "$LOGSTASHCA" \ - '{"name":"so-manager_logstash","id":"so-manager_logstash","type":"logstash","hosts":["{{ GLOBALS.manager_ip }}:5055"],"config_yaml":"","ssl":{"certificate": $LOGSTASHCRT,"key": $LOGSTASHKEY,"certificate_authorities":[ $LOGSTASHCA ]}}' + '{"name":"so-manager_logstash","is_default":true,"is_default_monitoring":true,"id":"so-manager_logstash","type":"logstash","hosts":["{{ GLOBALS.manager_ip }}:5055"],"config_yaml":"","ssl":{"certificate": $LOGSTASHCRT,"key": $LOGSTASHKEY,"certificate_authorities":[ $LOGSTASHCA ]},"proxy_id":null}' ) -{%- endif %} # Add SO-Manager Logstash Ouput curl -K /opt/so/conf/elasticsearch/curl.config -L -X POST "localhost:5601/api/fleet/outputs" -H 'kbn-xsrf: true' -H 'Content-Type: application/json' -d "$JSON_STRING" printf "\n\n" +{%- endif %} # Add Elastic Fleet Integrations diff --git a/salt/elasticfleet/init.sls b/salt/elasticfleet/init.sls index 4218eca67..0d393761c 100644 --- a/salt/elasticfleet/init.sls +++ b/salt/elasticfleet/init.sls @@ -52,11 +52,8 @@ so-elastic-fleet: - sobridge: - ipv4_address: {{ DOCKER.containers['so-elastic-fleet'].ip }} - extra_hosts: - {% if GLOBALS.is_manager %} - {{ GLOBALS.manager }}:{{ GLOBALS.manager_ip }} - {% else %} - {{ GLOBALS.hostname }}:{{ GLOBALS.node_ip }} - {% endif %} - port_bindings: {% for BINDING in DOCKER.containers['so-elastic-fleet'].port_bindings %} - {{ BINDING }} diff --git a/salt/top.sls b/salt/top.sls index 305fee9dc..8cad2816c 100644 --- a/salt/top.sls +++ b/salt/top.sls @@ -346,7 +346,7 @@ base: - telegraf - firewall - logstash - - elastic-fleet + - elasticfleet - schedule - docker_clean From cda67b28946a6e321a2d151eeeaa6a1bd7f7a175 Mon Sep 17 00:00:00 2001 From: Josh Brower Date: Tue, 4 Apr 2023 16:11:22 -0400 Subject: [PATCH 11/20] Ded Fleet Node - checkpoint --- salt/common/tools/sbin/so-firewall | 2 +- salt/common/tools/sbin/so-firewall-minion | 5 ++++- salt/elasticfleet/init.sls | 22 +++++++++++++++++++--- salt/firewall/assigned_hostgroups.map.yaml | 8 ++++++++ salt/firewall/containers.map.jinja | 6 ++++++ salt/firewall/ports/ports.yaml | 1 - salt/logstash/init.sls | 4 ++-- 7 files changed, 40 insertions(+), 8 deletions(-) diff --git a/salt/common/tools/sbin/so-firewall b/salt/common/tools/sbin/so-firewall index 16dcdf729..32fa84f3c 100755 --- a/salt/common/tools/sbin/so-firewall +++ b/salt/common/tools/sbin/so-firewall @@ -43,7 +43,7 @@ APPLY=${APPLY,,} function rolecall() { THEROLE=$1 - THEROLES="analyst analyst_workstations beats_endpoint beats_endpoint_ssl elastic_agent_endpoint elasticsearch_rest endgame eval heavynodes idh manager managersearch receivers searchnodes sensors standalone strelka_frontend syslog" + THEROLES="analyst analyst_workstations beats_endpoint beats_endpoint_ssl elastic_agent_endpoint elasticsearch_rest endgame eval fleet heavynodes idh manager managersearch receivers searchnodes sensors standalone strelka_frontend syslog" for AROLE in $THEROLES; do if [ "$AROLE" = "$THEROLE" ]; then diff --git a/salt/common/tools/sbin/so-firewall-minion b/salt/common/tools/sbin/so-firewall-minion index 19ea26864..0465f0bbb 100755 --- a/salt/common/tools/sbin/so-firewall-minion +++ b/salt/common/tools/sbin/so-firewall-minion @@ -56,8 +56,11 @@ fi so-firewall --role=sensors --ip="$IP" so-firewall --apply=true --role=searchnodes --ip="$IP" ;; - 'SENSOR' | 'SEARCHNODE' | 'HEAVYNODE' | 'IDH' | 'RECEIVER') + 'FLEET' | 'SENSOR' | 'SEARCHNODE' | 'HEAVYNODE' | 'IDH' | 'RECEIVER') case "$ROLE" in + 'FLEET') + so-firewall --apply=true --role=fleet --ip="$IP" + ;; 'SENSOR') so-firewall --apply=true --role=sensors --ip="$IP" ;; diff --git a/salt/elasticfleet/init.sls b/salt/elasticfleet/init.sls index 0d393761c..5ebcd5d37 100644 --- a/salt/elasticfleet/init.sls +++ b/salt/elasticfleet/init.sls @@ -9,7 +9,7 @@ # These values are generated during node install and stored in minion pillar {% set SERVICETOKEN = salt['pillar.get']('elasticfleet:server:es_token','') %} {% set FLEETSERVERPOLICY = salt['pillar.get']('elasticfleet:server:server_policy','so-manager') %} -{% set FLEETURL = salt['pillar.get']('elasticfleet:server:url') %} +#{% set FLEETURL = salt['pillar.get']('elasticfleet:server:url') %} # Add EA Group elasticsagentgroup: @@ -39,13 +39,29 @@ eastatedir: - group: 939 - makedirs: True +# Pull down the Logstash Cert from the Manager +/opt/so/conf/elastic-fleet/certs/elasticfleet-logstash.p8: + file.managed: + - replace: True + - source: salt://elasticfleet/files/certs/elasticfleet.p8 + - mode: 640 + - user: 931 + - group: 939 + +/opt/so/conf/elastic-fleet/certs/elasticfleet-logstash.crt: + file.managed: + - replace: True + - source: salt://elasticfleet/files/certs/elasticfleet.crt + - mode: 640 + - group: 939 + {% if SERVICETOKEN != '' %} so-elastic-fleet: docker_container.running: - image: {{ GLOBALS.registry_host }}:5000/{{ GLOBALS.image_repo }}/so-elastic-agent:{{ GLOBALS.so_version }} - name: so-elastic-fleet - - hostname: Fleet-{{ GLOBALS.hostname }} + - hostname: FleetServer-{{ GLOBALS.hostname }} - detach: True - user: 947 - networks: @@ -63,7 +79,7 @@ so-elastic-fleet: - /opt/so/conf/elastic-fleet/state:/usr/share/elastic-agent/state:rw - environment: - FLEET_SERVER_ENABLE=true - - FLEET_URL=https://{{ FLEETURL }}:8220 + - FLEET_URL=https://{{ GLOBALS.node_ip }}:8220 - FLEET_SERVER_ELASTICSEARCH_HOST=https://{{ GLOBALS.manager }}:9200 - FLEET_SERVER_SERVICE_TOKEN={{ SERVICETOKEN }} - FLEET_SERVER_POLICY_ID={{ FLEETSERVERPOLICY }} diff --git a/salt/firewall/assigned_hostgroups.map.yaml b/salt/firewall/assigned_hostgroups.map.yaml index 629712ca6..3039eee96 100644 --- a/salt/firewall/assigned_hostgroups.map.yaml +++ b/salt/firewall/assigned_hostgroups.map.yaml @@ -317,7 +317,15 @@ role: fleet: portgroups: - {{ portgroups.elasticsearch_rest }} + - {{ portgroups.docker_registry }} + - {{ portgroups.influxdb }} + - {{ portgroups.sensoroni }} + - {{ portgroups.yum }} + - {{ portgroups.beats_5044 }} + - {{ portgroups.beats_5644 }} - {{ portgroups.beats_5056 }} + - {{ portgroups.elastic_agent_control }} + - {{ portgroups.elastic_agent_data }} sensors: portgroups: - {{ portgroups.docker_registry }} diff --git a/salt/firewall/containers.map.jinja b/salt/firewall/containers.map.jinja index a2114258f..617b4a216 100644 --- a/salt/firewall/containers.map.jinja +++ b/salt/firewall/containers.map.jinja @@ -93,6 +93,12 @@ 'so-idh', ] %} +{% elif GLOBALS.role == 'so-fleet' %} +{% set NODE_CONTAINERS = [ + 'so-elastic-fleet', + 'so-logstash', +] %} + {% elif GLOBALS.role == 'so-sensor' %} {% set NODE_CONTAINERS = [] %} diff --git a/salt/firewall/ports/ports.yaml b/salt/firewall/ports/ports.yaml index 73741f723..79bdf93b4 100644 --- a/salt/firewall/ports/ports.yaml +++ b/salt/firewall/ports/ports.yaml @@ -35,7 +35,6 @@ firewall: elastic_agent_data: tcp: - 5055 - - 9200 endgame: tcp: - 3765 diff --git a/salt/logstash/init.sls b/salt/logstash/init.sls index 45daf95d9..35417848d 100644 --- a/salt/logstash/init.sls +++ b/salt/logstash/init.sls @@ -165,8 +165,8 @@ so-logstash: - /etc/pki/filebeat.p8:/usr/share/logstash/filebeat.key:ro {% endif %} {% if GLOBALS.role in ['so-fleet'] %} - - /etc/pki/elasticfleet.crt:/usr/share/logstash/filebeat.crt:ro - - /etc/pki/elasticfleet02.p8:/usr/share/logstash/filebeat.key:ro + - /opt/so/conf/elastic-fleet/certs/elasticfleet-logstash.crt:/usr/share/logstash/filebeat.crt:ro + - /opt/so/conf/elastic-fleet/certs/elasticfleet-logstash.p8:/usr/share/logstash/filebeat.key:ro {% endif %} {% if GLOBALS.role in ['so-manager', 'so-helix', 'so-managersearch', 'so-standalone', 'so-import'] %} - /etc/pki/ca.crt:/usr/share/filebeat/ca.crt:ro From 17bc96c3b3b3fe7750e465a09b56e838111bfa47 Mon Sep 17 00:00:00 2001 From: Josh Brower Date: Thu, 6 Apr 2023 13:21:19 -0400 Subject: [PATCH 12/20] Refactoring Fleet setup --- salt/common/tools/sbin/so-elastic-fleet-setup | 4 +- salt/common/tools/sbin/so-minion | 26 +++++++- salt/elasticfleet/init.sls | 3 +- salt/kibana/defaults.yaml | 61 +------------------ setup/so-setup | 4 +- 5 files changed, 30 insertions(+), 68 deletions(-) diff --git a/salt/common/tools/sbin/so-elastic-fleet-setup b/salt/common/tools/sbin/so-elastic-fleet-setup index c9c9ecf5c..46a0b8e9d 100755 --- a/salt/common/tools/sbin/so-elastic-fleet-setup +++ b/salt/common/tools/sbin/so-elastic-fleet-setup @@ -41,10 +41,10 @@ JSON_STRING=$( jq -n \ --arg LOGSTASHCRT "$LOGSTASHCRT" \ --arg LOGSTASHKEY "$LOGSTASHKEY" \ --arg LOGSTASHCA "$LOGSTASHCA" \ - '{"name":"so-manager_logstash","is_default":true,"is_default_monitoring":true,"id":"so-manager_logstash","type":"logstash","hosts":["{{ GLOBALS.manager_ip }}:5055"],"config_yaml":"","ssl":{"certificate": $LOGSTASHCRT,"key": $LOGSTASHKEY,"certificate_authorities":[ $LOGSTASHCA ]},"proxy_id":null}' + '{"name":"grid-logstash","is_default":true,"is_default_monitoring":true,"id":"so-manager_logstash","type":"logstash","hosts":["{{ GLOBALS.manager_ip }}:5055"],"config_yaml":"","ssl":{"certificate": $LOGSTASHCRT,"key": $LOGSTASHKEY,"certificate_authorities":[ $LOGSTASHCA ]},"proxy_id":null}' ) -# Add SO-Manager Logstash Ouput +# Add Logstash Ouput curl -K /opt/so/conf/elasticsearch/curl.config -L -X POST "localhost:5601/api/fleet/outputs" -H 'kbn-xsrf: true' -H 'Content-Type: application/json' -d "$JSON_STRING" printf "\n\n" {%- endif %} diff --git a/salt/common/tools/sbin/so-minion b/salt/common/tools/sbin/so-minion index 0fa642c83..7b698a119 100755 --- a/salt/common/tools/sbin/so-minion +++ b/salt/common/tools/sbin/so-minion @@ -139,9 +139,6 @@ function add_fleet_to_minion() { # TODO: Add error handling ESTOKEN=$(curl -K /opt/so/conf/elasticsearch/curl.config -L -X POST "localhost:5601/api/fleet/service_tokens" -H 'kbn-xsrf: true' -H 'Content-Type: application/json' | jq -r .value) - # Create Logstash Certs - - # Write out settings to minion file printf '%s\n'\ "elasticfleet:"\ @@ -221,6 +218,28 @@ function add_sensor_to_minion() { echo " enabled: True" >> $PILLARFILE } +function create_fleet_policy() { + + MINIONID="sa-29-261-jb_standalone" + JSON_STRING=$( jq -n \ + --arg NAME "FleetServer_$MINIONID" \ + --arg DESC "Fleet Server - $MINIONID" \ + '{"name": $NAME,"id":$NAME,"description":$DESC,"namespace":"default","monitoring_enabled":["logs"],"inactivity_timeout":1209600,"has_fleet_server":true}' + ) + + # Create Fleet Sever Policy + curl -K /opt/so/conf/elasticsearch/curl.config -L -X POST "localhost:5601/api/fleet/agent_policies" -H 'kbn-xsrf: true' -H 'Content-Type: application/json' -d "$JSON_STRING" + + JSON_STRING_UPDATE=$( jq -n \ + --arg NAME "FleetServer_$MINIONID" \ + --arg DESC "Fleet Server - $MINIONID" \ + '{"name":$NAME,"description":$DESC,"namespace":"default","monitoring_enabled":["logs"],"inactivity_timeout":1209600,"data_output_id":"so-manager_elasticsearch"}' + ) + + # Update Fleet Policy - ES Output + curl -K /opt/so/conf/elasticsearch/curl.config -L -X PUT "localhost:5601/api/fleet/agent_policies/FleetServer_$MINIONID" -H 'kbn-xsrf: true' -H 'Content-Type: application/json' -d "$JSON_STRING_UPDATE" +} + function updateMine() { salt "$MINION_ID" mine.send network.ip_addrs interface="$MNIC" } @@ -236,6 +255,7 @@ function createEVAL() { function createFLEET() { add_fleet_to_minion add_logstash_to_minion + create_fleet_policy } function createIDH() { diff --git a/salt/elasticfleet/init.sls b/salt/elasticfleet/init.sls index 5ebcd5d37..b457ccf5b 100644 --- a/salt/elasticfleet/init.sls +++ b/salt/elasticfleet/init.sls @@ -53,6 +53,7 @@ eastatedir: - replace: True - source: salt://elasticfleet/files/certs/elasticfleet.crt - mode: 640 + - user: 931 - group: 939 @@ -82,7 +83,7 @@ so-elastic-fleet: - FLEET_URL=https://{{ GLOBALS.node_ip }}:8220 - FLEET_SERVER_ELASTICSEARCH_HOST=https://{{ GLOBALS.manager }}:9200 - FLEET_SERVER_SERVICE_TOKEN={{ SERVICETOKEN }} - - FLEET_SERVER_POLICY_ID={{ FLEETSERVERPOLICY }} + - FLEET_SERVER_POLICY_ID=Fleet-Server_{{ GLOBALS.hostname }} - FLEET_SERVER_ELASTICSEARCH_CA=/etc/pki/intca.crt - FLEET_SERVER_CERT=/etc/pki/elasticfleet.crt - FLEET_SERVER_CERT_KEY=/etc/pki/elasticfleet.key diff --git a/salt/kibana/defaults.yaml b/salt/kibana/defaults.yaml index 64a5646e5..45dacd1da 100644 --- a/salt/kibana/defaults.yaml +++ b/salt/kibana/defaults.yaml @@ -30,63 +30,4 @@ kibana: secureCookies: true reporting: kibanaServer: - hostname: localhost - fleet: - packages: - - name: fleet_server - version: latest - - name: log - version: latest - - name: osquery_manager - version: latest - - name: system - version: latest - - name: windows - version: latest - agentPolicies: - - name: SO-Manager - id: so-manager - description: "SO Manager Fleet Server Policy" - namespace: default - is_default_fleet_server: true - monitoring_enabled: ['logs'] - package_policies: - - name: fleet-server_manager - package: - name: fleet_server - - name: SO-Grid-Nodes - id: so-grid-nodes - description: "SO Grid Node Policy" - namespace: default - monitoring_enabled: ['logs'] - package_policies: - - name: osquery-grid-nodes - package: - name: osquery_manager - - name: system-grid-nodes - package: - name: system - inputs: - - type: system/metrics - enabled: false - - name: Endpoints-Initial - id: endpoints-default - description: "Initial Endpoint Policy" - namespace: default - monitoring_enabled: ['logs'] - package_policies: - - name: system-endpoints - package: - name: system - inputs: - - type: system/metrics - enabled: false - - name: osquery-endpoints - package: - name: osquery_manager - - name: windows-endpoints - package: - name: windows - inputs: - - type: windows/metrics - enabled: false + hostname: localhost \ No newline at end of file diff --git a/setup/so-setup b/setup/so-setup index 56c2e38b8..9bd716880 100755 --- a/setup/so-setup +++ b/setup/so-setup @@ -637,8 +637,8 @@ if ! [[ -f $install_opt_file ]]; then add_web_user info "Restarting SOC to pick up initial user" logCmd "so-soc-restart" - title "Setting up Elastic Fleet" - logCmd "so-elastic-fleet-setup" + #title "Setting up Elastic Fleet" + # logCmd "so-elastic-fleet-setup" if [[ ! $is_import ]]; then title "Setting up Playbook" logCmd "so-playbook-reset" From 4ec31dbf35eeeb88a110ab73f9b22b649255ff6f Mon Sep 17 00:00:00 2001 From: Josh Brower Date: Wed, 12 Apr 2023 16:40:28 -0400 Subject: [PATCH 13/20] Refactoring Fleet setup redux --- salt/common/tools/sbin/so-elastic-fleet-setup | 124 ++++++++++++------ salt/common/tools/sbin/so-minion | 1 - .../endpoints-initial/osquery.json | 20 +++ .../integrations/grid-nodes/idh-logs.json | 29 ++++ .../integrations/grid-nodes/kratos-logs.json | 29 ++++ salt/elasticfleet/init.sls | 2 +- 6 files changed, 165 insertions(+), 40 deletions(-) create mode 100644 salt/elasticfleet/files/integrations/endpoints-initial/osquery.json create mode 100644 salt/elasticfleet/files/integrations/grid-nodes/idh-logs.json create mode 100644 salt/elasticfleet/files/integrations/grid-nodes/kratos-logs.json diff --git a/salt/common/tools/sbin/so-elastic-fleet-setup b/salt/common/tools/sbin/so-elastic-fleet-setup index 46a0b8e9d..3b41dd960 100755 --- a/salt/common/tools/sbin/so-elastic-fleet-setup +++ b/salt/common/tools/sbin/so-elastic-fleet-setup @@ -8,32 +8,58 @@ . /usr/sbin/so-common +elastic_fleet_policy_create() { -# Create ES Token -ESTOKEN=$(curl -K /opt/so/conf/elasticsearch/curl.config -L -X POST "localhost:5601/api/fleet/service_tokens" -H 'kbn-xsrf: true' -H 'Content-Type: application/json' | jq -r .value) -printf "ESTOKEN = $ESTOKEN \n" + NAME=$1 + DESC=$2 + FLEETSERVER=$3 -# Add SO-Manager Fleet URL -## This array replaces whatever URLs are currently configured -printf "\n" -curl -K /opt/so/conf/elasticsearch/curl.config -L -X PUT "localhost:5601/api/fleet/settings" -H 'kbn-xsrf: true' -H 'Content-Type: application/json' -d '{"fleet_server_hosts":["https://{{ GLOBALS.manager_ip }}:8220"]}' -printf "\n\n" + JSON_STRING=$( jq -n \ + --arg NAME "$NAME" \ + --arg DESC "$DESC" \ + --arg FLEETSERVER "$FLEETSERVER" \ + '{"name": $NAME,"id":$NAME,"description":$DESC,"namespace":"default","monitoring_enabled":["logs"],"inactivity_timeout":1209600,"has_fleet_server":$FLEETSERVER}' + ) + # Create Fleet Policy + curl -K /opt/so/conf/elasticsearch/curl.config -L -X POST "localhost:5601/api/fleet/agent_policies" -H 'kbn-xsrf: true' -H 'Content-Type: application/json' -d "$JSON_STRING" + +} + +elastic_fleet_policy_update() { + + POLICYID=$1 + JSONBLOB=$2 + + curl -K /opt/so/conf/elasticsearch/curl.config -L -X PUT "localhost:5601/api/fleet/agent_policies/$POLICYID" -H 'kbn-xsrf: true' -H 'Content-Type: application/json' -d "$JSON_STRING_UPDATE" +} + +elastic_fleet_integration_create() { + + JSONBLOB=$1 + + #curl -K /opt/so/conf/elasticsearch/curl.config -L -X PUT "localhost:5601/api/fleet/agent_policies/package_policies" -H 'kbn-xsrf: true' -H 'Content-Type: application/json' -d "$JSONBLOB" + curl -K /opt/so/conf/elasticsearch/curl.config -L -X POST "localhost:5601/api/fleet/package_policies" -H 'kbn-xsrf: true' -H 'Content-Type: application/json' -d "$JSONBLOB" + +} -# Configure certificates mkdir -p /opt/so/conf/elastic-fleet/certs cp /etc/ssl/certs/intca.crt /opt/so/conf/elastic-fleet/certs cp /etc/pki/elasticfleet* /opt/so/conf/elastic-fleet/certs -# Add SO-Manager Elasticsearch Ouput +printf "\n### Create ES Token ###\n" +ESTOKEN=$(curl -K /opt/so/conf/elasticsearch/curl.config -L -X POST "localhost:5601/api/fleet/service_tokens" -H 'kbn-xsrf: true' -H 'Content-Type: application/json' | jq -r .value) + +### Create Outputs & Fleet URLs ### +printf "\nAdd Manager Elasticsearch Ouput...\n" ESCACRT=$(openssl x509 -in /opt/so/conf/elastic-fleet/certs/intca.crt) JSON_STRING=$( jq -n \ --arg ESCACRT "$ESCACRT" \ - '{"name":"so-manager_elasticsearch","id":"so-manager_elasticsearch","type":"elasticsearch","hosts":["https://{{ GLOBALS.manager_ip }}:9200"],"is_default":true,"is_default_monitoring":true,"config_yaml":"","ssl":{"certificate_authorities": [$ESCACRT]}}' ) + '{"name":"so-manager_elasticsearch","id":"so-manager_elasticsearch","type":"elasticsearch","hosts":["https://{{ GLOBALS.manager_ip }}:9200","https://{{ GLOBALS.manager }}:9200"],"is_default":true,"is_default_monitoring":true,"config_yaml":"","ssl":{"certificate_authorities": [$ESCACRT]}}' ) curl -K /opt/so/conf/elasticsearch/curl.config -L -X POST "localhost:5601/api/fleet/outputs" -H 'kbn-xsrf: true' -H 'Content-Type: application/json' -d "$JSON_STRING" printf "\n\n" +printf "\nCreate Logstash Output if node is not an Import or Eval install\n" {% if grains.role not in ['so-import', 'so-eval'] %} -# Create Logstash Output payload LOGSTASHCRT=$(openssl x509 -in /opt/so/conf/elastic-fleet/certs/elasticfleet.crt) LOGSTASHKEY=$(openssl rsa -in /opt/so/conf/elastic-fleet/certs/elasticfleet.key) LOGSTASHCA=$(openssl x509 -in /opt/so/conf/elastic-fleet/certs/intca.crt) @@ -41,34 +67,42 @@ JSON_STRING=$( jq -n \ --arg LOGSTASHCRT "$LOGSTASHCRT" \ --arg LOGSTASHKEY "$LOGSTASHKEY" \ --arg LOGSTASHCA "$LOGSTASHCA" \ - '{"name":"grid-logstash","is_default":true,"is_default_monitoring":true,"id":"so-manager_logstash","type":"logstash","hosts":["{{ GLOBALS.manager_ip }}:5055"],"config_yaml":"","ssl":{"certificate": $LOGSTASHCRT,"key": $LOGSTASHKEY,"certificate_authorities":[ $LOGSTASHCA ]},"proxy_id":null}' + '{"name":"grid-logstash","is_default":true,"is_default_monitoring":true,"id":"so-manager_logstash","type":"logstash","hosts":["{{ GLOBALS.manager_ip }}:5055", "{{ GLOBALS.manager }}:5055"],"config_yaml":"","ssl":{"certificate": $LOGSTASHCRT,"key": $LOGSTASHKEY,"certificate_authorities":[ $LOGSTASHCA ]},"proxy_id":null}' ) - -# Add Logstash Ouput curl -K /opt/so/conf/elasticsearch/curl.config -L -X POST "localhost:5601/api/fleet/outputs" -H 'kbn-xsrf: true' -H 'Content-Type: application/json' -d "$JSON_STRING" printf "\n\n" {%- endif %} -# Add Elastic Fleet Integrations +printf "\nAdd SO-Manager Fleet URL\n" +## This array replaces whatever URLs are currently configured +curl -K /opt/so/conf/elasticsearch/curl.config -L -X PUT "localhost:5601/api/fleet/settings" -H 'kbn-xsrf: true' -H 'Content-Type: application/json' -d '{"fleet_server_hosts":["https://{{ GLOBALS.manager_ip }}:8220", "https://{{ GLOBALS.manager }}:8220"]}' +printf "\n\n" -# Add Elastic Fleet Server Agent Policy -#curl -vv -K /opt/so/conf/elasticsearch/curl.config -L \ -#-X POST "localhost:5601/api/fleet/agent_policies" \ -#-H 'kbn-xsrf: true' -H 'Content-Type: application/json' \ -#-d '{"name":"SO-Manager","id":"so-manager","description":"SO Manager Fleet Server Policy","namespace":"default","monitoring_enabled":["logs"],"has_fleet_server":true}' -# Add Agent Policy - SOS Grid Nodes -#curl -vv -K /opt/so/conf/elasticsearch/curl.config -L \ -#-X POST "localhost:5601/api/fleet/agent_policies" \ -#-H 'kbn-xsrf: true' -H 'Content-Type: application/json' \ -#-d '{"name":"SO-Grid","id":"so-grid","description":"SO Grid Endpoint Policy","namespace":"default","monitoring_enabled":["logs"]}' +### Create Policies & Associated Integration Configuration ### -# Add Agent Policy - Default endpoints -#curl -vv -K /opt/so/conf/elasticsearch/curl.config -L \ -#-X POST "localhost:5601/api/fleet/agent_policies" \ -#-H 'kbn-xsrf: true' -H 'Content-Type: application/json' \ -#-d '{"name":"Endpoints-Initalization","id":"endpoints","description":"Initial Endpoint Policy","namespace":"default","monitoring_enabled":["logs"]}' +# Manager Fleet Server Host +elastic_fleet_policy_create "FleetServer_{{ GLOBALS.hostname }}" "Fleet Server - {{ GLOBALS.hostname }}" "true" | jq +#elastic_fleet_policy_update "FleetServer_{{ GLOBALS.hostname }}" "@FleeServerHost_Fixup" +# Initial Endpoints +elastic_fleet_policy_create "endpoints-initial" "Initial Endpoint Policy" "false" | jq +for INTEGRATION in /opt/so/saltstack/opt/so/saltstack/default/salt/elasticfleet/files/integrations/endpoints-initial/*.json +do + elastic_fleet_integration_create "@$INTEGRATION" | jq +done + +# Grid Nodes +elastic_fleet_policy_create "so-grid-nodes" "SO Grid Node Policy" "false" +for INTEGRATION in /opt/so/saltstack/default/salt/elasticfleet/files/integrations/grid-nodes/*.json +do + elastic_fleet_integration_create "@$INTEGRATION" | jq +done + + +### Finalization ### + +# Query for Enrollment Tokens for default policies ENDPOINTSENROLLMENTOKEN=$(curl -K /opt/so/conf/elasticsearch/curl.config -L "localhost:5601/api/fleet/enrollment_api_keys" -H 'kbn-xsrf: true' -H 'Content-Type: application/json' | jq .list | jq -r -c '.[] | select(.policy_id | contains("endpoints-default")) | .api_key') GRIDNODESENROLLMENTOKEN=$(curl -K /opt/so/conf/elasticsearch/curl.config -L "localhost:5601/api/fleet/enrollment_api_keys" -H 'kbn-xsrf: true' -H 'Content-Type: application/json' | jq .list | jq -r -c '.[] | select(.policy_id | contains("so-grid-nodes")) | .api_key') @@ -80,7 +114,6 @@ printf '%s\n'\ " es_token: '$ESTOKEN'"\ " endpoints_enrollment: '$ENDPOINTSENROLLMENTOKEN'"\ " grid_enrollment: '$GRIDNODESENROLLMENTOKEN'"\ - " url: '{{ GLOBALS.manager_ip }}'"\ "" >> "$pillar_file" #Store Grid Nodes Enrollment token in Global pillar @@ -92,17 +125,32 @@ printf '%s\n'\ # Call Elastic-Fleet Salt State salt-call state.apply elasticfleet queue=True -# Load Elastic Fleet integrations -/usr/sbin/so-elastic-fleet-integration-policy-load + + + + + +### DEPRECATED # Temp +# Configure certificates +mkdir -p /opt/so/conf/elastic-fleet/certs +cp /etc/ssl/certs/intca.crt /opt/so/conf/elastic-fleet/certs +cp /etc/pki/elasticfleet* /opt/so/conf/elastic-fleet/certs + wget --progress=bar:force:noscroll -P /opt/so/saltstack/default/salt/elasticfleet/files/elastic-agent/ https://github.com/Security-Onion-Solutions/securityonion-docker-rpm/releases/download/so_elastic-agent-8.7.0/so-elastic-agent-8.7.0-darwin-x86_64.tar.gz wget --progress=bar:force:noscroll -P /opt/so/saltstack/default/salt/elasticfleet/files/elastic-agent/ https://github.com/Security-Onion-Solutions/securityonion-docker-rpm/releases/download/so_elastic-agent-8.7.0/so-elastic-agent-8.7.0-linux-x86_64.tar.gz wget --progress=bar:force:noscroll -P /opt/so/saltstack/default/salt/elasticfleet/files/elastic-agent/ https://github.com/Security-Onion-Solutions/securityonion-docker-rpm/releases/download/so_elastic-agent-8.7.0/so-elastic-agent-8.7.0-windows-x86_64.tar.gz -#git clone -b 2.4-so-elastic-agent https://github.com/Security-Onion-Solutions/securityonion-image.git -#cd securityonion-image/so-elastic-agent-builder -#docker build -t so-elastic-agent-builder . - so-elastic-agent-gen-installers salt-call state.apply elasticfleet.install_agent_grid queue=True + + +#Temp Fixup for Fleet Server Host Output +JSON_STRING_UPDATE=$( jq -n \ + --arg NAME "FleetServer_$MINIONID" \ + --arg DESC "Fleet Server - $MINIONID" \ + '{"name":$NAME,"description":$DESC,"namespace":"default","monitoring_enabled":["logs"],"inactivity_timeout":1209600,"data_output_id":"so-manager_elasticsearch"}' + ) +curl -K /opt/so/conf/elasticsearch/curl.config -L -X PUT "localhost:5601/api/fleet/agent_policies/FleetServer_$MINIONID" -H 'kbn-xsrf: true' -H 'Content-Type: application/json' -d "$JSON_STRING_UPDATE" + diff --git a/salt/common/tools/sbin/so-minion b/salt/common/tools/sbin/so-minion index 7b698a119..543315844 100755 --- a/salt/common/tools/sbin/so-minion +++ b/salt/common/tools/sbin/so-minion @@ -220,7 +220,6 @@ function add_sensor_to_minion() { function create_fleet_policy() { - MINIONID="sa-29-261-jb_standalone" JSON_STRING=$( jq -n \ --arg NAME "FleetServer_$MINIONID" \ --arg DESC "Fleet Server - $MINIONID" \ diff --git a/salt/elasticfleet/files/integrations/endpoints-initial/osquery.json b/salt/elasticfleet/files/integrations/endpoints-initial/osquery.json new file mode 100644 index 000000000..71d2345a5 --- /dev/null +++ b/salt/elasticfleet/files/integrations/endpoints-initial/osquery.json @@ -0,0 +1,20 @@ +{ + "package": { + "name": "osquery_manager", + "version": "1.6.0" + }, + "name": "osquery-endpoints", + "namespace": "default", + "policy_id": "endpoints-initial", + "inputs": { + "osquery_manager-osquery": { + "enabled": true, + "streams": { + "osquery_manager.result": { + "enabled": true, + "vars": {} + } + } + } + } +} diff --git a/salt/elasticfleet/files/integrations/grid-nodes/idh-logs.json b/salt/elasticfleet/files/integrations/grid-nodes/idh-logs.json new file mode 100644 index 000000000..1b918be1a --- /dev/null +++ b/salt/elasticfleet/files/integrations/grid-nodes/idh-logs.json @@ -0,0 +1,29 @@ +{ + "package": { + "name": "log", + "version": "1.1.1" + }, + "name": "idh-logs", + "namespace": "so", + "description": "IDH integration", + "policy_id": "so-grid-nodes", + "inputs": { + "logs-logfile": { + "enabled": true, + "streams": { + "log.log": { + "enabled": true, + "vars": { + "paths": [ + "/nsm/idh/opencanary.log" + ], + "data_stream.dataset": "idh", + "tags": [], + "processors": "\n- decode_json_fields:\n fields: [\"message\"]\n target: \"\"\n add_error_key: true\n- drop_fields:\n when:\n equals:\n logtype: \"1001\"\n fields: [\"src_host\", \"src_port\", \"dst_host\", \"dst_port\" ]\n ignore_missing: true\n- rename:\n fields:\n - from: \"src_host\"\n to: \"source.ip\"\n - from: \"src_port\"\n to: \"source.port\"\n - from: \"dst_host\"\n to: \"destination.host\"\n - from: \"dst_port\"\n to: \"destination.port\"\n ignore_missing: true\n- convert:\n fields:\n - {from: \"logtype\", to: \"event.code\", type: \"string\"}\n ignore_missing: true\n- drop_fields:\n fields: '[\"prospector\", \"input\", \"offset\", \"beat\"]'\n- add_fields:\n target: event\n fields:\n category: host\n module: opencanary", + "custom": "pipeline: common" + } + } + } + } + } +} diff --git a/salt/elasticfleet/files/integrations/grid-nodes/kratos-logs.json b/salt/elasticfleet/files/integrations/grid-nodes/kratos-logs.json new file mode 100644 index 000000000..87c4fc82c --- /dev/null +++ b/salt/elasticfleet/files/integrations/grid-nodes/kratos-logs.json @@ -0,0 +1,29 @@ +{ + "package": { + "name": "log", + "version": "1.1.0" + }, + "name": "kratos-logs", + "namespace": "so", + "description": "Kratos logs", + "policy_id": "so-grid-nodes", + "inputs": { + "logs-logfile": { + "enabled": true, + "streams": { + "log.log": { + "enabled": true, + "vars": { + "paths": [ + "/opt/so/log/kratos/kratos.log" + ], + "data_stream.dataset": "kratos", + "tags": [], + "processors": "- decode_json_fields:\n fields: [\"message\"]\n target: \"\"\n add_error_key: true \n- add_fields:\n target: event\n fields:\n category: iam\n module: kratos", + "custom": "pipeline: kratos" + } + } + } + } + } +} diff --git a/salt/elasticfleet/init.sls b/salt/elasticfleet/init.sls index b457ccf5b..2c3b5cfce 100644 --- a/salt/elasticfleet/init.sls +++ b/salt/elasticfleet/init.sls @@ -8,7 +8,7 @@ # These values are generated during node install and stored in minion pillar {% set SERVICETOKEN = salt['pillar.get']('elasticfleet:server:es_token','') %} -{% set FLEETSERVERPOLICY = salt['pillar.get']('elasticfleet:server:server_policy','so-manager') %} +#{% set FLEETSERVERPOLICY = salt['pillar.get']('elasticfleet:server:server_policy','so-manager') %} #{% set FLEETURL = salt['pillar.get']('elasticfleet:server:url') %} # Add EA Group From 2567ceea7449de97cd1b11bdebc3503733609f37 Mon Sep 17 00:00:00 2001 From: Josh Brower Date: Wed, 12 Apr 2023 16:51:40 -0400 Subject: [PATCH 14/20] Fix path --- salt/common/tools/sbin/so-elastic-fleet-setup | 34 ++----------------- 1 file changed, 2 insertions(+), 32 deletions(-) diff --git a/salt/common/tools/sbin/so-elastic-fleet-setup b/salt/common/tools/sbin/so-elastic-fleet-setup index 3b41dd960..87fe6f608 100755 --- a/salt/common/tools/sbin/so-elastic-fleet-setup +++ b/salt/common/tools/sbin/so-elastic-fleet-setup @@ -87,7 +87,7 @@ elastic_fleet_policy_create "FleetServer_{{ GLOBALS.hostname }}" "Fleet Server - # Initial Endpoints elastic_fleet_policy_create "endpoints-initial" "Initial Endpoint Policy" "false" | jq -for INTEGRATION in /opt/so/saltstack/opt/so/saltstack/default/salt/elasticfleet/files/integrations/endpoints-initial/*.json +for INTEGRATION in opt/so/saltstack/default/salt/elasticfleet/files/integrations/endpoints-initial/*.json do elastic_fleet_integration_create "@$INTEGRATION" | jq done @@ -123,34 +123,4 @@ printf '%s\n'\ "" >> "$global_pillar_file" # Call Elastic-Fleet Salt State -salt-call state.apply elasticfleet queue=True - - - - - - -### DEPRECATED - -# Temp -# Configure certificates -mkdir -p /opt/so/conf/elastic-fleet/certs -cp /etc/ssl/certs/intca.crt /opt/so/conf/elastic-fleet/certs -cp /etc/pki/elasticfleet* /opt/so/conf/elastic-fleet/certs - -wget --progress=bar:force:noscroll -P /opt/so/saltstack/default/salt/elasticfleet/files/elastic-agent/ https://github.com/Security-Onion-Solutions/securityonion-docker-rpm/releases/download/so_elastic-agent-8.7.0/so-elastic-agent-8.7.0-darwin-x86_64.tar.gz -wget --progress=bar:force:noscroll -P /opt/so/saltstack/default/salt/elasticfleet/files/elastic-agent/ https://github.com/Security-Onion-Solutions/securityonion-docker-rpm/releases/download/so_elastic-agent-8.7.0/so-elastic-agent-8.7.0-linux-x86_64.tar.gz -wget --progress=bar:force:noscroll -P /opt/so/saltstack/default/salt/elasticfleet/files/elastic-agent/ https://github.com/Security-Onion-Solutions/securityonion-docker-rpm/releases/download/so_elastic-agent-8.7.0/so-elastic-agent-8.7.0-windows-x86_64.tar.gz - -so-elastic-agent-gen-installers -salt-call state.apply elasticfleet.install_agent_grid queue=True - - -#Temp Fixup for Fleet Server Host Output -JSON_STRING_UPDATE=$( jq -n \ - --arg NAME "FleetServer_$MINIONID" \ - --arg DESC "Fleet Server - $MINIONID" \ - '{"name":$NAME,"description":$DESC,"namespace":"default","monitoring_enabled":["logs"],"inactivity_timeout":1209600,"data_output_id":"so-manager_elasticsearch"}' - ) -curl -K /opt/so/conf/elasticsearch/curl.config -L -X PUT "localhost:5601/api/fleet/agent_policies/FleetServer_$MINIONID" -H 'kbn-xsrf: true' -H 'Content-Type: application/json' -d "$JSON_STRING_UPDATE" - +salt-call state.apply elasticfleet queue=True \ No newline at end of file From 92a6eac9766bd6c7bf7d79662ab6f7c11fec2b74 Mon Sep 17 00:00:00 2001 From: Josh Brower Date: Fri, 14 Apr 2023 12:09:18 -0400 Subject: [PATCH 15/20] fix EA wrapper gen --- salt/common/tools/sbin/so-elastic-agent-gen-installers | 10 +++++----- salt/elasticfleet/init.sls | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/salt/common/tools/sbin/so-elastic-agent-gen-installers b/salt/common/tools/sbin/so-elastic-agent-gen-installers index 128f894e4..805f6152a 100755 --- a/salt/common/tools/sbin/so-elastic-agent-gen-installers +++ b/salt/common/tools/sbin/so-elastic-agent-gen-installers @@ -12,22 +12,22 @@ ENROLLMENTOKEN=$(curl -K /opt/so/conf/elasticsearch/curl.config -L "localhost:5601/api/fleet/enrollment_api_keys" -H 'kbn-xsrf: true' -H 'Content-Type: application/json' | jq .list | jq -r -c '.[] | select(.policy_id | contains("endpoints")) | .api_key') -FLEETHOST=$(lookup_pillar "server:url" "elasticfleet") +#FLEETHOST=$(lookup_pillar "server:url" "elasticfleet") +FLEETHOST="{{ GLOBALS.manager_ip }}" #FLEETHOST=$1 #ENROLLMENTOKEN=$2 CONTAINERGOOS=( "linux" "darwin" "windows" ) -rm -rf /tmp/elastic-agent-workspace -mkdir -p /tmp/elastic-agent-workspace +#rm -rf /tmp/elastic-agent-workspace +#mkdir -p /tmp/elastic-agent-workspace for OS in "${CONTAINERGOOS[@]}" do printf "\n\nGenerating $OS Installer..." - cp /opt/so/saltstack/default/salt/elasticfleet/files/elastic-agent/so-elastic-agent-*-$OS-x86_64.tar.gz /tmp/elastic-agent-workspace/$OS.tar.gz + #cp /opt/so/saltstack/default/salt/elasticfleet/files/elastic-agent/so-elastic-agent-*-$OS-x86_64.tar.gz /tmp/elastic-agent-workspace/$OS.tar.gz docker run -e CGO_ENABLED=0 -e GOOS=$OS \ --mount type=bind,source=/etc/ssl/certs/,target=/workspace/files/cert/ \ - --mount type=bind,source=/tmp/elastic-agent-workspace/,target=/workspace/files/elastic-agent/ \ --mount type=bind,source=/opt/so/saltstack/local/salt/elasticfleet/files/so_agent-installers/,target=/output/ \ {{ GLOBALS.registry_host }}:5000/{{ GLOBALS.image_repo }}/so-elastic-agent-builder:{{ GLOBALS.so_version }} go build -ldflags "-X main.fleetHost=$FLEETHOST -X main.enrollmentToken=$ENROLLMENTOKEN" -o /output/so-elastic-agent_$OS printf "\n $OS Installer Generated..." diff --git a/salt/elasticfleet/init.sls b/salt/elasticfleet/init.sls index 2c3b5cfce..5130c9a63 100644 --- a/salt/elasticfleet/init.sls +++ b/salt/elasticfleet/init.sls @@ -83,7 +83,7 @@ so-elastic-fleet: - FLEET_URL=https://{{ GLOBALS.node_ip }}:8220 - FLEET_SERVER_ELASTICSEARCH_HOST=https://{{ GLOBALS.manager }}:9200 - FLEET_SERVER_SERVICE_TOKEN={{ SERVICETOKEN }} - - FLEET_SERVER_POLICY_ID=Fleet-Server_{{ GLOBALS.hostname }} + - FLEET_SERVER_POLICY_ID=FleetServer_{{ GLOBALS.hostname }} - FLEET_SERVER_ELASTICSEARCH_CA=/etc/pki/intca.crt - FLEET_SERVER_CERT=/etc/pki/elasticfleet.crt - FLEET_SERVER_CERT_KEY=/etc/pki/elasticfleet.key From a7d282b412cef5dc41af231767de2c8996b95b01 Mon Sep 17 00:00:00 2001 From: Josh Brower Date: Sat, 15 Apr 2023 18:33:44 -0400 Subject: [PATCH 16/20] Firewall fixup --- salt/common/tools/sbin/so-elastic-fleet-setup | 26 ++-- salt/elasticfleet/init.sls | 8 +- salt/firewall/assigned_hostgroups.map.yaml | 3 + salt/ssl/init.sls | 119 ++++++++++++++++-- 4 files changed, 131 insertions(+), 25 deletions(-) diff --git a/salt/common/tools/sbin/so-elastic-fleet-setup b/salt/common/tools/sbin/so-elastic-fleet-setup index 87fe6f608..86b9c1107 100755 --- a/salt/common/tools/sbin/so-elastic-fleet-setup +++ b/salt/common/tools/sbin/so-elastic-fleet-setup @@ -28,7 +28,7 @@ elastic_fleet_policy_create() { elastic_fleet_policy_update() { POLICYID=$1 - JSONBLOB=$2 + JSON_STRING_UPDATE=$2 curl -K /opt/so/conf/elasticsearch/curl.config -L -X PUT "localhost:5601/api/fleet/agent_policies/$POLICYID" -H 'kbn-xsrf: true' -H 'Content-Type: application/json' -d "$JSON_STRING_UPDATE" } @@ -42,16 +42,12 @@ elastic_fleet_integration_create() { } -mkdir -p /opt/so/conf/elastic-fleet/certs -cp /etc/ssl/certs/intca.crt /opt/so/conf/elastic-fleet/certs -cp /etc/pki/elasticfleet* /opt/so/conf/elastic-fleet/certs - printf "\n### Create ES Token ###\n" ESTOKEN=$(curl -K /opt/so/conf/elasticsearch/curl.config -L -X POST "localhost:5601/api/fleet/service_tokens" -H 'kbn-xsrf: true' -H 'Content-Type: application/json' | jq -r .value) ### Create Outputs & Fleet URLs ### printf "\nAdd Manager Elasticsearch Ouput...\n" -ESCACRT=$(openssl x509 -in /opt/so/conf/elastic-fleet/certs/intca.crt) +ESCACRT=$(openssl x509 -in /etc/pki/tls/certs/intca.crt) JSON_STRING=$( jq -n \ --arg ESCACRT "$ESCACRT" \ '{"name":"so-manager_elasticsearch","id":"so-manager_elasticsearch","type":"elasticsearch","hosts":["https://{{ GLOBALS.manager_ip }}:9200","https://{{ GLOBALS.manager }}:9200"],"is_default":true,"is_default_monitoring":true,"config_yaml":"","ssl":{"certificate_authorities": [$ESCACRT]}}' ) @@ -60,9 +56,9 @@ printf "\n\n" printf "\nCreate Logstash Output if node is not an Import or Eval install\n" {% if grains.role not in ['so-import', 'so-eval'] %} -LOGSTASHCRT=$(openssl x509 -in /opt/so/conf/elastic-fleet/certs/elasticfleet.crt) -LOGSTASHKEY=$(openssl rsa -in /opt/so/conf/elastic-fleet/certs/elasticfleet.key) -LOGSTASHCA=$(openssl x509 -in /opt/so/conf/elastic-fleet/certs/intca.crt) +LOGSTASHCRT=$(openssl x509 -in /etc/pki/elasticfleet-logstash.crt) +LOGSTASHKEY=$(openssl rsa -in /etc/pki/elasticfleet-logstash.key) +LOGSTASHCA=$(openssl x509 -in /etc/pki/tls/certs/intca.crt) JSON_STRING=$( jq -n \ --arg LOGSTASHCRT "$LOGSTASHCRT" \ --arg LOGSTASHKEY "$LOGSTASHKEY" \ @@ -83,11 +79,19 @@ printf "\n\n" # Manager Fleet Server Host elastic_fleet_policy_create "FleetServer_{{ GLOBALS.hostname }}" "Fleet Server - {{ GLOBALS.hostname }}" "true" | jq -#elastic_fleet_policy_update "FleetServer_{{ GLOBALS.hostname }}" "@FleeServerHost_Fixup" +#elastic_fleet_policy_update "FleetServer_{{ GLOBALS.hostname }}" "@/opt/so/saltstack/default/salt/elasticfleet/files/FleeServerHost_Fixup.json" + +#Temp Fixup +JSON_STRING=$( jq -n \ + --arg NAME "FleetServer_{{ GLOBALS.hostname }}" \ + '{"name": $NAME,"description": $NAME,"namespace":"default","monitoring_enabled":["logs"],"inactivity_timeout":120,"data_output_id":"so-manager_elasticsearch"}' + ) +curl -K /opt/so/conf/elasticsearch/curl.config -L -X PUT "localhost:5601/api/fleet/agent_policies/FleetServer_{{ GLOBALS.hostname }}" -H 'kbn-xsrf: true' -H 'Content-Type: application/json' -d "$JSON_STRING" + # Initial Endpoints elastic_fleet_policy_create "endpoints-initial" "Initial Endpoint Policy" "false" | jq -for INTEGRATION in opt/so/saltstack/default/salt/elasticfleet/files/integrations/endpoints-initial/*.json +for INTEGRATION in /opt/so/saltstack/default/salt/elasticfleet/files/integrations/endpoints-initial/*.json do elastic_fleet_integration_create "@$INTEGRATION" | jq done diff --git a/salt/elasticfleet/init.sls b/salt/elasticfleet/init.sls index 5130c9a63..d03ec5e5e 100644 --- a/salt/elasticfleet/init.sls +++ b/salt/elasticfleet/init.sls @@ -76,18 +76,18 @@ so-elastic-fleet: - {{ BINDING }} {% endfor %} - binds: - - /opt/so/conf/elastic-fleet/certs:/etc/pki:ro - - /opt/so/conf/elastic-fleet/state:/usr/share/elastic-agent/state:rw + - /etc/pki:/etc/pki:ro + #- /opt/so/conf/elastic-fleet/state:/usr/share/elastic-agent/state:rw - environment: - FLEET_SERVER_ENABLE=true - FLEET_URL=https://{{ GLOBALS.node_ip }}:8220 - FLEET_SERVER_ELASTICSEARCH_HOST=https://{{ GLOBALS.manager }}:9200 - FLEET_SERVER_SERVICE_TOKEN={{ SERVICETOKEN }} - FLEET_SERVER_POLICY_ID=FleetServer_{{ GLOBALS.hostname }} - - FLEET_SERVER_ELASTICSEARCH_CA=/etc/pki/intca.crt + - FLEET_SERVER_ELASTICSEARCH_CA=/etc/pki/tls/certs/intca.crt - FLEET_SERVER_CERT=/etc/pki/elasticfleet.crt - FLEET_SERVER_CERT_KEY=/etc/pki/elasticfleet.key - - FLEET_CA=/etc/pki/intca.crt + - FLEET_CA=/etc/pki/tls/certs/intca.crt {% endif %} append_so-elastic-fleet_so-status.conf: diff --git a/salt/firewall/assigned_hostgroups.map.yaml b/salt/firewall/assigned_hostgroups.map.yaml index 3039eee96..b9a8f7fb2 100644 --- a/salt/firewall/assigned_hostgroups.map.yaml +++ b/salt/firewall/assigned_hostgroups.map.yaml @@ -391,6 +391,9 @@ role: dockernet: portgroups: - {{ portgroups.all }} + fleet: + portgroups: + - {{ portgroups.salt_manager }} localhost: portgroups: - {{ portgroups.all }} diff --git a/salt/ssl/init.sls b/salt/ssl/init.sls index 9c47d16f4..a28abe8af 100644 --- a/salt/ssl/init.sls +++ b/salt/ssl/init.sls @@ -147,6 +147,8 @@ rediskeyperms: {% endif %} {% if grains['role'] in ['so-manager', 'so-eval', 'so-managersearch', 'so-standalone', 'so-import', 'so-heavynode', 'so-fleet'] %} +# Create cert for Elastic Fleet Host + etc_elasticfleet_key: x509.private_key_managed: - name: /etc/pki/elasticfleet.key @@ -199,33 +201,130 @@ efperms: - mode: 640 - group: 939 -chownilogstashelasticfleetp8: +chownelasticfleetcrt: file.managed: - replace: False - - name: /etc/pki/elasticfleet.p8 + - name: /etc/pki/elasticfleet.crt - mode: 640 - user: 947 - group: 939 -# Create Symlinks to the keys so I can distribute it to all the things +chownelasticfleetkey: + file.managed: + - replace: False + - name: /etc/pki/elasticfleet.key + - mode: 640 + - user: 947 + - group: 939 + +# Create Symlinks to the keys to distribute it to all the things elasticfleetdircerts: file.directory: - name: /opt/so/saltstack/local/salt/elasticfleet/files/certs - makedirs: True -efkeylink: - file.symlink: - - name: /opt/so/saltstack/local/salt/elasticfleet/files/certs/elasticfleet.p8 - - target: /etc/pki/elasticfleet.p8 - - user: socore - - group: socore - efcrtlink: file.symlink: - name: /opt/so/saltstack/local/salt/elasticfleet/files/certs/elasticfleet.crt - target: /etc/pki/elasticfleet.crt - user: socore - group: socore + + +{% if grains.role not in ['so-fleet'] %} +# Create Cert for Elastic Fleet Logstash Input (Same cert used across all Fleet nodes) + +etc_elasticfleetlogstash_key: + x509.private_key_managed: + - name: /etc/pki/elasticfleet-logstash.key + - CN: {{ COMMONNAME }} + - bits: 4096 + - days_remaining: 0 + - days_valid: 820 + - backup: True + - new: True + {% if salt['file.file_exists']('/etc/pki/elasticfleet-logstash.key') -%} + - prereq: + - x509: etc_elasticfleet_crt + {%- endif %} + - timeout: 30 + - retry: + attempts: 5 + interval: 30 + +# Request a cert and drop it where it needs to go to be distributed +etc_elasticfleetlogstash_crt: + x509.certificate_managed: + - name: /etc/pki/elasticfleet-logstash.crt + - ca_server: {{ ca_server }} + - signing_policy: elasticfleet + - public_key: /etc/pki/elasticfleet-logstash.key + - CN: {{ GLOBALS.hostname }} + - subjectAltName: DNS:{{ GLOBALS.hostname }}, IP:{{ GLOBALS.node_ip }} + - days_remaining: 0 + - days_valid: 820 + - backup: True +{% if grains.role not in ['so-heavynode'] %} + - unless: + # https://github.com/saltstack/salt/issues/52167 + # Will trigger 5 days (432000 sec) from cert expiration + - 'enddate=$(date -d "$(openssl x509 -in /etc/pki/elasticfleet-logstash.crt -enddate -noout | cut -d= -f2)" +%s) ; now=$(date +%s) ; expire_date=$(( now + 432000)); [ $enddate -gt $expire_date ]' +{% endif %} + - timeout: 30 + - retry: + attempts: 5 + interval: 30 + cmd.run: + - name: "/usr/bin/openssl pkcs8 -in /etc/pki/elasticfleet-logstash.key -topk8 -out /etc/pki/elasticfleet-logstash.p8 -nocrypt" + - onchanges: + - x509: etc_elasticfleet_key + +eflogstashperms: + file.managed: + - replace: False + - name: /etc/pki/elasticfleet-logstash.key + - mode: 640 + - group: 939 + +chownilogstashelasticfleetp8: + file.managed: + - replace: False + - name: /etc/pki/elasticfleet-logstash.p8 + - mode: 640 + - user: 947 + - group: 939 + +chownilogstashelasticfleetlogstashcrt: + file.managed: + - replace: False + - name: /etc/pki/elasticfleet-logstash.crt + - mode: 640 + - user: 947 + - group: 939 + +chownilogstashelasticfleetlogstashkey: + file.managed: + - replace: False + - name: /etc/pki/elasticfleet-logstash.key + - mode: 640 + - user: 947 + - group: 939 + +eflogstashkeylink: + file.symlink: + - name: /opt/so/saltstack/local/salt/elasticfleet/files/certs/elasticfleet-logstash.p8 + - target: /etc/pki/elasticfleet.p8 + - user: socore + - group: socore + +eflogstashcrtlink: + file.symlink: + - name: /opt/so/saltstack/local/salt/elasticfleet/files/certs/elasticfleet-logstash.crt + - target: /etc/pki/elasticfleet.crt + - user: socore + - group: socore + +{% endif %} {% endif %} {% if grains['role'] in ['so-manager', 'so-eval', 'so-helix', 'so-managersearch', 'so-standalone', 'so-import', 'so-heavynode', 'so-receiver'] %} From 1944d0997899e44e1df99c5930538c82be792af7 Mon Sep 17 00:00:00 2001 From: Josh Brower Date: Mon, 17 Apr 2023 11:34:57 -0400 Subject: [PATCH 17/20] Logstash certs fixup --- salt/elasticfleet/files/certs/placeholder | 0 salt/elasticfleet/init.sls | 4 ++-- salt/logstash/init.sls | 6 +++--- .../config/so/0012_input_elastic_agent.conf | 4 ++-- salt/ssl/init.sls | 17 +++++++++++++++++ 5 files changed, 24 insertions(+), 7 deletions(-) create mode 100644 salt/elasticfleet/files/certs/placeholder diff --git a/salt/elasticfleet/files/certs/placeholder b/salt/elasticfleet/files/certs/placeholder new file mode 100644 index 000000000..e69de29bb diff --git a/salt/elasticfleet/init.sls b/salt/elasticfleet/init.sls index d03ec5e5e..ad0f62edd 100644 --- a/salt/elasticfleet/init.sls +++ b/salt/elasticfleet/init.sls @@ -43,7 +43,7 @@ eastatedir: /opt/so/conf/elastic-fleet/certs/elasticfleet-logstash.p8: file.managed: - replace: True - - source: salt://elasticfleet/files/certs/elasticfleet.p8 + - source: salt://elasticfleet/files/certs/elasticfleet-logstash.p8 - mode: 640 - user: 931 - group: 939 @@ -51,7 +51,7 @@ eastatedir: /opt/so/conf/elastic-fleet/certs/elasticfleet-logstash.crt: file.managed: - replace: True - - source: salt://elasticfleet/files/certs/elasticfleet.crt + - source: salt://elasticfleet/files/certs/elasticfleet-logstash.crt - mode: 640 - user: 931 - group: 939 diff --git a/salt/logstash/init.sls b/salt/logstash/init.sls index 35417848d..7f3aef0aa 100644 --- a/salt/logstash/init.sls +++ b/salt/logstash/init.sls @@ -164,9 +164,9 @@ so-logstash: - /etc/pki/filebeat.crt:/usr/share/logstash/filebeat.crt:ro - /etc/pki/filebeat.p8:/usr/share/logstash/filebeat.key:ro {% endif %} - {% if GLOBALS.role in ['so-fleet'] %} - - /opt/so/conf/elastic-fleet/certs/elasticfleet-logstash.crt:/usr/share/logstash/filebeat.crt:ro - - /opt/so/conf/elastic-fleet/certs/elasticfleet-logstash.p8:/usr/share/logstash/filebeat.key:ro + {% if GLOBALS.role in ['so-manager', 'so-managersearch', 'so-standalone', 'so-import', 'so-eval','so-fleet'] %} + - /opt/so/conf/elastic-fleet/certs/elasticfleet-logstash.crt:/usr/share/logstash/elasticfleet-logstash.crt:ro + - /opt/so/conf/elastic-fleet/certs/elasticfleet-logstash.p8:/usr/share/logstash/elasticfleet-logstash.key:ro {% endif %} {% if GLOBALS.role in ['so-manager', 'so-helix', 'so-managersearch', 'so-standalone', 'so-import'] %} - /etc/pki/ca.crt:/usr/share/filebeat/ca.crt:ro diff --git a/salt/logstash/pipelines/config/so/0012_input_elastic_agent.conf b/salt/logstash/pipelines/config/so/0012_input_elastic_agent.conf index ba89001b6..2cb31ed45 100644 --- a/salt/logstash/pipelines/config/so/0012_input_elastic_agent.conf +++ b/salt/logstash/pipelines/config/so/0012_input_elastic_agent.conf @@ -4,8 +4,8 @@ input { tags => [ "elastic-agent" ] ssl => true ssl_certificate_authorities => ["/usr/share/filebeat/ca.crt"] - ssl_certificate => "/usr/share/logstash/filebeat.crt" - ssl_key => "/usr/share/logstash/filebeat.key" + ssl_certificate => "/usr/share/logstash/elasticfleet-logstash.crt" + ssl_key => "/usr/share/logstash/elasticfleet-logstash.key" ssl_verify_mode => "force_peer" ecs_compatibility => v8 } diff --git a/salt/ssl/init.sls b/salt/ssl/init.sls index a28abe8af..3e6ce0512 100644 --- a/salt/ssl/init.sls +++ b/salt/ssl/init.sls @@ -325,6 +325,23 @@ eflogstashcrtlink: - group: socore {% endif %} + +/opt/so/conf/elastic-fleet/certs/elasticfleet-logstash.p8: + file.managed: + - replace: True + - source: salt://elasticfleet/files/certs/elasticfleet-logstash.p8 + - mode: 640 + - user: 931 + - group: 939 + +/opt/so/conf/elastic-fleet/certs/elasticfleet-logstash.crt: + file.managed: + - replace: True + - source: salt://elasticfleet/files/certs/elasticfleet-logstash.crt + - mode: 640 + - user: 931 + - group: 939 + {% endif %} {% if grains['role'] in ['so-manager', 'so-eval', 'so-helix', 'so-managersearch', 'so-standalone', 'so-import', 'so-heavynode', 'so-receiver'] %} From 8cccaef66422c0dc8ee62114ab44398e114563af Mon Sep 17 00:00:00 2001 From: Josh Brower Date: Mon, 17 Apr 2023 12:28:07 -0400 Subject: [PATCH 18/20] mkdirs as needed --- salt/elasticfleet/init.sls | 17 ----------------- salt/ssl/init.sls | 2 ++ 2 files changed, 2 insertions(+), 17 deletions(-) diff --git a/salt/elasticfleet/init.sls b/salt/elasticfleet/init.sls index ad0f62edd..da735ffac 100644 --- a/salt/elasticfleet/init.sls +++ b/salt/elasticfleet/init.sls @@ -39,23 +39,6 @@ eastatedir: - group: 939 - makedirs: True -# Pull down the Logstash Cert from the Manager -/opt/so/conf/elastic-fleet/certs/elasticfleet-logstash.p8: - file.managed: - - replace: True - - source: salt://elasticfleet/files/certs/elasticfleet-logstash.p8 - - mode: 640 - - user: 931 - - group: 939 - -/opt/so/conf/elastic-fleet/certs/elasticfleet-logstash.crt: - file.managed: - - replace: True - - source: salt://elasticfleet/files/certs/elasticfleet-logstash.crt - - mode: 640 - - user: 931 - - group: 939 - {% if SERVICETOKEN != '' %} so-elastic-fleet: diff --git a/salt/ssl/init.sls b/salt/ssl/init.sls index 3e6ce0512..5f7eb90df 100644 --- a/salt/ssl/init.sls +++ b/salt/ssl/init.sls @@ -330,6 +330,7 @@ eflogstashcrtlink: file.managed: - replace: True - source: salt://elasticfleet/files/certs/elasticfleet-logstash.p8 + - makedirs: True - mode: 640 - user: 931 - group: 939 @@ -338,6 +339,7 @@ eflogstashcrtlink: file.managed: - replace: True - source: salt://elasticfleet/files/certs/elasticfleet-logstash.crt + - makedirs: True - mode: 640 - user: 931 - group: 939 From 31f83c6dee5ea8b44ff7a9f37ca117ab1afcb966 Mon Sep 17 00:00:00 2001 From: Josh Brower Date: Mon, 17 Apr 2023 15:00:51 -0400 Subject: [PATCH 19/20] Re-enabled Fleet Setup during setup --- salt/common/tools/sbin/so-minion | 10 +++++----- setup/so-setup | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/salt/common/tools/sbin/so-minion b/salt/common/tools/sbin/so-minion index 543315844..cf50a49d7 100755 --- a/salt/common/tools/sbin/so-minion +++ b/salt/common/tools/sbin/so-minion @@ -221,8 +221,8 @@ function add_sensor_to_minion() { function create_fleet_policy() { JSON_STRING=$( jq -n \ - --arg NAME "FleetServer_$MINIONID" \ - --arg DESC "Fleet Server - $MINIONID" \ + --arg NAME "FleetServer_$LSHOSTNAME" \ + --arg DESC "Fleet Server - $LSHOSTNAME" \ '{"name": $NAME,"id":$NAME,"description":$DESC,"namespace":"default","monitoring_enabled":["logs"],"inactivity_timeout":1209600,"has_fleet_server":true}' ) @@ -230,13 +230,13 @@ function create_fleet_policy() { curl -K /opt/so/conf/elasticsearch/curl.config -L -X POST "localhost:5601/api/fleet/agent_policies" -H 'kbn-xsrf: true' -H 'Content-Type: application/json' -d "$JSON_STRING" JSON_STRING_UPDATE=$( jq -n \ - --arg NAME "FleetServer_$MINIONID" \ - --arg DESC "Fleet Server - $MINIONID" \ + --arg NAME "FleetServer_$LSHOSTNAME" \ + --arg DESC "Fleet Server - $LSHOSTNAME" \ '{"name":$NAME,"description":$DESC,"namespace":"default","monitoring_enabled":["logs"],"inactivity_timeout":1209600,"data_output_id":"so-manager_elasticsearch"}' ) # Update Fleet Policy - ES Output - curl -K /opt/so/conf/elasticsearch/curl.config -L -X PUT "localhost:5601/api/fleet/agent_policies/FleetServer_$MINIONID" -H 'kbn-xsrf: true' -H 'Content-Type: application/json' -d "$JSON_STRING_UPDATE" + curl -K /opt/so/conf/elasticsearch/curl.config -L -X PUT "localhost:5601/api/fleet/agent_policies/FleetServer_$LSHOSTNAME" -H 'kbn-xsrf: true' -H 'Content-Type: application/json' -d "$JSON_STRING_UPDATE" } function updateMine() { diff --git a/setup/so-setup b/setup/so-setup index 9bd716880..ddf39fdee 100755 --- a/setup/so-setup +++ b/setup/so-setup @@ -637,8 +637,8 @@ if ! [[ -f $install_opt_file ]]; then add_web_user info "Restarting SOC to pick up initial user" logCmd "so-soc-restart" - #title "Setting up Elastic Fleet" - # logCmd "so-elastic-fleet-setup" + title "Setting up Elastic Fleet" + logCmd "so-elastic-fleet-setup" if [[ ! $is_import ]]; then title "Setting up Playbook" logCmd "so-playbook-reset" From 4c4b873eca0ab0901c33d0227aa77b276412f1e6 Mon Sep 17 00:00:00 2001 From: Josh Brower Date: Wed, 19 Apr 2023 09:04:33 -0400 Subject: [PATCH 20/20] Add integrations and cleanup --- salt/common/tools/sbin/so-common | 33 +++++ .../so-elastic-fleet-integration-policy-load | 140 ++---------------- salt/common/tools/sbin/so-elastic-fleet-setup | 54 +------ salt/common/tools/sbin/so-minion | 20 ++- .../endpoints-initial/system-endpoints.json | 76 ++++++++++ .../endpoints-initial/windows-endpoints.json | 59 ++++++++ .../grid-nodes/elasticsearch-logs.json | 106 +++++++++++++ .../grid-nodes/import-evtx-logs.json | 29 ++++ .../grid-nodes/import-suricata-logs.json | 29 ++++ .../grid-nodes/import-zeek-logs.json | 29 ++++ .../grid-nodes/osquery-grid-nodes.json | 20 +++ .../integrations/grid-nodes/redis-logs.json | 76 ++++++++++ .../grid-nodes/soc-auth-sync-logs.json | 29 ++++ .../grid-nodes/soc-salt-relay-logs.json | 29 ++++ .../grid-nodes/soc-sensoroni-logs.json | 29 ++++ .../grid-nodes/soc-server-logs.json | 29 ++++ .../integrations/grid-nodes/strelka-logs.json | 29 ++++ .../grid-nodes/suricata-logs.json | 29 ++++ .../grid-nodes/syslog-tcp-514.json | 32 ++++ .../grid-nodes/syslog-udp-514.json | 33 +++++ .../grid-nodes/system-grid-nodes.json | 47 ++++++ .../integrations/grid-nodes/zeek-logs.json | 29 ++++ salt/top.sls | 1 + setup/so-setup | 2 + 24 files changed, 812 insertions(+), 177 deletions(-) create mode 100644 salt/elasticfleet/files/integrations/endpoints-initial/system-endpoints.json create mode 100644 salt/elasticfleet/files/integrations/endpoints-initial/windows-endpoints.json create mode 100644 salt/elasticfleet/files/integrations/grid-nodes/elasticsearch-logs.json create mode 100644 salt/elasticfleet/files/integrations/grid-nodes/import-evtx-logs.json create mode 100644 salt/elasticfleet/files/integrations/grid-nodes/import-suricata-logs.json create mode 100644 salt/elasticfleet/files/integrations/grid-nodes/import-zeek-logs.json create mode 100644 salt/elasticfleet/files/integrations/grid-nodes/osquery-grid-nodes.json create mode 100644 salt/elasticfleet/files/integrations/grid-nodes/redis-logs.json create mode 100644 salt/elasticfleet/files/integrations/grid-nodes/soc-auth-sync-logs.json create mode 100644 salt/elasticfleet/files/integrations/grid-nodes/soc-salt-relay-logs.json create mode 100644 salt/elasticfleet/files/integrations/grid-nodes/soc-sensoroni-logs.json create mode 100644 salt/elasticfleet/files/integrations/grid-nodes/soc-server-logs.json create mode 100644 salt/elasticfleet/files/integrations/grid-nodes/strelka-logs.json create mode 100644 salt/elasticfleet/files/integrations/grid-nodes/suricata-logs.json create mode 100644 salt/elasticfleet/files/integrations/grid-nodes/syslog-tcp-514.json create mode 100644 salt/elasticfleet/files/integrations/grid-nodes/syslog-udp-514.json create mode 100644 salt/elasticfleet/files/integrations/grid-nodes/system-grid-nodes.json create mode 100644 salt/elasticfleet/files/integrations/grid-nodes/zeek-logs.json diff --git a/salt/common/tools/sbin/so-common b/salt/common/tools/sbin/so-common index 06d359748..5089adb64 100755 --- a/salt/common/tools/sbin/so-common +++ b/salt/common/tools/sbin/so-common @@ -160,6 +160,39 @@ disable_fastestmirror() { sed -i 's/enabled=1/enabled=0/' /etc/yum/pluginconf.d/fastestmirror.conf } +elastic_fleet_integration_create() { + + JSON_STRING=$1 + + curl -K /opt/so/conf/elasticsearch/curl.config -L -X POST "localhost:5601/api/fleet/package_policies" -H 'kbn-xsrf: true' -H 'Content-Type: application/json' -d "$JSON_STRING" +} + +elastic_fleet_policy_create() { + + NAME=$1 + DESC=$2 + FLEETSERVER=$3 + + JSON_STRING=$( jq -n \ + --arg NAME "$NAME" \ + --arg DESC "$DESC" \ + --arg FLEETSERVER "$FLEETSERVER" \ + '{"name": $NAME,"id":$NAME,"description":$DESC,"namespace":"default","monitoring_enabled":["logs"],"inactivity_timeout":1209600,"has_fleet_server":$FLEETSERVER}' + ) + # Create Fleet Policy + curl -K /opt/so/conf/elasticsearch/curl.config -L -X POST "localhost:5601/api/fleet/agent_policies" -H 'kbn-xsrf: true' -H 'Content-Type: application/json' -d "$JSON_STRING" + +} + +elastic_fleet_policy_update() { + + POLICYID=$1 + JSON_STRING=$2 + + curl -K /opt/so/conf/elasticsearch/curl.config -L -X PUT "localhost:5601/api/fleet/agent_policies/$POLICYID" -H 'kbn-xsrf: true' -H 'Content-Type: application/json' -d "$JSON_STRING" +} + + elastic_license() { read -r -d '' message <<- EOM diff --git a/salt/common/tools/sbin/so-elastic-fleet-integration-policy-load b/salt/common/tools/sbin/so-elastic-fleet-integration-policy-load index 4efdd5784..a65e29244 100755 --- a/salt/common/tools/sbin/so-elastic-fleet-integration-policy-load +++ b/salt/common/tools/sbin/so-elastic-fleet-integration-policy-load @@ -6,132 +6,16 @@ . /usr/sbin/so-common -{%- set ZEEKVER = salt['pillar.get']('global:mdengine', '') %} -{%- set STRELKAENABLED = salt['pillar.get']('strelka:enabled', '0') %} -{%- set RITAENABLED = salt['pillar.get']('rita:enabled', False) %} +# Initial Endpoints +for INTEGRATION in /opt/so/saltstack/default/salt/elasticfleet/files/integrations/endpoints-initial/*.json +do + printf "\n\nInitial Endpoint Policy - Loading $INTEGRATION\n" + elastic_fleet_integration_create "@$INTEGRATION" +done -wait_for_web_response "http://localhost:5601/api/spaces/space/default" "default" 300 "curl -K /opt/so/conf/elasticsearch/curl.config" - -# Let's snag a cookie from Kibana -SESSIONCOOKIE=$(curl -K /opt/so/conf/elasticsearch/curl.config -c - -X GET http://localhost:5601/ | grep sid | awk '{print $7}') - -# Disable certain Features from showing up in the Kibana UI -echo -echo "Disable certain Features from showing up in the Kibana UI" -so-kibana-space-defaults -echo - -# Suricata logs -echo -echo "Setting up Suricata package policy..." -curl -K /opt/so/conf/elasticsearch/curl.config -b "sid=$SESSIONCOOKIE" -L -X POST "localhost:5601/api/fleet/package_policies" -H 'kbn-xsrf: true' -H 'Content-Type: application/json' -d'{ "policy_id": "so-grid-nodes", "package": { "name": "log", "version": "1.1.0" }, "id": "suricata-logs", "name": "suricata-logs", "description": "Suricata integration", "namespace": "so", "inputs": { "logs-logfile": { "enabled": true, "streams": { "log.log": { "enabled": true, "vars": { "paths": [ "/nsm/suricata/eve*.json" ], "data_stream.dataset": "suricata", "tags": [],"processors": "- add_fields:\n target: event\n fields:\n category: network\n module: suricata", "custom": "pipeline: suricata.common" }}}}}}' -echo - -# Zeek logs -echo -echo "Setting up Zeek package policy..." -curl -K /opt/so/conf/elasticsearch/curl.config -b "sid=$SESSIONCOOKIE" -L -X POST "localhost:5601/api/fleet/package_policies" -H 'kbn-xsrf: true' -H 'Content-Type: application/json' -d'{ "policy_id": "so-grid-nodes", "package": { "name": "log", "version": "1.1.0" }, "name": "zeek-logs", "description": "Zeek logs", "namespace": "so", "inputs": { "logs-logfile": { "enabled": true, "streams": { "log.log": { "enabled": true, "vars": { "paths": ["/nsm/zeek/logs/current/*.log"], "data_stream.dataset": "zeek", "tags": [], "processors": "- dissect:\n tokenizer: \"/nsm/zeek/logs/current/%{pipeline}.log\"\n field: \"log.file.path\"\n trim_chars: \".log\"\n target_prefix: \"\"\n- script:\n lang: javascript\n source: >\n function process(event) {\n var pl = event.Get(\"pipeline\");\n event.Put(\"@metadata.pipeline\", \"zeek.\" + pl);\n }\n- add_fields:\n target: event\n fields:\n category: network\n module: zeek\n- add_tags:\n tags: \"ics\"\n when:\n regexp:\n pipeline: \"^bacnet*|^bsap*|^cip*|^cotp*|^dnp3*|^ecat*|^enip*|^modbus*|^opcua*|^profinet*|^s7comm*\"", "custom": "exclude_files: [\"broker|capture_loss|ecat_arp_info|loaded_scripts|packet_filter|stats|stderr|stdout.log$\"]\n" } } } } } }' -echo - - -# Import - EVTX -echo -echo "Setting up EVTX import package policy..." -curl -K /opt/so/conf/elasticsearch/curl.config -b "sid=$SESSIONCOOKIE" -L -X POST "localhost:5601/api/fleet/package_policies" -H 'kbn-xsrf: true' -H 'Content-Type: application/json' -d '{ "package": { "name": "log", "version": "1.1.0" }, "name": "import-evtx-logs", "namespace": "so", "description": "Import Windows EVTX logs", "policy_id": "so-grid-nodes", "inputs": { "logs-logfile": { "enabled": true, "streams": { "log.log": { "enabled": true, "vars": { "paths": [ "/nsm/import/*/evtx/data.json" ], "data_stream.dataset": "import", "custom": "pipeline: import.wel", "processors": "- dissect:\n tokenizer: \"/nsm/import/%{import.id}/evtx/%{import.file}\"\n field: \"log.file.path\"\n target_prefix: \"\"\n- decode_json_fields:\n fields: [\"message\"]\n target: \"\"\n- add_fields:\n target: event\n fields:\n module: windows_eventlog\n imported: true", "tags": [] } } } } } }' -echo - -# Import - Suricata logs -echo -echo "Setting up Suricata import package policy..." -curl -K /opt/so/conf/elasticsearch/curl.config -b "sid=$SESSIONCOOKIE" -L -X POST "localhost:5601/api/fleet/package_policies" -H 'kbn-xsrf: true' -H 'Content-Type: application/json' -d '{ "policy_id": "so-grid-nodes", "package": { "name": "log", "version": "1.1.0" }, "id": "import-suricata-logs", "name": "import-suricata-logs", "description": "Import Suricata logs", "namespace": "so", "inputs": { "logs-logfile": { "enabled": true, "streams": { "log.log": { "enabled": true, "vars": { "paths": ["/nsm/import/*/suricata/eve*.json"], "data_stream.dataset": "import", "tags": [], "processors": "- add_fields:\n target: event\n fields:\n category: network\n module: suricata\n imported: true\n- dissect:\n tokenizer: \"/nsm/import/%{import.id}/suricata/%{import.file}\"\n field: \"log.file.path\"\n target_prefix: \"\"", "custom": "pipeline: suricata.common" } } } } } }' -echo - -# Import - Zeek logs -echo -echo "Setting up Zeek import package policy..." -curl -K /opt/so/conf/elasticsearch/curl.config -b "sid=$SESSIONCOOKIE" -L -X POST "localhost:5601/api/fleet/package_policies" -H 'kbn-xsrf: true' -H 'Content-Type: application/json' -d'{ "policy_id": "so-grid-nodes", "package": { "name": "log", "version": "1.1.0" }, "name": "import-zeek-logs", "description": "Zeek Import logs", "namespace": "so", "inputs": { "logs-logfile": { "enabled": true, "streams": { "log.log": { "enabled": true, "vars": { "paths": ["/nsm/import/*/zeek/logs/*.log"], "data_stream.dataset": "import", "tags": [], "processors": "- dissect:\n tokenizer: \"/nsm/import/%{import.id}/zeek/logs/%{import.file}\"\n field: \"log.file.path\"\n target_prefix: \"\"\n- script:\n lang: javascript\n source: >\n function process(event) {\n var pl = event.Get(\"import.file\").slice(0,-4);\n event.Put(\"@metadata.pipeline\", \"zeek.\" + pl);\n }\n- add_fields:\n target: event\n fields:\n category: network\n module: zeek\n imported: true\n- add_tags:\n tags: \"ics\"\n when:\n regexp:\n import.file: \"^bacnet*|^bsap*|^cip*|^cotp*|^dnp3*|^ecat*|^enip*|^modbus*|^opcua*|^profinet*|^s7comm*\"", "custom": "exclude_files: [\"broker|capture_loss|ecat_arp_info|loaded_scripts|packet_filter|stats|stderr|stdout.log$\"]\n" } } } } } }' -echo - -# Strelka logs -echo -echo "Setting up Strelka package policy..." -curl -K /opt/so/conf/elasticsearch/curl.config -b "sid=$SESSIONCOOKIE" -L -X POST "localhost:5601/api/fleet/package_policies" -H 'kbn-xsrf: true' -H 'Content-Type: application/json' -d'{ "policy_id": "so-grid-nodes", "package": { "name": "log", "version": "1.1.0" }, "id": "strelka-logs", "name": "strelka-logs", "description": "Strelka logs", "namespace": "so", "inputs": { "logs-logfile": { "enabled": true, "streams": { "log.log": { "enabled": true, "vars": { "paths": [ "/nsm/strelka/log/strelka.log" ], "data_stream.dataset": "strelka", "tags": [],"processors": "- add_fields:\n target: event\n fields:\n category: file\n module: strelka", "custom": "pipeline: strelka.file" }}}}}}' -echo - -# Syslog TCP Port 514 -echo -echo "Setting up Syslog TCP package policy..." -curl -K /opt/so/conf/elasticsearch/curl.config -b "sid=$SESSIONCOOKIE" -L -X POST "localhost:5601/api/fleet/package_policies" -H 'kbn-xsrf: true' -H 'Content-Type: application/json' -d '{ "policy_id": "so-grid-nodes", "package": { "name": "tcp", "version": "1.5.0" }, "id": "syslog-tcp-514", "name": "syslog-tcp-514", "description": "Syslog Over TCP Port 514", "namespace": "so", "inputs": { "tcp-tcp": { "enabled": true, "streams": { "tcp.generic": { "enabled": true, "vars": { "listen_address": "0.0.0.0", "listen_port": "514", "data_stream.dataset": "syslog", "pipeline": "syslog", "processors": "- add_fields:\n target: event\n fields:\n module: syslog", "tags": [ "syslog" ], "syslog_options": "field: message\n#format: auto\n#timezone: Local" } } } } } }' -echo - -# Syslog UDP Port 514 -echo -echo "Setting up Syslog UDP package policy..." -curl -K /opt/so/conf/elasticsearch/curl.config -b "sid=$SESSIONCOOKIE" -L -X POST "localhost:5601/api/fleet/package_policies" -H 'kbn-xsrf: true' -H 'Content-Type: application/json' -d '{ "policy_id": "so-grid-nodes", "package": { "name": "udp", "version": "1.5.0" }, "id": "syslog-udp-514", "name": "syslog-udp-514", "description": "Syslog over UDP Port 514", "namespace": "so", "inputs": { "udp-udp": { "enabled": true, "streams": { "udp.generic": { "enabled": true, "vars": { "listen_address": "0.0.0.0", "listen_port": "514", "data_stream.dataset": "syslog", "pipeline": "syslog", "max_message_size": "10KiB", "keep_null": false, "processors": "- add_fields:\n target: event\n fields: \n module: syslog\n", "tags": [ "syslog" ], "syslog_options": "field: message\n#format: auto\n#timezone: Local" } } } } } }' -echo - -# Kratos logs -echo -echo "Setting up Kratos package policy..." -curl -K /opt/so/conf/elasticsearch/curl.config -b "sid=$SESSIONCOOKIE" -L -X POST "localhost:5601/api/fleet/package_policies" -H 'kbn-xsrf: true' -H 'Content-Type: application/json' -d'{ "policy_id": "so-grid-nodes", "package": { "name": "log", "version": "1.1.0" }, "id": "kratos-logs", "name": "kratos-logs", "description": "Kratos logs", "namespace": "so", "inputs": { "logs-logfile": { "enabled": true, "streams": { "log.log": { "enabled": true, "vars": { "paths": [ "/opt/so/log/kratos/kratos.log" ], "data_stream.dataset": "kratos", "tags": [],"custom":"pipeline: kratos","processors": "- decode_json_fields:\n fields: [\"message\"]\n target: \"\"\n add_error_key: true \n- add_fields:\n target: event\n fields:\n category: iam\n module: kratos" }}}}}}' -echo - -# RITA Logs -#echo -#echo "Setting up RITA package policy..." -#curl -K /opt/so/conf/elasticsearch/curl.config -b "sid=$SESSIONCOOKIE" -L -X POST "localhost:5601/api/fleet/package_policies" -H 'kbn-xsrf: true' -H 'Content-Type: application/json' -d'{ "policy_id": "so-grid-nodes", "package": { "name": "log", "version": "1.1.0" }, "id": "rita-logs", "name": "rita-logs", "description": "RITA Beacon logs", "namespace": "so", "inputs": { "logs-logfile": { "enabled": true, "streams": { "log.log": { "enabled": true, "vars": { "paths": [ "/nsm/rita/beacons.csv", "/nsm/rita/long-connections.csv", "/nsm/rita/short-connections.csv", "/nsm/rita/exploded-dns.csv" ], "data_stream.dataset": "rita", "tags": [], "processors": "- add_fields:\n target: event\n fields:\n category: network\n module: rita\n- if:\n log.file.path: beacons.csv\n then: \n - add_fields:\n target: \"@metadata\"\n fields:\n pipeline: rita.beacon\n- if:\n regexp:\n log.file.path: \"*connections.csv\"\n then: \n - add_fields:\n target: \"@metadata\"\n fields:\n pipeline: rita.connection\n- if:\n log.file.path: \"exploded-dns.csv\"\n then: \n - add_fields:\n target: \"@metadata\"\n fields:\n pipeline: rita.dns" }}}}}}' -#echo - -# Elasticsearch logs -echo -echo "Setting up Elasticsearch package policy..." -curl -K /opt/so/conf/elasticsearch/curl.config -b "sid=$SESSIONCOOKIE" -L -X POST "localhost:5601/api/fleet/package_policies" -H 'kbn-xsrf: true' -H 'Content-Type: application/json' -d'{ "policy_id": "so-grid-nodes", "package": { "name": "elasticsearch", "version": "1.0.0" }, "id": "elasticsearch-logs", "name": "elasticsearch-logs", "description": "Elasticsearch Logs", "namespace": "default", "inputs": { "elasticsearch-logfile": { "enabled": true, "streams": { "elasticsearch.audit": { "enabled": false, "vars": { "paths": [ "/var/log/elasticsearch/*_audit.json" ] } }, "elasticsearch.deprecation": { "enabled": false, "vars": { "paths": [ "/var/log/elasticsearch/*_deprecation.json" ] } }, "elasticsearch.gc": { "enabled": false, "vars": { "paths": [ "/var/log/elasticsearch/gc.log.[0-9]*", "/var/log/elasticsearch/gc.log" ] } }, "elasticsearch.server": { "enabled": true, "vars": { "paths": [ "/opt/so/log/elasticsearch/*.log" ] } }, "elasticsearch.slowlog": { "enabled": false, "vars": { "paths": [ "/var/log/elasticsearch/*_index_search_slowlog.json", "/var/log/elasticsearch/*_index_indexing_slowlog.json" ] } } } }, "elasticsearch-elasticsearch/metrics": { "enabled": false, "vars": { "hosts": [ "http://localhost:9200" ], "scope": "node" }, "streams": { "elasticsearch.stack_monitoring.ccr": { "enabled": false }, "elasticsearch.stack_monitoring.cluster_stats": { "enabled": false }, "elasticsearch.stack_monitoring.enrich": { "enabled": false }, "elasticsearch.stack_monitoring.index": { "enabled": false }, "elasticsearch.stack_monitoring.index_recovery": { "enabled": false, "vars": { "active.only": true } }, "elasticsearch.stack_monitoring.index_summary": { "enabled": false }, "elasticsearch.stack_monitoring.ml_job": { "enabled": false }, "elasticsearch.stack_monitoring.node": { "enabled": false }, "elasticsearch.stack_monitoring.node_stats": { "enabled": false }, "elasticsearch.stack_monitoring.pending_tasks": { "enabled": false }, "elasticsearch.stack_monitoring.shard": { "enabled": false } } } } }' -echo - -# Logstash logs -#echo -#echo "Setting up Logstash package policy..." -#curl -K /opt/so/conf/elasticsearch/curl.config -b "sid=$SESSIONCOOKIE" -L -X POST "localhost:5601/api/fleet/package_policies" -H 'kbn-xsrf: true' -H 'Content-Type: application/json' -d'{ "policy_id": "so-grid-nodes", "package": { "name": "logstash", "version": "2.0.0" }, "id": "logstash-logs", "name": "logstash-logs", "description": "Logstash logs", "namespace": "default", "inputs": { "logstash-logfile": { "enabled": true, "streams": { "logstash.log": { "enabled": true, "vars": { "paths": [ "/opt/so/logs/logstash/logstash.log" ] } }, "logstash.slowlog": { "enabled": false, "vars": { "paths": [ "/var/log/logstash/logstash-slowlog-plain*.log", "/var/log/logstash/logstash-slowlog-json*.log" ] } } } }, "logstash-logstash/metrics": { "enabled": false, "vars": { "hosts": [ "http://localhost:9600" ], "period": "10s" }, "streams": { "logstash.stack_monitoring.node": { "enabled": false }, "logstash.stack_monitoring.node_stats": { "enabled": false } } } } }' -#echo - -# Kibana logs -#echo -#echo "Setting up Kibana package policy..." -#curl -K /opt/so/conf/elasticsearch/curl.config -b "sid=$SESSIONCOOKIE" -L -X POST "localhost:5601/api/fleet/package_policies" -H 'kbn-xsrf: true' -H 'Content-Type: application/json' -d'{ "policy_id": "so-grid-nodes", "package": { "name": "kibana", "version": "2.0.0" }, "id": "kibana-logs", "name": "kibana-logs", "description": "Kibana logs", "namespace": "default", "inputs": { "kibana-logfile": { "enabled": true, "streams": { "kibana.audit": { "enabled": false, "vars": { "paths": [ "/opt/so/log/kibana/kibana.log" ] } }, "kibana.log": { "enabled": true, "vars": { "paths": [ "/opt/so/log/kibana/kibana.log" ] } } } }, "kibana-kibana/metrics": { "enabled": false, "vars": { "hosts": [ "http://localhost:5601" ] }, "streams": { "kibana.stack_monitoring.cluster_actions": { "enabled": false }, "kibana.stack_monitoring.cluster_rules": { "enabled": false }, "kibana.stack_monitoring.node_actions": { "enabled": false }, "kibana.stack_monitoring.node_rules": { "enabled": false }, "kibana.stack_monitoring.stats": { "enabled": false }, "kibana.stack_monitoring.status": { "enabled": false } } } } }' -#echo - -# Redis logs -echo -echo "Setting up Redis package policy..." -curl -K /opt/so/conf/elasticsearch/curl.config -b "sid=$SESSIONCOOKIE" -L -X POST "localhost:5601/api/fleet/package_policies" -H 'kbn-xsrf: true' -H 'Content-Type: application/json' -d'{ "policy_id": "so-grid-nodes", "package": { "name": "redis", "version": "1.4.0" }, "id": "redis-logs", "name": "redis-logs", "description": "Redis logs", "namespace": "default", "inputs": { "redis-logfile": { "enabled": true, "streams": { "redis.log": { "enabled": true, "vars": { "paths": [ "/opt/so/log/redis/redis.log" ], "tags": [ "redis-log" ], "preserve_original_event": false } } } }, "redis-redis": { "enabled": false, "streams": { "redis.slowlog": { "enabled": false, "vars": { "hosts": [ "127.0.0.1:6379" ], "password": "" } } } }, "redis-redis/metrics": { "enabled": false, "vars": { "hosts": [ "127.0.0.1:6379" ], "idle_timeout": "20s", "maxconn": 10, "network": "tcp", "password": "" }, "streams": { "redis.info": { "enabled": false, "vars": { "period": "10s" } }, "redis.key": { "enabled": false, "vars": { "key.patterns": "- limit: 20\n pattern: '*'\n", "period": "10s" } }, "redis.keyspace": { "enabled": false, "vars": { "period": "10s" } } } } } }' -echo - -# IDH logs -echo -echo "Setting up IDH package policy..." -curl -K /opt/so/conf/elasticsearch/curl.config -b "sid=$SESSIONCOOKIE" -L -X POST "localhost:5601/api/fleet/package_policies" -H 'kbn-xsrf: true' -H 'Content-Type: application/json' -d'{"policy_id":"so-grid-nodes","package":{"name":"log","version":"1.1.1"},"id":"idh-logs","name":"idh-logs","namespace":"so","description":"IDH integration","inputs":{"logs-logfile":{"enabled":true,"streams":{"log.log":{"enabled":true,"vars":{"paths":["/nsm/idh/opencanary.log"],"data_stream.dataset":"idh","custom":"pipeline: common","processors": "\n- decode_json_fields:\n fields: [\"message\"]\n target: \"\"\n add_error_key: true\n- drop_fields:\n when:\n equals:\n logtype: \"1001\"\n fields: [\"src_host\", \"src_port\", \"dst_host\", \"dst_port\" ]\n ignore_missing: true\n- rename:\n fields:\n - from: \"src_host\"\n to: \"source.ip\"\n - from: \"src_port\"\n to: \"source.port\"\n - from: \"dst_host\"\n to: \"destination.host\"\n - from: \"dst_port\"\n to: \"destination.port\"\n ignore_missing: true\n- convert:\n fields:\n - {from: \"logtype\", to: \"event.code\", type: \"string\"}\n ignore_missing: true\n- drop_fields:\n fields: '\''[\"prospector\", \"input\", \"offset\", \"beat\"]'\''\n- add_fields:\n target: event\n fields:\n category: host\n module: opencanary","tags":[]}}}}}}' -echo - -# SOC - Server logs -echo -echo "Setting up SOC - Server Logs package policy..." -curl -K /opt/so/conf/elasticsearch/curl.config -b "sid=$SESSIONCOOKIE" -L -X POST "localhost:5601/api/fleet/package_policies" -H 'kbn-xsrf: true' -H 'Content-Type: application/json' -d'{"package":{"name":"log","version":"1.1.2"},"name":"soc-server-logs","namespace":"so","description":"Security Onion Console Logs","policy_id":"so-grid-nodes","inputs":{"logs-logfile":{"enabled":true,"streams":{"log.log":{"enabled":true,"vars":{"paths":["/opt/so/log/soc/sensoroni-server.log"],"data_stream.dataset":"soc","custom":"pipeline: common","processors": "- decode_json_fields:\n fields: [\"message\"]\n target: \"soc\"\n process_array: true\n max_depth: 2\n add_error_key: true \n- add_fields:\n target: event\n fields:\n category: host\n module: soc\n dataset_temp: server\n- rename:\n fields:\n - from: \"soc.fields.sourceIp\"\n to: \"source.ip\"\n - from: \"soc.fields.status\"\n to: \"http.response.status_code\"\n - from: \"soc.fields.method\"\n to: \"http.request.method\"\n - from: \"soc.fields.path\"\n to: \"url.path\"\n - from: \"soc.message\"\n to: \"event.action\"\n - from: \"soc.level\"\n to: \"log.level\"\n ignore_missing: true","tags":[]}}}}}}' -echo - -# SOC - Sensoroni logs -echo -echo "Setting up SOC - Sensoroni Logs package policy..." -curl -K /opt/so/conf/elasticsearch/curl.config -b "sid=$SESSIONCOOKIE" -L -X POST "localhost:5601/api/fleet/package_policies" -H 'kbn-xsrf: true' -H 'Content-Type: application/json' -d'{"package":{"name":"log","version":"1.1.2"},"name":"soc-sensoroni-logs","namespace":"so","description":"Security Onion - Sensoroni - Logs","policy_id":"so-grid-nodes","inputs":{"logs-logfile":{"enabled":true,"streams":{"log.log":{"enabled":true,"vars":{"paths":["/opt/so/log/sensoroni/sensoroni.log"],"data_stream.dataset":"soc","custom":"pipeline: common","processors": "- decode_json_fields:\n fields: [\"message\"]\n target: \"sensoroni\"\n process_array: true\n max_depth: 2\n add_error_key: true \n- add_fields:\n target: event\n fields:\n category: host\n module: soc\n dataset_temp: sensoroni\n- rename:\n fields:\n - from: \"sensoroni.fields.sourceIp\"\n to: \"source.ip\"\n - from: \"sensoroni.fields.status\"\n to: \"http.response.status_code\"\n - from: \"sensoroni.fields.method\"\n to: \"http.request.method\"\n - from: \"sensoroni.fields.path\"\n to: \"url.path\"\n - from: \"sensoroni.message\"\n to: \"event.action\"\n - from: \"sensoroni.level\"\n to: \"log.level\"\n ignore_missing: true","tags":[]}}}}}}' -echo - -# SOC - Elastic Auth Sync logs -echo -echo "Setting up SOC - Elastic Auth Sync Logs package policy..." -curl -K /opt/so/conf/elasticsearch/curl.config -b "sid=$SESSIONCOOKIE" -L -X POST "localhost:5601/api/fleet/package_policies" -H 'kbn-xsrf: true' -H 'Content-Type: application/json' -d'{"package":{"name":"log","version":"1.1.2"},"name":"soc-auth-sync-logs","namespace":"so","description":"Security Onion - Elastic Auth Sync - Logs","policy_id":"so-grid-nodes","inputs":{"logs-logfile":{"enabled":true,"streams":{"log.log":{"enabled":true,"vars":{"paths":["/opt/so/log/soc/sync.log"],"data_stream.dataset":"soc","custom":"pipeline: common","processors": "- dissect:\n tokenizer: \"%{event.action}\"\n field: \"message\"\n target_prefix: \"\"\n- add_fields:\n target: event\n fields:\n category: host\n module: soc\n dataset_temp: auth_sync","tags":[]}}}}}}' -echo - -# SOC - Salt Relay logs -echo -echo "Setting up SOC - Salt_Relay Logs package policy..." -curl -K /opt/so/conf/elasticsearch/curl.config -b "sid=$SESSIONCOOKIE" -L -X POST "localhost:5601/api/fleet/package_policies" -H 'kbn-xsrf: true' -H 'Content-Type: application/json' -d'{"package":{"name":"log","version":"1.1.2"},"name":"soc-salt-relay-logs","namespace":"so","description":"Security Onion - Salt Relay - Logs","policy_id":"so-grid-nodes","inputs":{"logs-logfile":{"enabled":true,"streams":{"log.log":{"enabled":true,"vars":{"paths":["/opt/so/log/soc/salt-relay.log"],"data_stream.dataset":"soc","custom":"pipeline: common","processors": "- dissect:\n tokenizer: \"%{soc.ts} | %{event.action}\"\n field: \"message\"\n target_prefix: \"\"\n- add_fields:\n target: event\n fields:\n category: host\n module: soc\n dataset_temp: salt_relay","tags":[]}}}}}}' -echo +# Grid Nodes +for INTEGRATION in /opt/so/saltstack/default/salt/elasticfleet/files/integrations/grid-nodes/*.json +do + printf "\n\nGrid Nodes Policy - Loading $INTEGRATION\n" + elastic_fleet_integration_create "@$INTEGRATION" +done \ No newline at end of file diff --git a/salt/common/tools/sbin/so-elastic-fleet-setup b/salt/common/tools/sbin/so-elastic-fleet-setup index 86b9c1107..7fe336625 100755 --- a/salt/common/tools/sbin/so-elastic-fleet-setup +++ b/salt/common/tools/sbin/so-elastic-fleet-setup @@ -8,40 +8,6 @@ . /usr/sbin/so-common -elastic_fleet_policy_create() { - - NAME=$1 - DESC=$2 - FLEETSERVER=$3 - - JSON_STRING=$( jq -n \ - --arg NAME "$NAME" \ - --arg DESC "$DESC" \ - --arg FLEETSERVER "$FLEETSERVER" \ - '{"name": $NAME,"id":$NAME,"description":$DESC,"namespace":"default","monitoring_enabled":["logs"],"inactivity_timeout":1209600,"has_fleet_server":$FLEETSERVER}' - ) - # Create Fleet Policy - curl -K /opt/so/conf/elasticsearch/curl.config -L -X POST "localhost:5601/api/fleet/agent_policies" -H 'kbn-xsrf: true' -H 'Content-Type: application/json' -d "$JSON_STRING" - -} - -elastic_fleet_policy_update() { - - POLICYID=$1 - JSON_STRING_UPDATE=$2 - - curl -K /opt/so/conf/elasticsearch/curl.config -L -X PUT "localhost:5601/api/fleet/agent_policies/$POLICYID" -H 'kbn-xsrf: true' -H 'Content-Type: application/json' -d "$JSON_STRING_UPDATE" -} - -elastic_fleet_integration_create() { - - JSONBLOB=$1 - - #curl -K /opt/so/conf/elasticsearch/curl.config -L -X PUT "localhost:5601/api/fleet/agent_policies/package_policies" -H 'kbn-xsrf: true' -H 'Content-Type: application/json' -d "$JSONBLOB" - curl -K /opt/so/conf/elasticsearch/curl.config -L -X POST "localhost:5601/api/fleet/package_policies" -H 'kbn-xsrf: true' -H 'Content-Type: application/json' -d "$JSONBLOB" - -} - printf "\n### Create ES Token ###\n" ESTOKEN=$(curl -K /opt/so/conf/elasticsearch/curl.config -L -X POST "localhost:5601/api/fleet/service_tokens" -H 'kbn-xsrf: true' -H 'Content-Type: application/json' | jq -r .value) @@ -79,30 +45,22 @@ printf "\n\n" # Manager Fleet Server Host elastic_fleet_policy_create "FleetServer_{{ GLOBALS.hostname }}" "Fleet Server - {{ GLOBALS.hostname }}" "true" | jq -#elastic_fleet_policy_update "FleetServer_{{ GLOBALS.hostname }}" "@/opt/so/saltstack/default/salt/elasticfleet/files/FleeServerHost_Fixup.json" -#Temp Fixup +#Temp Fixup for ES Output bug JSON_STRING=$( jq -n \ --arg NAME "FleetServer_{{ GLOBALS.hostname }}" \ '{"name": $NAME,"description": $NAME,"namespace":"default","monitoring_enabled":["logs"],"inactivity_timeout":120,"data_output_id":"so-manager_elasticsearch"}' ) curl -K /opt/so/conf/elasticsearch/curl.config -L -X PUT "localhost:5601/api/fleet/agent_policies/FleetServer_{{ GLOBALS.hostname }}" -H 'kbn-xsrf: true' -H 'Content-Type: application/json' -d "$JSON_STRING" +# Initial Endpoints Policy +elastic_fleet_policy_create "endpoints-initial" "Initial Endpoint Policy" "false" -# Initial Endpoints -elastic_fleet_policy_create "endpoints-initial" "Initial Endpoint Policy" "false" | jq -for INTEGRATION in /opt/so/saltstack/default/salt/elasticfleet/files/integrations/endpoints-initial/*.json -do - elastic_fleet_integration_create "@$INTEGRATION" | jq -done - -# Grid Nodes +# Grid Nodes Policy elastic_fleet_policy_create "so-grid-nodes" "SO Grid Node Policy" "false" -for INTEGRATION in /opt/so/saltstack/default/salt/elasticfleet/files/integrations/grid-nodes/*.json -do - elastic_fleet_integration_create "@$INTEGRATION" | jq -done +# Load Integrations for default policies +so-elastic-fleet-integration-policy-load ### Finalization ### diff --git a/salt/common/tools/sbin/so-minion b/salt/common/tools/sbin/so-minion index cf50a49d7..2f506863d 100755 --- a/salt/common/tools/sbin/so-minion +++ b/salt/common/tools/sbin/so-minion @@ -237,7 +237,23 @@ function create_fleet_policy() { # Update Fleet Policy - ES Output curl -K /opt/so/conf/elasticsearch/curl.config -L -X PUT "localhost:5601/api/fleet/agent_policies/FleetServer_$LSHOSTNAME" -H 'kbn-xsrf: true' -H 'Content-Type: application/json' -d "$JSON_STRING_UPDATE" -} +} + +function update_fleet_host_urls() { + # Query for current Fleet Host URLs & append New Fleet Node Hostname & IP + JSON_STRING=$(curl -K /opt/so/conf/elasticsearch/curl.config 'http://localhost:5601/api/fleet/fleet_server_hosts' | jq --arg HOSTNAME "https://$LSHOSTNAME:8220" --arg IP "https://$MAINIP:8220" -r '.items[].host_urls += [ $HOSTNAME, $IP ] | {"name":"Default","host_urls": .items[].host_urls,"is_default":true,"proxy_id":null}') + + # Update Fleet Host URLs + curl -K /opt/so/conf/elasticsearch/curl.config -L -X PUT "localhost:5601/api/fleet/fleet_server_hosts/fleet-default-fleet-server-host" -H 'kbn-xsrf: true' -H 'Content-Type: application/json' -d "$JSON_STRING" +} + +function update_logstash_outputs() { + # Query for current Logstash outputs & append New Fleet Node Hostname & IP + JSON_STRING=$(curl -K /opt/so/conf/elasticsearch/curl.config 'http://localhost:5601/api/fleet/outputs/so-manager_logstash' | jq --arg HOSTNAME "$LSHOSTNAME:5055" --arg IP "$MAINIP:5055" -r '.item.hosts += [ $HOSTNAME, $IP ] | {"name":"grid-logstash","type":"logstash","hosts": .item.hosts,"is_default":true,"is_default_monitoring":true,"config_yaml":""}') + + # Update Logstash Outputs + curl -K /opt/so/conf/elasticsearch/curl.config -L -X PUT "localhost:5601/api/fleet/outputs/so-manager_logstash" -H 'kbn-xsrf: true' -H 'Content-Type: application/json' -d "$JSON_STRING" +} function updateMine() { salt "$MINION_ID" mine.send network.ip_addrs interface="$MNIC" @@ -255,6 +271,8 @@ function createFLEET() { add_fleet_to_minion add_logstash_to_minion create_fleet_policy + update_fleet_host_urls + update_logstash_outputs } function createIDH() { diff --git a/salt/elasticfleet/files/integrations/endpoints-initial/system-endpoints.json b/salt/elasticfleet/files/integrations/endpoints-initial/system-endpoints.json new file mode 100644 index 000000000..eb5ef74e9 --- /dev/null +++ b/salt/elasticfleet/files/integrations/endpoints-initial/system-endpoints.json @@ -0,0 +1,76 @@ +{ + "package": { + "name": "system", + "version": "1.25.2" + }, + "name": "system-endpoints", + "namespace": "default", + "policy_id": "endpoints-initial", + "inputs": { + "system-logfile": { + "enabled": true, + "streams": { + "system.auth": { + "enabled": true, + "vars": { + "ignore_older": "72h", + "paths": [ + "/var/log/auth.log*", + "/var/log/secure*" + ], + "preserve_original_event": false, + "tags": [ + "system-auth" + ] + } + }, + "system.syslog": { + "enabled": true, + "vars": { + "paths": [ + "/var/log/messages*", + "/var/log/syslog*" + ], + "tags": [], + "ignore_older": "72h" + } + } + } + }, + "system-winlog": { + "enabled": true, + "streams": { + "system.application": { + "enabled": true, + "vars": { + "preserve_original_event": false, + "ignore_older": "72h", + "language": 0, + "tags": [] + } + }, + "system.security": { + "enabled": true, + "vars": { + "preserve_original_event": false, + "ignore_older": "72h", + "language": 0, + "tags": [] + } + }, + "system.system": { + "enabled": true, + "vars": { + "preserve_original_event": false, + "ignore_older": "72h", + "language": 0, + "tags": [] + } + } + } + }, + "system-system/metrics": { + "enabled": false + } + } +} diff --git a/salt/elasticfleet/files/integrations/endpoints-initial/windows-endpoints.json b/salt/elasticfleet/files/integrations/endpoints-initial/windows-endpoints.json new file mode 100644 index 000000000..9b647c8ab --- /dev/null +++ b/salt/elasticfleet/files/integrations/endpoints-initial/windows-endpoints.json @@ -0,0 +1,59 @@ +{ + "package": { + "name": "windows", + "version": "1.19.1" + }, + "name": "windows-endpoints", + "namespace": "default", + "policy_id": "endpoints-initial", + "inputs": { + "windows-winlog": { + "enabled": true, + "streams": { + "windows.forwarded": { + "enabled": true, + "vars": { + "preserve_original_event": false, + "ignore_older": "72h", + "language": 0, + "tags": [ + "forwarded" + ] + } + }, + "windows.powershell": { + "enabled": true, + "vars": { + "preserve_original_event": false, + "event_id": "400, 403, 600, 800", + "ignore_older": "72h", + "language": 0, + "tags": [] + } + }, + "windows.powershell_operational": { + "enabled": true, + "vars": { + "preserve_original_event": false, + "event_id": "4103, 4104, 4105, 4106", + "ignore_older": "72h", + "language": 0, + "tags": [] + } + }, + "windows.sysmon_operational": { + "enabled": true, + "vars": { + "preserve_original_event": false, + "ignore_older": "72h", + "language": 0, + "tags": [] + } + } + } + }, + "windows-windows/metrics": { + "enabled": false + } + } +} diff --git a/salt/elasticfleet/files/integrations/grid-nodes/elasticsearch-logs.json b/salt/elasticfleet/files/integrations/grid-nodes/elasticsearch-logs.json new file mode 100644 index 000000000..1a93a9022 --- /dev/null +++ b/salt/elasticfleet/files/integrations/grid-nodes/elasticsearch-logs.json @@ -0,0 +1,106 @@ +{ + "package": { + "name": "elasticsearch", + "version": "1.0.0" + }, + "name": "elasticsearch-logs", + "namespace": "default", + "description": "Elasticsearch Logs", + "policy_id": "so-grid-nodes", + "inputs": { + "elasticsearch-logfile": { + "enabled": true, + "streams": { + "elasticsearch.audit": { + "enabled": false, + "vars": { + "paths": [ + "/var/log/elasticsearch/*_audit.json" + ] + } + }, + "elasticsearch.deprecation": { + "enabled": false, + "vars": { + "paths": [ + "/var/log/elasticsearch/*_deprecation.json" + ] + } + }, + "elasticsearch.gc": { + "enabled": false, + "vars": { + "paths": [ + "/var/log/elasticsearch/gc.log.[0-9]*", + "/var/log/elasticsearch/gc.log" + ] + } + }, + "elasticsearch.server": { + "enabled": true, + "vars": { + "paths": [ + "/opt/so/log/elasticsearch/*.log" + ] + } + }, + "elasticsearch.slowlog": { + "enabled": false, + "vars": { + "paths": [ + "/var/log/elasticsearch/*_index_search_slowlog.json", + "/var/log/elasticsearch/*_index_indexing_slowlog.json" + ] + } + } + } + }, + "elasticsearch-elasticsearch/metrics": { + "enabled": false, + "vars": { + "hosts": [ + "http://localhost:9200" + ], + "scope": "node" + }, + "streams": { + "elasticsearch.stack_monitoring.ccr": { + "enabled": false + }, + "elasticsearch.stack_monitoring.cluster_stats": { + "enabled": false + }, + "elasticsearch.stack_monitoring.enrich": { + "enabled": false + }, + "elasticsearch.stack_monitoring.index": { + "enabled": false + }, + "elasticsearch.stack_monitoring.index_recovery": { + "enabled": false, + "vars": { + "active.only": true + } + }, + "elasticsearch.stack_monitoring.index_summary": { + "enabled": false + }, + "elasticsearch.stack_monitoring.ml_job": { + "enabled": false + }, + "elasticsearch.stack_monitoring.node": { + "enabled": false + }, + "elasticsearch.stack_monitoring.node_stats": { + "enabled": false + }, + "elasticsearch.stack_monitoring.pending_tasks": { + "enabled": false + }, + "elasticsearch.stack_monitoring.shard": { + "enabled": false + } + } + } + } +} diff --git a/salt/elasticfleet/files/integrations/grid-nodes/import-evtx-logs.json b/salt/elasticfleet/files/integrations/grid-nodes/import-evtx-logs.json new file mode 100644 index 000000000..aa54f7226 --- /dev/null +++ b/salt/elasticfleet/files/integrations/grid-nodes/import-evtx-logs.json @@ -0,0 +1,29 @@ +{ + "package": { + "name": "log", + "version": "1.1.0" + }, + "name": "import-evtx-logs", + "namespace": "so", + "description": "Import Windows EVTX logs", + "policy_id": "so-grid-nodes", + "inputs": { + "logs-logfile": { + "enabled": true, + "streams": { + "log.log": { + "enabled": true, + "vars": { + "paths": [ + "/nsm/import/*/evtx/data.json" + ], + "data_stream.dataset": "import", + "tags": [], + "processors": "- dissect:\n tokenizer: \"/nsm/import/%{import.id}/evtx/%{import.file}\"\n field: \"log.file.path\"\n target_prefix: \"\"\n- decode_json_fields:\n fields: [\"message\"]\n target: \"\"\n- add_fields:\n target: event\n fields:\n module: windows_eventlog\n imported: true", + "custom": "pipeline: import.wel" + } + } + } + } + } +} diff --git a/salt/elasticfleet/files/integrations/grid-nodes/import-suricata-logs.json b/salt/elasticfleet/files/integrations/grid-nodes/import-suricata-logs.json new file mode 100644 index 000000000..e8b05a7d1 --- /dev/null +++ b/salt/elasticfleet/files/integrations/grid-nodes/import-suricata-logs.json @@ -0,0 +1,29 @@ +{ + "package": { + "name": "log", + "version": "1.1.0" + }, + "name": "import-suricata-logs", + "namespace": "so", + "description": "Import Suricata logs", + "policy_id": "so-grid-nodes", + "inputs": { + "logs-logfile": { + "enabled": true, + "streams": { + "log.log": { + "enabled": true, + "vars": { + "paths": [ + "/nsm/import/*/suricata/eve*.json" + ], + "data_stream.dataset": "import", + "tags": [], + "processors": "- add_fields:\n target: event\n fields:\n category: network\n module: suricata\n imported: true\n- dissect:\n tokenizer: \"/nsm/import/%{import.id}/suricata/%{import.file}\"\n field: \"log.file.path\"\n target_prefix: \"\"", + "custom": "pipeline: suricata.common" + } + } + } + } + } +} diff --git a/salt/elasticfleet/files/integrations/grid-nodes/import-zeek-logs.json b/salt/elasticfleet/files/integrations/grid-nodes/import-zeek-logs.json new file mode 100644 index 000000000..ab752eaec --- /dev/null +++ b/salt/elasticfleet/files/integrations/grid-nodes/import-zeek-logs.json @@ -0,0 +1,29 @@ +{ + "package": { + "name": "log", + "version": "1.1.0" + }, + "name": "import-zeek-logs", + "namespace": "so", + "description": "Zeek Import logs", + "policy_id": "so-grid-nodes", + "inputs": { + "logs-logfile": { + "enabled": true, + "streams": { + "log.log": { + "enabled": true, + "vars": { + "paths": [ + "/nsm/import/*/zeek/logs/*.log" + ], + "data_stream.dataset": "import", + "tags": [], + "processors": "- dissect:\n tokenizer: \"/nsm/import/%{import.id}/zeek/logs/%{import.file}\"\n field: \"log.file.path\"\n target_prefix: \"\"\n- script:\n lang: javascript\n source: >\n function process(event) {\n var pl = event.Get(\"import.file\").slice(0,-4);\n event.Put(\"@metadata.pipeline\", \"zeek.\" + pl);\n }\n- add_fields:\n target: event\n fields:\n category: network\n module: zeek\n imported: true\n- add_tags:\n tags: \"ics\"\n when:\n regexp:\n import.file: \"^bacnet*|^bsap*|^cip*|^cotp*|^dnp3*|^ecat*|^enip*|^modbus*|^opcua*|^profinet*|^s7comm*\"", + "custom": "exclude_files: [\"broker|capture_loss|ecat_arp_info|loaded_scripts|packet_filter|stats|stderr|stdout.log$\"]\n" + } + } + } + } + } +} diff --git a/salt/elasticfleet/files/integrations/grid-nodes/osquery-grid-nodes.json b/salt/elasticfleet/files/integrations/grid-nodes/osquery-grid-nodes.json new file mode 100644 index 000000000..92f10f591 --- /dev/null +++ b/salt/elasticfleet/files/integrations/grid-nodes/osquery-grid-nodes.json @@ -0,0 +1,20 @@ +{ + "package": { + "name": "osquery_manager", + "version": "1.6.0" + }, + "name": "osquery-grid-nodes", + "namespace": "default", + "policy_id": "so-grid-nodes", + "inputs": { + "osquery_manager-osquery": { + "enabled": true, + "streams": { + "osquery_manager.result": { + "enabled": true, + "vars": {} + } + } + } + } +} diff --git a/salt/elasticfleet/files/integrations/grid-nodes/redis-logs.json b/salt/elasticfleet/files/integrations/grid-nodes/redis-logs.json new file mode 100644 index 000000000..8b71cbac7 --- /dev/null +++ b/salt/elasticfleet/files/integrations/grid-nodes/redis-logs.json @@ -0,0 +1,76 @@ +{ + "package": { + "name": "redis", + "version": "1.4.0" + }, + "name": "redis-logs", + "namespace": "default", + "description": "Redis logs", + "policy_id": "so-grid-nodes", + "inputs": { + "redis-logfile": { + "enabled": true, + "streams": { + "redis.log": { + "enabled": true, + "vars": { + "paths": [ + "/opt/so/log/redis/redis.log" + ], + "tags": [ + "redis-log" + ], + "preserve_original_event": false + } + } + } + }, + "redis-redis": { + "enabled": false, + "streams": { + "redis.slowlog": { + "enabled": false, + "vars": { + "hosts": [ + "127.0.0.1:6379" + ], + "password": "" + } + } + } + }, + "redis-redis/metrics": { + "enabled": false, + "vars": { + "hosts": [ + "127.0.0.1:6379" + ], + "idle_timeout": "20s", + "maxconn": 10, + "network": "tcp", + "password": "" + }, + "streams": { + "redis.info": { + "enabled": false, + "vars": { + "period": "10s" + } + }, + "redis.key": { + "enabled": false, + "vars": { + "key.patterns": "- limit: 20\n pattern: *\n", + "period": "10s" + } + }, + "redis.keyspace": { + "enabled": false, + "vars": { + "period": "10s" + } + } + } + } + } +} diff --git a/salt/elasticfleet/files/integrations/grid-nodes/soc-auth-sync-logs.json b/salt/elasticfleet/files/integrations/grid-nodes/soc-auth-sync-logs.json new file mode 100644 index 000000000..e5067490d --- /dev/null +++ b/salt/elasticfleet/files/integrations/grid-nodes/soc-auth-sync-logs.json @@ -0,0 +1,29 @@ +{ + "package": { + "name": "log", + "version": "1.1.2" + }, + "name": "soc-auth-sync-logs", + "namespace": "so", + "description": "Security Onion - Elastic Auth Sync - Logs", + "policy_id": "so-grid-nodes", + "inputs": { + "logs-logfile": { + "enabled": true, + "streams": { + "log.log": { + "enabled": true, + "vars": { + "paths": [ + "/opt/so/log/soc/sync.log" + ], + "data_stream.dataset": "soc", + "tags": [], + "processors": "- dissect:\n tokenizer: \"%{event.action}\"\n field: \"message\"\n target_prefix: \"\"\n- add_fields:\n target: event\n fields:\n category: host\n module: soc\n dataset_temp: auth_sync", + "custom": "pipeline: common" + } + } + } + } + } +} diff --git a/salt/elasticfleet/files/integrations/grid-nodes/soc-salt-relay-logs.json b/salt/elasticfleet/files/integrations/grid-nodes/soc-salt-relay-logs.json new file mode 100644 index 000000000..90ac79824 --- /dev/null +++ b/salt/elasticfleet/files/integrations/grid-nodes/soc-salt-relay-logs.json @@ -0,0 +1,29 @@ +{ + "package": { + "name": "log", + "version": "1.1.2" + }, + "name": "soc-salt-relay-logs", + "namespace": "so", + "description": "Security Onion - Salt Relay - Logs", + "policy_id": "so-grid-nodes", + "inputs": { + "logs-logfile": { + "enabled": true, + "streams": { + "log.log": { + "enabled": true, + "vars": { + "paths": [ + "/opt/so/log/soc/salt-relay.log" + ], + "data_stream.dataset": "soc", + "tags": [], + "processors": "- dissect:\n tokenizer: \"%{soc.ts} | %{event.action}\"\n field: \"message\"\n target_prefix: \"\"\n- add_fields:\n target: event\n fields:\n category: host\n module: soc\n dataset_temp: salt_relay", + "custom": "pipeline: common" + } + } + } + } + } +} diff --git a/salt/elasticfleet/files/integrations/grid-nodes/soc-sensoroni-logs.json b/salt/elasticfleet/files/integrations/grid-nodes/soc-sensoroni-logs.json new file mode 100644 index 000000000..8d94f2d8d --- /dev/null +++ b/salt/elasticfleet/files/integrations/grid-nodes/soc-sensoroni-logs.json @@ -0,0 +1,29 @@ +{ + "package": { + "name": "log", + "version": "1.1.2" + }, + "name": "soc-sensoroni-logs", + "namespace": "so", + "description": "Security Onion - Sensoroni - Logs", + "policy_id": "so-grid-nodes", + "inputs": { + "logs-logfile": { + "enabled": true, + "streams": { + "log.log": { + "enabled": true, + "vars": { + "paths": [ + "/opt/so/log/sensoroni/sensoroni.log" + ], + "data_stream.dataset": "soc", + "tags": [], + "processors": "- decode_json_fields:\n fields: [\"message\"]\n target: \"sensoroni\"\n process_array: true\n max_depth: 2\n add_error_key: true \n- add_fields:\n target: event\n fields:\n category: host\n module: soc\n dataset_temp: sensoroni\n- rename:\n fields:\n - from: \"sensoroni.fields.sourceIp\"\n to: \"source.ip\"\n - from: \"sensoroni.fields.status\"\n to: \"http.response.status_code\"\n - from: \"sensoroni.fields.method\"\n to: \"http.request.method\"\n - from: \"sensoroni.fields.path\"\n to: \"url.path\"\n - from: \"sensoroni.message\"\n to: \"event.action\"\n - from: \"sensoroni.level\"\n to: \"log.level\"\n ignore_missing: true", + "custom": "pipeline: common" + } + } + } + } + } +} diff --git a/salt/elasticfleet/files/integrations/grid-nodes/soc-server-logs.json b/salt/elasticfleet/files/integrations/grid-nodes/soc-server-logs.json new file mode 100644 index 000000000..908b1a782 --- /dev/null +++ b/salt/elasticfleet/files/integrations/grid-nodes/soc-server-logs.json @@ -0,0 +1,29 @@ +{ + "package": { + "name": "log", + "version": "1.1.2" + }, + "name": "soc-server-logs", + "namespace": "so", + "description": "Security Onion Console Logs", + "policy_id": "so-grid-nodes", + "inputs": { + "logs-logfile": { + "enabled": true, + "streams": { + "log.log": { + "enabled": true, + "vars": { + "paths": [ + "/opt/so/log/soc/sensoroni-server.log" + ], + "data_stream.dataset": "soc", + "tags": [], + "processors": "- decode_json_fields:\n fields: [\"message\"]\n target: \"soc\"\n process_array: true\n max_depth: 2\n add_error_key: true \n- add_fields:\n target: event\n fields:\n category: host\n module: soc\n dataset_temp: server\n- rename:\n fields:\n - from: \"soc.fields.sourceIp\"\n to: \"source.ip\"\n - from: \"soc.fields.status\"\n to: \"http.response.status_code\"\n - from: \"soc.fields.method\"\n to: \"http.request.method\"\n - from: \"soc.fields.path\"\n to: \"url.path\"\n - from: \"soc.message\"\n to: \"event.action\"\n - from: \"soc.level\"\n to: \"log.level\"\n ignore_missing: true", + "custom": "pipeline: common" + } + } + } + } + } +} diff --git a/salt/elasticfleet/files/integrations/grid-nodes/strelka-logs.json b/salt/elasticfleet/files/integrations/grid-nodes/strelka-logs.json new file mode 100644 index 000000000..75bd9d73c --- /dev/null +++ b/salt/elasticfleet/files/integrations/grid-nodes/strelka-logs.json @@ -0,0 +1,29 @@ +{ + "package": { + "name": "log", + "version": "1.1.0" + }, + "name": "strelka-logs", + "namespace": "so", + "description": "Strelka logs", + "policy_id": "so-grid-nodes", + "inputs": { + "logs-logfile": { + "enabled": true, + "streams": { + "log.log": { + "enabled": true, + "vars": { + "paths": [ + "/nsm/strelka/log/strelka.log" + ], + "data_stream.dataset": "strelka", + "tags": [], + "processors": "- add_fields:\n target: event\n fields:\n category: file\n module: strelka", + "custom": "pipeline: strelka.file" + } + } + } + } + } +} diff --git a/salt/elasticfleet/files/integrations/grid-nodes/suricata-logs.json b/salt/elasticfleet/files/integrations/grid-nodes/suricata-logs.json new file mode 100644 index 000000000..623513c34 --- /dev/null +++ b/salt/elasticfleet/files/integrations/grid-nodes/suricata-logs.json @@ -0,0 +1,29 @@ +{ + "package": { + "name": "log", + "version": "1.1.0" + }, + "name": "suricata-logs", + "namespace": "so", + "description": "Suricata integration", + "policy_id": "so-grid-nodes", + "inputs": { + "logs-logfile": { + "enabled": true, + "streams": { + "log.log": { + "enabled": true, + "vars": { + "paths": [ + "/nsm/suricata/eve*.json" + ], + "data_stream.dataset": "suricata", + "tags": [], + "processors": "- add_fields:\n target: event\n fields:\n category: network\n module: suricata", + "custom": "pipeline: suricata.common" + } + } + } + } + } +} diff --git a/salt/elasticfleet/files/integrations/grid-nodes/syslog-tcp-514.json b/salt/elasticfleet/files/integrations/grid-nodes/syslog-tcp-514.json new file mode 100644 index 000000000..a6321f19b --- /dev/null +++ b/salt/elasticfleet/files/integrations/grid-nodes/syslog-tcp-514.json @@ -0,0 +1,32 @@ +{ + "package": { + "name": "tcp", + "version": "1.5.0" + }, + "name": "syslog-tcp-514", + "namespace": "so", + "description": "Syslog Over TCP Port 514", + "policy_id": "so-grid-nodes", + "inputs": { + "tcp-tcp": { + "enabled": true, + "streams": { + "tcp.generic": { + "enabled": true, + "vars": { + "listen_address": "0.0.0.0", + "listen_port": "514", + "data_stream.dataset": "syslog", + "pipeline": "syslog", + "processors": "- add_fields:\n target: event\n fields:\n module: syslog", + "tags": [ + "syslog" + ], + "syslog_options": "field: message\n#format: auto\n#timezone: Local", + "ssl": "" + } + } + } + } + } +} diff --git a/salt/elasticfleet/files/integrations/grid-nodes/syslog-udp-514.json b/salt/elasticfleet/files/integrations/grid-nodes/syslog-udp-514.json new file mode 100644 index 000000000..b9dd14640 --- /dev/null +++ b/salt/elasticfleet/files/integrations/grid-nodes/syslog-udp-514.json @@ -0,0 +1,33 @@ +{ + "package": { + "name": "udp", + "version": "1.5.0" + }, + "name": "syslog-udp-514", + "namespace": "so", + "description": "Syslog over UDP Port 514", + "policy_id": "so-grid-nodes", + "inputs": { + "udp-udp": { + "enabled": true, + "streams": { + "udp.generic": { + "enabled": true, + "vars": { + "listen_address": "0.0.0.0", + "listen_port": "514", + "data_stream.dataset": "syslog", + "pipeline": "syslog", + "max_message_size": "10KiB", + "keep_null": false, + "processors": "- add_fields:\n target: event\n fields: \n module: syslog\n", + "tags": [ + "syslog" + ], + "syslog_options": "field: message\n#format: auto\n#timezone: Local" + } + } + } + } + } +} diff --git a/salt/elasticfleet/files/integrations/grid-nodes/system-grid-nodes.json b/salt/elasticfleet/files/integrations/grid-nodes/system-grid-nodes.json new file mode 100644 index 000000000..866bae8cd --- /dev/null +++ b/salt/elasticfleet/files/integrations/grid-nodes/system-grid-nodes.json @@ -0,0 +1,47 @@ +{ + "package": { + "name": "system", + "version": "1.25.2" + }, + "name": "system-grid-nodes", + "namespace": "default", + "policy_id": "so-grid-nodes", + "inputs": { + "system-logfile": { + "enabled": true, + "streams": { + "system.auth": { + "enabled": true, + "vars": { + "ignore_older": "72h", + "paths": [ + "/var/log/auth.log*", + "/var/log/secure*" + ], + "preserve_original_event": false, + "tags": [ + "system-auth" + ] + } + }, + "system.syslog": { + "enabled": true, + "vars": { + "paths": [ + "/var/log/messages*", + "/var/log/syslog*" + ], + "tags": [], + "ignore_older": "72h" + } + } + } + }, + "system-winlog": { + "enabled": false + }, + "system-system/metrics": { + "enabled": false + } + } +} diff --git a/salt/elasticfleet/files/integrations/grid-nodes/zeek-logs.json b/salt/elasticfleet/files/integrations/grid-nodes/zeek-logs.json new file mode 100644 index 000000000..a4e0c94ee --- /dev/null +++ b/salt/elasticfleet/files/integrations/grid-nodes/zeek-logs.json @@ -0,0 +1,29 @@ +{ + "package": { + "name": "log", + "version": "1.1.0" + }, + "name": "zeek-logs", + "namespace": "so", + "description": "Zeek logs", + "policy_id": "so-grid-nodes", + "inputs": { + "logs-logfile": { + "enabled": true, + "streams": { + "log.log": { + "enabled": true, + "vars": { + "paths": [ + "/nsm/zeek/logs/current/*.log" + ], + "data_stream.dataset": "zeek", + "tags": [], + "processors": "- dissect:\n tokenizer: \"/nsm/zeek/logs/current/%{pipeline}.log\"\n field: \"log.file.path\"\n trim_chars: \".log\"\n target_prefix: \"\"\n- script:\n lang: javascript\n source: >\n function process(event) {\n var pl = event.Get(\"pipeline\");\n event.Put(\"@metadata.pipeline\", \"zeek.\" + pl);\n }\n- add_fields:\n target: event\n fields:\n category: network\n module: zeek\n- add_tags:\n tags: \"ics\"\n when:\n regexp:\n pipeline: \"^bacnet*|^bsap*|^cip*|^cotp*|^dnp3*|^ecat*|^enip*|^modbus*|^opcua*|^profinet*|^s7comm*\"", + "custom": "exclude_files: [\"broker|capture_loss|ecat_arp_info|loaded_scripts|packet_filter|stats|stderr|stdout.log$\"]\n" + } + } + } + } + } +} diff --git a/salt/top.sls b/salt/top.sls index 8cad2816c..372c64115 100644 --- a/salt/top.sls +++ b/salt/top.sls @@ -347,6 +347,7 @@ base: - firewall - logstash - elasticfleet + - elasticfleet.install_agent_grid - schedule - docker_clean diff --git a/setup/so-setup b/setup/so-setup index ddf39fdee..3259fd079 100755 --- a/setup/so-setup +++ b/setup/so-setup @@ -634,6 +634,8 @@ if ! [[ -f $install_opt_file ]]; then logCmd "salt-call state.apply -l info manager" logCmd "salt-call state.apply influxdb -l info" logCmd "salt-call state.highstate -l info" + title "Setting up Kibana Default Space" + logCmd "so-kibana-space-defaults" add_web_user info "Restarting SOC to pick up initial user" logCmd "so-soc-restart"