From b9ff1704b0d6fa0845252a7f2b0b8026b238397a Mon Sep 17 00:00:00 2001 From: Josh Patterson Date: Thu, 11 Dec 2025 17:30:06 -0500 Subject: [PATCH] the great ssl refactor --- pillar/ca/init.sls | 2 + pillar/top.sls | 1 + salt/allowed_states.map.jinja | 21 +- salt/ca/dirs.sls | 4 - salt/ca/files/signing_policies.conf | 71 +-- salt/ca/init.sls | 60 +-- salt/ca/map.jinja | 3 + salt/ca/remove.sls | 20 +- salt/ca/server.sls | 53 ++ salt/ca/signing_policy.sls | 15 + salt/ca/trustca.sls | 24 + salt/desktop/trusted-ca.sls | 19 +- salt/docker/init.sls | 8 +- salt/elasticagent/enabled.sls | 3 + salt/elasticfleet/enabled.sls | 9 +- salt/elasticfleet/ssl.sls | 186 +++++++ salt/elasticsearch/ca.sls | 4 +- salt/elasticsearch/config.sls | 5 - salt/elasticsearch/enabled.sls | 24 +- salt/elasticsearch/ssl.sls | 66 +++ salt/influxdb/config.sls | 1 - salt/influxdb/enabled.sls | 3 + salt/influxdb/ssl.sls | 55 ++ salt/kafka/enabled.sls | 4 +- salt/kafka/ssl.sls | 24 +- salt/logstash/config.sls | 1 - salt/logstash/enabled.sls | 61 ++- salt/logstash/ssl.sls | 287 ++++++++++ salt/manager/elasticsearch.sls | 5 + salt/manager/kibana.sls | 7 +- salt/manager/sync_es_users.sls | 5 + salt/manager/tools/sbin/so-minion | 11 + salt/manager/tools/sbin/soup | 1 - salt/nginx/config.sls | 3 - salt/nginx/enabled.sls | 108 +--- salt/nginx/ssl.sls | 87 ++++ salt/pcap/ca.sls | 21 + salt/pcap/config.sls | 6 - salt/pcap/enabled.sls | 1 + salt/redis/config.sls | 3 - salt/redis/enabled.sls | 20 +- salt/redis/ssl.sls | 54 ++ salt/registry/config.sls | 3 - salt/registry/enabled.sls | 4 + salt/registry/ssl.sls | 55 ++ salt/salt/engines/master/checkmine.py | 27 - salt/salt/mine_functions.sls | 4 - salt/salt/minion/init.sls | 8 +- salt/sensoroni/enabled.sls | 1 + salt/soc/enabled.sls | 5 +- salt/ssl/init.sls | 720 -------------------------- salt/ssl/remove.sls | 82 ++- salt/telegraf/config.sls | 3 - salt/telegraf/enabled.sls | 26 +- salt/telegraf/ssl.sls | 55 ++ salt/top.sls | 20 +- setup/so-functions | 11 - setup/so-setup | 5 +- 58 files changed, 1236 insertions(+), 1159 deletions(-) create mode 100644 pillar/ca/init.sls delete mode 100644 salt/ca/dirs.sls create mode 100644 salt/ca/map.jinja create mode 100644 salt/ca/server.sls create mode 100644 salt/ca/signing_policy.sls create mode 100644 salt/ca/trustca.sls create mode 100644 salt/elasticfleet/ssl.sls create mode 100644 salt/elasticsearch/ssl.sls create mode 100644 salt/influxdb/ssl.sls create mode 100644 salt/logstash/ssl.sls create mode 100644 salt/nginx/ssl.sls create mode 100644 salt/pcap/ca.sls create mode 100644 salt/redis/ssl.sls create mode 100644 salt/registry/ssl.sls delete mode 100644 salt/ssl/init.sls create mode 100644 salt/telegraf/ssl.sls diff --git a/pillar/ca/init.sls b/pillar/ca/init.sls new file mode 100644 index 000000000..7d1ea9702 --- /dev/null +++ b/pillar/ca/init.sls @@ -0,0 +1,2 @@ +ca: + server: diff --git a/pillar/top.sls b/pillar/top.sls index 3557b8706..78d7191a0 100644 --- a/pillar/top.sls +++ b/pillar/top.sls @@ -1,5 +1,6 @@ base: '*': + - ca - global.soc_global - global.adv_global - docker.soc_docker diff --git a/salt/allowed_states.map.jinja b/salt/allowed_states.map.jinja index 2cd7f2f87..b8eb40f99 100644 --- a/salt/allowed_states.map.jinja +++ b/salt/allowed_states.map.jinja @@ -15,11 +15,7 @@ 'salt.minion-check', 'sensoroni', 'salt.lasthighstate', - 'salt.minion' -] %} - -{% set ssl_states = [ - 'ssl', + 'salt.minion', 'telegraf', 'firewall', 'schedule', @@ -29,6 +25,7 @@ {% set manager_states = [ 'salt.master', 'ca', + 'pcap.ca', 'registry', 'manager', 'nginx', @@ -77,28 +74,23 @@ {# Map role-specific states #} {% set role_states = { 'so-eval': ( - ssl_states + manager_states + sensor_states + elastic_stack_states | reject('equalto', 'logstash') | list ), 'so-heavynode': ( - ssl_states + sensor_states + ['elasticagent', 'elasticsearch', 'logstash', 'redis', 'nginx'] ), 'so-idh': ( - ssl_states + ['idh'] ), 'so-import': ( - ssl_states + manager_states + sensor_states | reject('equalto', 'strelka') | reject('equalto', 'healthcheck') | list + ['elasticsearch', 'elasticsearch.auth', 'kibana', 'kibana.secrets', 'strelka.manager'] ), 'so-manager': ( - ssl_states + manager_states + ['salt.cloud', 'libvirt.packages', 'libvirt.ssh.users', 'strelka.manager'] + stig_states + @@ -106,7 +98,6 @@ elastic_stack_states ), 'so-managerhype': ( - ssl_states + manager_states + ['salt.cloud', 'strelka.manager', 'hypervisor', 'libvirt'] + stig_states + @@ -114,7 +105,6 @@ elastic_stack_states ), 'so-managersearch': ( - ssl_states + manager_states + ['salt.cloud', 'libvirt.packages', 'libvirt.ssh.users', 'strelka.manager'] + stig_states + @@ -122,12 +112,10 @@ elastic_stack_states ), 'so-searchnode': ( - ssl_states + ['kafka.ca', 'kafka.ssl', 'elasticsearch', 'logstash', 'nginx'] + stig_states ), 'so-standalone': ( - ssl_states + manager_states + ['salt.cloud', 'libvirt.packages', 'libvirt.ssh.users'] + sensor_states + @@ -136,29 +124,24 @@ elastic_stack_states ), 'so-sensor': ( - ssl_states + sensor_states + ['nginx'] + stig_states ), 'so-fleet': ( - ssl_states + stig_states + ['logstash', 'nginx', 'healthcheck', 'elasticfleet'] ), 'so-receiver': ( - ssl_states + kafka_states + stig_states + ['logstash', 'redis'] ), 'so-hypervisor': ( - ssl_states + stig_states + ['hypervisor', 'libvirt'] ), 'so-desktop': ( - ['ssl', 'docker_clean', 'telegraf'] + stig_states ) } %} diff --git a/salt/ca/dirs.sls b/salt/ca/dirs.sls deleted file mode 100644 index 36f37b760..000000000 --- a/salt/ca/dirs.sls +++ /dev/null @@ -1,4 +0,0 @@ -pki_issued_certs: - file.directory: - - name: /etc/pki/issued_certs - - makedirs: True diff --git a/salt/ca/files/signing_policies.conf b/salt/ca/files/signing_policies.conf index 4fc04aacc..b6e4c8e17 100644 --- a/salt/ca/files/signing_policies.conf +++ b/salt/ca/files/signing_policies.conf @@ -1,5 +1,5 @@ x509_signing_policies: - filebeat: + general: - minions: '*' - signing_private_key: /etc/pki/ca.key - signing_cert: /etc/pki/ca.crt @@ -12,72 +12,3 @@ x509_signing_policies: - authorityKeyIdentifier: keyid,issuer:always - days_valid: 820 - copypath: /etc/pki/issued_certs/ - registry: - - minions: '*' - - signing_private_key: /etc/pki/ca.key - - signing_cert: /etc/pki/ca.crt - - C: US - - ST: Utah - - L: Salt Lake City - - basicConstraints: "critical CA:false" - - keyUsage: "critical keyEncipherment" - - subjectKeyIdentifier: hash - - authorityKeyIdentifier: keyid,issuer:always - - extendedKeyUsage: serverAuth - - days_valid: 820 - - copypath: /etc/pki/issued_certs/ - managerssl: - - minions: '*' - - signing_private_key: /etc/pki/ca.key - - signing_cert: /etc/pki/ca.crt - - C: US - - ST: Utah - - L: Salt Lake City - - basicConstraints: "critical CA:false" - - keyUsage: "critical keyEncipherment digitalSignature" - - subjectKeyIdentifier: hash - - authorityKeyIdentifier: keyid,issuer:always - - extendedKeyUsage: serverAuth - - days_valid: 820 - - copypath: /etc/pki/issued_certs/ - influxdb: - - minions: '*' - - signing_private_key: /etc/pki/ca.key - - signing_cert: /etc/pki/ca.crt - - C: US - - ST: Utah - - L: Salt Lake City - - basicConstraints: "critical CA:false" - - keyUsage: "critical keyEncipherment" - - subjectKeyIdentifier: hash - - authorityKeyIdentifier: keyid,issuer:always - - extendedKeyUsage: serverAuth - - days_valid: 820 - - copypath: /etc/pki/issued_certs/ - elasticfleet: - - minions: '*' - - signing_private_key: /etc/pki/ca.key - - signing_cert: /etc/pki/ca.crt - - C: US - - ST: Utah - - L: Salt Lake City - - basicConstraints: "critical CA:false" - - keyUsage: "digitalSignature, nonRepudiation" - - subjectKeyIdentifier: hash - - authorityKeyIdentifier: keyid,issuer:always - - days_valid: 820 - - copypath: /etc/pki/issued_certs/ - kafka: - - minions: '*' - - signing_private_key: /etc/pki/ca.key - - signing_cert: /etc/pki/ca.crt - - C: US - - ST: Utah - - L: Salt Lake City - - basicConstraints: "critical CA:false" - - keyUsage: "digitalSignature, keyEncipherment" - - subjectKeyIdentifier: hash - - authorityKeyIdentifier: keyid,issuer:always - - extendedKeyUsage: "serverAuth, clientAuth" - - days_valid: 820 - - copypath: /etc/pki/issued_certs/ diff --git a/salt/ca/init.sls b/salt/ca/init.sls index ccbe5e39e..9d30b0438 100644 --- a/salt/ca/init.sls +++ b/salt/ca/init.sls @@ -5,63 +5,13 @@ {% from 'allowed_states.map.jinja' import allowed_states %} {% if sls in allowed_states %} -{% from 'vars/globals.map.jinja' import GLOBALS %} - +{% from 'vars/globals.map.jinja' import GLOBALS %} include: - - ca.dirs - -/etc/salt/minion.d/signing_policies.conf: - file.managed: - - source: salt://ca/files/signing_policies.conf - -pki_private_key: - x509.private_key_managed: - - name: /etc/pki/ca.key - - keysize: 4096 - - passphrase: - - backup: True - {% if salt['file.file_exists']('/etc/pki/ca.key') -%} - - prereq: - - x509: /etc/pki/ca.crt - {%- endif %} - -pki_public_ca_crt: - x509.certificate_managed: - - name: /etc/pki/ca.crt - - signing_private_key: /etc/pki/ca.key - - CN: {{ GLOBALS.manager }} - - C: US - - ST: Utah - - L: Salt Lake City - - basicConstraints: "critical CA:true" - - keyUsage: "critical cRLSign, keyCertSign" - - extendedkeyUsage: "serverAuth, clientAuth" - - subjectKeyIdentifier: hash - - authorityKeyIdentifier: keyid:always, issuer - - days_valid: 3650 - - days_remaining: 7 - - backup: True - - replace: False - - require: - - sls: ca.dirs - - timeout: 30 - - retry: - attempts: 5 - interval: 30 - -mine_update_ca_crt: - module.run: - - mine.update: [] - - onchanges: - - x509: pki_public_ca_crt - -cakeyperms: - file.managed: - - replace: False - - name: /etc/pki/ca.key - - mode: 640 - - group: 939 +{% if GLOBALS.is_manager %} + - ca.server +{% endif %} + - ca.trustca {% else %} diff --git a/salt/ca/map.jinja b/salt/ca/map.jinja new file mode 100644 index 000000000..87641198d --- /dev/null +++ b/salt/ca/map.jinja @@ -0,0 +1,3 @@ +{% set CA = { + 'server': pillar.ca.server +}%} diff --git a/salt/ca/remove.sls b/salt/ca/remove.sls index 3af355951..7c410a10d 100644 --- a/salt/ca/remove.sls +++ b/salt/ca/remove.sls @@ -1,7 +1,23 @@ -pki_private_key: +# 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 as shown at +# https://securityonion.net/license; you may not use this file except in compliance with the +# Elastic License 2.0. + +include: + - ssl.remove + +remove_pki_private_key: file.absent: - name: /etc/pki/ca.key -pki_public_ca_crt: +remove_pki_public_ca_crt: file.absent: - name: /etc/pki/ca.crt + +remove_trusttheca: + file.absent: + - name: /etc/pki/tls/certs/intca.crt + +remove_pki_public_ca_crt_symlink: + file.absent: + - name: /opt/so/saltstack/local/salt/ca/files/ca.crt diff --git a/salt/ca/server.sls b/salt/ca/server.sls new file mode 100644 index 000000000..9143c6e75 --- /dev/null +++ b/salt/ca/server.sls @@ -0,0 +1,53 @@ +# 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 as shown at +# https://securityonion.net/license; you may not use this file except in compliance with the +# Elastic License 2.0. + +{% from 'vars/globals.map.jinja' import GLOBALS %} + +pki_private_key: + x509.private_key_managed: + - name: /etc/pki/ca.key + - keysize: 4096 + - passphrase: + - backup: True + {% if salt['file.file_exists']('/etc/pki/ca.key') -%} + - prereq: + - x509: /etc/pki/ca.crt + {%- endif %} + +pki_public_ca_crt: + x509.certificate_managed: + - name: /etc/pki/ca.crt + - signing_private_key: /etc/pki/ca.key + - CN: {{ GLOBALS.manager }} + - C: US + - ST: Utah + - L: Salt Lake City + - basicConstraints: "critical CA:true" + - keyUsage: "critical cRLSign, keyCertSign" + - extendedkeyUsage: "serverAuth, clientAuth" + - subjectKeyIdentifier: hash + - authorityKeyIdentifier: keyid:always, issuer + - days_valid: 3650 + - days_remaining: 7 + - backup: True + - replace: False + - timeout: 30 + - retry: + attempts: 5 + interval: 30 + +pki_public_ca_crt_symlink: + file.symlink: + - name: /opt/so/saltstack/local/salt/ca/files/ca.crt + - target: /etc/pki/ca.crt + - require: + - x509: pki_public_ca_crt + +cakeyperms: + file.managed: + - replace: False + - name: /etc/pki/ca.key + - mode: 640 + - group: 939 diff --git a/salt/ca/signing_policy.sls b/salt/ca/signing_policy.sls new file mode 100644 index 000000000..5deea929a --- /dev/null +++ b/salt/ca/signing_policy.sls @@ -0,0 +1,15 @@ +# 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 as shown at +# https://securityonion.net/license; you may not use this file except in compliance with the +# Elastic License 2.0. + +# when the salt-minion signs the cert, a copy is stored here +issued_certs_copypath: + file.directory: + - name: /etc/pki/issued_certs + - makedirs: True + +signing_policy: + file.managed: + - name: /etc/salt/minion.d/signing_policies.conf + - source: salt://ca/files/signing_policies.conf diff --git a/salt/ca/trustca.sls b/salt/ca/trustca.sls new file mode 100644 index 000000000..04db0e27d --- /dev/null +++ b/salt/ca/trustca.sls @@ -0,0 +1,24 @@ +# 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 as shown at +# https://securityonion.net/license; you may not use this file except in compliance with the +# Elastic License 2.0. + +{% from 'vars/globals.map.jinja' import GLOBALS %} + +cacertdir: + file.directory: + - name: /etc/pki/tls/certs + - makedirs: True + +# Trust the CA +trusttheca: + file.managed: + - name: /etc/pki/tls/certs/intca.crt + - source: salt://ca/files/ca.crt + +{% if GLOBALS.os_family == 'Debian' %} +symlinkca: + file.symlink: + - target: /etc/pki/tls/certs/intca.crt + - name: /etc/ssl/certs/intca.crt +{% endif %} diff --git a/salt/desktop/trusted-ca.sls b/salt/desktop/trusted-ca.sls index 87fc70ef9..5117de1cd 100644 --- a/salt/desktop/trusted-ca.sls +++ b/salt/desktop/trusted-ca.sls @@ -3,29 +3,16 @@ {# we only want this state to run it is CentOS #} {% if GLOBALS.os == 'OEL' %} - {% set global_ca_text = [] %} - {% set global_ca_server = [] %} - {% set manager = GLOBALS.manager %} - {% set x509dict = salt['mine.get'](manager | lower~'*', 'x509.get_pem_entries') %} - {% for host in x509dict %} - {% if host.split('_')|last in ['manager', 'managersearch', 'standalone', 'import', 'eval'] %} - {% do global_ca_text.append(x509dict[host].get('/etc/pki/ca.crt')|replace('\n', '')) %} - {% do global_ca_server.append(host) %} - {% endif %} - {% endfor %} - {% set trusttheca_text = global_ca_text[0] %} - {% set ca_server = global_ca_server[0] %} - trusted_ca: - x509.pem_managed: + file.managed: - name: /etc/pki/ca-trust/source/anchors/ca.crt - - text: {{ trusttheca_text }} + - source: salt://ca/files/ca.crt update_ca_certs: cmd.run: - name: update-ca-trust - onchanges: - - x509: trusted_ca + - file: trusted_ca {% else %} diff --git a/salt/docker/init.sls b/salt/docker/init.sls index 5a0d1f61a..026b72dea 100644 --- a/salt/docker/init.sls +++ b/salt/docker/init.sls @@ -6,9 +6,9 @@ {% from 'docker/docker.map.jinja' import DOCKER %} {% from 'vars/globals.map.jinja' import GLOBALS %} -# include ssl since docker service requires the intca +# docker service requires the ca.crt include: - - ssl + - ca dockergroup: group.present: @@ -89,10 +89,10 @@ docker_running: - enable: True - watch: - file: docker_daemon - - x509: trusttheca + - file: trusttheca - require: - file: docker_daemon - - x509: trusttheca + - file: trusttheca # Reserve OS ports for Docker proxy in case boot settings are not already applied/present diff --git a/salt/elasticagent/enabled.sls b/salt/elasticagent/enabled.sls index 3c20c916f..f59eae1fe 100644 --- a/salt/elasticagent/enabled.sls +++ b/salt/elasticagent/enabled.sls @@ -9,6 +9,7 @@ {% from 'docker/docker.map.jinja' import DOCKER %} include: + - ca - elasticagent.config - elasticagent.sostatus @@ -55,8 +56,10 @@ so-elastic-agent: {% endif %} - require: - file: create-elastic-agent-config + - file: trusttheca - watch: - file: create-elastic-agent-config + - file: trusttheca delete_so-elastic-agent_so-status.disabled: file.uncomment: diff --git a/salt/elasticfleet/enabled.sls b/salt/elasticfleet/enabled.sls index ec8c8337e..2a4f4d0db 100644 --- a/salt/elasticfleet/enabled.sls +++ b/salt/elasticfleet/enabled.sls @@ -13,9 +13,11 @@ {% set SERVICETOKEN = salt['pillar.get']('elasticfleet:config:server:es_token','') %} include: + - ca + - logstash.ssl + - elasticfleet.ssl - elasticfleet.config - elasticfleet.sostatus - - ssl {% if grains.role not in ['so-fleet'] %} # Wait for Elasticsearch to be ready - no reason to try running Elastic Fleet server if ES is not ready @@ -132,6 +134,11 @@ so-elastic-fleet: {% endfor %} {% endif %} - watch: + - file: trusttheca + - x509: etc_elasticfleet_key + - x509: etc_elasticfleet_crt + - require: + - file: trusttheca - x509: etc_elasticfleet_key - x509: etc_elasticfleet_crt {% endif %} diff --git a/salt/elasticfleet/ssl.sls b/salt/elasticfleet/ssl.sls new file mode 100644 index 000000000..c294d08ea --- /dev/null +++ b/salt/elasticfleet/ssl.sls @@ -0,0 +1,186 @@ +# 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 as shown at +# https://securityonion.net/license; 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.split('.')[0] in allowed_states %} +{% from 'vars/globals.map.jinja' import GLOBALS %} +{% from 'elasticfleet/map.jinja' import ELASTICFLEETMERGED %} +{% from 'ca/map.jinja' import CA %} + +{% if GLOBALS.is_manager or GLOBALS.role in ['so-heavynode', 'so-fleet', 'so-receiver'] %} + +{% if grains['role'] not in [ 'so-heavynode', 'so-receiver'] %} +# Start -- Elastic Fleet Host Cert +etc_elasticfleet_key: + x509.private_key_managed: + - name: /etc/pki/elasticfleet-server.key + - keysize: 4096 + - backup: True + - new: True + {% if salt['file.file_exists']('/etc/pki/elasticfleet-server.key') -%} + - prereq: + - x509: etc_elasticfleet_crt + {%- endif %} + - retry: + attempts: 5 + interval: 30 + +etc_elasticfleet_crt: + x509.certificate_managed: + - name: /etc/pki/elasticfleet-server.crt + - ca_server: {{ CA.server }} + - signing_policy: general + - private_key: /etc/pki/elasticfleet-server.key + - CN: {{ GLOBALS.hostname }} + - subjectAltName: DNS:{{ GLOBALS.hostname }},DNS:{{ GLOBALS.url_base }},IP:{{ GLOBALS.node_ip }}{% if ELASTICFLEETMERGED.config.server.custom_fqdn | length > 0 %},DNS:{{ ELASTICFLEETMERGED.config.server.custom_fqdn | join(',DNS:') }}{% endif %} + - days_remaining: 7 + - days_valid: 820 + - backup: True + - timeout: 30 + - retry: + attempts: 5 + interval: 30 + +efperms: + file.managed: + - replace: False + - name: /etc/pki/elasticfleet-server.key + - mode: 640 + - group: 939 + +chownelasticfleetcrt: + file.managed: + - replace: False + - name: /etc/pki/elasticfleet-server.crt + - mode: 640 + - user: 947 + - group: 939 + +chownelasticfleetkey: + file.managed: + - replace: False + - name: /etc/pki/elasticfleet-server.key + - mode: 640 + - user: 947 + - group: 939 +# End -- Elastic Fleet Host Cert +{% endif %} # endif is for not including HeavyNodes & Receivers + + +# Start -- Elastic Fleet Client Cert for Agent (Mutual Auth with Logstash Output) +etc_elasticfleet_agent_key: + x509.private_key_managed: + - name: /etc/pki/elasticfleet-agent.key + - keysize: 4096 + - backup: True + - new: True + {% if salt['file.file_exists']('/etc/pki/elasticfleet-agent.key') -%} + - prereq: + - x509: etc_elasticfleet_agent_crt + {%- endif %} + - retry: + attempts: 5 + interval: 30 + +etc_elasticfleet_agent_crt: + x509.certificate_managed: + - name: /etc/pki/elasticfleet-agent.crt + - ca_server: {{ CA.server }} + - signing_policy: general + - private_key: /etc/pki/elasticfleet-agent.key + - CN: {{ GLOBALS.hostname }} + - days_remaining: 7 + - days_valid: 820 + - backup: True + - timeout: 30 + - retry: + attempts: 5 + interval: 30 + cmd.run: + - name: "/usr/bin/openssl pkcs8 -in /etc/pki/elasticfleet-agent.key -topk8 -out /etc/pki/elasticfleet-agent.p8 -nocrypt" + - onchanges: + - x509: etc_elasticfleet_agent_key + +efagentperms: + file.managed: + - replace: False + - name: /etc/pki/elasticfleet-agent.key + - mode: 640 + - group: 939 + +chownelasticfleetagentcrt: + file.managed: + - replace: False + - name: /etc/pki/elasticfleet-agent.crt + - mode: 640 + - user: 947 + - group: 939 + +chownelasticfleetagentkey: + file.managed: + - replace: False + - name: /etc/pki/elasticfleet-agent.key + - mode: 640 + - user: 947 + - group: 939 +# End -- Elastic Fleet Client Cert for Agent (Mutual Auth with Logstash Output) + +{% endif %} + +{% if GLOBALS.role in ['so-manager', 'so-managerhype', 'so-managersearch', 'so-standalone'] %} +elasticfleet_kafka_key: + x509.private_key_managed: + - name: /etc/pki/elasticfleet-kafka.key + - keysize: 4096 + - backup: True + - new: True + {% if salt['file.file_exists']('/etc/pki/elasticfleet-kafka.key') -%} + - prereq: + - x509: elasticfleet_kafka_crt + {%- endif %} + - retry: + attempts: 5 + interval: 30 + +elasticfleet_kafka_crt: + x509.certificate_managed: + - name: /etc/pki/elasticfleet-kafka.crt + - ca_server: {{ CA.server }} + - signing_policy: general + - private_key: /etc/pki/elasticfleet-kafka.key + - CN: {{ GLOBALS.hostname }} + - subjectAltName: DNS:{{ GLOBALS.hostname }}, IP:{{ GLOBALS.node_ip }} + - days_remaining: 7 + - days_valid: 820 + - backup: True + - timeout: 30 + - retry: + attempts: 5 + interval: 30 + +elasticfleet_kafka_cert_perms: + file.managed: + - replace: False + - name: /etc/pki/elasticfleet-kafka.crt + - mode: 640 + - user: 947 + - group: 939 + +elasticfleet_kafka_key_perms: + file.managed: + - replace: False + - name: /etc/pki/elasticfleet-kafka.key + - mode: 640 + - user: 947 + - group: 939 +{% endif %} + +{% else %} + +{{sls}}_state_not_allowed: + test.fail_without_changes: + - name: {{sls}}_state_not_allowed + +{% endif %} diff --git a/salt/elasticsearch/ca.sls b/salt/elasticsearch/ca.sls index 188450311..39d33919c 100644 --- a/salt/elasticsearch/ca.sls +++ b/salt/elasticsearch/ca.sls @@ -26,14 +26,14 @@ catrustscript: GLOBALS: {{ GLOBALS }} {% endif %} -cacertz: +elasticsearch_cacerts: file.managed: - name: /opt/so/conf/ca/cacerts - source: salt://elasticsearch/cacerts - user: 939 - group: 939 -capemz: +elasticsearch_capems: file.managed: - name: /opt/so/conf/ca/tls-ca-bundle.pem - source: salt://elasticsearch/tls-ca-bundle.pem diff --git a/salt/elasticsearch/config.sls b/salt/elasticsearch/config.sls index 147975bb1..38cd73ffc 100644 --- a/salt/elasticsearch/config.sls +++ b/salt/elasticsearch/config.sls @@ -5,11 +5,6 @@ {% from 'allowed_states.map.jinja' import allowed_states %} {% if sls.split('.')[0] in allowed_states %} - -include: - - ssl - - elasticsearch.ca - {% from 'vars/globals.map.jinja' import GLOBALS %} {% from 'elasticsearch/config.map.jinja' import ELASTICSEARCHMERGED %} diff --git a/salt/elasticsearch/enabled.sls b/salt/elasticsearch/enabled.sls index 49f34314b..0eb9194fb 100644 --- a/salt/elasticsearch/enabled.sls +++ b/salt/elasticsearch/enabled.sls @@ -14,6 +14,9 @@ {% from 'elasticsearch/template.map.jinja' import ES_INDEX_SETTINGS %} include: + - ca + - elasticsearch.ca + - elasticsearch.ssl - elasticsearch.config - elasticsearch.sostatus @@ -61,11 +64,7 @@ so-elasticsearch: - /nsm/elasticsearch:/usr/share/elasticsearch/data:rw - /opt/so/log/elasticsearch:/var/log/elasticsearch:rw - /opt/so/conf/ca/cacerts:/usr/share/elasticsearch/jdk/lib/security/cacerts:ro - {% if GLOBALS.is_manager %} - - /etc/pki/ca.crt:/usr/share/elasticsearch/config/ca.crt:ro - {% else %} - /etc/pki/tls/certs/intca.crt:/usr/share/elasticsearch/config/ca.crt:ro - {% endif %} - /etc/pki/elasticsearch.crt:/usr/share/elasticsearch/config/elasticsearch.crt:ro - /etc/pki/elasticsearch.key:/usr/share/elasticsearch/config/elasticsearch.key:ro - /etc/pki/elasticsearch.p12:/usr/share/elasticsearch/config/elasticsearch.p12:ro @@ -82,22 +81,21 @@ so-elasticsearch: {% endfor %} {% endif %} - watch: - - file: cacertz + - file: trusttheca + - x509: elasticsearch_crt + - x509: elasticsearch_key + - file: elasticsearch_cacerts - file: esyml - require: + - file: trusttheca + - x509: elasticsearch_crt + - x509: elasticsearch_key + - file: elasticsearch_cacerts - file: esyml - file: eslog4jfile - file: nsmesdir - file: eslogdir - - file: cacertz - - x509: /etc/pki/elasticsearch.crt - - x509: /etc/pki/elasticsearch.key - file: elasticp12perms - {% if GLOBALS.is_manager %} - - x509: pki_public_ca_crt - {% else %} - - x509: trusttheca - {% endif %} - cmd: auth_users_roles_inode - cmd: auth_users_inode diff --git a/salt/elasticsearch/ssl.sls b/salt/elasticsearch/ssl.sls new file mode 100644 index 000000000..6b71072fc --- /dev/null +++ b/salt/elasticsearch/ssl.sls @@ -0,0 +1,66 @@ +# 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 as shown at +# https://securityonion.net/license; 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.split('.')[0] in allowed_states %} +{% from 'vars/globals.map.jinja' import GLOBALS %} +{% from 'ca/map.jinja' import CA %} + +# Create a cert for elasticsearch +elasticsearch_key: + x509.private_key_managed: + - name: /etc/pki/elasticsearch.key + - keysize: 4096 + - backup: True + - new: True + {% if salt['file.file_exists']('/etc/pki/elasticsearch.key') -%} + - prereq: + - x509: /etc/pki/elasticsearch.crt + {%- endif %} + - retry: + attempts: 5 + interval: 30 + +elasticsearch_crt: + x509.certificate_managed: + - name: /etc/pki/elasticsearch.crt + - ca_server: {{ CA.server }} + - signing_policy: general + - private_key: /etc/pki/elasticsearch.key + - CN: {{ GLOBALS.hostname }} + - subjectAltName: DNS:{{ GLOBALS.hostname }}, IP:{{ GLOBALS.node_ip }} + - days_remaining: 7 + - days_valid: 820 + - backup: True + - timeout: 30 + - retry: + attempts: 5 + interval: 30 + cmd.run: + - name: "/usr/bin/openssl pkcs12 -inkey /etc/pki/elasticsearch.key -in /etc/pki/elasticsearch.crt -export -out /etc/pki/elasticsearch.p12 -nodes -passout pass:" + - onchanges: + - x509: /etc/pki/elasticsearch.key + +elastickeyperms: + file.managed: + - replace: False + - name: /etc/pki/elasticsearch.key + - mode: 640 + - group: 930 + +elasticp12perms: + file.managed: + - replace: False + - name: /etc/pki/elasticsearch.p12 + - mode: 640 + - group: 930 + +{% else %} + +{{sls}}_state_not_allowed: + test.fail_without_changes: + - name: {{sls}}_state_not_allowed + +{% endif %} diff --git a/salt/influxdb/config.sls b/salt/influxdb/config.sls index 0f315666a..bf8b67b78 100644 --- a/salt/influxdb/config.sls +++ b/salt/influxdb/config.sls @@ -9,7 +9,6 @@ include: - salt.minion - - ssl # Influx DB influxconfdir: diff --git a/salt/influxdb/enabled.sls b/salt/influxdb/enabled.sls index 293a917cb..65ba4fafe 100644 --- a/salt/influxdb/enabled.sls +++ b/salt/influxdb/enabled.sls @@ -11,6 +11,7 @@ {% set TOKEN = salt['pillar.get']('influxdb:token') %} include: + - influxdb.ssl - influxdb.config - influxdb.sostatus @@ -59,6 +60,8 @@ so-influxdb: {% endif %} - watch: - file: influxdbconf + - x509: influxdb_key + - x509: influxdb_crt - require: - file: influxdbconf - x509: influxdb_key diff --git a/salt/influxdb/ssl.sls b/salt/influxdb/ssl.sls new file mode 100644 index 000000000..25dd35258 --- /dev/null +++ b/salt/influxdb/ssl.sls @@ -0,0 +1,55 @@ +# 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 as shown at +# https://securityonion.net/license; 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.split('.')[0] in allowed_states %} +{% from 'vars/globals.map.jinja' import GLOBALS %} +{% from 'ca/map.jinja' import CA %} + +influxdb_key: + x509.private_key_managed: + - name: /etc/pki/influxdb.key + - keysize: 4096 + - backup: True + - new: True + {% if salt['file.file_exists']('/etc/pki/influxdb.key') -%} + - prereq: + - x509: /etc/pki/influxdb.crt + {%- endif %} + - retry: + attempts: 5 + interval: 30 + +# Create a cert for the talking to influxdb +influxdb_crt: + x509.certificate_managed: + - name: /etc/pki/influxdb.crt + - ca_server: {{ CA.server }} + - signing_policy: general + - private_key: /etc/pki/influxdb.key + - CN: {{ GLOBALS.hostname }} + - subjectAltName: DNS:{{ GLOBALS.hostname }}, IP:{{ GLOBALS.node_ip }} + - days_remaining: 7 + - days_valid: 820 + - backup: True + - timeout: 30 + - retry: + attempts: 5 + interval: 30 + +influxkeyperms: + file.managed: + - replace: False + - name: /etc/pki/influxdb.key + - mode: 640 + - group: 939 + +{% else %} + +{{sls}}_state_not_allowed: + test.fail_without_changes: + - name: {{sls}}_state_not_allowed + +{% endif %} diff --git a/salt/kafka/enabled.sls b/salt/kafka/enabled.sls index 8448bd5aa..e5011553d 100644 --- a/salt/kafka/enabled.sls +++ b/salt/kafka/enabled.sls @@ -68,6 +68,8 @@ so-kafka: - file: kafka_server_jaas_properties {% endif %} - file: kafkacertz + - x509: kafka_client_crt + - file: kafka_pkcs12_perms - require: - file: kafkacertz @@ -95,4 +97,4 @@ include: test.fail_without_changes: - name: {{sls}}_state_not_allowed -{% endif %} \ No newline at end of file +{% endif %} diff --git a/salt/kafka/ssl.sls b/salt/kafka/ssl.sls index 77aedf9eb..fc49fb09b 100644 --- a/salt/kafka/ssl.sls +++ b/salt/kafka/ssl.sls @@ -6,18 +6,11 @@ {% from 'allowed_states.map.jinja' import allowed_states %} {% if sls.split('.')[0] in allowed_states or sls in allowed_states %} {% from 'vars/globals.map.jinja' import GLOBALS %} +{% from 'ca/map.jinja' import CA %} {% set kafka_password = salt['pillar.get']('kafka:config:password') %} include: - - ca.dirs - {% set global_ca_server = [] %} - {% set x509dict = salt['mine.get'](GLOBALS.manager | lower~'*', 'x509.get_pem_entries') %} - {% for host in x509dict %} - {% if 'manager' in host.split('_')|last or host.split('_')|last == 'standalone' %} - {% do global_ca_server.append(host) %} - {% endif %} - {% endfor %} - {% set ca_server = global_ca_server[0] %} + - ca {% if GLOBALS.pipeline == "KAFKA" %} @@ -39,9 +32,9 @@ kafka_client_key: kafka_client_crt: x509.certificate_managed: - name: /etc/pki/kafka-client.crt - - ca_server: {{ ca_server }} + - ca_server: {{ CA.server }} - subjectAltName: DNS:{{ GLOBALS.hostname }}, IP:{{ GLOBALS.node_ip }} - - signing_policy: kafka + - signing_policy: general - private_key: /etc/pki/kafka-client.key - CN: {{ GLOBALS.hostname }} - days_remaining: 7 @@ -87,9 +80,9 @@ kafka_key: kafka_crt: x509.certificate_managed: - name: /etc/pki/kafka.crt - - ca_server: {{ ca_server }} + - ca_server: {{ CA.server }} - subjectAltName: DNS:{{ GLOBALS.hostname }}, IP:{{ GLOBALS.node_ip }} - - signing_policy: kafka + - signing_policy: general - private_key: /etc/pki/kafka.key - CN: {{ GLOBALS.hostname }} - days_remaining: 7 @@ -103,6 +96,7 @@ kafka_crt: - name: "/usr/bin/openssl pkcs12 -inkey /etc/pki/kafka.key -in /etc/pki/kafka.crt -export -out /etc/pki/kafka.p12 -nodes -passout pass:{{ kafka_password }}" - onchanges: - x509: /etc/pki/kafka.key + kafka_key_perms: file.managed: - replace: False @@ -148,9 +142,9 @@ kafka_logstash_key: kafka_logstash_crt: x509.certificate_managed: - name: /etc/pki/kafka-logstash.crt - - ca_server: {{ ca_server }} + - ca_server: {{ CA.server }} - subjectAltName: DNS:{{ GLOBALS.hostname }}, IP:{{ GLOBALS.node_ip }} - - signing_policy: kafka + - signing_policy: general - private_key: /etc/pki/kafka-logstash.key - CN: {{ GLOBALS.hostname }} - days_remaining: 7 diff --git a/salt/logstash/config.sls b/salt/logstash/config.sls index 5a1727e9b..69b37cefc 100644 --- a/salt/logstash/config.sls +++ b/salt/logstash/config.sls @@ -11,7 +11,6 @@ {% set ASSIGNED_PIPELINES = LOGSTASH_MERGED.assigned_pipelines.roles[GLOBALS.role.split('-')[1]] %} include: - - ssl {% if GLOBALS.role not in ['so-receiver','so-fleet'] %} - elasticsearch {% endif %} diff --git a/salt/logstash/enabled.sls b/salt/logstash/enabled.sls index cd71cd574..3c083f4ce 100644 --- a/salt/logstash/enabled.sls +++ b/salt/logstash/enabled.sls @@ -12,6 +12,7 @@ {% set lsheap = LOGSTASH_MERGED.settings.lsheap %} include: + - ca {% if GLOBALS.role not in ['so-receiver','so-fleet'] %} - elasticsearch.ca {% endif %} @@ -20,9 +21,9 @@ include: - kafka.ca - kafka.ssl {% endif %} + - logstash.ssl - logstash.config - logstash.sostatus - - ssl so-logstash: docker_container.running: @@ -65,22 +66,18 @@ so-logstash: - /opt/so/log/logstash:/var/log/logstash:rw - /sys/fs/cgroup:/sys/fs/cgroup:ro - /opt/so/conf/logstash/etc/certs:/usr/share/logstash/certs:ro - {% if GLOBALS.role in ['so-manager', 'so-managerhype', 'so-managersearch', 'so-standalone', 'so-import', 'so-heavynode', 'so-receiver'] %} - - /etc/pki/filebeat.crt:/usr/share/logstash/filebeat.crt:ro - - /etc/pki/filebeat.p8:/usr/share/logstash/filebeat.key:ro - {% endif %} + - /etc/pki/tls/certs/intca.crt:/usr/share/filebeat/ca.crt:ro {% if GLOBALS.is_manager or GLOBALS.role in ['so-fleet', 'so-heavynode', 'so-receiver'] %} - /etc/pki/elasticfleet-logstash.crt:/usr/share/logstash/elasticfleet-logstash.crt:ro - /etc/pki/elasticfleet-logstash.key:/usr/share/logstash/elasticfleet-logstash.key:ro - /etc/pki/elasticfleet-lumberjack.crt:/usr/share/logstash/elasticfleet-lumberjack.crt:ro - /etc/pki/elasticfleet-lumberjack.key:/usr/share/logstash/elasticfleet-lumberjack.key:ro + {% if GLOBALS.role != 'so-fleet' %} + - /etc/pki/filebeat.crt:/usr/share/logstash/filebeat.crt:ro + - /etc/pki/filebeat.p8:/usr/share/logstash/filebeat.key:ro + {% endif %} {% endif %} - {% if GLOBALS.role in ['so-manager', 'so-managerhype', 'so-managersearch', 'so-standalone', 'so-import'] %} - - /etc/pki/ca.crt:/usr/share/filebeat/ca.crt:ro - {% else %} - - /etc/pki/tls/certs/intca.crt:/usr/share/filebeat/ca.crt:ro - {% endif %} - {% if GLOBALS.role in ['so-manager', 'so-managerhype', 'so-managersearch', 'so-standalone', 'so-import', 'so-heavynode', 'so-searchnode' ] %} + {% if GLOBALS.role not in ['so-receiver','so-fleet'] %} - /opt/so/conf/ca/cacerts:/etc/pki/ca-trust/extracted/java/cacerts:ro - /opt/so/conf/ca/tls-ca-bundle.pem:/etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem:ro {% endif %} @@ -100,11 +97,22 @@ so-logstash: {% endfor %} {% endif %} - watch: - {% if GLOBALS.is_manager or GLOBALS.role in ['so-fleet', 'so-receiver'] %} - - x509: etc_elasticfleet_logstash_key - - x509: etc_elasticfleet_logstash_crt - {% endif %} - file: lsetcsync + - file: trusttheca + {% if GLOBALS.is_manager %} + - file: elasticsearch_cacerts + - file: elasticsearch_capems + {% endif %} + {% if GLOBALS.is_manager or GLOBALS.role in ['so-fleet', 'so-heavynode', 'so-receiver'] %} + - x509: etc_elasticfleet_logstash_crt + - x509: etc_elasticfleet_logstash_key + - x509: etc_elasticfleetlumberjack_crt + - x509: etc_elasticfleetlumberjack_key + {% if GLOBALS.role != 'so-fleet' %} + - x509: etc_filebeat_crt + - file: logstash_filebeat_p8 + {% endif %} + {% endif %} {% for assigned_pipeline in LOGSTASH_MERGED.assigned_pipelines.roles[GLOBALS.role.split('-')[1]] %} - file: ls_pipeline_{{assigned_pipeline}} {% for CONFIGFILE in LOGSTASH_MERGED.defined_pipelines[assigned_pipeline] %} @@ -115,17 +123,20 @@ so-logstash: - file: kafkacertz {% endif %} - require: - {% if grains['role'] in ['so-manager', 'so-managerhype', 'so-managersearch', 'so-standalone', 'so-import', 'so-heavynode', 'so-receiver'] %} + - file: trusttheca + {% if GLOBALS.is_manager %} + - file: elasticsearch_cacerts + - file: elasticsearch_capems + {% endif %} + {% if GLOBALS.is_manager or GLOBALS.role in ['so-fleet', 'so-heavynode', 'so-receiver'] %} + - x509: etc_elasticfleet_logstash_crt + - x509: etc_elasticfleet_logstash_key + - x509: etc_elasticfleetlumberjack_crt + - x509: etc_elasticfleetlumberjack_key + {% if GLOBALS.role != 'so-fleet' %} - x509: etc_filebeat_crt - {% endif %} - {% if grains['role'] in ['so-manager', 'so-managerhype', 'so-managersearch', 'so-standalone', 'so-import'] %} - - x509: pki_public_ca_crt - {% else %} - - x509: trusttheca - {% endif %} - {% if grains.role in ['so-manager', 'so-managerhype', 'so-managersearch', 'so-standalone', 'so-import'] %} - - file: cacertz - - file: capemz + - file: logstash_filebeat_p8 + {% endif %} {% endif %} {% if GLOBALS.pipeline == 'KAFKA' and GLOBALS.role in ['so-manager', 'so-managerhype', 'so-managersearch', 'so-standalone', 'so-searchnode'] %} - file: kafkacertz diff --git a/salt/logstash/ssl.sls b/salt/logstash/ssl.sls new file mode 100644 index 000000000..c5865d00d --- /dev/null +++ b/salt/logstash/ssl.sls @@ -0,0 +1,287 @@ +# 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 as shown at +# https://securityonion.net/license; 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.split('.')[0] in allowed_states %} +{% from 'vars/globals.map.jinja' import GLOBALS %} +{% from 'elasticfleet/map.jinja' import ELASTICFLEETMERGED %} +{% from 'ca/map.jinja' import CA %} + +{% if GLOBALS.is_manager or GLOBALS.role in ['so-heavynode', 'so-fleet', 'so-receiver'] %} + +{% if grains['role'] not in [ 'so-heavynode'] %} +# Start -- Elastic Fleet Logstash Input Cert +etc_elasticfleet_logstash_key: + x509.private_key_managed: + - name: /etc/pki/elasticfleet-logstash.key + - keysize: 4096 + - backup: True + - new: True + {% if salt['file.file_exists']('/etc/pki/elasticfleet-logstash.key') -%} + - prereq: + - x509: etc_elasticfleet_logstash_crt + {%- endif %} + - retry: + attempts: 5 + interval: 30 + +etc_elasticfleet_logstash_crt: + x509.certificate_managed: + - name: /etc/pki/elasticfleet-logstash.crt + - ca_server: {{ CA.server }} + - signing_policy: general + - private_key: /etc/pki/elasticfleet-logstash.key + - CN: {{ GLOBALS.hostname }} + - subjectAltName: DNS:{{ GLOBALS.hostname }},DNS:{{ GLOBALS.url_base }},IP:{{ GLOBALS.node_ip }}{% if ELASTICFLEETMERGED.config.server.custom_fqdn | length > 0 %},DNS:{{ ELASTICFLEETMERGED.config.server.custom_fqdn | join(',DNS:') }}{% endif %} + - days_remaining: 7 + - days_valid: 820 + - backup: True + - 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_logstash_key + +eflogstashperms: + file.managed: + - replace: False + - name: /etc/pki/elasticfleet-logstash.key + - mode: 640 + - group: 939 + +chownelasticfleetlogstashcrt: + file.managed: + - replace: False + - name: /etc/pki/elasticfleet-logstash.crt + - mode: 640 + - user: 931 + - group: 939 + +chownelasticfleetlogstashkey: + file.managed: + - replace: False + - name: /etc/pki/elasticfleet-logstash.key + - mode: 640 + - user: 931 + - group: 939 +# End -- Elastic Fleet Logstash Input Cert +{% endif %} # endif is for not including HeavyNodes + +# Start -- Elastic Fleet Node - Logstash Lumberjack Input / Output +# Cert needed on: Managers, Receivers +etc_elasticfleetlumberjack_key: + x509.private_key_managed: + - name: /etc/pki/elasticfleet-lumberjack.key + - bits: 4096 + - backup: True + - new: True + {% if salt['file.file_exists']('/etc/pki/elasticfleet-lumberjack.key') -%} + - prereq: + - x509: etc_elasticfleetlumberjack_crt + {%- endif %} + - retry: + attempts: 5 + interval: 30 + +etc_elasticfleetlumberjack_crt: + x509.certificate_managed: + - name: /etc/pki/elasticfleet-lumberjack.crt + - ca_server: {{ CA.server }} + - signing_policy: general + - private_key: /etc/pki/elasticfleet-lumberjack.key + - CN: {{ GLOBALS.node_ip }} + - subjectAltName: DNS:{{ GLOBALS.hostname }} + - days_remaining: 7 + - days_valid: 820 + - backup: True + - timeout: 30 + - retry: + attempts: 5 + interval: 30 + cmd.run: + - name: "/usr/bin/openssl pkcs8 -in /etc/pki/elasticfleet-lumberjack.key -topk8 -out /etc/pki/elasticfleet-lumberjack.p8 -nocrypt" + - onchanges: + - x509: etc_elasticfleetlumberjack_key + +eflogstashlumberjackperms: + file.managed: + - replace: False + - name: /etc/pki/elasticfleet-lumberjack.key + - mode: 640 + - group: 939 + +chownilogstashelasticfleetlumberjackp8: + file.managed: + - replace: False + - name: /etc/pki/elasticfleet-lumberjack.p8 + - mode: 640 + - user: 931 + - group: 939 + +chownilogstashelasticfleetlogstashlumberjackcrt: + file.managed: + - replace: False + - name: /etc/pki/elasticfleet-lumberjack.crt + - mode: 640 + - user: 931 + - group: 939 + +chownilogstashelasticfleetlogstashlumberjackkey: + file.managed: + - replace: False + - name: /etc/pki/elasticfleet-lumberjack.key + - mode: 640 + - user: 931 + - group: 939 +# End -- Elastic Fleet Node - Logstash Lumberjack Input / Output +{% endif %} + +{% if GLOBALS.is_manager or GLOBALS.role in ['so-heavynode', 'so-receiver'] %} +etc_filebeat_key: + x509.private_key_managed: + - name: /etc/pki/filebeat.key + - keysize: 4096 + - backup: True + - new: True + {% if salt['file.file_exists']('/etc/pki/filebeat.key') -%} + - prereq: + - x509: etc_filebeat_crt + {%- endif %} + - retry: + attempts: 5 + interval: 30 + +# Request a cert and drop it where it needs to go to be distributed +etc_filebeat_crt: + x509.certificate_managed: + - name: /etc/pki/filebeat.crt + - ca_server: {{ CA.server }} + - signing_policy: general + - private_key: /etc/pki/filebeat.key + - CN: {{ GLOBALS.hostname }} + - subjectAltName: DNS:{{ GLOBALS.hostname }}, IP:{{ GLOBALS.node_ip }} + - days_remaining: 7 + - days_valid: 820 + - backup: True + - timeout: 30 + - retry: + attempts: 5 + interval: 30 + cmd.run: + - name: "/usr/bin/openssl pkcs8 -in /etc/pki/filebeat.key -topk8 -out /etc/pki/filebeat.p8 -nocrypt" + - onchanges: + - x509: etc_filebeat_key + +fbperms: + file.managed: + - replace: False + - name: /etc/pki/filebeat.key + - mode: 640 + - group: 939 + +logstash_filebeat_p8: + file.managed: + - replace: False + - name: /etc/pki/filebeat.p8 + - mode: 640 + - user: 931 + - group: 939 + +{% if grains.role not in ['so-heavynode', 'so-receiver'] %} +# Create Symlinks to the keys so I can distribute it to all the things +filebeatdir: + file.directory: + - name: /opt/so/saltstack/local/salt/filebeat/files + - makedirs: True + +fbkeylink: + file.symlink: + - name: /opt/so/saltstack/local/salt/filebeat/files/filebeat.p8 + - target: /etc/pki/filebeat.p8 + - user: socore + - group: socore + +fbcrtlink: + file.symlink: + - name: /opt/so/saltstack/local/salt/filebeat/files/filebeat.crt + - target: /etc/pki/filebeat.crt + - user: socore + - group: socore + +{% endif %} +{% endif %} + +{% if GLOBALS.is_manager or GLOBALS.role in ['so-sensor', 'so-searchnode', 'so-heavynode', 'so-fleet', 'so-idh', 'so-receiver'] %} + +fbcertdir: + file.directory: + - name: /opt/so/conf/filebeat/etc/pki + - makedirs: True + +conf_filebeat_key: + x509.private_key_managed: + - name: /opt/so/conf/filebeat/etc/pki/filebeat.key + - keysize: 4096 + - backup: True + - new: True + {% if salt['file.file_exists']('/opt/so/conf/filebeat/etc/pki/filebeat.key') -%} + - prereq: + - x509: conf_filebeat_crt + {%- endif %} + - retry: + attempts: 5 + interval: 30 + +# Request a cert and drop it where it needs to go to be distributed +conf_filebeat_crt: + x509.certificate_managed: + - name: /opt/so/conf/filebeat/etc/pki/filebeat.crt + - ca_server: {{ CA.server }} + - signing_policy: general + - private_key: /opt/so/conf/filebeat/etc/pki/filebeat.key + - CN: {{ GLOBALS.hostname }} + - subjectAltName: DNS:{{ GLOBALS.hostname }}, IP:{{ GLOBALS.node_ip }} + - days_remaining: 7 + - days_valid: 820 + - backup: True + - timeout: 30 + - retry: + attempts: 5 + interval: 30 + +# Convert the key to pkcs#8 so logstash will work correctly. +filebeatpkcs: + cmd.run: + - name: "/usr/bin/openssl pkcs8 -in /opt/so/conf/filebeat/etc/pki/filebeat.key -topk8 -out /opt/so/conf/filebeat/etc/pki/filebeat.p8 -passout pass:" + - onchanges: + - x509: conf_filebeat_key + +filebeatkeyperms: + file.managed: + - replace: False + - name: /opt/so/conf/filebeat/etc/pki/filebeat.key + - mode: 640 + - group: 939 + +chownfilebeatp8: + file.managed: + - replace: False + - name: /opt/so/conf/filebeat/etc/pki/filebeat.p8 + - mode: 640 + - user: 931 + - group: 939 + +{% endif %} + +{% else %} + +{{sls}}_state_not_allowed: + test.fail_without_changes: + - name: {{sls}}_state_not_allowed + +{% endif %} diff --git a/salt/manager/elasticsearch.sls b/salt/manager/elasticsearch.sls index ab9dbb287..7731859e3 100644 --- a/salt/manager/elasticsearch.sls +++ b/salt/manager/elasticsearch.sls @@ -1,3 +1,8 @@ +# 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 as shown at +# https://securityonion.net/license; you may not use this file except in compliance with the +# Elastic License 2.0. + elastic_curl_config_distributed: file.managed: - name: /opt/so/saltstack/local/salt/elasticsearch/curl.config diff --git a/salt/manager/kibana.sls b/salt/manager/kibana.sls index 17ac826c2..8ff876051 100644 --- a/salt/manager/kibana.sls +++ b/salt/manager/kibana.sls @@ -1,3 +1,8 @@ +# 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 as shown at +# https://securityonion.net/license; you may not use this file except in compliance with the +# Elastic License 2.0. + kibana_curl_config_distributed: file.managed: - name: /opt/so/conf/kibana/curl.config @@ -5,4 +10,4 @@ kibana_curl_config_distributed: - template: jinja - mode: 600 - show_changes: False - - makedirs: True \ No newline at end of file + - makedirs: True diff --git a/salt/manager/sync_es_users.sls b/salt/manager/sync_es_users.sls index 5b9fb4efd..29b090e18 100644 --- a/salt/manager/sync_es_users.sls +++ b/salt/manager/sync_es_users.sls @@ -1,3 +1,8 @@ +# 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 as shown at +# https://securityonion.net/license; you may not use this file except in compliance with the +# Elastic License 2.0. + include: - elasticsearch.auth - kratos diff --git a/salt/manager/tools/sbin/so-minion b/salt/manager/tools/sbin/so-minion index 860faf445..2b3281fc8 100755 --- a/salt/manager/tools/sbin/so-minion +++ b/salt/manager/tools/sbin/so-minion @@ -726,6 +726,16 @@ function checkMine() { } } +# Add Elastic Agent settings to the minion file +function create_ca_pillar() { + local capillar=/opt/so/saltstack/local/pillar/ca/init.sls + /usr/sbin/so-yaml.py replace $capillar ca.server $MINION_ID + if [ $? -ne 0 ]; then + log "ERROR" "Failed to add $MINION_ID to $capillar" + return 1 + fi +} + function createEVAL() { log "INFO" "Creating EVAL configuration for minion $MINION_ID" is_pcaplimit=true @@ -1029,6 +1039,7 @@ function setupMinionFiles() { managers=("EVAL" "STANDALONE" "IMPORT" "MANAGER" "MANAGERSEARCH") if echo "${managers[@]}" | grep -qw "$NODETYPE"; then add_sensoroni_with_analyze_to_minion || return 1 + create_ca_pillar || return 1 else add_sensoroni_to_minion || return 1 fi diff --git a/salt/manager/tools/sbin/soup b/salt/manager/tools/sbin/soup index 32553b5c3..cada91a44 100755 --- a/salt/manager/tools/sbin/soup +++ b/salt/manager/tools/sbin/soup @@ -362,7 +362,6 @@ masterlock() { echo "base:" > $TOPFILE echo " $MINIONID:" >> $TOPFILE echo " - ca" >> $TOPFILE - echo " - ssl" >> $TOPFILE echo " - elasticsearch" >> $TOPFILE } diff --git a/salt/nginx/config.sls b/salt/nginx/config.sls index 27611034c..ead3d9986 100644 --- a/salt/nginx/config.sls +++ b/salt/nginx/config.sls @@ -6,9 +6,6 @@ {% from 'allowed_states.map.jinja' import allowed_states %} {% if sls.split('.')[0] in allowed_states %} -include: - - ssl - # Drop the correct nginx config based on role nginxconfdir: file.directory: diff --git a/salt/nginx/enabled.sls b/salt/nginx/enabled.sls index 8af48a766..4ebeb9349 100644 --- a/salt/nginx/enabled.sls +++ b/salt/nginx/enabled.sls @@ -8,81 +8,14 @@ {% from 'vars/globals.map.jinja' import GLOBALS %} {% from 'docker/docker.map.jinja' import DOCKER %} {% from 'nginx/map.jinja' import NGINXMERGED %} -{% set ca_server = GLOBALS.minion_id %} include: + - nginx.ssl - nginx.config - nginx.sostatus - -{% if grains.role not in ['so-fleet'] %} - -{# if the user has selected to replace the crt and key in the ui #} -{% if NGINXMERGED.ssl.replace_cert %} - -managerssl_key: - file.managed: - - name: /etc/pki/managerssl.key - - source: salt://nginx/ssl/ssl.key - - mode: 640 - - group: 939 - - watch_in: - - docker_container: so-nginx - -managerssl_crt: - file.managed: - - name: /etc/pki/managerssl.crt - - source: salt://nginx/ssl/ssl.crt - - mode: 644 - - watch_in: - - docker_container: so-nginx - -{% else %} - -managerssl_key: - x509.private_key_managed: - - name: /etc/pki/managerssl.key - - keysize: 4096 - - backup: True - - new: True - {% if salt['file.file_exists']('/etc/pki/managerssl.key') -%} - - prereq: - - x509: /etc/pki/managerssl.crt - {%- endif %} - - retry: - attempts: 5 - interval: 30 - - watch_in: - - docker_container: so-nginx - -# Create a cert for the reverse proxy -managerssl_crt: - x509.certificate_managed: - - name: /etc/pki/managerssl.crt - - ca_server: {{ ca_server }} - - signing_policy: managerssl - - private_key: /etc/pki/managerssl.key - - CN: {{ GLOBALS.hostname }} - - subjectAltName: "DNS:{{ GLOBALS.hostname }}, IP:{{ GLOBALS.node_ip }}, DNS:{{ GLOBALS.url_base }}" - - days_remaining: 7 - - days_valid: 820 - - backup: True - - timeout: 30 - - retry: - attempts: 5 - interval: 30 - - watch_in: - - docker_container: so-nginx - -{% endif %} - -msslkeyperms: - file.managed: - - replace: False - - name: /etc/pki/managerssl.key - - mode: 640 - - group: 939 - +{% if GLOBALS.role != 'so-fleet' %} +{% set container_config = 'so-nginx' %} make-rule-dir-nginx: file.directory: - name: /nsm/rules @@ -92,15 +25,11 @@ make-rule-dir-nginx: - user - group - show_changes: False - -{% endif %} -{# if this is an so-fleet node then we want to use the port bindings, custom bind mounts defined for fleet #} -{% if GLOBALS.role == 'so-fleet' %} -{% set container_config = 'so-nginx-fleet-node' %} -{% else %} -{% set container_config = 'so-nginx' %} -{% endif %} +{% else %} +{# if this is an so-fleet node then we want to use the port bindings, custom bind mounts defined for fleet #} +{% set container_config = 'so-nginx-fleet-node' %} +{% endif %} so-nginx: docker_container.running: @@ -154,18 +83,27 @@ so-nginx: - watch: - file: nginxconf - file: nginxconfdir - - require: - - file: nginxconf -{% if GLOBALS.is_manager %} -{% if NGINXMERGED.ssl.replace_cert %} + {% if GLOBALS.is_manager %} + {% if NGINXMERGED.ssl.replace_cert %} - file: managerssl_key - file: managerssl_crt -{% else %} + {% else %} - x509: managerssl_key - x509: managerssl_crt -{% endif%} + {% endif%} + {% endif %} + - require: + - file: nginxconf + {% if GLOBALS.is_manager %} + {% if NGINXMERGED.ssl.replace_cert %} + - file: managerssl_key + - file: managerssl_crt + {% else %} + - x509: managerssl_key + - x509: managerssl_crt + {% endif%} - file: navigatorconfig -{% endif %} + {% endif %} delete_so-nginx_so-status.disabled: file.uncomment: diff --git a/salt/nginx/ssl.sls b/salt/nginx/ssl.sls new file mode 100644 index 000000000..1c77dc28b --- /dev/null +++ b/salt/nginx/ssl.sls @@ -0,0 +1,87 @@ +# 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 as shown at +# https://securityonion.net/license; 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.split('.')[0] in allowed_states %} +{% from 'vars/globals.map.jinja' import GLOBALS %} +{% from 'nginx/map.jinja' import NGINXMERGED %} +{% from 'ca/map.jinja' import CA %} + +{% if GLOBALS.role != 'so-fleet' %} +{# if the user has selected to replace the crt and key in the ui #} +{% if NGINXMERGED.ssl.replace_cert %} + +managerssl_key: + file.managed: + - name: /etc/pki/managerssl.key + - source: salt://nginx/ssl/ssl.key + - mode: 640 + - group: 939 + - watch_in: + - docker_container: so-nginx + +managerssl_crt: + file.managed: + - name: /etc/pki/managerssl.crt + - source: salt://nginx/ssl/ssl.crt + - mode: 644 + - watch_in: + - docker_container: so-nginx + +{% else %} + +managerssl_key: + x509.private_key_managed: + - name: /etc/pki/managerssl.key + - keysize: 4096 + - backup: True + - new: True + {% if salt['file.file_exists']('/etc/pki/managerssl.key') -%} + - prereq: + - x509: /etc/pki/managerssl.crt + {%- endif %} + - retry: + attempts: 5 + interval: 30 + - watch_in: + - docker_container: so-nginx + +# Create a cert for the reverse proxy +managerssl_crt: + x509.certificate_managed: + - name: /etc/pki/managerssl.crt + - ca_server: {{ CA.server }} + - signing_policy: general + - private_key: /etc/pki/managerssl.key + - CN: {{ GLOBALS.hostname }} + - subjectAltName: "DNS:{{ GLOBALS.hostname }}, IP:{{ GLOBALS.node_ip }}, DNS:{{ GLOBALS.url_base }}" + - days_remaining: 7 + - days_valid: 820 + - backup: True + - timeout: 30 + - retry: + attempts: 5 + interval: 30 + - watch_in: + - docker_container: so-nginx + +{% endif %} + +msslkeyperms: + file.managed: + - replace: False + - name: /etc/pki/managerssl.key + - mode: 640 + - group: 939 + +{% endif %} + +{% else %} + +{{sls}}_state_not_allowed: + test.fail_without_changes: + - name: {{sls}}_state_not_allowed + +{% endif %} diff --git a/salt/pcap/ca.sls b/salt/pcap/ca.sls new file mode 100644 index 000000000..42081c9e6 --- /dev/null +++ b/salt/pcap/ca.sls @@ -0,0 +1,21 @@ +# 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 as shown at +# https://securityonion.net/license; 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.split('.')[0] in allowed_states or sls in allowed_states%} + +stenoca: + file.directory: + - name: /opt/so/conf/steno/certs + - user: 941 + - group: 939 + +{% else %} + +{{sls}}_state_not_allowed: + test.fail_without_changes: + - name: {{sls}}_state_not_allowed + +{% endif %} diff --git a/salt/pcap/config.sls b/salt/pcap/config.sls index c37da9694..3df29da1b 100644 --- a/salt/pcap/config.sls +++ b/salt/pcap/config.sls @@ -57,12 +57,6 @@ stenoconf: PCAPMERGED: {{ PCAPMERGED }} STENO_BPF_COMPILED: "{{ STENO_BPF_COMPILED }}" -stenoca: - file.directory: - - name: /opt/so/conf/steno/certs - - user: 941 - - group: 939 - pcaptmpdir: file.directory: - name: /nsm/pcaptmp diff --git a/salt/pcap/enabled.sls b/salt/pcap/enabled.sls index b7b030516..a62c3ee3c 100644 --- a/salt/pcap/enabled.sls +++ b/salt/pcap/enabled.sls @@ -10,6 +10,7 @@ include: + - pcap.ca - pcap.config - pcap.sostatus diff --git a/salt/redis/config.sls b/salt/redis/config.sls index 053d46707..11aaa1f0e 100644 --- a/salt/redis/config.sls +++ b/salt/redis/config.sls @@ -7,9 +7,6 @@ {% if sls.split('.')[0] in allowed_states %} {% from 'redis/map.jinja' import REDISMERGED %} -include: - - ssl - # Redis Setup redisconfdir: file.directory: diff --git a/salt/redis/enabled.sls b/salt/redis/enabled.sls index fc206e3cb..3406b63d4 100644 --- a/salt/redis/enabled.sls +++ b/salt/redis/enabled.sls @@ -9,6 +9,8 @@ {% from 'vars/globals.map.jinja' import GLOBALS %} include: + - ca + - redis.ssl - redis.config - redis.sostatus @@ -31,11 +33,7 @@ so-redis: - /nsm/redis/data:/data:rw - /etc/pki/redis.crt:/certs/redis.crt:ro - /etc/pki/redis.key:/certs/redis.key:ro - {% if grains['role'] in ['so-manager', 'so-managersearch', 'so-standalone', 'so-import'] %} - - /etc/pki/ca.crt:/certs/ca.crt:ro - {% else %} - /etc/pki/tls/certs/intca.crt:/certs/ca.crt:ro - {% endif %} {% if DOCKER.containers['so-redis'].custom_bind_mounts %} {% for BIND in DOCKER.containers['so-redis'].custom_bind_mounts %} - {{ BIND }} @@ -55,16 +53,14 @@ so-redis: {% endif %} - entrypoint: "redis-server /usr/local/etc/redis/redis.conf" - watch: - - file: /opt/so/conf/redis/etc - - require: - - file: redisconf + - file: trusttheca + - x509: redis_crt + - x509: redis_key + - file: /opt/so/conf/redis/etc + - require: + - file: trusttheca - x509: redis_crt - x509: redis_key - {% if grains['role'] in ['so-manager', 'so-managersearch', 'so-standalone', 'so-import'] %} - - x509: pki_public_ca_crt - {% else %} - - x509: trusttheca - {% endif %} delete_so-redis_so-status.disabled: file.uncomment: diff --git a/salt/redis/ssl.sls b/salt/redis/ssl.sls new file mode 100644 index 000000000..58af6486d --- /dev/null +++ b/salt/redis/ssl.sls @@ -0,0 +1,54 @@ +# 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 as shown at +# https://securityonion.net/license; 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.split('.')[0] in allowed_states %} +{% from 'vars/globals.map.jinja' import GLOBALS %} +{% from 'ca/map.jinja' import CA %} + +redis_key: + x509.private_key_managed: + - name: /etc/pki/redis.key + - keysize: 4096 + - backup: True + - new: True + {% if salt['file.file_exists']('/etc/pki/redis.key') -%} + - prereq: + - x509: /etc/pki/redis.crt + {%- endif %} + - retry: + attempts: 5 + interval: 30 + +redis_crt: + x509.certificate_managed: + - name: /etc/pki/redis.crt + - ca_server: {{ CA.server }} + - subjectAltName: DNS:{{ GLOBALS.hostname }}, IP:{{ GLOBALS.node_ip }} + - signing_policy: general + - private_key: /etc/pki/redis.key + - CN: {{ GLOBALS.hostname }} + - days_remaining: 7 + - days_valid: 820 + - backup: True + - timeout: 30 + - retry: + attempts: 5 + interval: 30 + +rediskeyperms: + file.managed: + - replace: False + - name: /etc/pki/redis.key + - mode: 640 + - group: 939 + +{% else %} + +{{sls}}_state_not_allowed: + test.fail_without_changes: + - name: {{sls}}_state_not_allowed + +{% endif %} diff --git a/salt/registry/config.sls b/salt/registry/config.sls index 098633829..299d80437 100644 --- a/salt/registry/config.sls +++ b/salt/registry/config.sls @@ -6,9 +6,6 @@ {% from 'allowed_states.map.jinja' import allowed_states %} {% if sls.split('.')[0] in allowed_states %} -include: - - ssl - # Create the config directory for the docker registry dockerregistryconfdir: file.directory: diff --git a/salt/registry/enabled.sls b/salt/registry/enabled.sls index ed5b180cd..7009f135e 100644 --- a/salt/registry/enabled.sls +++ b/salt/registry/enabled.sls @@ -9,6 +9,7 @@ {% from 'docker/docker.map.jinja' import DOCKER %} include: + - registry.ssl - registry.config - registry.sostatus @@ -53,6 +54,9 @@ so-dockerregistry: - retry: attempts: 5 interval: 30 + - watch: + - x509: registry_crt + - x509: registry_key - require: - file: dockerregistryconf - x509: registry_crt diff --git a/salt/registry/ssl.sls b/salt/registry/ssl.sls new file mode 100644 index 000000000..8d53b4214 --- /dev/null +++ b/salt/registry/ssl.sls @@ -0,0 +1,55 @@ +# 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 as shown at +# https://securityonion.net/license; 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.split('.')[0] in allowed_states %} +{% from 'vars/globals.map.jinja' import GLOBALS %} +{% from 'ca/map.jinja' import CA %} + +registry_key: + x509.private_key_managed: + - name: /etc/pki/registry.key + - keysize: 4096 + - backup: True + - new: True + {% if salt['file.file_exists']('/etc/pki/registry.key') -%} + - prereq: + - x509: /etc/pki/registry.crt + {%- endif %} + - retry: + attempts: 5 + interval: 30 + +# Create a cert for the docker registry +registry_crt: + x509.certificate_managed: + - name: /etc/pki/registry.crt + - ca_server: {{ CA.server }} + - subjectAltName: DNS:{{ GLOBALS.manager }}, IP:{{ GLOBALS.manager_ip }} + - signing_policy: general + - private_key: /etc/pki/registry.key + - CN: {{ GLOBALS.manager }} + - days_remaining: 7 + - days_valid: 820 + - backup: True + - timeout: 30 + - retry: + attempts: 5 + interval: 30 + +regkeyperms: + file.managed: + - replace: False + - name: /etc/pki/registry.key + - mode: 640 + - group: 939 + +{% else %} + +{{sls}}_state_not_allowed: + test.fail_without_changes: + - name: {{sls}}_state_not_allowed + +{% endif %} diff --git a/salt/salt/engines/master/checkmine.py b/salt/salt/engines/master/checkmine.py index f33392575..68127bacb 100644 --- a/salt/salt/engines/master/checkmine.py +++ b/salt/salt/engines/master/checkmine.py @@ -46,33 +46,6 @@ def start(interval=60): mine_update(minion) continue - # if a manager check that the ca in in the mine and it is correct - if minion.split('_')[-1] in ['manager', 'managersearch', 'eval', 'standalone', 'import']: - x509 = __salt__['saltutil.runner']('mine.get', tgt=minion, fun='x509.get_pem_entries') - try: - ca_crt = x509[minion]['/etc/pki/ca.crt'] - log.debug('checkmine engine: found minion %s has ca_crt: %s' % (minion, ca_crt)) - # since the cert is defined, make sure it is valid - import salt.modules.x509_v2 as x509_v2 - if not x509_v2.verify_private_key('/etc/pki/ca.key', '/etc/pki/ca.crt'): - log.error('checkmine engine: found minion %s does\'t have a valid ca_crt in the mine' % (minion)) - log.error('checkmine engine: %s: ca_crt: %s' % (minion, ca_crt)) - mine_delete(minion, 'x509.get_pem_entries') - mine_update(minion) - continue - else: - log.debug('checkmine engine: found minion %s has a valid ca_crt in the mine' % (minion)) - except IndexError: - log.error('checkmine engine: found minion %s does\'t have a ca_crt in the mine' % (minion)) - mine_delete(minion, 'x509.get_pem_entries') - mine_update(minion) - continue - except KeyError: - log.error('checkmine engine: found minion %s is not in the mine' % (minion)) - mine_flush(minion) - mine_update(minion) - continue - # Update the mine if the ip in the mine doesn't match returned from manage.alived network_ip_addrs = __salt__['saltutil.runner']('mine.get', tgt=minion, fun='network.ip_addrs') try: diff --git a/salt/salt/mine_functions.sls b/salt/salt/mine_functions.sls index ae3df1ce9..dd164503b 100644 --- a/salt/salt/mine_functions.sls +++ b/salt/salt/mine_functions.sls @@ -18,10 +18,6 @@ mine_functions: mine_functions: network.ip_addrs: - interface: {{ interface }} - {%- if role in ['so-eval','so-import','so-manager','so-managerhype','so-managersearch','so-standalone'] %} - x509.get_pem_entries: - - glob_path: '/etc/pki/ca.crt' - {% endif %} mine_update_mine_functions: module.run: diff --git a/salt/salt/minion/init.sls b/salt/salt/minion/init.sls index 374e6954c..2f59e0029 100644 --- a/salt/salt/minion/init.sls +++ b/salt/salt/minion/init.sls @@ -17,8 +17,8 @@ include: - repo.client - salt.mine_functions - salt.minion.service_file -{% if GLOBALS.role in GLOBALS.manager_roles %} - - ca +{% if GLOBALS.is_manager %} + - ca.signing_policy {% endif %} {% if INSTALLEDSALTVERSION|string != SALTVERSION|string %} @@ -111,7 +111,7 @@ salt_minion_service: {% if INSTALLEDSALTVERSION|string == SALTVERSION|string %} - file: set_log_levels {% endif %} -{% if GLOBALS.role in GLOBALS.manager_roles %} - - file: /etc/salt/minion.d/signing_policies.conf +{% if GLOBALS.is_manager %} + - file: signing_policy {% endif %} - order: last diff --git a/salt/sensoroni/enabled.sls b/salt/sensoroni/enabled.sls index 4b0b6b317..f76288fec 100644 --- a/salt/sensoroni/enabled.sls +++ b/salt/sensoroni/enabled.sls @@ -8,6 +8,7 @@ include: + - pcap.ca - sensoroni.config - sensoroni.sostatus diff --git a/salt/soc/enabled.sls b/salt/soc/enabled.sls index fdf4d1e6e..aeb05287e 100644 --- a/salt/soc/enabled.sls +++ b/salt/soc/enabled.sls @@ -11,6 +11,7 @@ {% from 'soc/merged.map.jinja' import SOCMERGED %} include: + - ca - soc.config - soc.sostatus @@ -54,7 +55,7 @@ so-soc: - /opt/so/conf/soc/migrations:/opt/so/conf/soc/migrations:rw - /nsm/backup/detections-migration:/nsm/backup/detections-migration:ro - /opt/so/state:/opt/so/state:rw - - /etc/pki/ca.crt:/opt/sensoroni/html/so-ca.crt:ro + - /etc/pki/tls/certs/intca.crt:/opt/sensoroni/html/so-ca.crt:ro - extra_hosts: {% for node in DOCKER_EXTRA_HOSTS %} {% for hostname, ip in node.items() %} @@ -77,8 +78,10 @@ so-soc: {% endfor %} {% endif %} - watch: + - file: trusttheca - file: /opt/so/conf/soc/* - require: + - file: trusttheca - file: socdatadir - file: soclogdir - file: socconfig diff --git a/salt/ssl/init.sls b/salt/ssl/init.sls deleted file mode 100644 index 9dfef9fc8..000000000 --- a/salt/ssl/init.sls +++ /dev/null @@ -1,720 +0,0 @@ -# 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 as shown at -# https://securityonion.net/license; 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 'elasticfleet/map.jinja' import ELASTICFLEETMERGED %} - -{% set global_ca_text = [] %} -{% set global_ca_server = [] %} -{% if grains.role in ['so-heavynode'] %} - {% set COMMONNAME = GLOBALS.hostname %} -{% else %} - {% set COMMONNAME = GLOBALS.manager %} -{% endif %} - -{% if GLOBALS.is_manager %} -include: - - ca - {% set trusttheca_text = salt['cp.get_file_str']('/etc/pki/ca.crt')|replace('\n', '') %} - {% set ca_server = grains.id %} -{% else %} -include: - - ca.dirs - {% set x509dict = salt['mine.get'](GLOBALS.manager | lower~'*', 'x509.get_pem_entries') %} - {% for host in x509dict %} - {% if 'manager' in host.split('_')|last or host.split('_')|last == 'standalone' %} - {% do global_ca_text.append(x509dict[host].get('/etc/pki/ca.crt')|replace('\n', '')) %} - {% do global_ca_server.append(host) %} - {% endif %} - {% endfor %} - {% set trusttheca_text = global_ca_text[0] %} - {% set ca_server = global_ca_server[0] %} -{% endif %} - -cacertdir: - file.directory: - - name: /etc/pki/tls/certs - - makedirs: True - -# Trust the CA -trusttheca: - x509.pem_managed: - - name: /etc/pki/tls/certs/intca.crt - - text: {{ trusttheca_text }} - -{% if GLOBALS.os_family == 'Debian' %} -symlinkca: - file.symlink: - - target: /etc/pki/tls/certs/intca.crt - - name: /etc/ssl/certs/intca.crt -{% endif %} - -# Install packages needed for the sensor -m2cryptopkgs: - pkg.installed: - - skip_suggestions: False - - pkgs: - - python3-m2crypto - -influxdb_key: - x509.private_key_managed: - - name: /etc/pki/influxdb.key - - keysize: 4096 - - backup: True - - new: True - {% if salt['file.file_exists']('/etc/pki/influxdb.key') -%} - - prereq: - - x509: /etc/pki/influxdb.crt - {%- endif %} - - retry: - attempts: 5 - interval: 30 - -# Create a cert for the talking to influxdb -influxdb_crt: - x509.certificate_managed: - - name: /etc/pki/influxdb.crt - - ca_server: {{ ca_server }} - - signing_policy: influxdb - - private_key: /etc/pki/influxdb.key - - CN: {{ GLOBALS.hostname }} - - subjectAltName: DNS:{{ GLOBALS.hostname }}, IP:{{ GLOBALS.node_ip }} - - days_remaining: 7 - - days_valid: 820 - - backup: True - - timeout: 30 - - retry: - attempts: 5 - interval: 30 - -influxkeyperms: - file.managed: - - replace: False - - name: /etc/pki/influxdb.key - - mode: 640 - - group: 939 - -{% if GLOBALS.is_manager or GLOBALS.role in ['so-heavynode', 'so-fleet', 'so-receiver'] %} -# Create a cert for Redis encryption -redis_key: - x509.private_key_managed: - - name: /etc/pki/redis.key - - keysize: 4096 - - backup: True - - new: True - {% if salt['file.file_exists']('/etc/pki/redis.key') -%} - - prereq: - - x509: /etc/pki/redis.crt - {%- endif %} - - retry: - attempts: 5 - interval: 30 - -redis_crt: - x509.certificate_managed: - - name: /etc/pki/redis.crt - - ca_server: {{ ca_server }} - - subjectAltName: DNS:{{ GLOBALS.hostname }}, IP:{{ GLOBALS.node_ip }} - - signing_policy: registry - - private_key: /etc/pki/redis.key - - CN: {{ GLOBALS.hostname }} - - days_remaining: 7 - - days_valid: 820 - - backup: True - - timeout: 30 - - retry: - attempts: 5 - interval: 30 - -rediskeyperms: - file.managed: - - replace: False - - name: /etc/pki/redis.key - - mode: 640 - - group: 939 -{% endif %} - -{% if GLOBALS.is_manager or GLOBALS.role in ['so-heavynode', 'so-fleet', 'so-receiver'] %} - -{% if grains['role'] not in [ 'so-heavynode', 'so-receiver'] %} -# Start -- Elastic Fleet Host Cert -etc_elasticfleet_key: - x509.private_key_managed: - - name: /etc/pki/elasticfleet-server.key - - keysize: 4096 - - backup: True - - new: True - {% if salt['file.file_exists']('/etc/pki/elasticfleet-server.key') -%} - - prereq: - - x509: etc_elasticfleet_crt - {%- endif %} - - retry: - attempts: 5 - interval: 30 - -etc_elasticfleet_crt: - x509.certificate_managed: - - name: /etc/pki/elasticfleet-server.crt - - ca_server: {{ ca_server }} - - signing_policy: elasticfleet - - private_key: /etc/pki/elasticfleet-server.key - - CN: {{ GLOBALS.hostname }} - - subjectAltName: DNS:{{ GLOBALS.hostname }},DNS:{{ GLOBALS.url_base }},IP:{{ GLOBALS.node_ip }}{% if ELASTICFLEETMERGED.config.server.custom_fqdn | length > 0 %},DNS:{{ ELASTICFLEETMERGED.config.server.custom_fqdn | join(',DNS:') }}{% endif %} - - days_remaining: 7 - - days_valid: 820 - - backup: True - - timeout: 30 - - retry: - attempts: 5 - interval: 30 - -efperms: - file.managed: - - replace: False - - name: /etc/pki/elasticfleet-server.key - - mode: 640 - - group: 939 - -chownelasticfleetcrt: - file.managed: - - replace: False - - name: /etc/pki/elasticfleet-server.crt - - mode: 640 - - user: 947 - - group: 939 - -chownelasticfleetkey: - file.managed: - - replace: False - - name: /etc/pki/elasticfleet-server.key - - mode: 640 - - user: 947 - - group: 939 -# End -- Elastic Fleet Host Cert -{% endif %} # endif is for not including HeavyNodes & Receivers - -{% if grains['role'] not in [ 'so-heavynode'] %} -# Start -- Elastic Fleet Logstash Input Cert -etc_elasticfleet_logstash_key: - x509.private_key_managed: - - name: /etc/pki/elasticfleet-logstash.key - - keysize: 4096 - - backup: True - - new: True - {% if salt['file.file_exists']('/etc/pki/elasticfleet-logstash.key') -%} - - prereq: - - x509: etc_elasticfleet_logstash_crt - {%- endif %} - - retry: - attempts: 5 - interval: 30 - -etc_elasticfleet_logstash_crt: - x509.certificate_managed: - - name: /etc/pki/elasticfleet-logstash.crt - - ca_server: {{ ca_server }} - - signing_policy: elasticfleet - - private_key: /etc/pki/elasticfleet-logstash.key - - CN: {{ GLOBALS.hostname }} - - subjectAltName: DNS:{{ GLOBALS.hostname }},DNS:{{ GLOBALS.url_base }},IP:{{ GLOBALS.node_ip }}{% if ELASTICFLEETMERGED.config.server.custom_fqdn | length > 0 %},DNS:{{ ELASTICFLEETMERGED.config.server.custom_fqdn | join(',DNS:') }}{% endif %} - - days_remaining: 7 - - days_valid: 820 - - backup: True - - 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_logstash_key - -eflogstashperms: - file.managed: - - replace: False - - name: /etc/pki/elasticfleet-logstash.key - - mode: 640 - - group: 939 - -chownelasticfleetlogstashcrt: - file.managed: - - replace: False - - name: /etc/pki/elasticfleet-logstash.crt - - mode: 640 - - user: 931 - - group: 939 - -chownelasticfleetlogstashkey: - file.managed: - - replace: False - - name: /etc/pki/elasticfleet-logstash.key - - mode: 640 - - user: 931 - - group: 939 -# End -- Elastic Fleet Logstash Input Cert -{% endif %} # endif is for not including HeavyNodes - -# Start -- Elastic Fleet Node - Logstash Lumberjack Input / Output -# Cert needed on: Managers, Receivers -etc_elasticfleetlumberjack_key: - x509.private_key_managed: - - name: /etc/pki/elasticfleet-lumberjack.key - - bits: 4096 - - backup: True - - new: True - {% if salt['file.file_exists']('/etc/pki/elasticfleet-lumberjack.key') -%} - - prereq: - - x509: etc_elasticfleetlumberjack_crt - {%- endif %} - - retry: - attempts: 5 - interval: 30 - -etc_elasticfleetlumberjack_crt: - x509.certificate_managed: - - name: /etc/pki/elasticfleet-lumberjack.crt - - ca_server: {{ ca_server }} - - signing_policy: elasticfleet - - private_key: /etc/pki/elasticfleet-lumberjack.key - - CN: {{ GLOBALS.node_ip }} - - subjectAltName: DNS:{{ GLOBALS.hostname }} - - days_remaining: 7 - - days_valid: 820 - - backup: True - - timeout: 30 - - retry: - attempts: 5 - interval: 30 - cmd.run: - - name: "/usr/bin/openssl pkcs8 -in /etc/pki/elasticfleet-lumberjack.key -topk8 -out /etc/pki/elasticfleet-lumberjack.p8 -nocrypt" - - onchanges: - - x509: etc_elasticfleetlumberjack_key - -eflogstashlumberjackperms: - file.managed: - - replace: False - - name: /etc/pki/elasticfleet-lumberjack.key - - mode: 640 - - group: 939 - -chownilogstashelasticfleetlumberjackp8: - file.managed: - - replace: False - - name: /etc/pki/elasticfleet-lumberjack.p8 - - mode: 640 - - user: 931 - - group: 939 - -chownilogstashelasticfleetlogstashlumberjackcrt: - file.managed: - - replace: False - - name: /etc/pki/elasticfleet-lumberjack.crt - - mode: 640 - - user: 931 - - group: 939 - -chownilogstashelasticfleetlogstashlumberjackkey: - file.managed: - - replace: False - - name: /etc/pki/elasticfleet-lumberjack.key - - mode: 640 - - user: 931 - - group: 939 - -# End -- Elastic Fleet Node - Logstash Lumberjack Input / Output - -# Start -- Elastic Fleet Client Cert for Agent (Mutual Auth with Logstash Output) -etc_elasticfleet_agent_key: - x509.private_key_managed: - - name: /etc/pki/elasticfleet-agent.key - - keysize: 4096 - - backup: True - - new: True - {% if salt['file.file_exists']('/etc/pki/elasticfleet-agent.key') -%} - - prereq: - - x509: etc_elasticfleet_agent_crt - {%- endif %} - - retry: - attempts: 5 - interval: 30 - -etc_elasticfleet_agent_crt: - x509.certificate_managed: - - name: /etc/pki/elasticfleet-agent.crt - - ca_server: {{ ca_server }} - - signing_policy: elasticfleet - - private_key: /etc/pki/elasticfleet-agent.key - - CN: {{ GLOBALS.hostname }} - - days_remaining: 7 - - days_valid: 820 - - backup: True - - timeout: 30 - - retry: - attempts: 5 - interval: 30 - cmd.run: - - name: "/usr/bin/openssl pkcs8 -in /etc/pki/elasticfleet-agent.key -topk8 -out /etc/pki/elasticfleet-agent.p8 -nocrypt" - - onchanges: - - x509: etc_elasticfleet_agent_key - -efagentperms: - file.managed: - - replace: False - - name: /etc/pki/elasticfleet-agent.key - - mode: 640 - - group: 939 - -chownelasticfleetagentcrt: - file.managed: - - replace: False - - name: /etc/pki/elasticfleet-agent.crt - - mode: 640 - - user: 947 - - group: 939 - -chownelasticfleetagentkey: - file.managed: - - replace: False - - name: /etc/pki/elasticfleet-agent.key - - mode: 640 - - user: 947 - - group: 939 -# End -- Elastic Fleet Client Cert for Agent (Mutual Auth with Logstash Output) - -{% endif %} - -{% if GLOBALS.is_manager or GLOBALS.role in ['so-heavynode', 'so-receiver'] %} -etc_filebeat_key: - x509.private_key_managed: - - name: /etc/pki/filebeat.key - - keysize: 4096 - - backup: True - - new: True - {% if salt['file.file_exists']('/etc/pki/filebeat.key') -%} - - prereq: - - x509: etc_filebeat_crt - {%- endif %} - - retry: - attempts: 5 - interval: 30 - -# Request a cert and drop it where it needs to go to be distributed -etc_filebeat_crt: - x509.certificate_managed: - - name: /etc/pki/filebeat.crt - - ca_server: {{ ca_server }} - - signing_policy: filebeat - - private_key: /etc/pki/filebeat.key - - CN: {{ GLOBALS.hostname }} - - subjectAltName: DNS:{{ GLOBALS.hostname }}, IP:{{ GLOBALS.node_ip }} - - days_remaining: 7 - - days_valid: 820 - - backup: True - - timeout: 30 - - retry: - attempts: 5 - interval: 30 - cmd.run: - - name: "/usr/bin/openssl pkcs8 -in /etc/pki/filebeat.key -topk8 -out /etc/pki/filebeat.p8 -nocrypt" - - onchanges: - - x509: etc_filebeat_key - -fbperms: - file.managed: - - replace: False - - name: /etc/pki/filebeat.key - - mode: 640 - - group: 939 - -chownilogstashfilebeatp8: - file.managed: - - replace: False - - name: /etc/pki/filebeat.p8 - - mode: 640 - - user: 931 - - group: 939 - - {% if grains.role not in ['so-heavynode', 'so-receiver'] %} -# Create Symlinks to the keys so I can distribute it to all the things -filebeatdir: - file.directory: - - name: /opt/so/saltstack/local/salt/filebeat/files - - makedirs: True - -fbkeylink: - file.symlink: - - name: /opt/so/saltstack/local/salt/filebeat/files/filebeat.p8 - - target: /etc/pki/filebeat.p8 - - user: socore - - group: socore - -fbcrtlink: - file.symlink: - - name: /opt/so/saltstack/local/salt/filebeat/files/filebeat.crt - - target: /etc/pki/filebeat.crt - - user: socore - - group: socore - -registry_key: - x509.private_key_managed: - - name: /etc/pki/registry.key - - keysize: 4096 - - backup: True - - new: True - {% if salt['file.file_exists']('/etc/pki/registry.key') -%} - - prereq: - - x509: /etc/pki/registry.crt - {%- endif %} - - retry: - attempts: 5 - interval: 30 - -# Create a cert for the docker registry -registry_crt: - x509.certificate_managed: - - name: /etc/pki/registry.crt - - ca_server: {{ ca_server }} - - subjectAltName: DNS:{{ GLOBALS.manager }}, IP:{{ GLOBALS.manager_ip }} - - signing_policy: registry - - private_key: /etc/pki/registry.key - - CN: {{ GLOBALS.manager }} - - days_remaining: 7 - - days_valid: 820 - - backup: True - - timeout: 30 - - retry: - attempts: 5 - interval: 30 - -regkeyperms: - file.managed: - - replace: False - - name: /etc/pki/registry.key - - mode: 640 - - group: 939 - - {% endif %} - {% if grains.role not in ['so-receiver'] %} -# Create a cert for elasticsearch -/etc/pki/elasticsearch.key: - x509.private_key_managed: - - keysize: 4096 - - backup: True - - new: True - {% if salt['file.file_exists']('/etc/pki/elasticsearch.key') -%} - - prereq: - - x509: /etc/pki/elasticsearch.crt - {%- endif %} - - retry: - attempts: 5 - interval: 30 - -/etc/pki/elasticsearch.crt: - x509.certificate_managed: - - ca_server: {{ ca_server }} - - signing_policy: registry - - private_key: /etc/pki/elasticsearch.key - - CN: {{ GLOBALS.hostname }} - - subjectAltName: DNS:{{ GLOBALS.hostname }}, IP:{{ GLOBALS.node_ip }} - - days_remaining: 7 - - days_valid: 820 - - backup: True - - timeout: 30 - - retry: - attempts: 5 - interval: 30 - cmd.run: - - name: "/usr/bin/openssl pkcs12 -inkey /etc/pki/elasticsearch.key -in /etc/pki/elasticsearch.crt -export -out /etc/pki/elasticsearch.p12 -nodes -passout pass:" - - onchanges: - - x509: /etc/pki/elasticsearch.key - -elastickeyperms: - file.managed: - - replace: False - - name: /etc/pki/elasticsearch.key - - mode: 640 - - group: 930 - -elasticp12perms: - file.managed: - - replace: False - - name: /etc/pki/elasticsearch.p12 - - mode: 640 - - group: 930 - - {% endif %} - - -{% endif %} - -{% if GLOBALS.is_manager or GLOBALS.role in ['so-sensor', 'so-searchnode', 'so-heavynode', 'so-fleet', 'so-idh', 'so-receiver'] %} - -fbcertdir: - file.directory: - - name: /opt/so/conf/filebeat/etc/pki - - makedirs: True - -conf_filebeat_key: - x509.private_key_managed: - - name: /opt/so/conf/filebeat/etc/pki/filebeat.key - - keysize: 4096 - - backup: True - - new: True - {% if salt['file.file_exists']('/opt/so/conf/filebeat/etc/pki/filebeat.key') -%} - - prereq: - - x509: conf_filebeat_crt - {%- endif %} - - retry: - attempts: 5 - interval: 30 - -# Request a cert and drop it where it needs to go to be distributed -conf_filebeat_crt: - x509.certificate_managed: - - name: /opt/so/conf/filebeat/etc/pki/filebeat.crt - - ca_server: {{ ca_server }} - - signing_policy: filebeat - - private_key: /opt/so/conf/filebeat/etc/pki/filebeat.key - - CN: {{ GLOBALS.hostname }} - - subjectAltName: DNS:{{ GLOBALS.hostname }}, IP:{{ GLOBALS.node_ip }} - - days_remaining: 7 - - days_valid: 820 - - backup: True - - timeout: 30 - - retry: - attempts: 5 - interval: 30 - -# Convert the key to pkcs#8 so logstash will work correctly. -filebeatpkcs: - cmd.run: - - name: "/usr/bin/openssl pkcs8 -in /opt/so/conf/filebeat/etc/pki/filebeat.key -topk8 -out /opt/so/conf/filebeat/etc/pki/filebeat.p8 -passout pass:" - - onchanges: - - x509: conf_filebeat_key - -filebeatkeyperms: - file.managed: - - replace: False - - name: /opt/so/conf/filebeat/etc/pki/filebeat.key - - mode: 640 - - group: 939 - -chownfilebeatp8: - file.managed: - - replace: False - - name: /opt/so/conf/filebeat/etc/pki/filebeat.p8 - - mode: 640 - - user: 931 - - group: 939 - -{% endif %} - -{% if grains['role'] == 'so-searchnode' %} -# Create a cert for elasticsearch -/etc/pki/elasticsearch.key: - x509.private_key_managed: - - keysize: 4096 - - backup: True - - new: True - {% if salt['file.file_exists']('/etc/pki/elasticsearch.key') -%} - - prereq: - - x509: /etc/pki/elasticsearch.crt - {%- endif %} - - retry: - attempts: 5 - interval: 30 - -/etc/pki/elasticsearch.crt: - x509.certificate_managed: - - ca_server: {{ ca_server }} - - signing_policy: registry - - private_key: /etc/pki/elasticsearch.key - - CN: {{ GLOBALS.hostname }} - - subjectAltName: DNS:{{ GLOBALS.hostname }}, IP:{{ GLOBALS.node_ip }} - - days_remaining: 7 - - days_valid: 820 - - backup: True - - timeout: 30 - - retry: - attempts: 5 - interval: 30 - cmd.run: - - name: "/usr/bin/openssl pkcs12 -inkey /etc/pki/elasticsearch.key -in /etc/pki/elasticsearch.crt -export -out /etc/pki/elasticsearch.p12 -nodes -passout pass:" - - onchanges: - - x509: /etc/pki/elasticsearch.key - -elasticp12perms: - file.managed: - - replace: False - - name: /etc/pki/elasticsearch.p12 - - mode: 640 - - group: 930 - -elastickeyperms: - file.managed: - - replace: False - - name: /etc/pki/elasticsearch.key - - mode: 640 - - group: 930 -{%- endif %} - -{% if GLOBALS.role in ['so-manager', 'so-managerhype', 'so-managersearch', 'so-standalone'] %} -elasticfleet_kafka_key: - x509.private_key_managed: - - name: /etc/pki/elasticfleet-kafka.key - - keysize: 4096 - - backup: True - - new: True - {% if salt['file.file_exists']('/etc/pki/elasticfleet-kafka.key') -%} - - prereq: - - x509: elasticfleet_kafka_crt - {%- endif %} - - retry: - attempts: 5 - interval: 30 - -elasticfleet_kafka_crt: - x509.certificate_managed: - - name: /etc/pki/elasticfleet-kafka.crt - - ca_server: {{ ca_server }} - - signing_policy: kafka - - private_key: /etc/pki/elasticfleet-kafka.key - - CN: {{ GLOBALS.hostname }} - - subjectAltName: DNS:{{ GLOBALS.hostname }}, IP:{{ GLOBALS.node_ip }} - - days_remaining: 7 - - days_valid: 820 - - backup: True - - timeout: 30 - - retry: - attempts: 5 - interval: 30 - -elasticfleet_kafka_cert_perms: - file.managed: - - replace: False - - name: /etc/pki/elasticfleet-kafka.crt - - mode: 640 - - user: 947 - - group: 939 - -elasticfleet_kafka_key_perms: - file.managed: - - replace: False - - name: /etc/pki/elasticfleet-kafka.key - - mode: 640 - - user: 947 - - group: 939 -{% endif %} - -{% else %} - -{{sls}}_state_not_allowed: - test.fail_without_changes: - - name: {{sls}}_state_not_allowed - -{% endif %} diff --git a/salt/ssl/remove.sls b/salt/ssl/remove.sls index 28b860205..08e97180e 100644 --- a/salt/ssl/remove.sls +++ b/salt/ssl/remove.sls @@ -1,3 +1,8 @@ +# 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 as shown at +# https://securityonion.net/license; you may not use this file except in compliance with the +# Elastic License 2.0. + trusttheca: file.absent: - name: /etc/pki/tls/certs/intca.crt @@ -14,6 +19,14 @@ influxdb_crt: file.absent: - name: /etc/pki/influxdb.crt +telegraf_key: + file.absent: + - name: /etc/pki/telegraf.key + +telegraf_crt: + file.absent: + - name: /etc/pki/telegraf.crt + redis_key: file.absent: - name: /etc/pki/redis.key @@ -42,11 +55,13 @@ registry_crt: file.absent: - name: /etc/pki/registry.crt -/etc/pki/elasticsearch.key: - file.absent: [] +elasticsearch_key: + file.absent: + - name: /etc/pki/elasticsearch.key -/etc/pki/elasticsearch.crt: - file.absent: [] +elasticsearch_crt: + file.absent: + - name: /etc/pki/elasticsearch.crt remove_elasticsearch.p12: file.absent: @@ -75,6 +90,7 @@ fbcertdir: kafka_crt: file.absent: - name: /etc/pki/kafka.crt + kafka_key: file.absent: - name: /etc/pki/kafka.key @@ -82,9 +98,67 @@ kafka_key: kafka_logstash_crt: file.absent: - name: /etc/pki/kafka-logstash.crt + kafka_logstash_key: file.absent: - name: /etc/pki/kafka-logstash.key + kafka_logstash_keystore: file.absent: - name: /etc/pki/kafka-logstash.p12 + +elasticfleet_agent_crt: + file.absent: + - name: /etc/pki/elasticfleet-agent.crt + +elasticfleet_agent_key: + file.absent: + - name: /etc/pki/elasticfleet-agent.key + +elasticfleet_agent_p8: + file.absent: + - name: /etc/pki/elasticfleet-agent.p8 + +elasticfleet_kafka_crt: + file.absent: + - name: /etc/pki/elasticfleet-kafka.crt + +elasticfleet_kafka_key: + file.absent: + - name: /etc/pki/elasticfleet-kafka.key + +elasticfleet_logstash_crt: + file.absent: + - name: /etc/pki/elasticfleet-logstash.crt + +elasticfleet_logstash_key: + file.absent: + - name: /etc/pki/elasticfleet-logstash.key + +elasticfleet_logstash_p8: + file.absent: + - name: /etc/pki/elasticfleet-logstash.p8 + +elasticfleet_lumberjack_crt: + file.absent: + - name: /etc/pki/elasticfleet-lumberjack.crt + +elasticfleet_lumberjack_key: + file.absent: + - name: /etc/pki/elasticfleet-lumberjack.key + +elasticfleet_lumberjack_p8: + file.absent: + - name: /etc/pki/elasticfleet-lumberjack.p8 + +elasticfleet_server_crt: + file.absent: + - name: /etc/pki/elasticfleet-server.crt + +elasticfleet_server_key: + file.absent: + - name: /etc/pki/elasticfleet-server.key + +filebeat_p8: + file.absent: + - name: /etc/pki/filebeat.p8 diff --git a/salt/telegraf/config.sls b/salt/telegraf/config.sls index 171bd41f5..f9a7bbfdb 100644 --- a/salt/telegraf/config.sls +++ b/salt/telegraf/config.sls @@ -8,9 +8,6 @@ {% from 'vars/globals.map.jinja' import GLOBALS %} {% from 'telegraf/map.jinja' import TELEGRAFMERGED %} -include: - - ssl - # add Telegraf to monitor all the things tgraflogdir: file.directory: diff --git a/salt/telegraf/enabled.sls b/salt/telegraf/enabled.sls index 451c78dda..e77b04995 100644 --- a/salt/telegraf/enabled.sls +++ b/salt/telegraf/enabled.sls @@ -9,8 +9,9 @@ {% from 'docker/docker.map.jinja' import DOCKER %} {% from 'telegraf/map.jinja' import TELEGRAFMERGED %} - include: + - ca + - telegraf.ssl - telegraf.config - telegraf.sostatus @@ -42,13 +43,9 @@ so-telegraf: - /proc:/host/proc:ro - /nsm:/host/nsm:ro - /etc:/host/etc:ro - {% if GLOBALS.role in ['so-manager', 'so-eval', 'so-managersearch' ] %} - - /etc/pki/ca.crt:/etc/telegraf/ca.crt:ro - {% else %} - /etc/pki/tls/certs/intca.crt:/etc/telegraf/ca.crt:ro - {% endif %} - - /etc/pki/influxdb.crt:/etc/telegraf/telegraf.crt:ro - - /etc/pki/influxdb.key:/etc/telegraf/telegraf.key:ro + - /etc/pki/telegraf.crt:/etc/telegraf/telegraf.crt:ro + - /etc/pki/telegraf.key:/etc/telegraf/telegraf.key:ro - /opt/so/conf/telegraf/scripts:/scripts:ro - /opt/so/log/stenographer:/var/log/stenographer:ro - /opt/so/log/suricata:/var/log/suricata:ro @@ -71,21 +68,20 @@ so-telegraf: {% endfor %} {% endif %} - watch: + - file: trusttheca + - x509: telegraf_crt + - x509: telegraf_key - file: tgrafconf - file: node_config {% for script in TELEGRAFMERGED.scripts[GLOBALS.role.split('-')[1]] %} - file: tgraf_sync_script_{{script}} {% endfor %} - - require: + - require: + - file: trusttheca + - x509: telegraf_crt + - x509: telegraf_key - file: tgrafconf - file: node_config - {% if GLOBALS.role in ['so-manager', 'so-eval', 'so-managersearch' ] %} - - x509: pki_public_ca_crt - {% else %} - - x509: trusttheca - {% endif %} - - x509: influxdb_crt - - x509: influxdb_key delete_so-telegraf_so-status.disabled: file.uncomment: diff --git a/salt/telegraf/ssl.sls b/salt/telegraf/ssl.sls new file mode 100644 index 000000000..9fab48958 --- /dev/null +++ b/salt/telegraf/ssl.sls @@ -0,0 +1,55 @@ +# 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 as shown at +# https://securityonion.net/license; 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.split('.')[0] in allowed_states %} +{% from 'vars/globals.map.jinja' import GLOBALS %} +{% from 'ca/map.jinja' import CA %} + +telegraf_key: + x509.private_key_managed: + - name: /etc/pki/telegraf.key + - keysize: 4096 + - backup: True + - new: True + {% if salt['file.file_exists']('/etc/pki/telegraf.key') -%} + - prereq: + - x509: /etc/pki/telegraf.crt + {%- endif %} + - retry: + attempts: 5 + interval: 30 + +# Create a cert for the talking to telegraf +telegraf_crt: + x509.certificate_managed: + - name: /etc/pki/telegraf.crt + - ca_server: {{ CA.server }} + - signing_policy: general + - private_key: /etc/pki/telegraf.key + - CN: {{ GLOBALS.hostname }} + - subjectAltName: DNS:{{ GLOBALS.hostname }}, IP:{{ GLOBALS.node_ip }} + - days_remaining: 7 + - days_valid: 820 + - backup: True + - timeout: 30 + - retry: + attempts: 5 + interval: 30 + +telegraf_key_perms: + file.managed: + - replace: False + - name: /etc/pki/telegraf.key + - mode: 640 + - group: 939 + +{% else %} + +{{sls}}_state_not_allowed: + test.fail_without_changes: + - name: {{sls}}_state_not_allowed + +{% endif %} diff --git a/salt/top.sls b/salt/top.sls index 6c3135b45..9184bd3e3 100644 --- a/salt/top.sls +++ b/salt/top.sls @@ -37,6 +37,7 @@ base: 'not ( *_manager* or *_eval or *_import or *_standalone ) and G@saltversion:{{saltversion}}': - match: compound - salt.minion + - ca - patch.os.schedule - motd - salt.minion-check @@ -49,6 +50,7 @@ base: '( *_manager* or *_eval or *_import or *_standalone ) and G@saltversion:{{saltversion}} and not I@node_data:False': - match: compound - salt.minion + - ca - patch.os.schedule - motd - salt.minion-check @@ -61,8 +63,6 @@ base: - match: compound - salt.master - sensor - - ca - - ssl - registry - manager - backup.config_backup @@ -93,8 +93,6 @@ base: - match: compound - salt.master - sensor - - ca - - ssl - registry - manager - backup.config_backup @@ -128,8 +126,6 @@ base: '*_manager or *_managerhype and G@saltversion:{{saltversion}} and not I@node_data:False': - match: compound - salt.master - - ca - - ssl - registry - nginx - influxdb @@ -163,8 +159,6 @@ base: '*_managersearch and G@saltversion:{{saltversion}} and not I@node_data:False': - match: compound - salt.master - - ca - - ssl - registry - nginx - influxdb @@ -195,8 +189,6 @@ base: - match: compound - salt.master - sensor - - ca - - ssl - registry - manager - nginx @@ -222,7 +214,6 @@ base: '*_searchnode and G@saltversion:{{saltversion}}': - match: compound - firewall - - ssl - elasticsearch - logstash - sensoroni @@ -235,7 +226,6 @@ base: '*_sensor and G@saltversion:{{saltversion}}': - match: compound - sensor - - ssl - sensoroni - telegraf - firewall @@ -251,7 +241,6 @@ base: '*_heavynode and G@saltversion:{{saltversion}}': - match: compound - sensor - - ssl - sensoroni - telegraf - nginx @@ -269,7 +258,6 @@ base: '*_receiver and G@saltversion:{{saltversion}}': - match: compound - - ssl - sensoroni - telegraf - firewall @@ -281,7 +269,6 @@ base: '*_idh and G@saltversion:{{saltversion}}': - match: compound - - ssl - sensoroni - telegraf - firewall @@ -290,7 +277,6 @@ base: '*_fleet and G@saltversion:{{saltversion}}': - match: compound - - ssl - sensoroni - telegraf - firewall @@ -303,7 +289,6 @@ base: '*_hypervisor and I@features:vrt and G@saltversion:{{saltversion}}': - match: compound - - ssl - sensoroni - telegraf - firewall @@ -314,7 +299,6 @@ base: - stig '*_desktop and G@saltversion:{{saltversion}}': - - ssl - sensoroni - telegraf - elasticfleet.install_agent_grid diff --git a/setup/so-functions b/setup/so-functions index 3ac27f26b..3262f6ece 100755 --- a/setup/so-functions +++ b/setup/so-functions @@ -1122,16 +1122,6 @@ generate_ca() { logCmd "openssl x509 -in /etc/pki/ca.crt -noout -subject -issuer -dates" } -generate_ssl() { - # if the install type is a manager then we need to wait for the minion to be ready before trying - # to run the ssl state since we need the minion to sign the certs - if [[ $waitforstate ]]; then - (wait_for_salt_minion "$MINION_ID" "5" '/dev/stdout' || fail_setup) 2>&1 | tee -a "$setup_log" - fi - info "Applying SSL state" - logCmd "salt-call state.apply ssl -l info" -} - generate_passwords(){ title "Generate Random Passwords" INFLUXPASS=$(get_random_value) @@ -1661,7 +1651,6 @@ reinstall_init() { fi logCmd "salt-call state.apply ca.remove -linfo --local --file-root=../salt" - logCmd "salt-call state.apply ssl.remove -linfo --local --file-root=../salt" # Kill any salt processes (safely) for service in "${salt_services[@]}"; do diff --git a/setup/so-setup b/setup/so-setup index d09e8fc35..19cdb450e 100755 --- a/setup/so-setup +++ b/setup/so-setup @@ -773,12 +773,9 @@ if ! [[ -f $install_opt_file ]]; then # wait here until we get a response from the salt-master since it may have just restarted # exit setup after 5-6 minutes of trying check_salt_master_status || fail "Can't access salt master or it is not ready" - # apply the ca state to create the ca and put it in the mine early in the install + # apply the ca state to create the ca and symlink to local/salt/ca/files/ca.crt # the minion ip will already be in the mine from configure_minion function in so-functions generate_ca - # this will also call the ssl state since docker requires the intca - # the salt-minion service will need to be up on the manager to sign requests - generate_ssl logCmd "salt-call state.apply docker" firewall_generate_templates set_initial_firewall_policy