Fix domain-service mapping parsing and validation
This commit is contained in:
@@ -843,14 +843,23 @@ _ProvideCertDomainService() {
|
||||
|
||||
MyIsError=0
|
||||
|
||||
# Split list by '&' into individual domain-service mappings
|
||||
IFS=$'\n' DomainServiceAry=$(echo "$DYNTLS_DOMAINSERVICE_LIST" | sed 's/&/\n/g')
|
||||
for ServiceEntry in $DomainServiceAry; do
|
||||
# Normalize DYNTLS_DOMAINSERVICE_LIST: '&' separated -> one mapping per line
|
||||
DomainServiceRaw=$(printf '%s\n' "$DYNTLS_DOMAINSERVICE_LIST" | tr '&' '\n')
|
||||
|
||||
# Split one mapping into fields
|
||||
IFS=":" set -- $ServiceEntry
|
||||
Domain="$1"; PkiDir="$2"; UserGroup="$3"; FilePerm="$4"
|
||||
Service="$5"; ServiceOwner="$6"; RestartFlag="$7"; RestartMode="$8"; DisplayName="$9"
|
||||
# Nothing to do if no mappings are configured
|
||||
if [ -z "$DomainServiceRaw" ]; then
|
||||
_log "No domain-service mappings configured." 1
|
||||
_log "Leave the function '_ProvideCertDomainService()'..." 1
|
||||
return 0
|
||||
fi
|
||||
|
||||
# Process each mapping line-by-line, split into colon-separated fields
|
||||
while IFS=':' read -r \
|
||||
Domain PkiDir UserGroup FilePerm Service ServiceOwner RestartFlag RestartMode DisplayName || \
|
||||
[ -n "$Domain" ]
|
||||
do
|
||||
# Skip empty lines
|
||||
[ -z "$Domain" ] && continue
|
||||
|
||||
# Decide whether PkiDir is relative (default) or absolute (contains '/')
|
||||
case "$PkiDir" in
|
||||
@@ -858,104 +867,188 @@ _ProvideCertDomainService() {
|
||||
# Absolute path (or in general a path containing '/')
|
||||
EffectivePkiDir="$PkiDir"
|
||||
;;
|
||||
"")
|
||||
_log "Skipping mapping with empty pkiDir for domain=$Domain" 2
|
||||
MyIsError=1
|
||||
continue
|
||||
;;
|
||||
*)
|
||||
# Relative service name > located below DYNTLS_PKI
|
||||
EffectivePkiDir="$DYNTLS_PKI/$PkiDir"
|
||||
;;
|
||||
esac
|
||||
|
||||
# Convert legacy user.group notation to user:group for chown to avoid deprecation warnings
|
||||
UG_USER=${UserGroup%%.*}
|
||||
UG_GROUP=${UserGroup#*.}
|
||||
UserGroup=$UG_USER:$UG_GROUP
|
||||
# Convert legacy user.group notation to user:group
|
||||
case "$UserGroup" in
|
||||
*.*)
|
||||
UG_USER=${UserGroup%%.*}
|
||||
UG_GROUP=${UserGroup#*.}
|
||||
|
||||
# Legacy special case: "user." -> "user:user"
|
||||
[ -n "$UG_GROUP" ] || UG_GROUP=$UG_USER
|
||||
|
||||
UserGroup="$UG_USER:$UG_GROUP"
|
||||
;;
|
||||
esac
|
||||
|
||||
# Validate required ownership field
|
||||
case "$UserGroup" in
|
||||
*:*)
|
||||
;;
|
||||
"")
|
||||
_log "Skipping mapping with empty userGroup for domain=$Domain" 4
|
||||
MyIsError=1
|
||||
continue
|
||||
;;
|
||||
*)
|
||||
_log "Skipping mapping with invalid userGroup '$UserGroup' for domain=$Domain" 4
|
||||
MyIsError=1
|
||||
continue
|
||||
;;
|
||||
esac
|
||||
|
||||
# Validate file permission field
|
||||
case "$FilePerm" in
|
||||
[0-7][0-7][0-7]|[0-7][0-7][0-7][0-7])
|
||||
;;
|
||||
*)
|
||||
_log "Skipping mapping with invalid file permission '$FilePerm' for domain=$Domain" 4
|
||||
MyIsError=1
|
||||
continue
|
||||
;;
|
||||
esac
|
||||
|
||||
# Normalize restart flag
|
||||
case "$RestartFlag" in
|
||||
1)
|
||||
;;
|
||||
""|0)
|
||||
RestartFlag=0
|
||||
;;
|
||||
*)
|
||||
_log "Invalid restart flag '$RestartFlag' for domain=$Domain, forcing 0" 3
|
||||
RestartFlag=0
|
||||
;;
|
||||
esac
|
||||
|
||||
# Fallback display name for logs if missing
|
||||
[ -n "$DisplayName" ] || DisplayName=$Service
|
||||
|
||||
_log "Processing mapping: domain=$Domain, pkiDir=$PkiDir, userGroup=$UserGroup, perm=$FilePerm, service=$Service, owner=$ServiceOwner, restart=$RestartFlag, mode=$RestartMode, name=$DisplayName" 1
|
||||
|
||||
# Match against current hostname
|
||||
if [ "$Domain" = "$DYNTLS_MEMBER_HOSTNAME" ]; then
|
||||
_log "$DisplayName-Domain recognized! Try to provide the certificate to $DisplayName..." 2
|
||||
[ "$Domain" = "$DYNTLS_MEMBER_HOSTNAME" ] || continue
|
||||
|
||||
# Ensure required directories exist
|
||||
_log "Domain '$Domain' matches CN. Preparing service directory '$EffectivePkiDir'..." 1
|
||||
mkdir -p "$EffectivePkiDir/certs" "$EffectivePkiDir/private"
|
||||
_log "$DisplayName-Domain recognized! Try to provide the certificate to $DisplayName..." 2
|
||||
_log "Domain '$Domain' matches CN. Preparing service directory '$EffectivePkiDir'..." 1
|
||||
|
||||
# Set ownership/permissions on directories
|
||||
_log "Adjust the owner of '$EffectivePkiDir/'..." 1
|
||||
find "$EffectivePkiDir" -type d | xargs -r chown "$UserGroup"
|
||||
find "$EffectivePkiDir" -type d | xargs -r chmod 750
|
||||
# Ensure required directories exist
|
||||
mkdir -p "$EffectivePkiDir/certs" "$EffectivePkiDir/private" || {
|
||||
_log "Failed to create service PKI directories under '$EffectivePkiDir'." 4
|
||||
MyIsError=1
|
||||
continue
|
||||
}
|
||||
|
||||
# Provide base server key if missing
|
||||
_log "Check whether the server base key '$EffectivePkiDir/private/$DYNTLS_PKI_SERVER_BASEKEY_FILE' exists..." 1
|
||||
if [ ! -f "$EffectivePkiDir/private/$DYNTLS_PKI_SERVER_BASEKEY_FILE" ]; then
|
||||
_log "$DYNTLS_PKI_SERVER_BASEKEY doesn't exist. Copy it..." 1
|
||||
cp "$DYNTLS_PKI_SERVER_BASEKEY" "$EffectivePkiDir/private/"
|
||||
fi
|
||||
# Set ownership/permissions on directories
|
||||
_log "Adjust the owner of '$EffectivePkiDir/'..." 1
|
||||
find "$EffectivePkiDir" -type d -exec chown "$UserGroup" {} \; || {
|
||||
_log "Failed to adjust directory ownership under '$EffectivePkiDir'." 4
|
||||
MyIsError=1
|
||||
}
|
||||
find "$EffectivePkiDir" -type d -exec chmod 750 {} \; || {
|
||||
_log "Failed to adjust directory permissions under '$EffectivePkiDir'." 4
|
||||
MyIsError=1
|
||||
}
|
||||
|
||||
# Copy issued certificates into service PKI area
|
||||
_log "Copy the domain certificate, LE_CA chain and full chain from $DYNTLS_PKI_HTTP_CERT_DIR to the PKI service dir '$EffectivePkiDir/certs/'..." 1
|
||||
#cp "$DYNTLS_DOMAIN_TARGET_CERT" \
|
||||
# "$DYNTLS_PKI_LECA_CHAIN" \
|
||||
# "$DYNTLS_PKI_LECA_R12_CHAIN" \
|
||||
# "$DYNTLS_PKI_LECA_R13_CHAIN" \
|
||||
# "$DYNTLS_PKI_HTTP_CERT_DIR/$DYNTLS_MEMBER_HOSTNAME.$DYNTLS_PKI_FULLCHAIN_SUFFIX" \
|
||||
# "$EffectivePkiDir/certs/"
|
||||
# Provide base server key if missing
|
||||
_log "Check whether the server base key '$EffectivePkiDir/private/$DYNTLS_PKI_SERVER_BASEKEY_FILE' exists..." 1
|
||||
if [ ! -f "$EffectivePkiDir/private/$DYNTLS_PKI_SERVER_BASEKEY_FILE" ]; then
|
||||
_log "$DYNTLS_PKI_SERVER_BASEKEY doesn't exist. Copy it..." 1
|
||||
cp "$DYNTLS_PKI_SERVER_BASEKEY" "$EffectivePkiDir/private/" || {
|
||||
_log "Failed to copy base server key to '$EffectivePkiDir/private/'." 4
|
||||
MyIsError=1
|
||||
continue
|
||||
}
|
||||
fi
|
||||
|
||||
cp "$DYNTLS_DOMAIN_TARGET_CERT" \
|
||||
"$DYNTLS_PKI_HTTP_CERT_DIR/$DYNTLS_MEMBER_HOSTNAME.$DYNTLS_PKI_CHAIN_SUFFIX" \
|
||||
"$DYNTLS_PKI_HTTP_CERT_DIR/$DYNTLS_MEMBER_HOSTNAME.$DYNTLS_PKI_FULLCHAIN_SUFFIX" \
|
||||
"$EffectivePkiDir/certs/"
|
||||
# Copy issued certificates into service PKI area
|
||||
_log "Copy the domain certificate, chain and full chain from $DYNTLS_PKI_HTTP_CERT_DIR to the PKI service dir '$EffectivePkiDir/certs/'..." 1
|
||||
cp "$DYNTLS_DOMAIN_TARGET_CERT" \
|
||||
"$DYNTLS_PKI_HTTP_CERT_DIR/$DYNTLS_MEMBER_HOSTNAME.$DYNTLS_PKI_CHAIN_SUFFIX" \
|
||||
"$DYNTLS_PKI_HTTP_CERT_DIR/$DYNTLS_MEMBER_HOSTNAME.$DYNTLS_PKI_FULLCHAIN_SUFFIX" \
|
||||
"$EffectivePkiDir/certs/" || {
|
||||
_log "Failed to copy certificate files to '$EffectivePkiDir/certs/'." 4
|
||||
MyIsError=1
|
||||
continue
|
||||
}
|
||||
|
||||
# Provide server key: either symlink to base or copy unique key
|
||||
KeyPath="$EffectivePkiDir/private/$DYNTLS_MEMBER_HOSTNAME.$DYNTLS_PKI_KEY_SUFFIX"
|
||||
# Provide server key: either symlink to base or copy unique key
|
||||
KeyPath="$EffectivePkiDir/private/$DYNTLS_MEMBER_HOSTNAME.$DYNTLS_PKI_KEY_SUFFIX"
|
||||
|
||||
if [ "$DYNTLS_PKI_KEY_LNS" -eq 1 ]; then
|
||||
_log "Using relative symlink for service key: $KeyPath -> $DYNTLS_PKI_SERVER_BASEKEY_FILE" 1
|
||||
ln -sf "$DYNTLS_PKI_SERVER_BASEKEY_FILE" "$KeyPath"
|
||||
else
|
||||
_log "Using dedicated service key copy at: $KeyPath (source: $EffectivePkiDir/private/$DYNTLS_PKI_SERVER_BASEKEY_FILE)" 1
|
||||
cp "$EffectivePkiDir/private/$DYNTLS_PKI_SERVER_BASEKEY_FILE" "$KeyPath"
|
||||
fi
|
||||
if [ "$DYNTLS_PKI_KEY_LNS" -eq 1 ]; then
|
||||
_log "Using relative symlink for service key: $KeyPath -> $DYNTLS_PKI_SERVER_BASEKEY_FILE" 1
|
||||
ln -sf "$DYNTLS_PKI_SERVER_BASEKEY_FILE" "$KeyPath" || {
|
||||
_log "Failed to create service key symlink '$KeyPath'." 4
|
||||
MyIsError=1
|
||||
continue
|
||||
}
|
||||
else
|
||||
_log "Using dedicated service key copy at: $KeyPath (source: $EffectivePkiDir/private/$DYNTLS_PKI_SERVER_BASEKEY_FILE)" 1
|
||||
cp "$EffectivePkiDir/private/$DYNTLS_PKI_SERVER_BASEKEY_FILE" "$KeyPath" || {
|
||||
_log "Failed to copy service key to '$KeyPath'." 4
|
||||
MyIsError=1
|
||||
continue
|
||||
}
|
||||
fi
|
||||
|
||||
# Adjust ownership and permissions on .pem files
|
||||
_log "Adjust the ownership of '$EffectivePkiDir/certs/*.pem'..." 1
|
||||
find "$EffectivePkiDir/certs" -type f -name '*.pem' | xargs -r chown "$UserGroup"
|
||||
_log "Adjust the ownership of '$EffectivePkiDir/private/*.pem'..." 1
|
||||
find "$EffectivePkiDir/private" -type f -name '*.pem' | xargs -r chown "$UserGroup"
|
||||
_log "Adjust the permissions of '$EffectivePkiDir/certs/*.pem'..." 1
|
||||
find "$EffectivePkiDir/certs" -type f -name '*.pem' | xargs -r chmod "$FilePerm"
|
||||
_log "Adjust the permissions of '$EffectivePkiDir/private/*.pem'..." 1
|
||||
find "$EffectivePkiDir/private" -type f -name '*.pem' | xargs -r chmod 440
|
||||
# Adjust ownership and permissions on .pem files
|
||||
find "$EffectivePkiDir/certs" -type f -name '*.pem' -exec chown "$UserGroup" {} \; || {
|
||||
_log "Failed to adjust certificate ownership under '$EffectivePkiDir/certs/'." 4
|
||||
MyIsError=1
|
||||
}
|
||||
find "$EffectivePkiDir/private" -type f -name '*.pem' -exec chown "$UserGroup" {} \; || {
|
||||
_log "Failed to adjust key ownership under '$EffectivePkiDir/private/'." 4
|
||||
MyIsError=1
|
||||
}
|
||||
find "$EffectivePkiDir/certs" -type f -name '*.pem' -exec chmod "$FilePerm" {} \; || {
|
||||
_log "Failed to adjust certificate permissions under '$EffectivePkiDir/certs/'." 4
|
||||
MyIsError=1
|
||||
}
|
||||
find "$EffectivePkiDir/private" -type f -name '*.pem' -exec chmod 440 {} \; || {
|
||||
_log "Failed to adjust key permissions under '$EffectivePkiDir/private/'." 4
|
||||
MyIsError=1
|
||||
}
|
||||
|
||||
_log "Certificates and keys provided for service '$DisplayName'." 2
|
||||
_log "Certificates and keys provided for service '$DisplayName'." 2
|
||||
|
||||
# Restart or reload the service if configured
|
||||
if [ "$RestartFlag" -eq 1 ] && [ -n "$Service" ]; then
|
||||
# fallback to restart if mode is missing or invalid
|
||||
[ "$RestartMode" = "restart" ] || [ "$RestartMode" = "reload" ] || RestartMode="restart"
|
||||
# Restart or reload the service if configured
|
||||
if [ "$RestartFlag" -eq 1 ] && [ -n "$Service" ]; then
|
||||
[ "$RestartMode" = "restart" ] || [ "$RestartMode" = "reload" ] || RestartMode="restart"
|
||||
|
||||
if [ -n "$ServiceOwner" ] && [ "$ServiceOwner" != "root" ]; then
|
||||
_log "Reloading service '$Service' as non-root user '$ServiceOwner'..." 1
|
||||
if sudo -u "$ServiceOwner" XDG_RUNTIME_DIR="/run/user/$(id -u $ServiceOwner)" \
|
||||
systemctl --user "$RestartMode" "$Service.service"; then
|
||||
_log "Service '$DisplayName' successfully $RestartMode-ed as '$ServiceOwner'." 2
|
||||
else
|
||||
_log "Error while $RestartMode-ing service '$DisplayName'." 4
|
||||
MyIsError=1
|
||||
fi
|
||||
if [ -n "$ServiceOwner" ] && [ "$ServiceOwner" != "root" ]; then
|
||||
_log "Reloading service '$Service' as non-root user '$ServiceOwner'..." 1
|
||||
if sudo -u "$ServiceOwner" XDG_RUNTIME_DIR="/run/user/$(id -u "$ServiceOwner")" \
|
||||
systemctl --user "$RestartMode" "$Service.service"; then
|
||||
_log "Service '$DisplayName' successfully $RestartMode-ed as '$ServiceOwner'." 2
|
||||
else
|
||||
_log "Reloading service '$Service' as root..." 1
|
||||
if systemctl "$RestartMode" "$Service.service"; then
|
||||
_log "Service '$DisplayName' successfully $RestartMode-ed as root." 2
|
||||
else
|
||||
_log "Error while $RestartMode-ing service '$DisplayName'." 4
|
||||
MyIsError=1
|
||||
fi
|
||||
_log "Error while $RestartMode-ing service '$DisplayName'." 4
|
||||
MyIsError=1
|
||||
fi
|
||||
else
|
||||
_log "No restart required for service '$DisplayName'." 2
|
||||
_log "Reloading service '$Service' as root..." 1
|
||||
if systemctl "$RestartMode" "$Service.service"; then
|
||||
_log "Service '$DisplayName' successfully $RestartMode-ed as root." 2
|
||||
else
|
||||
_log "Error while $RestartMode-ing service '$DisplayName'." 4
|
||||
MyIsError=1
|
||||
fi
|
||||
fi
|
||||
else
|
||||
_log "No restart required for service '$DisplayName'." 2
|
||||
fi
|
||||
done
|
||||
done <<EOF
|
||||
$DomainServiceRaw
|
||||
EOF
|
||||
|
||||
_log "Leave the function '_ProvideCertDomainService()'..." 1
|
||||
|
||||
|
||||
Reference in New Issue
Block a user