Netgate Discussion Forum
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Search
    • Register
    • Login

    Acme & cPanel/WHM

    Scheduled Pinned Locked Moved ACME
    3 Posts 1 Posters 903 Views
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • V
      VinzzB
      last edited by

      Hello,

      I am seeking for a way to automatically copy my Let's Encrypt certificate from my cPanel host to pfSense. cPanel does the auto-renewal for this (wildcard) certificate.
      I copied the certificate manually by opening a FTP session to my cPanel host and grabbing the lets-encrypt config file from my domain.
      The certificate data is stored as JSON in file /.cpanel/nvdata/letsencrypt-cpanel. This file holds every certificate requested by the Let's encrypt plugin in cPanel. I have manually extracted the private and public key (for my wildcard domain *.lan.domain.com) and inserted these in pfSense. This seems to work great. The router and even my captive portal have a valid certificate now. Great!

      Next step is to automate the renewal process... Do I need to write a pfSense plugin for this? Or am I overlooking something?
      I still have to figure out if I need to copy the private key again after a certificate renewal. I assume that the private key stays the same and I only need the public key to be renewed on pfSense. Which would be easier as I can grab this key from an https request.

      What would be the best option to automate these renewals with a host running on cPanel/WHM? Any advice?

      Sincerely yours, VinzzB

      1 Reply Last reply Reply Quote 0
      • V
        VinzzB
        last edited by

        I have never developed on freenas or pfSense before so i am searching for good (and easy) ways to accomplish my task.

        I just discovered the PHP shell and i made a small script to download the json file from my host. This seems to work just fine.
        Now i need to parse this json file and extract the necessary ssl keys (public/private/issuer). This should be an easy one. But the next step is still unknown territory for me.
        How can i replace a certificate in pfSense within this PHP shell?
        Can i run this script as a cronjob (including the php pfsense tools)?

        This is the code i have so far (downloading file through FTPS protocol):

        <?php
        $ftp_server = 'ftp.domain.com';
        $local_file = '/home/letsencrypt-cpanel';
        $server_file = '/.cpanel/nvdata/letsencrypt-cpanel';
        $ftp_user_name = 'username';
        $ftp_user_pass = 'password';
        $conn_id = ftp_ssl_connect($ftp_server);
        $login_result = ftp_login($conn_id, $ftp_user_name, $ftp_user_pass);
        ftp_pasv($conn_id, true);
        if (!$login_result)
            die("can't login");
        
        if (ftp_get($conn_id, $local_file, $server_file, FTP_BINARY))
            echo "Successfully written to $local_file\n";
        else
            echo "There was a problem\n";
        ftp_close($conn_id);
        

        I will update this post when i got more stuff working. (json parser, updating certs on pfsense)

        1 Reply Last reply Reply Quote 0
        • V
          VinzzB
          last edited by VinzzB

          I've completed my small php script and it seems to work well.
          This is the result in case anyone needs it:

          // -- CONFIG 
          $certname = 'lan.domain.com'; //a registered FQDN in cPanel with acme let's encrypt enabled (wildcard cert)
          $pfsense_cert_id = 1; // certificate id in pfsense to overwrite. (The correct ID can be found by hovering over an icon in the cert manager or by looking in the config file.
          $ftp_server = 'ftp.domain.com'; //ftps location to your domain (cpanel).
          $ftp_user_name = ''; 
          $ftp_user_pass = '';
          $server_file = '/.cpanel/nvdata/letsencrypt-cpanel'; //download file used by cPanel holding every certificate (in JSON format).
          
          // -- PROGRAM
          $conn_id = ftp_ssl_connect($ftp_server);
          $login_result = ftp_login($conn_id, $ftp_user_name, $ftp_user_pass);
          ftp_pasv($conn_id, true);
          if (!$login_result)
              die("can't login");
          
          ob_start();
          $dataLoaded = ftp_get($conn_id, "php://output", $server_file, FTP_BINARY);
          $data = ob_get_contents();
          ob_end_clean();
          ftp_close($conn_id);
          
          if (!$dataLoaded)
          	die("There was a problem downloading the json data from $ftp_server");
          
          $jsonData = json_decode($data, true);
          $cert = $jsonData['certs'][$certname];
          
          if(empty($cert))
          	die("Certificate with name $certname not found");
          
          $config['cert'][$pfsense_cert_id ]['prv'] = base64_encode($cert['key']);
          $config['cert'][$pfsense_cert_id ]['crt'] = base64_encode($cert['cert']);
          write_config();
          exec('/etc/rc.restart_webgui');
          
          //echo 'Certificate:', PHP_EOL, $cert['cert'], PHP_EOL;
          //echo 'Key:', PHP_EOL, $cert['key'], PHP_EOL;
          echo 'New certificate for ', $certname, ' is valid untill ', gmdate('r',$cert['cert_expiry']), PHP_EOL;
          exit;
          
          

          I've uploaded the file (named sslupdate) to the /etc/phpshellsessions directory in pfsense and I added the following cron job (through the cron package):

          0 0 1 1/3 * :  /usr/local/sbin/pfSsh.php playback sslupdate
          
          1 Reply Last reply Reply Quote 0
          • First post
            Last post
          Copyright 2025 Rubicon Communications LLC (Netgate). All rights reserved.