{"id":3193,"date":"2020-04-10T02:10:41","date_gmt":"2020-04-10T07:10:41","guid":{"rendered":"http:\/\/www.incredigeek.com\/home\/?p=3193"},"modified":"2020-04-10T02:10:41","modified_gmt":"2020-04-10T07:10:41","slug":"auto-renew-ssl-cert-with-unifi-running-in-docker","status":"publish","type":"post","link":"https:\/\/www.incredigeek.com\/home\/auto-renew-ssl-cert-with-unifi-running-in-docker\/","title":{"rendered":"Auto renew SSL Cert with UniFi running in Docker"},"content":{"rendered":"\n<p>Setting up the SSL cert for UniFi service when running in docker is fairly easy to do.  All you have to do is modify the <a href=\"https:\/\/www.incredigeek.com\/home\/auto-renew-ssl-cert-for-unifi-and-unifi-video\/\">UniFi SSL renew script<\/a> to use the UniFi Docker directory and change the start and stop service to start and stop the Docker container.  The script below should be ready to go.  <\/p>\n\n\n\n<p>Download, chmod +x it, and run, drop it in cron to auto renew.<\/p>\n\n\n\n<p>In the below script, change (unifiDir=&#8221;\/docker\/unifi&#8221;) to your UniFi directory.<\/p>\n\n\n\n<p>Note: this triggers calling the teams.sh script that will send an update to Microsoft Teams to let you know that the certs should be renewed.  Check here for more <a href=\"https:\/\/www.incredigeek.com\/home\/bash-script-to-send-messages-to-microsoft-teams\/\">info<\/a>.<\/p>\n\n\n\n<div style=\"height: 250px; position:relative; margin-bottom: 50px;\" class=\"wp-block-simple-code-block-ace\"><pre class=\"wp-block-simple-code-block-ace\" style=\"position:absolute;top:0;right:0;bottom:0;left:0\" data-mode=\"php\" data-theme=\"monokai\" data-fontsize=\"14\" data-lines=\"Infinity\" data-showlines=\"true\" data-copy=\"false\">#!\/usr\/bin\/env bash\n# Added support to do UniFi and UniFi controllers at the same time using the same cert.\n# Original script from https:\/\/git.sosdg.org\/brielle\/lets-encrypt-scripts\/raw\/branch\/master\/gen-unifi-cert.sh\n# More info here https:\/\/www.reddit.com\/r\/Ubiquiti\/comments\/43v23u\/using_letsencrypt_with_the_unifi_controller\/ \n# And here https:\/\/www.reddit.com\/r\/Ubiquiti\/comments\/43v23u\/using_letsencrypt_with_the_unifi_controller\/\n# Modified script from here: https:\/\/github.com\/FarsetLabs\/letsencrypt-helper-scripts\/blob\/master\/letsencrypt-unifi.sh\n# Modified by: Brielle Bruns &lt;bruns@2mbit.com>\n# Download URL: https:\/\/source.sosdg.org\/brielle\/lets-encrypt-scripts\n# Version: 1.7\n# Last Changed: 04\/10\/2020\n# 04\/10\/2020: Changed directories and commands to work with a UniFi Docker install\n# 02\/02\/2016: Fixed some errors with key export\/import, removed lame docker requirements\n# 02\/27\/2016: More verbose progress report\n# 03\/08\/2016: Add renew option, reformat code, command line options\n# 03\/24\/2016: More sanity checking, embedding cert\n# 10\/23\/2017: Apparently don't need the ace.jar parts, so disable them\n# 02\/04\/2018: LE disabled tls-sni-01, so switch to just tls-sni, as certbot 0.22 and later automatically fall back to http\/80 for auth\n# 05\/29\/2018: Integrate patch from Donald Webster &lt;fryfrog[at]gmail.com> to cleanup and improve tests\n# 09\/26\/2018: Change from TLS to HTTP authenticator\n\n# Location of LetsEncrypt binary we use.  Leave unset if you want to let it find automatically\n# LEBINARY=\"\/usr\/src\/letsencrypt\/certbot-auto\"\n\n# Change to your UniFi Docker directory\nunifiDir=\"\/docker\/unifi\"\n\nPATH=\"\/usr\/local\/sbin:\/usr\/local\/bin:\/usr\/sbin:\/usr\/bin:\/sbin:\/bin\"\n\nfunction usage() {\n  echo \"Usage: $0 -d &lt;domain> [-e &lt;email>] [-r] [-i]\"\n  echo \"  -d &lt;domain>: The domain name to use.\"\n  echo \"  -e &lt;email>: Email address to use for certificate.\"\n  echo \"  -r: Renew domain.\"\n  echo \"  -i: Insert only, use to force insertion of certificate.\"\n}\n\nwhile getopts \"hird:e:\" opt; do\n  case $opt in\n    i) onlyinsert=\"yes\";;\n    r) renew=\"yes\";;\n    d) domains+=(\"$OPTARG\");;\n    e) email=\"$OPTARG\";;\n    h) usage\n       exit;;\n  esac\ndone\n\nDEFAULTLEBINARY=\"\/usr\/bin\/certbot \/usr\/bin\/letsencrypt \/usr\/sbin\/certbot\n  \/usr\/sbin\/letsencrypt \/usr\/local\/bin\/certbot \/usr\/local\/sbin\/certbot\n  \/usr\/local\/bin\/letsencrypt \/usr\/local\/sbin\/letsencrypt\n  \/usr\/src\/letsencrypt\/certbot-auto \/usr\/src\/letsencrypt\/letsencrypt-auto\n  \/usr\/src\/certbot\/certbot-auto \/usr\/src\/certbot\/letsencrypt-auto\n  \/usr\/src\/certbot-master\/certbot-auto \/usr\/src\/certbot-master\/letsencrypt-auto\"\n\nif [[ ! -v LEBINARY ]]; then\n  for i in ${DEFAULTLEBINARY}; do\n    if [[ -x ${i} ]]; then\n      LEBINARY=${i}\n      echo \"Found LetsEncrypt\/Certbot binary at ${LEBINARY}\"\n      break\n    fi\n  done\nfi\n\n# Command line options depending on New or Renew.\nNEWCERT=\"--renew-by-default certonly\"\nRENEWCERT=\"-n renew\"\n\n# Check for required binaries\nif [[ ! -x ${LEBINARY} ]]; then\n  echo \"Error: LetsEncrypt binary not found in ${LEBINARY} !\"\n  echo \"You'll need to do one of the following:\"\n  echo \"1) Change LEBINARY variable in this script\"\n  echo \"2) Install LE manually or via your package manager and do #1\"\n  echo \"3) Use the included get-letsencrypt.sh script to install it\"\n  exit 1\nfi\n\nif [[ ! -x $( which keytool ) ]]; then\n  echo \"Error: Java keytool binary not found.\"\n  exit 1\nfi\n\nif [[ ! -x $( which openssl ) ]]; then\n  echo \"Error: OpenSSL binary not found.\"\n  exit 1\nfi\n\nif [[ ! -z ${email} ]]; then\n  email=\"--email ${email}\"\nelse\n  email=\"\"\nfi\n\nshift $((OPTIND -1))\nfor val in \"${domains[@]}\"; do\n        DOMAINS=\"${DOMAINS} -d ${val} \"\ndone\n\nMAINDOMAIN=${domains[0]}\n\nif [[ -z ${MAINDOMAIN} ]]; then\n  echo \"Error: At least one -d argument is required\"\n  usage\n  exit 1\nfi\n\nif [[ ${renew} == \"yes\" ]]; then\n  LEOPTIONS=\"${RENEWCERT}\"\nelse\n  LEOPTIONS=\"${email} ${DOMAINS} ${NEWCERT}\"\nfi\n\nif [[ ${onlyinsert} != \"yes\" ]]; then\n  echo \"Firing up standalone authenticator on TCP port 80 and requesting cert...\"\n  ${LEBINARY} --server https:\/\/acme-v01.api.letsencrypt.org\/directory \\\n              --agree-tos --standalone --preferred-challenges http ${LEOPTIONS}\nfi\n\nif [[ ${onlyinsert} != \"yes\" ]] &amp;&amp; md5sum -c \"\/etc\/letsencrypt\/live\/${MAINDOMAIN}\/cert.pem.md5\" &amp;>\/dev\/null; then\n  echo \"Cert has not changed, not updating controller.\"\n  exit 0\nelse\n  echo \"Cert has changed or -i option was used, updating controller...\"\n  TEMPFILE=$(mktemp)\n  CATEMPFILE=$(mktemp)\n\n  # Identrust cross-signed CA cert needed by the java keystore for import.\n  # Can get original here: https:\/\/www.identrust.com\/certificates\/trustid\/root-download-x3.html\n  cat > \"${CATEMPFILE}\" &lt;&lt;'_EOF'\n-----BEGIN CERTIFICATE-----\nMIIDSjCCAjKgAwIBAgIQRK+wgNajJ7qJMDmGLvhAazANBgkqhkiG9w0BAQUFADA\/\nMSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT\nDkRTVCBSb290IENBIFgzMB4XDTAwMDkzMDIxMTIxOVoXDTIxMDkzMDE0MDExNVow\nPzEkMCIGA1UEChMbRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3QgQ28uMRcwFQYDVQQD\nEw5EU1QgUm9vdCBDQSBYMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB\nAN+v6ZdQCINXtMxiZfaQguzH0yxrMMpb7NnDfcdAwRgUi+DoM3ZJKuM\/IUmTrE4O\nrz5Iy2Xu\/NMhD2XSKtkyj4zl93ewEnu1lcCJo6m67XMuegwGMoOifooUMM0RoOEq\nOLl5CjH9UL2AZd+3UWODyOKIYepLYYHsUmu5ouJLGiifSKOeDNoJjj4XLh7dIN9b\nxiqKqy69cK3FCxolkHRyxXtqqzTWMIn\/5WgTe1QLyNau7Fqckh49ZLOMxt+\/yUFw\n7BZy1SbsOFU5Q9D8\/RhcQPGX69Wam40dutolucbY38EVAjqr2m7xPi71XAicPNaD\naeQQmxkqtilX4+U9m5\/wAl0CAwEAAaNCMEAwDwYDVR0TAQH\/BAUwAwEB\/zAOBgNV\nHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFMSnsaR7LHH62+FLkHX\/xBVghYkQMA0GCSqG\nSIb3DQEBBQUAA4IBAQCjGiybFwBcqR7uKGY3Or+Dxz9LwwmglSBd49lZRNI+DT69\nikugdB\/OEIKcdBodfpga3csTS7MgROSR6cz8faXbauX+5v3gTt23ADq1cEmv8uXr\nAvHRAosZy5Q6XkjEGB5YGV8eAlrwDPGxrancWYaLbumR9YbK+rlmM6pZW87ipxZz\nR8srzJmwN0jP41ZL9c8PDHIyh8bwRLtTcm1D9SZImlJnt1ir\/md2cXjbDaJWFBM5\nJDGFoqgCWjBH4d1QB7wCCZAA62RjYJsWvIjJEubSfZGL+T0yjWW06XyxV3bqxbYo\nOb8VZRzI9neWagqNdwvYkQsEjgfbKbYK7p2CNTUQ\n-----END CERTIFICATE-----\n_EOF\n\n  md5sum \"\/etc\/letsencrypt\/live\/${MAINDOMAIN}\/cert.pem\" > \"\/etc\/letsencrypt\/live\/${MAINDOMAIN}\/cert.pem.md5\"\n  echo \"Using openssl to prepare certificate...\"\n  cat \"\/etc\/letsencrypt\/live\/${MAINDOMAIN}\/chain.pem\" >> \"${CATEMPFILE}\"\n  openssl pkcs12 -export  -passout pass:aircontrolenterprise \\\n          -in \"\/etc\/letsencrypt\/live\/${MAINDOMAIN}\/cert.pem\" \\\n          -inkey \"\/etc\/letsencrypt\/live\/${MAINDOMAIN}\/privkey.pem\" \\\n          -out \"${TEMPFILE}\" -name unifi \\\n          -CAfile \"${CATEMPFILE}\" -caname root\n\n  docker container stop ${dockerContainerId}\n  sleep 10\n  dockerContainerId=$(sudo docker container list | grep unifi-controller | awk '{print $1}')\n  echo \"Removing existing certificate from Unifi protected keystore...\"\n  keytool -delete -alias unifi -keystore ${unifiDir}\/keystore -deststorepass aircontrolenterprise\n\n  echo \"Inserting certificate into Unifi keystore...\"\n  keytool -trustcacerts -importkeystore \\\n          -deststorepass aircontrolenterprise \\\n          -destkeypass aircontrolenterprise \\\n          -destkeystore ${unifiDir}\/keystore \\\n          -srckeystore \"${TEMPFILE}\" -srcstoretype PKCS12 \\\n          -srcstorepass aircontrolenterprise \\\n          -alias unifi\n\n  sleep 2\n  echo \"Starting Unifi controllers...\"\n  docker container start ${dockerContainerId}\n  .\/teams.sh -b \"$(hostname) - UniFi service is restarting, ssl cert should be renewed.\"\n\n  echo \"Done!\"\nfi\n<\/pre><\/div>\n\n\n\n<div class=\"wp-block-group\"><div class=\"wp-block-group__inner-container is-layout-flow wp-block-group-is-layout-flow\">\n<pre class=\"wp-block-code\"><code><\/code><\/pre>\n<\/div><\/div>\n","protected":false},"excerpt":{"rendered":"<p>Setting up the SSL cert for UniFi service when running in docker is fairly easy to do. All you have to do is modify the UniFi SSL renew script to use the UniFi Docker directory and change the start and &hellip; <a href=\"https:\/\/www.incredigeek.com\/home\/auto-renew-ssl-cert-with-unifi-running-in-docker\/\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[129,370],"tags":[246,357,356,188],"class_list":["post-3193","post","type-post","status-publish","format-standard","hentry","category-ubiquiti","category-unifi-video","tag-docker","tag-https","tag-ssl","tag-unifi"],"_links":{"self":[{"href":"https:\/\/www.incredigeek.com\/home\/wp-json\/wp\/v2\/posts\/3193","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.incredigeek.com\/home\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.incredigeek.com\/home\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.incredigeek.com\/home\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.incredigeek.com\/home\/wp-json\/wp\/v2\/comments?post=3193"}],"version-history":[{"count":3,"href":"https:\/\/www.incredigeek.com\/home\/wp-json\/wp\/v2\/posts\/3193\/revisions"}],"predecessor-version":[{"id":3213,"href":"https:\/\/www.incredigeek.com\/home\/wp-json\/wp\/v2\/posts\/3193\/revisions\/3213"}],"wp:attachment":[{"href":"https:\/\/www.incredigeek.com\/home\/wp-json\/wp\/v2\/media?parent=3193"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.incredigeek.com\/home\/wp-json\/wp\/v2\/categories?post=3193"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.incredigeek.com\/home\/wp-json\/wp\/v2\/tags?post=3193"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}