V8.00.000.2025.06.17
All checks were successful
🛡️ Shell Script Linting / 🛡️ Shell Script Linting (push) Successful in 2m1s
All checks were successful
🛡️ Shell Script Linting / 🛡️ Shell Script Linting (push) Successful in 2m1s
Signed-off-by: Marc S. Weidner <msw@coresecret.dev>
This commit is contained in:
@@ -12,12 +12,6 @@
|
||||
|
||||
guard_sourcing
|
||||
|
||||
# TODO: sudo TOTP deactivation
|
||||
# TODO: PAM Module
|
||||
# TODO: Check Password activation
|
||||
# TODO: Check expiration and other dates
|
||||
# TODO: Logic
|
||||
|
||||
#######################################
|
||||
# Updating user accounts.
|
||||
# Globals:
|
||||
@@ -59,6 +53,12 @@ accounts_setup() {
|
||||
|
||||
chroot_logger "${var_target}${var_logfile}"
|
||||
|
||||
### Update pam modules for 2fa.
|
||||
write_pam_login "${var_target}"
|
||||
write_pam_sshd "${var_target}"
|
||||
write_pam_su "${var_target}"
|
||||
write_pam_sudo "${var_target}"
|
||||
|
||||
### Prepare the '2fa'-seed variable.
|
||||
read_totp_seed
|
||||
do_log "debug" "file_only" "4520() Command: [read_totp_seed]"
|
||||
@@ -66,56 +66,17 @@ accounts_setup() {
|
||||
### 0) The 'root' account is generated via debootstrap by default.
|
||||
|
||||
### 1) Prepare the 'root' account.
|
||||
install -d -m 0700 -o root -g root "${var_target}/root/.ssh"
|
||||
install -m 0600 -o root -g root /dev/null "${var_target}/root/.ssh/authorized_keys"
|
||||
install -m 0600 -o root -g root "${VAR_SETUP_PATH}/includes/target/etc/skel/.bashrc" "${var_target}/root/"
|
||||
install -m 0600 -o root -g root "${VAR_SETUP_PATH}/includes/target/etc/skel/.ciss/theme_eza_ciss.yml" "${var_target}/root/.ciss/"
|
||||
install -m 0600 -o root -g root "${VAR_SETUP_PATH}/includes/target/root/.ciss/alias" "${var_target}/root/.ciss/"
|
||||
install -m 0700 -o root -g root "${VAR_SETUP_PATH}/includes/target/etc/skel/.ciss/check_chrony.sh" "${var_target}/root/.ciss/"
|
||||
install -m 0700 -o root -g root "${VAR_SETUP_PATH}/includes/target/root/.ciss/clean_logout.sh" "${var_target}/root/.ciss/"
|
||||
install -m 0600 -o root -g root "${VAR_SETUP_PATH}/includes/target/root/.ciss/f2bchk" "${var_target}/root/.ciss/"
|
||||
install -m 0600 -o root -g root "${VAR_SETUP_PATH}/includes/target/root/.ciss/scan_libwrap" "${var_target}/root/.ciss/"
|
||||
install -m 0600 -o root -g root "${VAR_SETUP_PATH}/includes/target/root/.ciss/shortcuts" "${var_target}/root/.ciss/"
|
||||
case "${VAR_USER_ROOT_SPECIFIC}" in
|
||||
|
||||
if [[ "${user_root_shell}" == "/bin/zsh" ]]; then
|
||||
"ciss" ) accounts_setup_ciss_root ;;
|
||||
|
||||
if [[ -x "${var_target}${user_root_shell}" ]]; then
|
||||
"physnet") accounts_setup_physnet_root ;;
|
||||
|
||||
case "${VAR_USER_ROOT_SPECIFIC,,}" in
|
||||
"none" ) do_log "info" "file_only" "4520() Account preparation [none] selected." ;;
|
||||
|
||||
"ciss")
|
||||
zsh_omz_installer "root" "${var_target}"
|
||||
mv "${var_target}/root/.zshrc" "${var_target}/root/.zshrc.bak"
|
||||
install -m 0600 -o root -g root "${VAR_SETUP_PATH}/includes/target/etc/skel/.zshrc" "${var_target}/root/"
|
||||
;;
|
||||
* ) do_log "warn" "file_only" "4520() Account preparation nothing selected. Keeping defaults." ;;
|
||||
|
||||
"physnet")
|
||||
:
|
||||
;;
|
||||
|
||||
"none"|*)
|
||||
:
|
||||
;;
|
||||
|
||||
esac
|
||||
|
||||
chroot_exec "${var_target}" chsh -s "${user_root_shell}" root
|
||||
do_log "info" "file_only" "4520() Shell: '${user_root_shell}' used for: 'root'."
|
||||
|
||||
else
|
||||
|
||||
chroot_exec "${var_target}" chsh -s /bin/bash root
|
||||
do_log "info" "file_only" "4520() Shell: '${user_root_shell}' not found for: 'root'. Using '/bin/bash' instead."
|
||||
|
||||
fi
|
||||
|
||||
fi
|
||||
|
||||
### To be able to copy/paste from vim, one needs to create a '.vimrc' with the following content:
|
||||
echo 'set clipboard=unnamed' >| "${var_target}/root/.vimrc"
|
||||
chmod 0600 "${var_target}/root/.vimrc"
|
||||
|
||||
do_log "info" "file_only" "4520() Skeleton: 'root' successfully generated."
|
||||
esac
|
||||
|
||||
### 2) Check SSH access capabilities.
|
||||
case "${user_root_authentication_access_ssh,,}" in
|
||||
@@ -126,6 +87,7 @@ accounts_setup() {
|
||||
;;
|
||||
|
||||
true)
|
||||
### SSH Public Key per default, only.
|
||||
sed -i -E "s|^[[:space:]]*PermitRootLogin[[:space:]]+.*$|$(printf '%-29s%s' 'PermitRootLogin' 'prohibit-password')|" "${var_target}/etc/ssh/sshd_config"
|
||||
do_log "info" "file_only" "4520() User: 'root' SSH access: [PermitRootLogin prohibit-password]"
|
||||
;;
|
||||
@@ -141,54 +103,26 @@ accounts_setup() {
|
||||
case "${user_root_authentication_access_tty,,}" in
|
||||
|
||||
false)
|
||||
### 3) A) 1) Ensure the 'pam_access' line is not activated in '/etc/pam.d/login' and '/etc/pam.d/sshd' in parallel.
|
||||
pam_access_sync_login_sshd
|
||||
|
||||
### 3) A) 2) Ensure 'pam_securetty' in the auth phase; requisite causes immediate fail for disallowed ttys.
|
||||
chroot_stdin "${var_target}" "__payload__" <<'EOF'
|
||||
export LC_ALL=C
|
||||
if ! grep -Eq '^[[:space:]]*auth[[:space:]]+requisite[[:space:]]+pam_securetty[.]so([[:space:]]|$)' /etc/pam.d/login; then
|
||||
tmp="$(mktemp /etc/pam.d/login.XXXXXX)"
|
||||
awk '
|
||||
BEGIN { ins=0 }
|
||||
{
|
||||
if (!ins && $0 ~ /^[[:space:]]*auth[[:space:]]+.*pam_unix[.]so/) {
|
||||
print "auth requisite pam_securetty.so"
|
||||
ins=1
|
||||
}
|
||||
print
|
||||
}
|
||||
END {
|
||||
if (!ins) print "auth requisite pam_securetty.so"
|
||||
}
|
||||
' /etc/pam.d/login >| "${tmp}"
|
||||
|
||||
test -s "${tmp}"
|
||||
mv -f "${tmp}" /etc/pam.d/login
|
||||
rm -f -- "${tmp}"
|
||||
fi
|
||||
:
|
||||
EOF
|
||||
|
||||
### 3) A) 3) Disallow all local access for root in '/etc/security/access.conf'.
|
||||
### Disallow all local access for root in '/etc/security/access.conf'.
|
||||
printf -- '-: root:ALL\n' >> "${var_target}/etc/security/access.conf"
|
||||
do_log "info" "file_only" "4520() User: 'root' [disallow all local access in '/etc/security/access.conf']"
|
||||
|
||||
### 3) A) 4) Empty "/etc/securetty".
|
||||
### Empty "/etc/securetty".
|
||||
cat << 'EOF' >| "${var_target}/etc/securetty"
|
||||
EOF
|
||||
|
||||
do_log "info" "file_only" "4520() User: 'root' tty access: [false]"
|
||||
do_log "info" "file_only" "4520() User: 'root' [empty '/etc/securetty']"
|
||||
;;
|
||||
|
||||
true)
|
||||
### 3) B) 1) Allow local access for 'root' only on 'tty1' in '/etc/security/access.conf'.
|
||||
### Allow local access for 'root' only on 'tty1' in '/etc/security/access.conf'.
|
||||
printf -- "+: root:tty1 \n" >> "${var_target}/etc/security/access.conf"
|
||||
do_log "info" "file_only" "4520() User: 'root' [allow local access on tty1 in '/etc/security/access.conf']"
|
||||
|
||||
### 3) B) 2) Allow local access for 'root' only on 'tty1' in '/etc/securetty'.
|
||||
### Allow local access for 'root' only on 'tty1' in '/etc/securetty'.
|
||||
cat << 'EOF' >| "${var_target}/etc/securetty"
|
||||
tty1
|
||||
EOF
|
||||
do_log "info" "file_only" "4520() User: 'root' tty access: [true]"
|
||||
do_log "info" "file_only" "4520() User: 'root' [tty1 in '/etc/securetty']."
|
||||
;;
|
||||
|
||||
*)
|
||||
@@ -199,6 +133,8 @@ EOF
|
||||
esac
|
||||
|
||||
### 4) Check the password policy for the 'root' account.
|
||||
chroot_script "${var_target}" "printf '%s:%s\n' 'root' '${user_root_password}' | /usr/sbin/chpasswd -e"
|
||||
|
||||
case "${user_root_authentication_password,,}" in
|
||||
|
||||
false)
|
||||
@@ -207,8 +143,7 @@ EOF
|
||||
;;
|
||||
|
||||
true)
|
||||
chroot_script "${var_target}" "printf '%s:%s\n' 'root' '${var_password}' | /usr/sbin/chpasswd -e"
|
||||
#chroot_script "${var_target}" "/usr/sbin/usermod -p '${user_root_password}' root"
|
||||
chroot_script "${var_target}" "passwd -u root"
|
||||
do_log "info" "file_only" "4520() User: 'root' password access: [true]"
|
||||
;;
|
||||
|
||||
@@ -227,17 +162,16 @@ EOF
|
||||
|
||||
fi
|
||||
|
||||
### 6) Update the 'root' 'totp'-policy and write the '.google_authenticator'-file.
|
||||
### 6) Update the 'root' 'totp'-policy-user file and write the '.google_authenticator'-file.
|
||||
if [[ "${user_root_authentication_2fa_ssh}" == "true" || "${user_root_authentication_2fa_tty}" == "true" ]]; then
|
||||
|
||||
write_google_authenticator_file "root" "0" "0" "${var_target}"
|
||||
printf '%s\n' "root" >> "${var_target}/etc/ciss/2fa.users"
|
||||
|
||||
fi
|
||||
|
||||
|
||||
if [[ "${user_root_authentication_2fa_ssh}" == "true" ]]; then
|
||||
|
||||
pam_access_totp_enable "root" "sshd" "${var_target}"
|
||||
var_ssh_totp_update="true"
|
||||
cat << EOF >> "${var_target}/etc/ssh/sshd_config"
|
||||
Match User root
|
||||
@@ -246,8 +180,6 @@ Match User root
|
||||
EOF
|
||||
fi
|
||||
|
||||
[[ "${user_root_authentication_2fa_tty}" == "true" ]] && pam_access_totp_enable "root" "login" "${var_target}"
|
||||
|
||||
### 7) Install eza themes.
|
||||
eza_installer "root" "${var_target}"
|
||||
|
||||
@@ -844,172 +776,6 @@ EOF
|
||||
# shellcheck disable=SC2034
|
||||
readonly -f hardening_sudo
|
||||
|
||||
#######################################
|
||||
# Ensure the 'pam_access' line is not activated in '/etc/pam.d/login' and '/etc/pam.d/sshd' in parallel.
|
||||
# MUST be executed inside chroot.
|
||||
# Globals:
|
||||
# None
|
||||
# Arguments:
|
||||
# None
|
||||
# Returns:
|
||||
# 0: on success
|
||||
#######################################
|
||||
pam_access_sync_login_sshd() {
|
||||
### Declare Arrays, HashMaps, and Variables.
|
||||
declare var_file_login="/etc/pam.d/login"
|
||||
declare var_file_sshd="/etc/pam.d/sshd"
|
||||
|
||||
### Guard: The file must exist, no-op otherwise.
|
||||
if [[ ! -f "${var_target}${var_file_login}" ]]; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
### 1) If the 'pam_access' line is commented in '/etc/pam.d/login', uncomment exactly one occurrence.
|
||||
chroot_stdin "${var_target}" "__payload__" <<'EOF'
|
||||
tmp="$(mktemp /etc/pam.d/login.XXXXXX)"
|
||||
export LC_ALL=C
|
||||
awk '
|
||||
BEGIN { done=0 }
|
||||
{
|
||||
if (!done) {
|
||||
line=$0
|
||||
sub(/^[[:space:]]*#+[[:space:]]*/, "", line)
|
||||
if (line ~ /^[[:space:]]*account[[:space:]]+required[[:space:]]+pam_access[.]so([[:space:]]|$)/) {
|
||||
print line; done=1; next
|
||||
}
|
||||
}
|
||||
print
|
||||
}
|
||||
' /etc/pam.d/login >| "${tmp}"
|
||||
test -s "${tmp}"
|
||||
mv -f "${tmp}" /etc/pam.d/login
|
||||
rm -f "${tmp}" || :
|
||||
:
|
||||
EOF
|
||||
|
||||
### 2) If '/etc/pam.d/login' now has an active pam_access line, ensure '/etc/pam.d/sshd' pam_access line(s) are commented out.
|
||||
### No-op if '/etc/pam.d/sshd' is absent.
|
||||
[[ -f "${var_target}${var_file_sshd}" ]] || return 0
|
||||
|
||||
chroot_stdin "${var_target}" "__payload__" <<'EOF'
|
||||
export LC_ALL=C
|
||||
if grep -Eq '^[[:space:]]*account[[:space:]]+required[[:space:]]+pam_access[.]so([[:space:]]|$)' /etc/pam.d/login; then
|
||||
tmp="$(mktemp /etc/pam.d/sshd.XXXXXX)"
|
||||
awk '
|
||||
/^[[:space:]]*account[[:space:]]+required[[:space:]]+pam_access[.]so([[:space:]]|$)/ { print "# " $0; next }
|
||||
{ print }
|
||||
' /etc/pam.d/sshd >| "${tmp}"
|
||||
test -s "${tmp}"
|
||||
mv -f "${tmp}" /etc/pam.d/sshd
|
||||
rm -f "${tmp}" || :
|
||||
fi
|
||||
:
|
||||
EOF
|
||||
|
||||
return 0
|
||||
}
|
||||
### Prevents accidental 'unset -f'.
|
||||
# shellcheck disable=SC2034
|
||||
readonly -f pam_access_sync_login_sshd
|
||||
|
||||
#######################################
|
||||
# Enable per-user TOTP in a given PAM service (login, sshd, su, sudo).
|
||||
# Globals:
|
||||
# None
|
||||
# Arguments:
|
||||
# 1: username
|
||||
# 2: pam_module
|
||||
# 3: target
|
||||
# Returns:
|
||||
# 0: on success
|
||||
#######################################
|
||||
pam_access_totp_enable() {
|
||||
### Declare Arrays, HashMaps, and Variables.
|
||||
declare -r var_user="${1}" var_module="${2}" var_target="${3}"
|
||||
declare -r var_pam_file="/etc/pam.d/${var_module}"
|
||||
declare -r var_users_file="${var_target}/etc/ciss/2fa.users"
|
||||
declare -r var_allowlist="/etc/ciss/2fa.users"
|
||||
|
||||
### Basic sanitation; module must be a safe 'pam.d' filename.
|
||||
[[ -n "${var_user:-}" && -n "${var_module:-}" ]] || return 0
|
||||
[[ "${var_module}" =~ ^[A-Za-z0-9._+-]+$ ]] || return 0
|
||||
[[ -f "${var_target}${var_pam_file}" ]] || return 0
|
||||
|
||||
### 0) Ensure the allowlist file contains the user (deduplicated).
|
||||
if ! grep -Fxq "${var_user}" "${var_users_file}"; then
|
||||
printf '%s\n' "${var_user}" >> "${var_users_file}"
|
||||
fi
|
||||
|
||||
### 1) Ensure a single CISS TOTP framework block is present in the PAM file.
|
||||
### The block gates GA by pam_listfile over '/etc/ciss/2fa.users'.
|
||||
### We place it right after pam_unix.so or @include common-auth; fallback: append.
|
||||
chroot_stdin "${var_target}" "__payload__" -- "${var_pam_file}" "${var_allowlist}" <<'EOF'
|
||||
export LC_ALL=C
|
||||
pam="$1"
|
||||
allowlist="$2"
|
||||
tmp="$(mktemp "${pam}.XXXXXX")"
|
||||
|
||||
awk -v MARK_S="# CISS TOTP START" -v MARK_E="# CISS TOTP END" -v allowlist="${allowlist}" '
|
||||
BEGIN { ins=0 }
|
||||
{
|
||||
print
|
||||
if (!ins && ($0 ~ /^[[:space:]]*auth[[:space:]]+.*pam_unix[.]so/ \
|
||||
|| $0 ~ /^[[:space:]]*@include[[:space:]]+common-auth/)) {
|
||||
print MARK_S
|
||||
### Only users in allowlist must pass GA:
|
||||
### pam_listfile sense=deny succeeds for non-listed > skip next line (GA)
|
||||
print "auth [success=1 default=ignore] pam_listfile.so item=user sense=deny file=" allowlist " onerr=ignore"
|
||||
print "auth required pam_google_authenticator.so"
|
||||
print MARK_E
|
||||
ins=1
|
||||
}
|
||||
}
|
||||
END {
|
||||
if (!ins) {
|
||||
print MARK_S
|
||||
print "auth [success=1 default=ignore] pam_listfile.so item=user sense=deny file=" allowlist " onerr=ignore"
|
||||
print "auth required pam_google_authenticator.so"
|
||||
print MARK_E
|
||||
}
|
||||
}
|
||||
' "${pam}" >| "${tmp}"
|
||||
|
||||
test -s "${tmp}"
|
||||
mv -f "${tmp}" "${pam}"
|
||||
rm -f -- "${tmp}" || :
|
||||
:
|
||||
EOF
|
||||
|
||||
### 2) Comment out any other active GA lines to avoid double prompts.
|
||||
chroot_stdin "${var_target}" "__payload__" -- "${var_pam_file}" <<'EOF'
|
||||
export LC_ALL=C
|
||||
pam="$1"
|
||||
tmp="$(mktemp "${pam}.XXXXXX")"
|
||||
awk '
|
||||
BEGIN { in_ciss=0 }
|
||||
/^# CISS TOTP START$/ { in_ciss=1; print; next }
|
||||
/^# CISS TOTP END$/ { in_ciss=0; print; next }
|
||||
{
|
||||
if (!in_ciss && $0 ~ /^[[:space:]]*auth[[:space:]]+.*pam_google_authenticator[.]so/ && $0 !~ /^[[:space:]]*#/) {
|
||||
print "# " $0
|
||||
} else {
|
||||
print
|
||||
}
|
||||
}
|
||||
' "${pam}" >| "${tmp}"
|
||||
|
||||
test -s "${tmp}"
|
||||
mv -f "${tmp}" "${pam}"
|
||||
rm -f -- "${tmp}" || :
|
||||
:
|
||||
EOF
|
||||
|
||||
return 0
|
||||
}
|
||||
### Prevents accidental 'unset -f'.
|
||||
# shellcheck disable=SC2034
|
||||
readonly -f pam_access_totp_enable
|
||||
|
||||
#######################################
|
||||
# Reads a 256-bit seed from '${DIR_CNF}/mfa_master.txt' (64 hex chars) into VAR_TEMP_PLAIN_MFA_SEED.
|
||||
# Globals:
|
||||
@@ -1113,6 +879,379 @@ write_google_authenticator_file() {
|
||||
# shellcheck disable=SC2034
|
||||
readonly -f write_google_authenticator_file
|
||||
|
||||
#######################################
|
||||
# Writes CISS Header for '/etc/pam.d/login'.
|
||||
# Globals:
|
||||
# None
|
||||
# Arguments:
|
||||
# 1: TARGET
|
||||
# Returns:
|
||||
# 0: on success
|
||||
#######################################
|
||||
write_pam_login() {
|
||||
### Declare Arrays, HashMaps, and Variables.
|
||||
declare -r var_target="$1"
|
||||
|
||||
mv "${var_target}/etc/pam.d/login" "${var_target}/root/.ciss/cdi/backup/etc/pam.d/login"
|
||||
|
||||
insert_header "${var_target}/etc/pam.d/login"
|
||||
insert_comments "${var_target}/etc/pam.d/login"
|
||||
cat << EOF >> "${var_target}/etc/pam.d/login"
|
||||
#
|
||||
# The PAM configuration file for the Shadow 'login' service
|
||||
#
|
||||
|
||||
# --- AUTH phase ---------------------------------------------------------------------------------------------------------------
|
||||
|
||||
# Root only on secure ttys listed in '/etc/securetty' (fail fast, no prompts).
|
||||
auth requisite pam_securetty.so
|
||||
|
||||
# Enforce a minimal delay in case of failure (in microseconds). (Replaces the 'FAIL_DELAY' setting from login.defs).
|
||||
# Note that other modules may require another minimal delay. (For example, to disable any delay, you should add the 'nodelay'
|
||||
# option to pam_unix).
|
||||
auth optional pam_faildelay.so delay=3200000
|
||||
|
||||
# Outputs an issue file prior to each login prompt (Replaces the ISSUE_FILE option from login.defs). Uncomment for use.
|
||||
#auth required pam_issue.so issue=/etc/issue
|
||||
|
||||
# Disallows other than root logins when /etc/nologin exists. (Replaces the 'NOLOGINS_FILE' option from login.defs).
|
||||
auth requisite pam_nologin.so
|
||||
|
||||
# SELinux needs to be the first session rule. This ensures that any lingering context has been cleared. Without this it is
|
||||
# possible that a module could execute code in the wrong domain. When the module is present, "required" would be sufficient
|
||||
# (When SELinux is disabled, this returns success.)
|
||||
session [success=ok ignore=ignore module_unknown=ignore default=bad] pam_selinux.so close
|
||||
|
||||
# Sets the loginuid process attribute
|
||||
session required pam_loginuid.so
|
||||
|
||||
# Prints the message of the day upon successful login. (Replaces the 'MOTD_FILE' option in login.defs). This includes a
|
||||
# dynamically generated part from /run/motd.dynamic, and a static (admin-editable) part from /etc/motd.
|
||||
session optional pam_motd.so motd=/run/motd.dynamic
|
||||
session optional pam_motd.so noupdate
|
||||
|
||||
# SELinux needs to intervene at login time to ensure that the process starts in the proper default security context. Only
|
||||
# sessions which are intended to run in the user's context should be run after this. The module pam_selinux.so changes the
|
||||
# SELinux context of the used TTY and configures SELinux in order to transition to the user context with the next execve()
|
||||
# call.
|
||||
session [success=ok ignore=ignore module_unknown=ignore default=bad] pam_selinux.so open
|
||||
# When the module is present, "required" would be sufficient (When SELinux is disabled, this returns success.)
|
||||
|
||||
# This module parses environment configuration file(s) and also allows you to use an extended config file
|
||||
# /etc/security/pam_env.conf. Parsing /etc/environment needs "readenv=1"
|
||||
session required pam_env.so readenv=1
|
||||
# Locale variables can also be set in /etc/default/locale reading this file *in addition to /etc/environment* does not hurt.
|
||||
session required pam_env.so readenv=1 envfile=/etc/default/locale
|
||||
|
||||
# Standard Un*x authentication.
|
||||
@include common-auth
|
||||
|
||||
|
||||
# ===== CISS 2FA block ========
|
||||
|
||||
# If user is NOT listed -> succeed and SKIP next two lines (no TOTP prompt).
|
||||
auth [success=2 default=ignore] pam_listfile.so item=user sense=deny file=/etc/ciss/2fa.users onerr=ignore
|
||||
|
||||
# For listed users: enforce that the secret file exists, else deny without prompting.
|
||||
# pam_google_authenticator will itself fail if the file is absent; we add a clear hint before it.
|
||||
# No 'nullok' here: listed users MUST have a secret; missing -> hard fail.
|
||||
auth required pam_echo.so file=/etc/ciss/pam_login_totp.prompt
|
||||
auth required pam_google_authenticator.so disallow-reuse
|
||||
|
||||
# ===== CISS 2FA block end =====
|
||||
|
||||
|
||||
# This allows certain extra groups to be granted to a user based on things like time of day, tty, service, and user. Please
|
||||
# edit /etc/security/group.conf to fit your needs (Replaces the 'CONSOLE_GROUPS' option in login.defs).
|
||||
auth optional pam_group.so
|
||||
|
||||
|
||||
|
||||
# Uncomment and edit /etc/security/time.conf if you need to set time restraint on logins. (Replaces the 'PORTTIME_CHECKS_ENAB'
|
||||
# option from login.defs as well as /etc/porttime).
|
||||
#account requisite pam_time.so
|
||||
|
||||
# Uncomment and edit /etc/security/access.conf if you need to set access limits. (Replaces /etc/login.access file).
|
||||
#account required pam_access.so
|
||||
|
||||
# Sets up user limits according to /etc/security/limits.conf. (Replaces the use of /etc/limits in old login).
|
||||
session required pam_limits.so
|
||||
|
||||
# Prints the status of the user's mailbox upon successful login (Replaces the 'MAIL_CHECK_ENAB' option from login.defs).
|
||||
# This also defines the MAIL environment variable. However, userdel also needs MAIL_DIR and MAIL_FILE variables in
|
||||
# /etc/login.defs to make sure that removing a user also removes the user's mail spool file. See comments in /etc/login.defs.
|
||||
session optional pam_mail.so standard
|
||||
|
||||
# Create a new session keyring.
|
||||
session optional pam_keyinit.so force revoke
|
||||
|
||||
# Console-only access control for this service (do NOT also enable in common-account).
|
||||
account requisite pam_access.so
|
||||
|
||||
# Standard Un*x account and session
|
||||
@include common-account
|
||||
@include common-session
|
||||
@include common-password
|
||||
|
||||
# vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=conf
|
||||
EOF
|
||||
do_log "info" "file_only" "4520() Written: [/etc/pam.d/login]."
|
||||
|
||||
cat << 'EOF' >| "${var_target}/etc/ciss/pam_login_totp.prompt"
|
||||
Please enter your 6-digit TOTP or 8-digit Backup code:
|
||||
EOF
|
||||
chmod 0444 "${var_target}/etc/ciss/pam_login_totp.prompt"
|
||||
do_log "info" "file_only" "4520() Written: [/etc/ciss/pam_login_totp.prompt]."
|
||||
|
||||
return 0
|
||||
}
|
||||
### Prevents accidental 'unset -f'.
|
||||
# shellcheck disable=SC2034
|
||||
readonly -f write_pam_login
|
||||
|
||||
#######################################
|
||||
# Writes CISS Header for '/etc/pam.d/sshd'.
|
||||
# Globals:
|
||||
# None
|
||||
# Arguments:
|
||||
# 1: TARGET
|
||||
# Returns:
|
||||
# 0: on success
|
||||
#######################################
|
||||
write_pam_sshd() {
|
||||
### Declare Arrays, HashMaps, and Variables.
|
||||
declare -r var_target="$1"
|
||||
|
||||
mv "${var_target}/etc/pam.d/sshd" "${var_target}/root/.ciss/cdi/backup/etc/pam.d/sshd"
|
||||
|
||||
insert_header "${var_target}/etc/pam.d/sshd"
|
||||
insert_comments "${var_target}/etc/pam.d/sshd"
|
||||
cat << EOF >> "${var_target}/etc/pam.d/sshd"
|
||||
#
|
||||
# PAM configuration for the Secure Shell service
|
||||
#
|
||||
|
||||
# ===== CISS 2FA block ========
|
||||
|
||||
# If user is NOT listed -> succeed and SKIP next two lines (silent Keyboard-Interactive (KI) success).
|
||||
auth [success=2 default=ignore] pam_listfile.so item=user sense=deny file=/etc/ciss/2fa.users onerr=ignore
|
||||
|
||||
# For listed users: enforce that the secret file exists, else deny without prompting.
|
||||
# pam_google_authenticator will itself fail if the file is absent; we add a clear hint before it.
|
||||
# No 'nullok' here: listed users MUST have a secret; missing -> hard fail.
|
||||
auth required pam_echo.so file=/etc/ciss/pam_ssh_totp.prompt
|
||||
auth required pam_google_authenticator.so disallow-reuse
|
||||
|
||||
# For non-2FA users KI must be a silent success to satisfy AuthenticationMethods.
|
||||
auth sufficient pam_permit.so
|
||||
|
||||
# ===== CISS 2FA block end =====
|
||||
|
||||
|
||||
# Keep the rest as shipped by Debian. It will be short-circuited by pam_permit for KI and never reached for 2FA users after
|
||||
# successful GA.
|
||||
|
||||
# Standard Un*x authentication.
|
||||
@include common-auth
|
||||
|
||||
# Disallow non-root logins when /etc/nologin exists.
|
||||
account required pam_nologin.so
|
||||
|
||||
# Uncomment and edit /etc/security/access.conf if you need to set complex access limits that are hard to express in sshd_config.
|
||||
#account required pam_access.so
|
||||
|
||||
# Standard Un*x authorization.
|
||||
@include common-account
|
||||
|
||||
# SELinux needs to be the first session rule. This ensures that any lingering context has been cleared. Without this it is
|
||||
# possible that a module could execute code in the wrong domain.
|
||||
session [success=ok ignore=ignore module_unknown=ignore default=bad] pam_selinux.so close
|
||||
|
||||
# Set the loginuid process attribute.
|
||||
session required pam_loginuid.so
|
||||
|
||||
# Create a new session keyring.
|
||||
session optional pam_keyinit.so force revoke
|
||||
|
||||
# Standard Un*x session setup and teardown.
|
||||
@include common-session
|
||||
|
||||
# Print the message of the day upon successful login. This includes a dynamically generated part from /run/motd.dynamic and a
|
||||
# static (admin-editable) part from /etc/motd.
|
||||
session optional pam_motd.so motd=/run/motd.dynamic
|
||||
session optional pam_motd.so noupdate
|
||||
|
||||
# Print the status of the user's mailbox upon successful login.
|
||||
session optional pam_mail.so standard noenv
|
||||
|
||||
# Set up user limits from /etc/security/limits.conf.
|
||||
session required pam_limits.so
|
||||
|
||||
# Read environment variables from /etc/environment and /etc/security/pam_env.conf.
|
||||
session required pam_env.so
|
||||
|
||||
# In Debian 4.0 (etch), locale-related environment variables were moved to /etc/default/locale, so read that as well.
|
||||
session required pam_env.so envfile=/etc/default/locale
|
||||
|
||||
# SELinux needs to intervene at login time to ensure that the process starts in the proper default security context. Only
|
||||
# sessions which are intended to run in the user's context should be run after this.
|
||||
session [success=ok ignore=ignore module_unknown=ignore default=bad] pam_selinux.so open
|
||||
|
||||
# Standard Un*x password updating.
|
||||
@include common-password
|
||||
|
||||
# vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=conf
|
||||
EOF
|
||||
|
||||
do_log "info" "file_only" "4520() Written: [/etc/pam.d/sshd]."
|
||||
|
||||
cat << 'EOF' >| "${var_target}/etc/ciss/pam_ssh_totp.prompt"
|
||||
Please enter your 6-digit TOTP or 8-digit Backup code:
|
||||
EOF
|
||||
chmod 0444 "${var_target}/etc/ciss/pam_ssh_totp.prompt"
|
||||
do_log "info" "file_only" "4520() Written: [/etc/ciss/pam_ssh_totp.prompt]."
|
||||
|
||||
return 0
|
||||
}
|
||||
### Prevents accidental 'unset -f'.
|
||||
# shellcheck disable=SC2034
|
||||
readonly -f write_pam_sshd
|
||||
|
||||
#######################################
|
||||
# Writes CISS Header for '/etc/pam.d/su'.
|
||||
# Globals:
|
||||
# None
|
||||
# Arguments:
|
||||
# 1: TARGET
|
||||
# Returns:
|
||||
# 0: on success
|
||||
#######################################
|
||||
write_pam_sudo() {
|
||||
### Declare Arrays, HashMaps, and Variables.
|
||||
declare -r var_target="$1"
|
||||
|
||||
mv "${var_target}/etc/pam.d/su" "${var_target}/root/.ciss/cdi/backup/etc/pam.d/su"
|
||||
|
||||
insert_header "${var_target}/etc/pam.d/su"
|
||||
insert_comments "${var_target}/etc/pam.d/su"
|
||||
cat << EOF >> "${var_target}/etc/pam.d/su"
|
||||
#
|
||||
# PAM configuration for the su service
|
||||
#
|
||||
|
||||
# If caller is already root, allow quickly without further auth:
|
||||
auth sufficient pam_rootok.so
|
||||
|
||||
# Reuse a recent successful su-auth within the TTL:
|
||||
auth sufficient pam_timestamp.so
|
||||
|
||||
# Standard password for the target account (root or other):
|
||||
@include common-auth
|
||||
|
||||
|
||||
# ===== CISS 2FA block ========
|
||||
|
||||
# If user is NOT listed -> succeed and SKIP next two lines (no TOTP prompt).
|
||||
auth [success=2 default=ignore] pam_listfile.so item=user sense=deny file=/etc/ciss/2fa.users onerr=ignore
|
||||
|
||||
# For listed users: enforce that the secret file exists, else deny without prompting.
|
||||
# pam_google_authenticator will itself fail if the file is absent; we add a clear hint before it.
|
||||
# No 'nullok' here: listed users MUST have a secret; missing -> hard fail.
|
||||
auth required pam_echo.so file=/etc/ciss/pam_su_totp.prompt
|
||||
auth required pam_google_authenticator.so disallow-reuse
|
||||
|
||||
# ===== CISS 2FA block end =====
|
||||
|
||||
|
||||
@include common-account
|
||||
@include common-session
|
||||
# Keep a ticket to avoid re-prompts during this shell session:
|
||||
session optional pam_timestamp.so
|
||||
|
||||
# vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=conf
|
||||
EOF
|
||||
|
||||
do_log "info" "file_only" "4520() Written: [/etc/pam.d/su]."
|
||||
|
||||
cat << 'EOF' >| "${var_target}/etc/ciss/pam_su_totp.prompt"
|
||||
Please enter the 6-digit TOTP or 8-digit Backup code of the target user:
|
||||
EOF
|
||||
chmod 0444 "${var_target}/etc/ciss/pam_su_totp.prompt"
|
||||
do_log "info" "file_only" "4520() Written: [/etc/ciss/pam_su_totp.prompt]."
|
||||
|
||||
return 0
|
||||
}
|
||||
### Prevents accidental 'unset -f'.
|
||||
# shellcheck disable=SC2034
|
||||
readonly -f write_pam_su
|
||||
|
||||
#######################################
|
||||
# Writes CISS Header for '/etc/pam.d/sudo'.
|
||||
# Globals:
|
||||
# None
|
||||
# Arguments:
|
||||
# 1: TARGET
|
||||
# Returns:
|
||||
# 0: on success
|
||||
#######################################
|
||||
write_pam_sudo() {
|
||||
### Declare Arrays, HashMaps, and Variables.
|
||||
declare -r var_target="$1"
|
||||
|
||||
mv "${var_target}/etc/pam.d/sudo" "${var_target}/root/.ciss/cdi/backup/etc/pam.d/sudo"
|
||||
|
||||
insert_header "${var_target}/etc/pam.d/sudo"
|
||||
insert_comments "${var_target}/etc/pam.d/sudo"
|
||||
cat << EOF >> "${var_target}/etc/pam.d/sudo"
|
||||
#
|
||||
# PAM configuration for the sudo service
|
||||
#
|
||||
|
||||
# Reuse a recent successful auth to avoid re-prompting within the TTL.
|
||||
auth sufficient pam_timestamp.so
|
||||
|
||||
# Standard UNIX password:
|
||||
@include common-auth
|
||||
|
||||
|
||||
# ===== CISS 2FA block ========
|
||||
|
||||
# If user is NOT listed -> succeed and SKIP next two lines (no TOTP prompt).
|
||||
auth [success=2 default=ignore] pam_listfile.so item=user sense=deny file=/etc/ciss/2fa.users onerr=ignore
|
||||
|
||||
# For listed users: enforce that the secret file exists, else deny without prompting.
|
||||
# pam_google_authenticator will itself fail if the file is absent; we add a clear hint before it.
|
||||
# No 'nullok' here: listed users MUST have a secret; missing -> hard fail.
|
||||
auth required pam_echo.so file=/etc/ciss/pam_sudo_totp.prompt
|
||||
auth required pam_google_authenticator.so disallow-reuse
|
||||
|
||||
# ===== CISS 2FA block end =====
|
||||
|
||||
|
||||
# Accounts, sessions:
|
||||
@include common-account
|
||||
@include common-session-noninteractive
|
||||
|
||||
# Maintain a pam_timestamp ticket on successful sudo to suppress re-prompts.
|
||||
session optional pam_timestamp.so
|
||||
|
||||
# vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=conf
|
||||
EOF
|
||||
|
||||
do_log "info" "file_only" "4520() Written: [/etc/pam.d/sudo]."
|
||||
|
||||
cat << 'EOF' >| "${var_target}/etc/ciss/pam_sudo_totp.prompt"
|
||||
Please enter your 6-digit TOTP or 8-digit Backup code:
|
||||
EOF
|
||||
chmod 0444 "${var_target}/etc/ciss/pam_sudo_totp.prompt"
|
||||
do_log "info" "file_only" "4520() Written: [/etc/ciss/pam_sudo_totp.prompt]."
|
||||
|
||||
return 0
|
||||
}
|
||||
### Prevents accidental 'unset -f'.
|
||||
# shellcheck disable=SC2034
|
||||
readonly -f write_pam_sudo
|
||||
|
||||
#######################################
|
||||
# Use the official ohmyzsh-installer but force non-interactive behavior; do not run zsh; do not chsh.
|
||||
# Globals:
|
||||
@@ -1240,228 +1379,4 @@ EOF
|
||||
### Prevents accidental 'unset -f'.
|
||||
# shellcheck disable=SC2034
|
||||
readonly -f zsh_omz_installer
|
||||
|
||||
|
||||
|
||||
#######################################
|
||||
# Writes CISS Header for '/etc/pam.d/login'.
|
||||
# Globals:
|
||||
# None
|
||||
# Arguments:
|
||||
# 1: TARGET
|
||||
# Returns:
|
||||
# 0: on success
|
||||
#######################################
|
||||
write_pam_login() {
|
||||
### Declare Arrays, HashMaps, and Variables.
|
||||
declare -r var_target="$1"
|
||||
|
||||
mv "${var_target}/etc/pam.d/sshd" "${var_target}/root/.ciss/cdi/backup/etc/pam.d/login"
|
||||
|
||||
insert_header "${var_target}/etc/pam.d/login"
|
||||
insert_comments "${var_target}/etc/pam.d/login"
|
||||
cat << EOF >> "${var_target}/etc/pam.d/login"
|
||||
#
|
||||
# The PAM configuration file for the Shadow 'login' service
|
||||
#
|
||||
|
||||
# Enforce a minimal delay in case of failure (in microseconds). (Replaces the 'FAIL_DELAY' setting from login.defs).
|
||||
# Note that other modules may require another minimal delay. (For example, to disable any delay, you should add the 'nodelay'
|
||||
# option to pam_unix).
|
||||
auth optional pam_faildelay.so delay=3000000
|
||||
|
||||
# Outputs an issue file prior to each login prompt (Replaces the ISSUE_FILE option from login.defs). Uncomment for use.
|
||||
# auth required pam_issue.so issue=/etc/issue
|
||||
|
||||
# Disallows other than root logins when /etc/nologin exists. (Replaces the 'NOLOGINS_FILE' option from login.defs).
|
||||
auth requisite pam_nologin.so
|
||||
|
||||
# SELinux needs to be the first session rule. This ensures that any lingering context has been cleared. Without this it is
|
||||
# possible that a module could execute code in the wrong domain. When the module is present, "required" would be sufficient
|
||||
# (When SELinux is disabled, this returns success.)
|
||||
session [success=ok ignore=ignore module_unknown=ignore default=bad] pam_selinux.so close
|
||||
|
||||
# Sets the loginuid process attribute
|
||||
session required pam_loginuid.so
|
||||
|
||||
# Prints the message of the day upon successful login. (Replaces the 'MOTD_FILE' option in login.defs). This includes a
|
||||
# dynamically generated part from /run/motd.dynamic, and a static (admin-editable) part from /etc/motd.
|
||||
session optional pam_motd.so motd=/run/motd.dynamic
|
||||
session optional pam_motd.so noupdate
|
||||
|
||||
# SELinux needs to intervene at login time to ensure that the process starts in the proper default security context. Only
|
||||
# sessions which are intended to run in the user's context should be run after this. The module pam_selinux.so changes the
|
||||
# SELinux context of the used TTY and configures SELinux in order to transition to the user context with the next execve()
|
||||
# call.
|
||||
session [success=ok ignore=ignore module_unknown=ignore default=bad] pam_selinux.so open
|
||||
# When the module is present, "required" would be sufficient (When SELinux is disabled, this returns success.)
|
||||
|
||||
# This module parses environment configuration file(s) and also allows you to use an extended config file
|
||||
# /etc/security/pam_env.conf. Parsing /etc/environment needs "readenv=1"
|
||||
session required pam_env.so readenv=1
|
||||
# Locale variables can also be set in /etc/default/locale reading this file *in addition to /etc/environment* does not hurt.
|
||||
session required pam_env.so readenv=1 envfile=/etc/default/locale
|
||||
|
||||
# Standard Un*x authentication.
|
||||
@include common-auth
|
||||
|
||||
# ===== CISS 2FA block =====
|
||||
|
||||
# If user is NOT listed -> succeed and SKIP next two lines (no TOTP prompt).
|
||||
auth [success=2 default=ignore] pam_listfile.so item=user sense=deny file=/etc/ciss/2fa onerr=ignore
|
||||
|
||||
# Listed users: show a clear hint and then require GA. No 'nullok': missing secret -> fail.
|
||||
auth required pam_echo.so file=/etc/ciss/login_totp.prompt
|
||||
auth required pam_google_authenticator.so
|
||||
|
||||
# ===== CISS 2FA block end =====
|
||||
|
||||
# This allows certain extra groups to be granted to a user based on things like time of day, tty, service, and user. Please
|
||||
# edit /etc/security/group.conf to fit your needs (Replaces the 'CONSOLE_GROUPS' option in login.defs).
|
||||
auth optional pam_group.so
|
||||
|
||||
# Uncomment and edit /etc/security/time.conf if you need to set time restraint on logins. (Replaces the 'PORTTIME_CHECKS_ENAB'
|
||||
# option from login.defs as well as /etc/porttime).
|
||||
# account requisite am_time.so
|
||||
|
||||
# Uncomment and edit /etc/security/access.conf if you need to set access limits. (Replaces /etc/login.access file).
|
||||
# account required pam_access.so
|
||||
|
||||
# Sets up user limits according to /etc/security/limits.conf. (Replaces the use of /etc/limits in old login).
|
||||
session required pam_limits.so
|
||||
|
||||
# Prints the status of the user's mailbox upon successful login (Replaces the 'MAIL_CHECK_ENAB' option from login.defs).
|
||||
# This also defines the MAIL environment variable. However, userdel also needs MAIL_DIR and MAIL_FILE variables in
|
||||
# /etc/login.defs to make sure that removing a user also removes the user's mail spool file. See comments in /etc/login.defs.
|
||||
session optional pam_mail.so standard
|
||||
|
||||
# Create a new session keyring.
|
||||
session optional pam_keyinit.so force revoke
|
||||
|
||||
# Standard Un*x account and session
|
||||
@include common-account
|
||||
@include common-session
|
||||
@include common-password
|
||||
|
||||
# vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=conf
|
||||
EOF
|
||||
do_log "info" "file_only" "4520() Written: [/etc/pam.d/login]."
|
||||
|
||||
cat << 'EOF' >| "${var_target}/etc/ciss/login_totp.prompt"
|
||||
After your UNIX password, please enter your 6-digit TOTP code.
|
||||
EOF
|
||||
chmod 0444 "${var_target}/etc/ciss/login_totp.prompt"
|
||||
do_log "info" "file_only" "4520() Written: [/etc/ciss/login_totp.prompt]."
|
||||
|
||||
return 0
|
||||
}
|
||||
### Prevents accidental 'unset -f'.
|
||||
# shellcheck disable=SC2034
|
||||
readonly -f write_pam_login
|
||||
|
||||
#######################################
|
||||
# Writes CISS Header for '/etc/pam.d/sshd'.
|
||||
# Globals:
|
||||
# None
|
||||
# Arguments:
|
||||
# 1: TARGET
|
||||
# Returns:
|
||||
# 0: on success
|
||||
#######################################
|
||||
write_pam_sshd() {
|
||||
### Declare Arrays, HashMaps, and Variables.
|
||||
declare -r var_target="$1"
|
||||
|
||||
mv "${var_target}/etc/pam.d/sshd" "${var_target}/root/.ciss/cdi/backup/etc/pam.d/sshd"
|
||||
|
||||
insert_header "${var_target}/etc/pam.d/sshd"
|
||||
insert_comments "${var_target}/etc/pam.d/sshd"
|
||||
cat << EOF >> "${var_target}/etc/pam.d/sshd"
|
||||
#
|
||||
# PAM configuration for the Secure Shell service
|
||||
#
|
||||
|
||||
# ===== CISS 2FA block =====
|
||||
|
||||
# If user is NOT listed -> succeed and SKIP next two lines (silent Keyboard-Interactive (KI) success).
|
||||
auth [success=2 default=ignore] pam_listfile.so item=user sense=deny file=/etc/ciss/2fa onerr=ignore
|
||||
|
||||
# For listed users: enforce that the secret file exists, else deny without prompting.
|
||||
# pam_google_authenticator will itself fail if the file is absent; we add a clear hint before it.
|
||||
auth required pam_echo.so file=/etc/ciss/ssh_totp.prompt
|
||||
auth required pam_google_authenticator.so
|
||||
# No 'nullok' here: listed users MUST have a secret; missing -> hard fail.
|
||||
|
||||
# For non-2FA users KI must be a silent success to satisfy AuthenticationMethods.
|
||||
auth sufficient pam_permit.so
|
||||
# ===== CISS 2FA block end =====
|
||||
|
||||
# Keep the rest as shipped by Debian. It will be short-circuited by pam_permit for KI and never reached for 2FA users after
|
||||
# successful GA.
|
||||
|
||||
# Standard Un*x authentication.
|
||||
@include common-auth
|
||||
|
||||
# Disallow non-root logins when /etc/nologin exists.
|
||||
account required pam_nologin.so
|
||||
|
||||
# Uncomment and edit /etc/security/access.conf if you need to set complex access limits that are hard to express in sshd_config.
|
||||
# account required pam_access.so
|
||||
|
||||
# Standard Un*x authorization.
|
||||
@include common-account
|
||||
|
||||
# SELinux needs to be the first session rule. This ensures that any lingering context has been cleared. Without this it is
|
||||
# possible that a module could execute code in the wrong domain.
|
||||
session [success=ok ignore=ignore module_unknown=ignore default=bad] pam_selinux.so close
|
||||
|
||||
# Set the loginuid process attribute.
|
||||
session required pam_loginuid.so
|
||||
|
||||
# Create a new session keyring.
|
||||
session optional pam_keyinit.so force revoke
|
||||
|
||||
# Standard Un*x session setup and teardown.
|
||||
@include common-session
|
||||
|
||||
# Print the message of the day upon successful login. This includes a dynamically generated part from /run/motd.dynamic and a
|
||||
# static (admin-editable) part from /etc/motd.
|
||||
session optional pam_motd.so motd=/run/motd.dynamic
|
||||
session optional pam_motd.so noupdate
|
||||
|
||||
# Print the status of the user's mailbox upon successful login.
|
||||
session optional pam_mail.so standard noenv # [1]
|
||||
|
||||
# Set up user limits from /etc/security/limits.conf.
|
||||
session required pam_limits.so
|
||||
|
||||
# Read environment variables from /etc/environment and /etc/security/pam_env.conf.
|
||||
session required pam_env.so # [1]
|
||||
|
||||
# In Debian 4.0 (etch), locale-related environment variables were moved to /etc/default/locale, so read that as well.
|
||||
session required pam_env.so envfile=/etc/default/locale
|
||||
|
||||
# SELinux needs to intervene at login time to ensure that the process starts in the proper default security context. Only
|
||||
# sessions which are intended to run in the user's context should be run after this.
|
||||
session [success=ok ignore=ignore module_unknown=ignore default=bad] pam_selinux.so open
|
||||
|
||||
# Standard Un*x password updating.
|
||||
@include common-password
|
||||
|
||||
# vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=conf
|
||||
EOF
|
||||
|
||||
do_log "info" "file_only" "4520() Written: [/etc/pam.d/sshd]."
|
||||
|
||||
cat << 'EOF' >| "${var_target}/etc/ciss/ssh_totp.prompt"
|
||||
Please enter your 6-digit TOTP code for %u@%H.
|
||||
EOF
|
||||
chmod 0444 "${var_target}/etc/ciss/ssh_totp.prompt"
|
||||
do_log "info" "file_only" "4520() Written: [/etc/ciss/ssh_totp.prompt]."
|
||||
|
||||
return 0
|
||||
}
|
||||
### Prevents accidental 'unset -f'.
|
||||
# shellcheck disable=SC2034
|
||||
readonly -f write_pam_sshd
|
||||
# vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=sh
|
||||
|
||||
Reference in New Issue
Block a user