lsc-project / lsc

LSC engine
http://lsc-project.org/wiki/documentation/latest/start
Other
108 stars 41 forks source link

Allow for self-signed certificates #73

Open mrvanes opened 5 years ago

mrvanes commented 5 years ago

We're using LSC against LDAPS connected servers of which some serve self-signed certificates. We don't care about the chain of trust as much as the protected channel so we need to 'silence' the strict certificate checking. This can (and we do) be accomplished by adding the public part of the certificate to the trust store, but as the connections are quite ad-hoc and the provisioning of the certificate store is somewhat cumbersome it would be nice to to have a "use this public key" option for the certificate check.

coudot commented 5 years ago

We need to see if we can indeed add a configuration parameter for certificate

coudot commented 4 years ago

The best is to import your certificate in the java keystore : https://lsc-project.org/documentation/howto/ssltls

coudot commented 3 years ago

Contribution welcome to add a new option

cyrilstoll commented 8 months ago

Since our AD admins struggle to create valid certificates I needed a solution to this issue as well. Feel free to delete this comment if it is not appropriate being a bash script and not a real contribution to LSC itself. However I think it would solve @mrvanes problem. The script needs to run on the same machine as LSC. I created a cronjob which runs the script a couple minutes after LSC ran. The script then checks the lsc.status logfile for the sentence "Error opening LDAP connection" which occurs when the cert is invalid. If you want to use the script you need to adjust a couple of the variable values (almost) at the top of the script.

RECIPIENT= the script sends a report to this address if it has done anything (if your server allows sending mails) ADSERVER= this is the server of which you need to import the certificate LOGFILE= path to the lsc.status logfile CERTFILE= path to a dir where the cert can be downloaded to FRESHCERT= same path again but keep the _$DATETODAY part in the variable name KEYSTORE= path to your java keystore file CERTALIAS= alias for the cert in the keystore

You also need the following commands installed: mail (or mailx) nc (nmap-ncat) openssl keytool

#!/bin/bash

# Scope:   Executed by cron this script regularly checks if there are connection issues with AD.
#          In case of issues the script tries to fix them and reports by mail what has been done.
#          Print debug messages by supplying 'debug' as argument: ./ad-connection.sh debug

#
# define variables
#

RECIPIENT=your-mail-address@domain.com
ADSERVER=ad-or-ldap-server.domain.com
ADPORT=636
LOGFILE=/var/log/lsc/lsc.status
DATETODAY=$(date +%Y%m%d)
CERTFILE=/home/lsc/ad-cert.pem
FRESHCERT=/home/lsc/ad-cert_$DATETODAY.pem
KEYSTORE=/usr/lib/jvm/jre/lib/security/cacerts
CERTALIAS=ad_cert
KEYSTOREPASS=changeit
DEBUGGING=$1

#
# define functions
#

checkForDebugMode(){
    if [ "$DEBUGGING" = "debug" ]; then echo "DEBUG: debug mode active" ; else DEBUGGING="false" ; fi
}

checkLogForErrors(){
    CHECKLOG=$(grep "Error opening LDAP connection" $LOGFILE &>/dev/null)
    ERRORSINLOG=$?
    if [ "$DEBUGGING" = "debug" ]; then echo "DEBUG: content of ERRORSINLOG variable: $ERRORSINLOG" ; fi
}

checkAdConnection(){
    CHECKCONNECTION=$(nc -z -w 3 $ADSERVER $ADPORT &>/dev/null)
    CONNECTIONSTATUS=$?
    if [ "$DEBUGGING" = "debug" ] ; then echo "DEBUG: content of CONNECTIONSTATUS variable: $CONNECTIONSTATUS" ; fi
}

checkIfCertInKeystore(){
    CHECKKEYSTORE=$(keytool -list -storepass $KEYSTOREPASS -keystore $KEYSTORE -alias $CERTALIAS &>/dev/null)
    CERTINKEYSTORE=$?
}

downloadAdCert(){
    openssl s_client -showcerts -connect ${ADSERVER}:${ADPORT} </dev/null 2>/dev/null|openssl x509 -outform PEM >$FRESHCERT
}

ensureCertIsCurrent(){
    if [ -f $FRESHCERT ]
    then
        if diff -q $CERTFILE $FRESHCERT &>/dev/null
        then
            cat $FRESHCERT > $CERTFILE
        fi
        rm -f $FRESHCERT
    fi
}

removeOldCertFromKeystore(){
    keytool -delete -storepass $KEYSTOREPASS -keystore $KEYSTORE -alias $CERTALIAS
}

importCertToKeystore(){
    keytool -importcert -file $CERTFILE -storepass $KEYSTOREPASS -keystore $KEYSTORE -alias $CERTALIAS -noprompt &>/dev/null
}

sendStatusMail(){
    echo -e "$(hostname)\n\nIssue detected with ldaps connection to ${ADSERVER}:${ADPORT}\nThe following mitigation was attempted:\n$INFOTEXT\n\nBye" | mail -s "$(hostname -s) issue detected with group import from AD to OpenLDAP" $RECIPIENT
}

#
# execute
#

checkForDebugMode
checkLogForErrors

if [[ $ERRORSINLOG -eq "0" ]]
then
    if [ "$DEBUGGING" = "debug" ] ; then echo "DEBUG: connection errors detected in $LOGFILE" ; fi
    checkAdConnection
    if [[ $CONNECTIONSTATUS -eq "0" ]]
    then
        if [ "$DEBUGGING" = "debug" ] ; then echo "DEBUG: network connection to AD server looks fine" ; fi
        checkIfCertInKeystore
        if [[ $CERTINKEYSTORE -eq "0" ]]
        then
            if [ "$DEBUGGING" = "debug" ] ; then echo "DEBUG: cert in keystore probably not valid anymore, downloading and importing again" ; fi
            downloadAdCert
            ensureCertIsCurrent
            removeOldCertFromKeystore
            importCertToKeystore
            if [ "$DEBUGGING" = "debug" ] ; then echo "DEBUG: downloaded and imported cert from $ADSERVER into keystore $KEYSTORE as $CERTALIAS" ; fi
            INFOTEXT="Downloaded new AD certificate and imported it into keystore."
        else
            if [ "$DEBUGGING" = "debug" ] ; then echo "DEBUG: cert not found in keystore" ; fi
            importCertToKeystore
            if [ "$DEBUGGING" = "debug" ] ; then echo "DEBUG: cert imported into keystore again" ; fi
            INFOTEXT="AD certificate was imported into keystore as it was not present anymore".
        fi
    else
        if [ "$DEBUGGING" = "debug" ] ; then echo "DEBUG: network connection to AD server not possible" ; fi
        INFOTEXT="No mitigation as network connection to $ADSERVER is currently not possible."
    fi
    if [ "$DEBUGGING" = "debug" ] ; then echo "DEBUG: sending mail to $RECIPIENT" ; fi
    sendStatusMail
    if [ "$DEBUGGING" = "debug" ] ; then echo -e "DEBUG: attempted resolution: $INFOTEXT" ; fi
else
    if [ "$DEBUGGING" = "debug" ] ; then echo -e "DEBUG: no issues detected\nDEBUG: exiting" ; fi
    exit 0
fi

exit 0
coudot commented 8 months ago

Hello,

I don't really understand the goal of the script. You can simply test the connection by running the connector in dry-run mode, or with openssl s_client command.

The server certificate should not change so often.

On my side, I add the self-signed certificate in system ca certificates with update-ca-certificates, and it works.

cyrilstoll commented 8 months ago

The script is to avoid having to retrieve and import the cert manually. As @mrvanes wrote their connections are quite ad-hoc. Implementing this script or parts of it somehow would allow them to not care about the certs as the script handles that. I wrote it after our AD admins changed the cert on a Saturday without informing me causing the import to my OpenLDAP server to break. Now I don't care anymore if they change the cert on my off-hours or if the java keystone just forgets the cert (as has also happened after some software updates). If you run the cert and LSC as cronjobs you can just start the cert after LSC and if the latter fails the script fixes it and the next LSC run goes smooth again. But as I said, feel free to delete my comment if it is off-topic or useless. I'm sorry if I caused extra work. I will stop writing comments now unless I have something related and meaningful to contribute.

coudot commented 8 months ago

Hello, sorry if my comment was too rude, we will keep this issue opened for the moment to see if we include such script in the project.

From a security point of view, it is clearly dangerous to trust any certificate.

Thanks for your work and for sharing it here.