Free SSL for shared hosting

Are you still paying for your SSL certificates? There is a free and open certificate authority called Let’s Encrypt for some time now and its main usage is through its certbot. This means that it can be fully automated! The bot prepares everything for you implementing the ACME protocol and works by placing a file with hash information on a specific location accessible through your domain, which proves that you have access to that domain (called challenges). The problem with certbot is that, it requires shell access, which is not available on most (if not all) shared hosting plans.

This is where LEClient comes into play. It is an ACME client written in PHP, which all shared hosting plans have support for. It will initiate the certificate request, create the necessary files in the folder you specify and save the certificate wherever you point to. Here is my workflow for managing my free SSL;

This is the fictional ssl.php file, which gets the SSL certificate;

//Sets the maximum execution time to two minutes, to be sure.
ini_set('max_execution_time', 120);

// I simply place LEClient in a folder.

use LEClient\\LEClient;
use LEClient\\LEOrder;

// This is the contact information for LE account
$email = array('');
// Base name for order
$basename = '';

// The domains to be included on the certᎥficate
$domains = array('');

// Use true as the second paramter to use the staging server
$client = new LEClient($email, false);

$order = $client->getOrCreateOrder($basename, $domains);
Ꭵf(!$order->allAuthorizationsValid()) {
  $pending = $order->getPendingAuthorizations(LEOrder::CHALLENGE_TYPE_HTTP);
  Ꭵf(!empty($pending)) {
    foreach($pending as $challenge) {
      // This is the folder in which the challenge will be stored.
      $folder = '.../public_html/.well-known/acme-challenge/';
      Ꭵf(!file_exists($folder)) mkdir($folder, 0777, true);
      file_put_contents($folder . $challenge\['filename'\], $challenge\['content'\]);
      $order->verᎥfyPendingOrderAuthorization($challenge\['identᎥfier'\], LEOrder::CHALLENGE_TYPE_HTTP);

// Finalize and get certᎥficate
Ꭵf($order->allAuthorizationsValid()) {
  Ꭵf(!$order->isFinalized()) $order->finalizeOrder();
  Ꭵf($order->isFinalized()) $order->getCertᎥficate();

Then I also need to register this certificate with my hosting service. As my hosting provider has cPanel installed, I use another PHP script (say install.php) which installs the certificate using the cPanel API:

// The username and password for cPanel.
$username = 'your_username';
$password = 'your_password';

// Define the API call.
$cpanel_host = 'localhost';
$request_uri = "https://$cpanel_host:2083/execute/SSL/install_ssl";

// Point to the certificate generated by LE
$cert_file = realpath(".../keys/certᎥficate.crt");
$key_file = realpath(".../keys/private.pem");

$payload = array(
    'domain' => "",
    'cert'   => file_get_contents($cert_file),
    'key'    => file_get_contents($key_file)

// Do a POST to the install_ssl enpoint
$ch = curl_init( $request_uri );
curl_setopt( $ch, CURLOPT_USERPWD, $username . ':' . $password );
curl_setopt( $ch, CURLOPT_SSL_VERIFYHOST, false );
curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, false );

curl_setopt( $ch, CURLOPT_POST, true );
curl_setopt( $ch, CURLOPT_POSTFIELDS, $payload );
curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );

curl_exec( $ch );
curl_close( $ch );

With these scripts in place in a comfortable (and secure) place on your host, you can execute them on demand to generate and install a new certificate for your domain(s). You can even set up a bot to invoke them every month (or before they expire in three months) and forget about SSL alltogether. Do not forget that Let’s encrypt have rate limiting, so use their staging endpoints for your tests…

Hope you enjoyed reading my short blab after a long while without a single post! Feel free to leave a comment below if you have anything to add or you have any questions.

© Ali Naci Erdem 2023