Synchronize SOC passwords with Elastic

This commit is contained in:
Jason Ertel
2021-05-25 17:16:05 -04:00
parent 8c6489a49a
commit ec2f8fe6c8

View File

@@ -40,7 +40,8 @@ email=$2
kratosUrl=${KRATOS_URL:-http://127.0.0.1:4434} kratosUrl=${KRATOS_URL:-http://127.0.0.1:4434}
databasePath=${KRATOS_DB_PATH:-/opt/so/conf/kratos/db/db.sqlite} databasePath=${KRATOS_DB_PATH:-/opt/so/conf/kratos/db/db.sqlite}
bcryptRounds=${BCRYPT_ROUNDS:-12} bcryptRounds=${BCRYPT_ROUNDS:-12}
extractedHashFile=${EXTRACTED_HASH_FILE:-/opt/so/conf/elasticsearch/users} elasticUsersFile=${ELASTIC_USERS_FILE:-/opt/so/conf/elasticsearch/users}
elasticRolesFile=${ELASTIC_ROLES_FILE:-/opt/so/conf/elasticsearch/users_roles}
function fail() { function fail() {
msg=$1 msg=$1
@@ -93,6 +94,16 @@ function validateEmail() {
fi fi
} }
function hashPassword() {
password=$1
passwordHash=$(echo "${password}" | htpasswd -niBC $bcryptRounds SOUSER)
passwordHash=$(echo "$passwordHash" | cut -c 11-)
passwordHash="\$2a${passwordHash}" # still waiting for https://github.com/elastic/elasticsearch/issues/51132
echo "$passwordHash"
}
function updatePassword() { function updatePassword() {
identityId=$1 identityId=$1
@@ -109,17 +120,54 @@ function updatePassword() {
if [[ -n $identityId ]]; then if [[ -n $identityId ]]; then
# Generate password hash # Generate password hash
passwordHash=$(echo "${password}" | htpasswd -niBC $bcryptRounds SOUSER) passwordHash=$(hashPassword "$password")
passwordHash=$(echo "$passwordHash" | cut -c 11-)
passwordHash="\$2a${passwordHash}"
# Update DB with new hash # Update DB with new hash
echo "update identity_credentials set config=CAST('{\"hashed_password\":\"${passwordHash}\"}' as BLOB) where identity_id=${identityId};" | sqlite3 "$databasePath" echo "update identity_credentials set config=CAST('{\"hashed_password\":\"$passwordHash\"}' as BLOB) where identity_id=${identityId};" | sqlite3 "$databasePath"
[[ $? != 0 ]] && fail "Unable to update password" [[ $? != 0 ]] && fail "Unable to update password"
fi fi
} }
function extractHashes() { function createElasticTmpFile() {
echo "select ici.identifier || ':' || json_extract(ic.config, '$.hashed_password') from identity_credential_identifiers ici, identity_credentials ic where ici.identity_credential_id=ic.id and json_extract(ic.config, '$.hashed_password') is not null order by ici.identifier" | sqlite3 "$databasePath" > "$extractedHashFile" filename=$1
tmpFile=${filename}.tmp
truncate -s 0 "$tmpFile"
chmod 600 "$tmpFile"
chown elasticsearch:elasticsearch "$tmpFile"
echo "$tmpFile"
}
function syncElastic() {
usersFileTmp=$(createElasticTmpFile "${elasticUsersFile}")
rolesFileTmp=$(createElasticTmpFile "${elasticRolesFile}")
sysUser=$(lookup_pillar "auth:user" "elasticsearch")
sysPass=$(lookup_pillar "auth:pass" "elasticsearch")
sysHash=$(hashPassword "$sysPass")
# Generate the new users file
echo "${sysUser}:${sysHash}" >> "$usersFileTmp"
echo "select '{\"user\":\"' || ici.identifier || '\", \"data\":' || ic.config || '}'" \
"from identity_credential_identifiers ici, identity_credentials ic " \
"where ici.identity_credential_id=ic.id and ic.config like '%hashed_password%' " \
"order by ici.identifier;" | \
sqlite3 "$databasePath" | \
jq -r '.user + ":" + .data.hashed_password' \
>> "$usersFileTmp"
mv -f "$usersFileTmp" "$elasticUsersFile"
# Generate the new users_roles file
echo "superuser:${sysUser}" >> "$rolesFileTmp"
echo "select 'superuser:' || ici.identifier " \
"from identity_credential_identifiers ici, identity_credentials ic " \
"where ici.identity_credential_id=ic.id and ic.config like '%hashed_password%' " \
"order by ici.identifier;" | \
sqlite3 "$databasePath" \
>> "$rolesFileTmp"
mv -f "$rolesFileTmp" "$elasticRolesFile"
}
function syncAll() {
syncElastic
} }
function listUsers() { function listUsers() {
@@ -213,7 +261,7 @@ case "${operation}" in
validateEmail "$email" validateEmail "$email"
updatePassword updatePassword
createUser "$email" createUser "$email"
extractHashes syncAll
echo "Successfully added new user to SOC" echo "Successfully added new user to SOC"
check_container thehive && echo $password | so-thehive-user-add "$email" check_container thehive && echo $password | so-thehive-user-add "$email"
check_container fleet && echo $password | so-fleet-user-add "$email" check_container fleet && echo $password | so-fleet-user-add "$email"
@@ -229,7 +277,7 @@ case "${operation}" in
[[ "$email" == "" ]] && fail "Email address must be provided" [[ "$email" == "" ]] && fail "Email address must be provided"
updateUser "$email" updateUser "$email"
extractHashes syncAll
echo "Successfully updated user" echo "Successfully updated user"
;; ;;
@@ -238,7 +286,7 @@ case "${operation}" in
[[ "$email" == "" ]] && fail "Email address must be provided" [[ "$email" == "" ]] && fail "Email address must be provided"
updateStatus "$email" 'active' updateStatus "$email" 'active'
extractHashes syncAll
echo "Successfully enabled user" echo "Successfully enabled user"
check_container thehive && so-thehive-user-enable "$email" true check_container thehive && so-thehive-user-enable "$email" true
check_container fleet && so-fleet-user-enable "$email" true check_container fleet && so-fleet-user-enable "$email" true
@@ -249,7 +297,7 @@ case "${operation}" in
[[ "$email" == "" ]] && fail "Email address must be provided" [[ "$email" == "" ]] && fail "Email address must be provided"
updateStatus "$email" 'locked' updateStatus "$email" 'locked'
extractHashes syncAll
echo "Successfully disabled user" echo "Successfully disabled user"
check_container thehive && so-thehive-user-enable "$email" false check_container thehive && so-thehive-user-enable "$email" false
check_container fleet && so-fleet-user-enable "$email" false check_container fleet && so-fleet-user-enable "$email" false
@@ -260,14 +308,14 @@ case "${operation}" in
[[ "$email" == "" ]] && fail "Email address must be provided" [[ "$email" == "" ]] && fail "Email address must be provided"
deleteUser "$email" deleteUser "$email"
extractHashes syncAll
echo "Successfully deleted user" echo "Successfully deleted user"
check_container thehive && so-thehive-user-enable "$email" false check_container thehive && so-thehive-user-enable "$email" false
check_container fleet && so-fleet-user-enable "$email" false check_container fleet && so-fleet-user-enable "$email" false
;; ;;
"sync") "sync")
extractHashes syncAll
echo "Synchronization complete" echo "Synchronization complete"
;; ;;