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

Acme & cPanel/WHM

ACME
1
3
848
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 Aug 18, 2019, 7:34 PM

    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 Aug 19, 2019, 6:32 PM

      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 Aug 23, 2019, 10:36 AM Aug 23, 2019, 9:26 AM

        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
        3 out of 3
        • First post
          3/3
          Last post
        Copyright 2025 Rubicon Communications LLC (Netgate). All rights reserved.