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

    Update SSL Certificate from command line

    Scheduled Pinned Locked Moved webGUI
    20 Posts 8 Posters 13.5k 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.
    • B
      bartgrefte
      last edited by bartgrefte

      Well, I ended up making a script of my own and it looks like I've got it working :) , but I'll check again once there's a newer wildcard certificate. The script I made assumes the current certificate and key are stored in text-files, encoded just like in config.xml. Using the contents of those files, a simple search and replace of the certificate and key can be done. There's no need to look for some kind of pattern in config.xml like the script from the other topic, it's just looking for two specific strings and replace them.

      For those who'd like to try it:

      #!/bin/bash
      host="ipaddress"
      username="username"
      password="password"
      certificate="certificate.pem"
      privatekey="privatekey.pem"
      oldcertificate=$(<certificate.crt.old.txt)
      oldprivatekey=$(<certificate.key.old.txt)
      
      mv $certificate $certificate.combo
      csplit -f $certificate.part $certificate.combo '/-----BEGIN CERTIFICATE-----/' '{*}'
      
      for file in $certificate.part*;
      do echo "Processing $file file..";
      output=$(openssl x509 -noout -subject -in $file);
      if [[ $output = *CN=*.* ]]
      then
              mv $file certificate.pem
      fi
      if [[ $output = *Authority* ]]
      then
              mv $file CA_LetsEncrypt.pem
      fi
      done
      
      cert=$(base64 $certificate)
      cert=$(echo $cert | sed "s/ //g")
      key=$(base64 $privatekey)
      key=$(echo $key | sed "s/ //g")
      
      sshpass -p $password scp $username@$host:/conf/config.xml config.xml
      
      if grep "$cert" config.xml > /dev/null
      then
          echo "Identical certificate found, renewal not required"
      else
          echo "Certificate not found, renewal required"
          sed -i -e "s|$oldcertificate|$cert|g" config.xml
          sed -i -e "s|$oldprivatekey|$key|g" config.xml
          echo $cert > certificate.crt.old.txt
          echo $key > certificate.key.old.txt
          sshpass -p $password scp config.xml $username@$host:/conf/config.xml
          sshpass -p $password ssh $username@$host rm /tmp/config.cache
          sshpass -p $password ssh $username@$host /etc/rc.restart_webgui
          find . -size  0 -name $certificate.part* -print0 |xargs -0 rm --
          rm $certificate.combo
          rm certificate.pem
          rm privatekey.pem
          rm CA_LetsEncrypt.pem
          rm config.xml
      fi
      
      
      L C 2 Replies Last reply Reply Quote 3
      • L
        luisenrique
        last edited by

        This post is deleted!
        1 Reply Last reply Reply Quote 0
        • L
          luisenrique @bartgrefte
          last edited by

          @bartgrefte said in Update SSL Certificate from command line:

          Well, I ended up making a script of my own and it looks like I've got it working :) , but I'll check again once there's a newer wildcard certificate. The script I made assumes the current certificate and key are stored in text-files, encoded just like in config.xml. Using the contents of those files, a simple search and replace of the certificate and key can be done. There's no need to look for some kind of pattern in config.xml like the script from the other topic, it's just looking for two specific strings and replace them.

          For those who'd like to try it:

          #!/bin/bash
          host="ipaddress"
          username="username"
          password="password"
          certificate="certificate.pem"
          privatekey="privatekey.pem"
          oldcertificate=$(<certificate.crt.old.txt)
          oldprivatekey=$(<certificate.key.old.txt)
          
          mv $certificate $certificate.combo
          csplit -f $certificate.part $certificate.combo '/-----BEGIN CERTIFICATE-----/' '{*}'
          
          for file in $certificate.part*;
          do echo "Processing $file file..";
          output=$(openssl x509 -noout -subject -in $file);
          if [[ $output = *CN=*.* ]]
          then
                  mv $file certificate.pem
          fi
          if [[ $output = *Authority* ]]
          then
                  mv $file CA_LetsEncrypt.pem
          fi
          done
          
          cert=$(base64 $certificate)
          cert=$(echo $cert | sed "s/ //g")
          key=$(base64 $privatekey)
          key=$(echo $key | sed "s/ //g")
          
          sshpass -p $password scp $username@$host:/conf/config.xml config.xml
          
          if grep "$cert" config.xml > /dev/null
          then
              echo "Identical certificate found, renewal not required"
          else
              echo "Certificate not found, renewal required"
              sed -i -e "s|$oldcertificate|$cert|g" config.xml
              sed -i -e "s|$oldprivatekey|$key|g" config.xml
              echo $cert > certificate.crt.old.txt
              echo $key > certificate.key.old.txt
              sshpass -p $password scp config.xml $username@$host:/conf/config.xml
              sshpass -p $password ssh $username@$host rm /tmp/config.cache
              sshpass -p $password ssh $username@$host /etc/rc.restart_webgui
              find . -size  0 -name $certificate.part* -print0 |xargs -0 rm --
              rm $certificate.combo
              rm certificate.pem
              rm privatekey.pem
              rm CA_LetsEncrypt.pem
              rm config.xml
          fi
          
          

          hi @bartgrefte , i had spent a lot time looking for something like that...
          the solution on that topic https://forum.netgate.com/topic/95774/automating-certificate-imports-with-letencrypt-script . not run for me too
          I have an enviroment similar, we generate certificates in a particular server but i need to copy them to another servers in cuestion, for example haproxy, captive portal(over pfsense) (on linux postfix, dovecot, apache webserver realy is easy to import/overwrite files directly and restart), and many others in my internal net without internet access on they, so the acme alone by command line i'm not shure if can be work on internal server and integrate it with the server were the certificate are beig generate.
          On pfsense all are in the xml config and here is were become more complex to me.

          Correctme please, at least to my understanding acme client go to internet letsencrypt services ...validate domain by any method and generate certificate if all are fine...it cam be integrate in same server with many services...,to here fine. ok so whats happend in another pfsense were wee need these certificate too?

          I found another small script writen in php wich it cam be import a certificate including the own system libraries of pfsense on it...
          https://github.com/zxsecurity/pfsense-import-certificate
          with some adjuntemens maby it can run that we wants..
          i had tested it in this afternoon but the name in description cam confuse to the other services because enter a name diferent each time certificate are imported with date time in name descritcion.. can u take a look at here
          tomorrow i will a test your script

          regards
          and sorry about my english

          B 1 Reply Last reply Reply Quote 0
          • B
            bartgrefte @luisenrique
            last edited by bartgrefte

            @luisenrique said in Update SSL Certificate from command line:

            Correctme please, at least to my understanding acme client go to internet letsencrypt services ...validate domain by any method and generate certificate if all are fine...it cam be integrate in same server with many services...,to here fine. ok so whats happend in another pfsense were wee need these certificate too?

            I am using a Raspberry Pi with certbot-auto to get a wildcard certificate, so it's valid for any device using my domainname. For example pfsense.domainname.com, switch.domainname.com and webmin.domainname.com to name some.

            The only device doing the validating is the Raspberry Pi, the certificate is copied from there. The devices using that certificate don't have to validate it because the Raspberry Pi has already done that.

            Once I got certbot-auto working, it's basically just a matter of copying and importing the certificate and key from (in my case) the Raspberry Pi to other devices.

            If you've got another pfSense install, just modify the script to connect to that one.

            L 1 Reply Last reply Reply Quote 0
            • L
              luisenrique @bartgrefte
              last edited by

              @bartgrefte said in Update SSL Certificate from command line:

              Once I got certbot-auto working, i

              Hi i was testing u script last friday so i geting somes issues, tomorrow i will tell exactly.. i'm at home rigth now.
              I really do not understand at all, in all or almost all the post I read that acme package does the job of importing the certificate, but my other devices are without connection to the internet, some think like you are describe. it is clear to me that those options are there in the code of acme package to import it into the pfsense interface, but the question would be that parameter is passed for the case that is not to validate or renew the certificate and this only download or copy from or to another devise without internet conection like internal intranet.
              thanks.

              1 Reply Last reply Reply Quote 0
              • M
                marksantos
                last edited by

                how about, installing ssl cert in debian os

                1 Reply Last reply Reply Quote 0
                • C
                  Callan05 @bartgrefte
                  last edited by

                  @bartgrefte HI Bart, is this still your latest version of this script?
                  I just installed a LE wildcart cert manually into PFSense and would like to automate this from my other machine where the LE client runs.

                  Thanks,
                  Callan

                  B 2 Replies Last reply Reply Quote 0
                  • B
                    bartgrefte @Callan05
                    last edited by

                    @Callan05 said in Update SSL Certificate from command line:

                    @bartgrefte HI Bart, is this still your latest version of this script?
                    I just installed a LE wildcart cert manually into PFSense and would like to automate this from my other machine where the LE client runs.

                    Thanks,
                    Callan

                    Yep, it is, haven't had the need to change it. Still works :)

                    1 Reply Last reply Reply Quote 1
                    • B
                      bartgrefte @Callan05
                      last edited by bartgrefte

                      @Callan05 I updated the script a little bit, now it's no longer necessary to look up the old certificate and key, the script does that itself :) One thing needs to be checked, the name of the certificate to replace in pfSense, in this script the name contains "WebConfCA". If it's called different, that needs to be replaced.

                      #!/bin/bash
                      host="ipaddress"
                      username="username"
                      password="password"
                      certificate="certificate.pem"
                      privatekey="privatekey.pem"
                      
                      mv $certificate $certificate.combo
                      csplit -f $certificate.part $certificate.combo '/-----BEGIN CERTIFICATE-----/' '{*}'
                      
                      for file in $certificate.part*;
                      do echo "Processing $file file..";
                      output=$(openssl x509 -noout -subject -in $file);
                      if [[ $output = *CN*=*.* ]]
                      then
                              mv $file certificate.pem
                      fi
                      if [[ $output = *Authority* ]]
                      then
                              mv $file CA_LetsEncrypt.pem
                      fi
                      done
                      
                      cert=$(base64 $certificate)
                      cert=$(echo $cert | sed "s/ //g")
                      key=$(base64 $privatekey)
                      key=$(echo $key | sed "s/ //g")
                      
                      sshpass -p $password scp $username@$host:/conf/config.xml config.xml
                      oldcertificate=$(grep -A4 -P 'WebConfCA' config.xml | awk '/<crt>/ { print $1}' | sed "s|<crt>||g" | sed "s|</crt>||g")
                      oldprivatekey=$(grep -A4 -P 'WebConfCA' config.xml | awk '/<prv>/ { print $1}' | sed "s|<prv>||g" | sed "s|</prv>||g")
                      
                      if grep "$cert" config.xml > /dev/null
                      then
                          echo "Identical certificate found, renewal not required"
                      else
                          echo "Certificate not found, renewal required"
                          sed -i -e "s|$oldcertificate|$cert|g" config.xml
                          sed -i -e "s|$oldprivatekey|$key|g" config.xml
                          sshpass -p $password scp config.xml $username@$host:/conf/config.xml
                          sshpass -p $password ssh $username@$host rm /tmp/config.cache
                          sshpass -p $password ssh $username@$host /etc/rc.restart_webgui
                          find . -size  0 -name $certificate.part* -print0 |xargs -0 rm --
                          rm $certificate.combo
                          rm certificate.pem
                          rm privatekey.pem
                          rm CA_LetsEncrypt.pem
                          rm config.xml
                      fi
                      
                      
                      1 Reply Last reply Reply Quote 0
                      • B
                        bitranox
                        last edited by

                        While the proposed solutions here involve directly editing the /conf/config.xml file with scripts, it is important to note that modifying the /conf/config.xml file directly is a delicate operation and should be approached with caution.
                        If you choose to install such scripts, be sure to create a backup of the /conf/config.xml file before making any changes.

                        I had a similar task to install tailscale certificates on the pfSense firewall and created some scripts to import that certificates on pfSense, using acme-command.sh of the acme package.

                        Github Repository

                        I might extend that repository with the great ideas and examples of that thread on demand.

                        1 Reply Last reply Reply Quote 0
                        • First post
                          Last post
                        Copyright 2025 Rubicon Communications LLC (Netgate). All rights reserved.