Possible to add a script to be executed before and after Certbot runs?

SYSTEM INFORMATION
OS type and version Redhat 9.4
Virtualmin version Virtualmin 7.20.2

I have a bash script that puts some iptables rules to block all server iPs in the world. i want the server to only be accessible from residential IPs. I also have a script that rmeoves those rules (basically iptables -A and iptables -D).

Since i still want to use LetsEncrypt, is it possible to make those scripts execute each time Virtualmin wants to renew a domain’s SSL (either automatically or manually)?

by default Virtualmin uses Firewalld, have you reconfigured for Iptables?

Why don’t you let Virtualmin fail the http validation of Let’s Encrypt and fall back to DNS validation? You have to do nothing to your firewall if you are using Virtualmin DNS server to manage DNS records for your domains.

I am using CloudFlare DNS, which is not included in the free Virtualmin.

I still need way to unblock servers during the check, as otherwise the issued SSL download will fail, no?

If Virtualmin DNS is not managing your domains and your firewall is blocking Let’s Encrypt http validation then, yes, SSL certificate requests will fail.

Yes, hence the question is:

stop firewall (i have script)
certbot …
start firewall (i have script)

Certbot has option to make hooks, how to make virtualmin use it for all vhosts (on creation, automatic renewal, manual renewal) etc.? Hope you understood.

Unless you put the cart before your metaphorical horse.

Instead of altering the firewall rules just before the Virtualmin triggers the Let’s Encrypt certificate renewal process on its own schedule, you could run a sequence of commands on a schedule of your own choosing to:

  1. change firewall rules
  2. renew SSL certificates
  3. change firewall rules again

And all this with the Virtualmin API!

I did too. We both had the same idea at almost the same time. :slight_smile:

I am little clueless how to use the API…

Suppose it can be made on a cron job every evening to check for what is expiring and run script… I am clueless to make the script interacting with the APIs…

See:

Also see:

It really surprises me that people expect a default install of virtualmin to do exactly what they need nor should they expect it. If somebody wants to ‘off road’ best they learn how to do it rather than saying virtualmin/webmin has a flaw

1 Like

If you meant me, i never expect Virtualmin to have what i asked for by default - hence the thread asks if it is possible to do what I need.

I am circling back to this due to forgetting some SSLs and I have a question:

I found this command that renews SSLs of virtualservers, which previously requested it with Virtualmin , made by @Ilia

doms=`virtualmin list-domains --name-only --with-feature letsencrypt_renew` ; for dom in $doms; do virtualmin generate-letsencrypt-cert --domain $dom --renew ; done

What I am wondering is, is there way to add a condition to the for dom in $doms cycle to only renew domains which have expired SSL cert ?

I will then put that into a .sh file:
/root/iptables-remove-rules.sh
doms=virtualmin list-domains --name-only --with-feature letsencrypt_renew ; for dom in $doms; do virtualmin generate-letsencrypt-cert --domain $dom --renew ; done
/root/iptables-put-rules.sh

And let that run daily. My other question is, since i would be then renewing SSLs this way, I guess it won’t conflict with the panel itself trying to renew them (or is there option to disable autorenewal from its side)?

Yes, especially if you combine it with virtualmin list-certs-expiry command, for example.

Can you help with the correct one-liner to only renew expired certs?

Don’t think you can, you would need to create a script.

Something like this?

#!/bin/bash

# Check if virtualmin command is available
if ! command -v virtualmin &> /dev/null
then
    echo "Virtualmin command not found. Make sure Virtualmin is installed and the 'virtualmin' command is in your PATH."
    exit 1
fi

# Get a list of all domains Virtualmin manages
domains=$(virtualmin list-domains --name-only --with-feature ssl)

# Loop through each domain and check if the SSL certificate is expired or close to expiring
for domain in $domains; do
    echo "Checking SSL certificate for domain: $domain"
    
    # Check if the certificate is expired or will expire within 30 days
    cert_info=$(virtualmin list-certs --domain "$domain" --multiline)
    expiry_date=$(echo "$cert_info" | grep "Expiry date" | awk '{print $3" "$4" "$5}')
    expiry_seconds=$(date -d "$expiry_date" +%s)
    current_seconds=$(date +%s)
    days_left=$(( ($expiry_seconds - $current_seconds) / 86400 ))

    # Renew the certificate if expired or expiring within 30 days
    if [ "$days_left" -le 30 ]; then
        echo "Renewing SSL certificate for domain: $domain (expires in $days_left days)"
        virtualmin generate-letsencrypt-cert --domain "$domain" --renew-only
        if [ $? -eq 0 ]; then
            echo "Successfully renewed SSL certificate for $domain"
        else
            echo "Failed to renew SSL certificate for $domain"
        fi
    else
        echo "SSL certificate for $domain is valid for $days_left more days. Skipping renewal."
    fi
done

echo "SSL renewal check complete."

1 Like