From e22421ec99f39ea5babbfac76a3bb53c35d19f79 Mon Sep 17 00:00:00 2001 From: Jason Ertel Date: Fri, 4 Jun 2021 20:01:30 -0400 Subject: [PATCH] Refactor users/roles management via salt due to Salt's clobbering of the inode which breaks Docker mounts --- salt/common/tools/sbin/so-user | 47 +++++++++---------- salt/elasticsearch/init.sls | 20 +++++++- .../config/so/9100_output_osquery.conf.jinja | 2 +- 3 files changed, 41 insertions(+), 28 deletions(-) diff --git a/salt/common/tools/sbin/so-user b/salt/common/tools/sbin/so-user index 4a7b6f0da..877f245c8 100755 --- a/salt/common/tools/sbin/so-user +++ b/salt/common/tools/sbin/so-user @@ -129,13 +129,12 @@ function updatePassword() { fi } -function createElasticTmpFile() { +function createElasticFile() { filename=$1 - tmpFile=${filename}.tmp + tmpFile=${filename} truncate -s 0 "$tmpFile" chmod 600 "$tmpFile" chown "${esUID}:${esGID}" "$tmpFile" - echo "$tmpFile" } function syncElasticSystemUser() { @@ -166,26 +165,27 @@ function syncElasticSystemRole() { } function syncElastic() { - usersFileTmp=$(createElasticTmpFile "${elasticUsersFile}") - rolesFileTmp=$(createElasticTmpFile "${elasticRolesFile}") + createElasticFile "${elasticUsersFile}" + createElasticFile "${elasticRolesFile}" authPillarJson=$(lookup_salt_value "auth" "elasticsearch" "pillar" "json") - syncElasticSystemUser "$authPillarJson" "so_elastic_user" "$usersFileTmp" - syncElasticSystemRole "$authPillarJson" "so_elastic_user" "superuser" "$rolesFileTmp" + syncElasticSystemUser "$authPillarJson" "so_elastic_user" "$elasticUsersFile" + syncElasticSystemRole "$authPillarJson" "so_elastic_user" "superuser" "$elasticRolesFile" - syncElasticSystemUser "$authPillarJson" "so_kibana_user" "$usersFileTmp" - syncElasticSystemRole "$authPillarJson" "so_kibana_user" "kibana_system" "$rolesFileTmp" + syncElasticSystemUser "$authPillarJson" "so_kibana_user" "$elasticUsersFile" + syncElasticSystemRole "$authPillarJson" "so_kibana_user" "superuser" "$elasticRolesFile" - syncElasticSystemUser "$authPillarJson" "so_logstash_user" "$usersFileTmp" - syncElasticSystemRole "$authPillarJson" "so_logstash_user" "logstash_system" "$rolesFileTmp" + syncElasticSystemUser "$authPillarJson" "so_logstash_user" "$elasticUsersFile" + syncElasticSystemRole "$authPillarJson" "so_logstash_user" "superuser" "$elasticRolesFile" - syncElasticSystemUser "$authPillarJson" "so_beats_user" "$usersFileTmp" - syncElasticSystemRole "$authPillarJson" "so_beats_user" "beats_system" "$rolesFileTmp" + syncElasticSystemUser "$authPillarJson" "so_beats_user" "$elasticUsersFile" + syncElasticSystemRole "$authPillarJson" "so_beats_user" "superuser" "$elasticRolesFile" - syncElasticSystemUser "$authPillarJson" "so_monitor_user" "$usersFileTmp" - syncElasticSystemRole "$authPillarJson" "so_monitor_user" "remote_monitoring_collector" "$rolesFileTmp" - syncElasticSystemRole "$authPillarJson" "so_monitor_user" "remote_monitoring_agent" "$rolesFileTmp" + syncElasticSystemUser "$authPillarJson" "so_monitor_user" "$elasticUsersFile" + syncElasticSystemRole "$authPillarJson" "so_monitor_user" "remote_monitoring_collector" "$elasticRolesFile" + syncElasticSystemRole "$authPillarJson" "so_monitor_user" "remote_monitoring_agent" "$elasticRolesFile" + syncElasticSystemRole "$authPillarJson" "so_monitor_user" "monitoring_user" "$elasticRolesFile" if [[ -f "$databasePath" ]]; then # Generate the new users file @@ -195,7 +195,7 @@ function syncElastic() { "order by ici.identifier;" | \ sqlite3 "$databasePath" | \ jq -r '.user + ":" + .data.hashed_password' \ - >> "$usersFileTmp" + >> "$elasticUsersFile" [[ $? != 0 ]] && fail "Unable to read credential hashes from database" # Generate the new users_roles file @@ -205,29 +205,26 @@ function syncElastic() { "where ici.identity_credential_id=ic.id and ic.config like '%hashed_password%' " \ "order by ici.identifier;" | \ sqlite3 "$databasePath" \ - >> "$rolesFileTmp" + >> "$elasticRolesFile" [[ $? != 0 ]] && fail "Unable to read credential IDs from database" else echo "Database file does not exist yet, skipping users export" fi - # Move the temp files over onto the final files - mv -f "$usersFileTmp" "$elasticUsersFile" - [[ $? != 0 ]] && fail "Unable to create users file: $elasticUsersFile" - - mv -f "$rolesFileTmp" "$elasticRolesFile" - [[ $? != 0 ]] && fail "Unable to create users file: $elasticRolesFile" + echo "Applying elastic state..." + salt-call state.apply elasticsearch queue=True } function syncAll() { if [[ -n "$STALE_MIN" ]]; then - staleCount=$(echo "select from identity_credentials where updated_at >= Datetime('now', '-${STALE_MIN} minutes');" \ + staleCount=$(echo "select count(*) from identity_credentials where updated_at >= Datetime('now', '-${STALE_MIN} minutes');" \ | sqlite3 "$databasePath") if [[ "$staleCount" == "0" ]]; then return 1 fi fi syncElastic + return 0 } function listUsers() { diff --git a/salt/elasticsearch/init.sls b/salt/elasticsearch/init.sls index 0bf442587..05b58b79a 100644 --- a/salt/elasticsearch/init.sls +++ b/salt/elasticsearch/init.sls @@ -173,7 +173,7 @@ eslogdir: auth_users: file.managed: - - name: /opt/so/conf/elasticsearch/users + - name: /opt/so/conf/elasticsearch/users.tmp - source: salt://elasticsearch/files/users - user: 930 - group: 930 @@ -181,12 +181,28 @@ auth_users: auth_users_roles: file.managed: - - name: /opt/so/conf/elasticsearch/users_roles + - name: /opt/so/conf/elasticsearch/users_roles.tmp - source: salt://elasticsearch/files/users_roles - user: 930 - group: 930 - mode: 600 +auth_users_inode: + require: + - file: auth_users + cmd.run: + - name: cat /opt/so/conf/elasticsearch/users.tmp > /opt/so/conf/elasticsearch/users && chown 930:930 /opt/so/conf/elasticsearch/users && chmod 600 /opt/so/conf/elasticsearch/users + - onchanges: + - file: /opt/so/conf/elasticsearch/users.tmp + +auth_users_roles_inode: + require: + - file: auth_users_roles + cmd.run: + - name: cat /opt/so/conf/elasticsearch/users_roles.tmp > /opt/so/conf/elasticsearch/users_roles && chown 930:930 /opt/so/conf/elasticsearch/users_roles && chmod 600 /opt/so/conf/elasticsearch/users_roles + - onchanges: + - file: /opt/so/conf/elasticsearch/users_roles.tmp + so-elasticsearch: docker_container.running: - image: {{ MANAGER }}:5000/{{ IMAGEREPO }}/so-elasticsearch:{{ VERSION }} diff --git a/salt/logstash/pipelines/config/so/9100_output_osquery.conf.jinja b/salt/logstash/pipelines/config/so/9100_output_osquery.conf.jinja index 7ed8c58e5..43596c1cd 100644 --- a/salt/logstash/pipelines/config/so/9100_output_osquery.conf.jinja +++ b/salt/logstash/pipelines/config/so/9100_output_osquery.conf.jinja @@ -4,7 +4,7 @@ {%- set ES = salt['pillar.get']('elasticsearch:mainip', '') -%} {%- endif %} {%- set ES_USER = salt['pillar.get']('elasticsearch:auth:users:so_logstash_user:user', '') %} -{%- set ES_PASS = salt['pillar.get']('elasticsearch:auth:users:so_logstash_pass:pass', '') %} +{%- set ES_PASS = salt['pillar.get']('elasticsearch:auth:users:so_logstash_user:pass', '') %} output { if [module] =~ "osquery" and "live_query" not in [dataset] { elasticsearch {