From d97423e9f8c1983caa837a429f5c60059f9bbec8 Mon Sep 17 00:00:00 2001 From: Jason Ertel Date: Tue, 15 Feb 2022 07:49:12 -0500 Subject: [PATCH] Enable MFA support --- salt/common/tools/sbin/so-user | 16 ++++++++++++---- salt/kratos/files/kratos.yaml | 8 ++++++++ salt/kratos/files/schema.json | 3 +++ salt/nginx/etc/nginx.conf | 6 ++++++ 4 files changed, 29 insertions(+), 4 deletions(-) diff --git a/salt/common/tools/sbin/so-user b/salt/common/tools/sbin/so-user index 0d8a9a900..5901cbd1b 100755 --- a/salt/common/tools/sbin/so-user +++ b/salt/common/tools/sbin/so-user @@ -147,7 +147,10 @@ function updatePassword() { # Generate password hash passwordHash=$(hashPassword "$password") # Update DB with new hash - echo "update identity_credentials set config=CAST('{\"hashed_password\":\"$passwordHash\"}' as BLOB), updated_at=datetime('now') where identity_id='${identityId}';" | sqlite3 "$databasePath" + echo "update identity_credentials set config=CAST('{\"hashed_password\":\"$passwordHash\"}' as BLOB), updated_at=datetime('now') where identity_id='${identityId}' and identity_credential_type_id=(select id from identity_credential_types where name='password');" | sqlite3 "$databasePath" + # Deactivate MFA + echo "delete from identity_credential_identifiers where identity_credential_id=(select id from identity_credentials where identity_id='${identityId}' and identity_credential_type_id=(select id from identity_credential_types where name='totp'));" | sqlite3 "$databasePath" + echo "delete from identity_credentials where identity_id='${identityId}' and identity_credential_type_id=(select id from identity_credential_types where name='totp');" | sqlite3 "$databasePath" [[ $? != 0 ]] && fail "Unable to update password" fi } @@ -244,10 +247,12 @@ function syncElastic() { if [[ -f "$databasePath" && -f "$socRolesFile" ]]; then # Append the SOC users echo "select '{\"user\":\"' || ici.identifier || '\", \"data\":' || ic.config || '}'" \ - "from identity_credential_identifiers ici, identity_credentials ic, identities i " \ + "from identity_credential_identifiers ici, identity_credentials ic, identities i, identity_credential_types ict " \ "where " \ " ici.identity_credential_id=ic.id " \ " and ic.identity_id=i.id " \ + " and ict.id=ic.identity_credential_type_id " \ + " and ict.name='password' " \ " and instr(ic.config, 'hashed_password') " \ " and i.state == 'active' " \ "order by ici.identifier;" | \ @@ -261,8 +266,11 @@ function syncElastic() { userId=$(echo "$rolePair" | cut -d: -f2) role=$(echo "$rolePair" | cut -d: -f1) echo "select '$role:' || ici.identifier " \ - "from identity_credential_identifiers ici, identity_credentials ic " \ - "where ici.identity_credential_id=ic.id and ic.identity_id = '$userId';" | \ + "from identity_credential_identifiers ici, identity_credentials ic, identity_credential_types ict " \ + "where ici.identity_credential_id=ic.id " \ + " and ict.id=ic.identity_credential_type_id " \ + " and ict.name='password' " \ + " and ic.identity_id = '$userId';" | \ sqlite3 "$databasePath" >> "$rolesTmpFile" done < "$socRolesFile" diff --git a/salt/kratos/files/kratos.yaml b/salt/kratos/files/kratos.yaml index b1174af58..d10cdd1e5 100644 --- a/salt/kratos/files/kratos.yaml +++ b/salt/kratos/files/kratos.yaml @@ -1,9 +1,12 @@ {%- set WEBACCESS = salt['pillar.get']('global:url_base', '') -%} {%- set KRATOSKEY = salt['pillar.get']('kratos:kratoskey', '') -%} {%- set SESSIONTIMEOUT = salt['pillar.get']('kratos:sessiontimeout', '24h') -%} +{%- set MFA_ISSUER = salt['pillar.get']('kratos:mfa_issuer', 'Security Onion') -%} session: lifespan: {{ SESSIONTIMEOUT }} + whoami: + required_aal: highest_available selfservice: methods: @@ -11,10 +14,15 @@ selfservice: enabled: true config: haveibeenpwned_enabled: false + totp: + enabled: true + config: + issuer: {{ MFA_ISSUER }} flows: settings: ui_url: https://{{ WEBACCESS }}/?r=/settings + required_aal: highest_available verification: ui_url: https://{{ WEBACCESS }}/ diff --git a/salt/kratos/files/schema.json b/salt/kratos/files/schema.json index 782d1b78b..610c250d8 100644 --- a/salt/kratos/files/schema.json +++ b/salt/kratos/files/schema.json @@ -17,6 +17,9 @@ "credentials": { "password": { "identifier": true + }, + "totp": { + "account_name": true } }, "verification": { diff --git a/salt/nginx/etc/nginx.conf b/salt/nginx/etc/nginx.conf index 55995c368..7f3731c75 100644 --- a/salt/nginx/etc/nginx.conf +++ b/salt/nginx/etc/nginx.conf @@ -399,12 +399,18 @@ http { } error_page 401 = @error401; + error_page 403 = @error403; location @error401 { add_header Set-Cookie "AUTH_REDIRECT=$request_uri;Path=/;Max-Age=14400"; return 302 /auth/self-service/login/browser; } + location @error403 { + add_header Set-Cookie "ory_kratos_session=;Path=/;Max-Age=0;expires=Thu, 01 Jan 1970 00:00:00 GMT;"; + return 302 /auth/self-service/login/browser; + } + error_page 500 502 503 504 /50x.html; location = /usr/share/nginx/html/50x.html { }