acme.sh DNS challenges for ISPconfig-3.2.11p2 on LOCAL LAN

Discussion in 'Installation/Configuration' started by Michel-André, Jun 9, 2024.

  1. Michel-André

    Michel-André New Member

    Hi all,

    I installed ISPconfig-3.2.11p2 on my LOCAL LAN.
    To be able to get a Let's Encrypt certificate I have to use the script .acme.sh with DNS challenges,
    Code:
    # Delete the original .acme.sh folder to have no original parameters,
    rm -rf /root/.acme.sh
    
    # Install a new .acme.sh
    curl https://get.acme.sh | sh -s [email protected]
    
    # Display the version
    /root/.acme.sh/acme.sh -v
    
    # Display the email address
    cat /root/.acme.sh/account.conf | grep ACCOUNT_EMAIL
    
    # To make sure the CA is Let's Encrypt
    /root/.acme.sh/acme.sh --set-default-ca  --server  letsencrypt
    
    # Export the Globel API key from Cloudflare.com
    export CF_Key="Cloudflare-Global-API-key"
    
    # Export the mail address used to connect to Cloudflare.co,
    export CF_Email="Email-Address-For-Cloudflare"
    
    # Display the exported variables
    env | grep -i CF_
    
    # - Using TEST certificates until I am sure that all is working correctly
    #   and to make sure to not reach the 5/7 limit of Let's Encrypt.
    # - I am using the DNS challenges with Cloudflare.
    # - All the DNS record are set at Cloudflare with Proxy disabled.
    # - The FQDN of the ISPconfig server is: debian.toto.org.
    
    # - Requesting a TEST certificate.
    /root/.acme.sh/acme.sh                                            \
         --issue                                                      \
         --dns dns_cf                                                 \
         -d debian.toto.org                                           \
         -d toto.org                                                  \
         -d mail.toto.org                                             \
         -d smtp.toto.org                                             \
         -d imap.toto.org                                             \
         -d wap.toto.org                                              \
         -d www.toto.org                                              \
         --keylength 4096                                             \
         --cert-file /usr/local/ispconfig/interface/ssl/ispserver.crt \
         --ca-file /usr/local/ispconfig/interface/ssl/ispserver.pem   \
         --key-file /usr/local/ispconfig/interface/ssl/ispserver.key  \
         --reloadcmd "/usr/sbin/service pure-ftpd-mysql restart;      \
                      /usr/sbin/service postfix restart;              \
                      /usr/sbin/service dovecot restart;              \
                      /usr/sbin/service mysql restart;                \
                      /usr/sbin/service apache2 restart"              \
         --log '/var/log/ispconfig/acme.log'                          \
         --test                                                       \
         --force
    This is working as I am able to connect to the ISPconfig control panel and the certificate displayed is this TEST one from Let's Encrypt.

    Question:
    Should I put the reload commands in a bash script in the /root/.acme.sh/deploy folder to make sure the renewal of the certificate will deploy the certifiate files in the right place?

    My next step will be to get a Let's Encrypt certificate for the web site...

    Any suggestion or comment appreciated,

    Michel-André
     
    Last edited: Jun 9, 2024
  2. ztk.me

    ztk.me Well-Known Member HowtoForge Supporter

    for one: do not do this on the ispconfig host, use a seperate host.
    also, you could use -d *.toto.org for a wildcard cert instead of putting so many subdomains in it.
    Having one cert for many domains enlarges a security risk on the other hand.
    you could ask chatgpt to write a reloadcmd which would update websites ssl cert using ispconfig api and it would 99% work :D but don't blame ispconfig or me if not

    in fact, this is what chatgpt got me for a simple bash variant, might need some testing and looking at the api
    but it should be adaptable. jq and curl might need to be installed as dependency
    Code:
    #!/bin/bash
    
    API_URL="https://your-ispconfig-api-url:8080/remote/json.php"
    USERNAME="your-api-username"
    PASSWORD="your-api-password"
    DOMAIN=$1
    
    if [ -z "$DOMAIN" ]; then
        echo "Usage: $0 <domain>"
        exit 1
    fi
    
    CERT_FILE_PATH="/path/to/certificates/${DOMAIN}.crt"
    KEY_FILE_PATH="/path/to/private-keys/${DOMAIN}.key"
    CA_FILE_PATH="/path/to/ca-bundles/${DOMAIN}.ca-bundle.crt"
    
    # Function to log in and get session ID
    get_session_id() {
        local response=$(curl -s -X POST -d "{
            \"username\": \"$USERNAME\",
            \"password\": \"$PASSWORD\",
            \"method\": \"session_login\"
        }" $API_URL)
    
        echo $(echo $response | jq -r '.response')
    }
    
    # Function to get the domain ID
    get_domain_id() {
        local session_id=$1
        local response=$(curl -s -X POST -d "{
            \"session_id\": \"$session_id\",
            \"method\": \"sites_web_domain_get_all\",
            \"params\": [{}]
        }" $API_URL)
    
        echo $(echo $response | jq -r --arg DOMAIN "$DOMAIN" '.response[] | select(.domain == $DOMAIN) | .domain_id')
    }
    
    # Function to update SSL certificates
    update_ssl_certificates() {
        local session_id=$1
        local domain_id=$2
        local cert_content=$(cat $CERT_FILE_PATH)
        local key_content=$(cat $KEY_FILE_PATH)
        local ca_content=$(cat $CA_FILE_PATH)
    
        local response=$(curl -s -X POST -d "{
            \"session_id\": \"$session_id\",
            \"method\": \"sites_web_domain_update\",
            \"params\": [{
                \"domain_id\": \"$domain_id\",
                \"ssl\": \"y\",
                \"ssl_cert\": \"$cert_content\",
                \"ssl_key\": \"$key_content\",
                \"ssl_bundle\": \"$ca_content\"
            }]
        }" $API_URL)
    
        echo $response
    }
    
    # Main script execution
    SESSION_ID=$(get_session_id)
    if [ -z "$SESSION_ID" ]; then
        echo "Failed to login and get session ID"
        exit 1
    fi
    
    DOMAIN_ID=$(get_domain_id $SESSION_ID)
    if [ -z "$DOMAIN_ID" ]; then
        echo "Failed to get domain ID for $DOMAIN"
        exit 1
    fi
    
    UPDATE_RESPONSE=$(update_ssl_certificates $SESSION_ID $DOMAIN_ID)
    echo "Update Response: $UPDATE_RESPONSE"
    
    # Log out to clean up session
    curl -s -X POST -d "{
        \"session_id\": \"$SESSION_ID\",
        \"method\": \"session_logout\"
    }" $API_URL
    
    echo "SSL certificates updated successfully for $DOMAIN"
    
    
     
    Last edited: Jun 9, 2024
  3. Michel-André

    Michel-André New Member

    Hi ztk.me,

    Thank you for your reply. Very interesting script.

    I am on a Proxmox VE virtual machine so there is no limit to return to a snapshot.
    I installed jq.
    I created a remote user.
    I ajusted the .acme.sh script to use only *.toto.org as you suggested.
    I created a reloadcmd and ajusted it for *.toto.org etc.
    After a few trials with the reloadcmd I checked all the functions for the remote user.
    There is something wrong with the "session_id". I added echo "THE SESSION ID is => "$session_id in a few places but it is always empty.
    I added an "echo" for $USERNAME, $PASSWORD, $DOMAIN, $CERT_FILE_PATH, $KEY_FILE_PATH, $CA_FILE_PATH, $0, $1, and all looked OK.

    Code:
    [root@debian ~]# ./mar-reloadcmd.sh toto.org
    DISPLAY DOMAIN =>  toto.org
    DISPLAY USERNAME => deploy
    DISPLAY PASSWORD => deploy-password
    DISPLAY CERT_FILE_PATH =>  /root/.acme.sh/toto.org/toto.org.cer
    DISPLAY KEY_FILE_PATH =>  /root/.acme.sh/toto.org/toto.org.key
    DISPLAY CA_FILE_PATH =>  /root/.acme.sh/toto.org/fullchain.cer
    DISPLAY response =>
    DISPLAY username =>
    DISPLAY password =>
    DISPLAY method =>
    DISPLAY API_URL => https://toto.org:8080/remote/json.php
    AFTER => # Function to log in and get session ID
    AFTER => # Function to get the domain ID
    THIS IS THE SESSION ID =>
    AFTER => # Function to update SSL certificates
    Next line is: ***** DOMAIN_ID=$(get_domain_id $SESSION_ID) *****
    jq: error (at <stdin>:1): Cannot iterate over boolean (false)
    Failed to get domain ID for toto.org
    [root@debian ~]#
    The error is from those lines.
    Code:
    if [ -z "$DOMAIN_ID" ]; then
        echo "Failed to get domain ID for $DOMAIN"
        exit 1
    fi
    Because of this function returning nothing:
    Code:
    # Function to log in and get session ID
    get_session_id() {
        local response=$(curl -s -X POST -d "{
            \"username\": \"$USERNAME\",
            \"password\": \"$PASSWORD\",
            \"method\": \"session_login\"
        }" $API_URL)
    
        echo $(echo $response | jq -r '.response')
    }
    I tried with *.toto.org, debian.toto.org, and toto.org. I alway have the same error.

    Any suggestion or comment appreciated,

    Michel-André
     
    Last edited: Jun 9, 2024
  4. till

    till Super Moderator Staff Member ISPConfig Developer

    Please be aware that you can not set the central ISPConfig SSL cert using remote API, so the script that @ztk.me posted will not do what you did in post #1. Your approach from first post should be generally ok for that cert. The only thing that I would change is to create a bash script for reloading the services instead of putting all commands in the --reloadcmd option of acme.sh and that it might be useful to create a wilcard cert, like @ztk.me mentioned.

    Such a remote API script could only be used to set an external SSL cert statically for a website, and that script looks a bit crude to me anyway as one would e.g. not use sites_web_domain_get_all to get the ID for a domain, even if it might work, just not really effective on larger systems. Normally one would use sites_web_domain_get function and pass an array 'domain' => 'domain.tld' as primary_id parameter. The problem with ChatGPT and ISPConfig is that most answers from ChatGPT regarding ISPConfig are incorrect, at least what I found out testing it a few months ago, so it would not surprise me if it would get a remote API script right on its own.
     
    Michel-André likes this.
  5. Michel-André

    Michel-André New Member

    Hi Till,

    Thank you so much for your support.
    I will ajust the acme.sh script to reflect you suggestion and use *.toto.org as ztk.me recommended.
    I will post the results when everything will be workiing properly.

    I now have confidence that my documentation project for using ISPconfig as a home server has real good prospects for success,

    Michel-André
     
    ahrasis likes this.
  6. ztk.me

    ztk.me Well-Known Member HowtoForge Supporter

    exactly, chatgpt can help getting an idea sort of structured, but one should always question the output.
    Actually it did not try the domains_get_all before, I just remembered a forum thread where this was an issue that one could not add a domain name as argument, so I made it correct itself :D

    Also yes, this will not secure the ispconfig or server certificate. One could use those set certificates for other places,. too w/o having a maybe in the future conflicting ispconfig setup?

    This was the first code, which I thought could not work

    Code:
    #!/bin/bash
    
    API_URL="https://your-ispconfig-api-url:8080/remote/json.php"
    USERNAME="your-api-username"
    PASSWORD="your-api-password"
    DOMAIN=$1
    
    if [ -z "$DOMAIN" ]; then
        echo "Usage: $0 <domain>"
        exit 1
    fi
    
    CERT_FILE_PATH="/path/to/certificates/${DOMAIN}.crt"
    KEY_FILE_PATH="/path/to/private-keys/${DOMAIN}.key"
    CA_FILE_PATH="/path/to/ca-bundles/${DOMAIN}.ca-bundle.crt"
    
    # Function to log in and get session ID
    get_session_id() {
        local response=$(curl -s -X POST -d "{
            \"username\": \"$USERNAME\",
            \"password\": \"$PASSWORD\",
            \"method\": \"session_login\"
        }" $API_URL)
    
        echo $(echo $response | jq -r '.response')
    }
    
    # Function to get domain ID
    get_domain_id() {
        local session_id=$1
        local response=$(curl -s -X POST -d "{
            \"session_id\": \"$session_id\",
            \"method\": \"sites_web_domain_get\",
            \"params\": [{\"primary_id\": \"$DOMAIN\"}]
        }" $API_URL)
    
        echo $(echo $response | jq -r '.response[0].domain_id')
    }
    
    # Function to update SSL certificates
    update_ssl_certificates() {
        local session_id=$1
        local domain_id=$2
        local cert_content=$(cat $CERT_FILE_PATH)
        local key_content=$(cat $KEY_FILE_PATH)
        local ca_content=$(cat $CA_FILE_PATH)
    
        local response=$(curl -s -X POST -d "{
            \"session_id\": \"$session_id\",
            \"method\": \"sites_web_domain_update\",
            \"params\": [{
                \"domain_id\": \"$domain_id\",
                \"ssl\": \"y\",
                \"ssl_cert\": \"$cert_content\",
                \"ssl_key\": \"$key_content\",
                \"ssl_bundle\": \"$ca_content\"
            }]
        }" $API_URL)
    
        echo $response
    }
    
    # Main script execution
    SESSION_ID=$(get_session_id)
    if [ -z "$SESSION_ID" ]; then
        echo "Failed to login and get session ID"
        exit 1
    fi
    
    DOMAIN_ID=$(get_domain_id $SESSION_ID)
    if [ -z "$DOMAIN_ID" ]; then
        echo "Failed to get domain ID"
        exit 1
    fi
    
    UPDATE_RESPONSE=$(update_ssl_certificates $SESSION_ID $DOMAIN_ID)
    echo "Update Response: $UPDATE_RESPONSE"
    
    # Log out to clean up session
    curl -s -X POST -d "{
        \"session_id\": \"$SESSION_ID\",
        \"method\": \"session_logout\"
    }" $API_URL
    
    echo "SSL certificates updated successfully for $DOMAIN"
    
     
    ahrasis likes this.
  7. ahrasis

    ahrasis Well-Known Member HowtoForge Supporter

    Agreed. Plus you can also use some of code from the ISPConfig installer which adds/uses LE hook scripts instead, to achieve the same objective. The ISPConfig LE hook scripts are customizable and would only need to copy them from /conf to /conf-custom for such customization. With that, you don't need other scripts.
     
    Michel-André and ztk.me like this.
  8. Michel-André

    Michel-André New Member

    Hi all,

    As wriiten above:
    Code:
    **** FOR ISPconfig 3.2.11p2 ON A LOCAL LAN ****
    2024-06-13  22h00 Corrected some typos in comments.
    
    #### CREATE DNS RECORDS AT YOUR DNS REGISTRAR
    
    #### AT THE DEVICE CONNECTED TO THE INTERNET
    # CREATE REDIRECTIONS TO YOUR LOCAL ISPconfig SERVER
    
    #### IN ISPconfig
    # System | Server config | Web tab | Settings
    #     Skip Lets Encrypt Check: => Checked.
    # Sites | Your domain | Domain tab
    #     Let's Encrypt: =>  Not Checked.
    # Sites | Your domain | SSL tab
    #     Domaine SSL: => *.your-domain.tld
    # DNS
    #     Create your-domain.tld ZONE
    Code:
    ** AT THE ISPconfig SERVER CONSOLE **
    
    #### Delete /root/.acme.sh to delete all previous parameters
    #### Install .acme.sh
    
    #### REQUEST 2 CERTIFICATES:
    #### = ONE FOR ISPconfig
    #### - ONE FOR THE WEB DOMAIN
    
    # Set default CA to Let's Encrypt
    /root/.acme.sh/acme.sh --set-default-ca  --server  letsencrypt
    
    # Export Global API from Cloudflare
    export CF_Key="abcdefghijklmnopqrestuvwxyz0123456789"
     
    # Export login email used to connect to Cloudflare
    export CF_Email="[email protected]"
    
    # Verify exported variables
    env | grep -i CF_
    
    #### CERTIFICATE FOR ISPCONFIG
    ##   Request a TEST certificate
    #    FQDN domain has to be the first one
    #    - EXAMPLE: debian.toto.org
    #    The reloadcmd: "/root/reload.sh FQDN"
    #    - EXAMPLE:     "/root/reload.sh debian.toto.org"
    ##   Request a PRODUCTION certificate by REMOVING line: "--test   \"
    
    #### CERTIFICATE FOR WEBSITE
    ##   Request a TEST certificate
    #    Website domain has to be the first one
    #    - EXAMPLE: toto.org
    #    The reloadcmd: "/root/reload.sh Domain ClientNumber WebNumber"
    #    - EXAMPLE:     "/root/reload.sh toto.org client1 web1"
    ##   Request a PRODUCTION certificate by REMOVING line: "--test   \"
    
    # /root/.acme.sh/acme.sh                                                \
                           --issue                                          \
                           --dns dns_cf                                     \
                           -d debian.toto.org                               \
                           -d toto.org                                      \
                           -d mail.toto.org                                 \
                           -d smtp.toto.org                                 \
                           -d imap.toto.org                                 \
                           -d wap.toto.org                                  \
                           -d www.toto.org                                  \
                           --keylength 4096                                 \
                           --reloadcmd "/root/reload.sh  debian.toto.org"   \
                           --log '/var/log/ispconfig/acme.log'              \
                           --test                                           \
                           --force
    
    NOTE:
      --renew-hook <command>   Command to be run after each successfully renewed certificate.
    This parameter does nothing in a request except putting the BASE64 name of the command in the conf file.
    
    Might be interesting, as a line in the certificate requests, to add
    for ISPconfig:
      --renew-hook  "/root/reload.sh debian.toto.org"
    for Website:
      --renew-hook  "/root/reload.sh toto.org client1 web1"
    Below is the "reload.sh" I am using for the "reloadcmd".
    It should work for any FQDN and any website domain.
    All is working correctly and no problem with a Thunderbird account.
    I am not a programmer, but the script is working.
    Code:
    #!/bin/bash
    
    #### Routine for managing files from a Let's Encrypt certificate
    # Author: Michel-André Robillard
    # Website: https://www.micronator.org/affaires
    # Date: 2024-06-12 @ 22h17
    # © 2024  RF-232  Any reproduction prohibited.
    # I should put the © like BSD, it will be better.
    
    #### USAGE for ISPconfig certificate
    # /root/reload.sh  <FQDN>
    #
    # EXAMPLE:
    # /root/reload.sh debian.toto.org
    
    # If the certificate is for ISPconfig.
    if [ "$1" = "$(hostname -f)" ]; then
        HostName=$(hostname -f);
    
        # Folder of Let's Encrypt files.
        RepertoireLE=/root/.acme.sh/$HostName ;
    
        # Directory of ISPconfig certificate files for the manager.
        RepertoireSSL="/usr/local/ispconfig/interface/ssl" ;
    
        # We save the contents of the ISPconfig files directory
        # for the manager: /usr/local/ispconfig/interface/ssl
    
        # If the backup directory does not exist, we create it.
        DirDeSauvegarde="/tmp/Sauvegarde";
        if [ ! -d "$DirDeSauvegarde" ]; then
            mkdir $DirDeSauvegarde;
        fi
    
        # We save the contents of the /usr/local/ispconfig/interface/ssl
        # directory in /tmp/Backup.
        cp $RepertoireSSL/*  $DirDeSauvegarde;
     
        # In the SSL Directory, we delete all the content.
        rm -rf $RepertoireSSL/*;
    
        # In the SSL Directory, we bring back the Diffie-Hellman exchange
        # key file "dhparam4096.pem".
        cp $DirDeSauvegarde/dhparam4096.pem $RepertoireSSL;
    
        # We copy the new Let's Encrypt files into the SSL Directory.
        # CERTIFICATE => .acme.sh: .cer => ssl: ispserver.crt.
        # PRIVATE KEY => .acme.sh: .key => ssl: ispserver.key.
        #INTERMEDIATE CERTIFICATE => .acme.sh: .key + .fullchain.cer => ispserver.pem.
        cp $RepertoireLE/$HostName.cer  $RepertoireSSL/ispserver.crt;
        cp $RepertoireLE/$HostName.key  $RepertoireSSL/ispserver.key;
        cat $RepertoireLE/$HostName.key $RepertoireLE/fullchain.cer > $RepertoireSSL/ispserver.pem;
    
        # We protect the PRIVATE KEY
        /usr/bin/chmod 600 $RepertoireSSL/ispserver.key
    
        # If the dhparam4096.pem file has been recovered,
        # we can delete the backup directory in /tmp.
        if [ -f $DirDeSauvegarde/dhparam4096.pem ]; then
            rm -rf $DirDeSauvegarde;
        else
            exit 1;
        fi
    
        # Warning message
        printf \\n"The command "reload.sh" may take a few seconds."\\n;
    
        # We launch the command to restart the server services.
    
        if [ $(dpkg-query -W -f='${Status}' pure-ftpd-mysql 2>/dev/null | grep -c "ok installed") -eq 1 ]; then service pure-ftpd-mysql restart; fi
        if [ $(dpkg-query -W -f='${Status}' monit 2>/dev/null | grep -c "ok installed") -eq 1 ]; then service monit restart; fi
        if [ $(dpkg-query -W -f='${Status}' postfix 2>/dev/null | grep -c "ok installed") -eq 1 ]; then service postfix restart; fi
        if [ $(dpkg-query -W -f='${Status}' dovecot-imapd 2>/dev/null | grep -c "ok installed") -eq 1 ]; then service dovecot restart; fi
        if [ $(dpkg-query -W -f='${Status}' mysql 2>/dev/null | grep -c "ok installed") -eq 1 ]; then service mysql restart; fi
        if [ $(dpkg-query -W -f='${Status}' mariadb 2>/dev/null | grep -c "ok installed") -eq 1 ]; then service mysql restart; fi
        if [ $(dpkg-query -W -f='${Status}' nginx 2>/dev/null | grep -c "ok installed") -eq 1 ]; then service nginx restart; fi
        if [ $(dpkg-query -W -f='${Status}' apache2 2>/dev/null | grep -c "ok installed") -eq 1 ]; then service apache2 restart; fi
    
        # All is done
        printf \\n"The new Let\'s Encrypt certificate for ISPconfig manager \nof the server \"$HostName\" was installed successfully."\\n\\n;
     
        exit 0;
    fi;
    
    ###############################################################################
    ###############################################################################
    
    #### Routine for managing website certificate files.
    # USAGE => /root/reload.sh  NomDuSiteWeb  NumeroDuClient NumeroDuWeb
    #
    # EXAMPLE:
    # /root/reload.sh /root/reload.sh toto.org client1 web1
    
    # Is this a certificate from a website if yes,
    # we check the existence of 3 arguments otherwise,
    # Exit the script indicating an error in its execution.
    if [ $# -eq 3 ]; then
        test=OK
        else
            echo -e \\n"The number of arguments is not correct" \\n;
            echo -e "USAGE: /root/test.sh  NomDuSiteWeb  NumeroDuClient NumeroDuWeb" \\n;
            # Exit the script indicating an error in its execution.
            exit 1;
    fi
    
    # Checking if the 2nd argument starts with "client".
    TEXTE=$2;
    PREFIXE=client;
    if [[ $TEXTE =~ ^"$PREFIXE" ]]; then
        test=OK
        else
            echo -e "The customer number does not begin with: \"client\", but by" \"$TEXTE\" \\n;
            echo -e "USAGE: /root/test.sh  NomDuSiteWeb  NumeroDuClient NumeroDuWeb" \\n;
            # Exit the script indicating an error in its execution.
            exit 1;
    fi
    
    if [ [$2] ]; then
        test=3
        else
            echo -e "USAGE: /root/test.sh  NomDuSiteWeb  NumeroDuClient NumeroDuWeb" \\n;
            # Exit the script indicating an error in its execution.
            exit 1;
    fi
    
    # Initialization of variables.
    HostName=$1;
    
    # The Let's Encrypt files directory.
    RepertoireLE=/root/.acme.sh/$HostName ;
    
    # Customer number.
    NoClient=$2;
    
    # Website number.
    NoWeb=$3;
    
    # Client Directory.
    RepertoireClient="/var/www/clients/$NoClient/$NoWeb/ssl" ;
    
    # We go to the website client certificate file directory.
    cd $RepertoireClient;
    
    #Content of the directory.
    ContenuDuRepClient=*.*;
    
    # We create a backup directory and save all the client certificate files in it.
    mkdir -p /tmp/Sauvegarde;
    cp $ContenuDuRepClient /tmp/Sauvegarde;
    
    # We delete the contents of the website's certificate directory.
    rm -rf $ContenuDuRepClient;
    
    ## Description of website certificate files.
    # toto.org.key    => toto.org.key
    # toto.org.csr    => toto.org.csr
    # fullchain.cer  +   ca.cer => toto.org.crt
    cp $RepertoireLE/$HostName.key  $RepertoireClient/'*.'$HostName.key
    cp $RepertoireLE/$HostName.csr  $RepertoireClient/'*.'$HostName.csr
    cat $RepertoireLE/fullchain.cer $RepertoireLE/ca.cer > $RepertoireClient/'*.'$HostName.crt
    
    # Warning message
    printf \\n"The command \"reload.sh\" may take a few seconds."\\n\\n;
    
    ## Command "reload"
    if [ $(dpkg-query -W -f='${Status}' pure-ftpd-mysql 2>/dev/null | grep -c "ok installed") -eq 1 ]; then service pure-ftpd-mysql restart; fi
    if [ $(dpkg-query -W -f='${Status}' monit 2>/dev/null | grep -c "ok installed") -eq 1 ]; then service monit restart; fi
    if [ $(dpkg-query -W -f='${Status}' postfix 2>/dev/null | grep -c "ok installed") -eq 1 ]; then service postfix restart; fi
    if [ $(dpkg-query -W -f='${Status}' dovecot-imapd 2>/dev/null | grep -c "ok installed") -eq 1 ]; then service dovecot restart; fi
    if [ $(dpkg-query -W -f='${Status}' mysql 2>/dev/null | grep -c "ok installed") -eq 1 ]; then service mysql restart; fi
    if [ $(dpkg-query -W -f='${Status}' mariadb 2>/dev/null | grep -c "ok installed") -eq 1 ]; then service mysql restart; fi
    if [ $(dpkg-query -W -f='${Status}' nginx 2>/dev/null | grep -c "ok installed") -eq 1 ]; then service nginx restart; fi
    if [ $(dpkg-query -W -f='${Status}' apache2 2>/dev/null | grep -c "ok installed") -eq 1 ]; then service apache2 restart; fi
    
    # All is done
    printf "The new Let\'s Encrypt certificate for the site \"$NoWeb\" of \"$NoClient\" \nof the domain \"$HostName\" was installed successfully."\\n\\n;
     
    exit 0;
    
    ###############################################################################
    ###############################################################################
    
    Any suggestion or comment appreciated,

    Michel-André
     
    Last edited: Jun 14, 2024

Share This Page