-
-
Notifications
You must be signed in to change notification settings - Fork 717
Import from official letsencrypt client
The scripts below have been written back when dehydrated was new and lacked a lot of functionality. They are not maintained anymore and may or may not work with current version of certbot and dehydrated.
If you want to import your existing certificates from the official letsencrypt client place this script next to dehydrated
and run it.
You may want to check if dehydrated
is working and all paths are set correctly.
By default it will copy the certificates to the certs/
directory next to dehydrated
.
#!/usr/bin/env bash
set -e
set -u
set -o pipefail
umask 077 # paranoid umask, we're creating private keys
SCRIPTDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
BASEDIR="${SCRIPTDIR}"
LETSENCRYPT="/etc/letsencrypt"
eval "$("${SCRIPTDIR}/dehydrated" --env)"
if [[ ! -e "${LETSENCRYPT}" ]]; then
echo "No existing letsencrypt files found."
exit 1
fi
if [[ -e "${BASEDIR}/domains.txt" ]]; then
DOMAINS_TXT="${BASEDIR}/domains.txt"
elif [[ -e "${SCRIPTDIR}/domains.txt" ]]; then
DOMAINS_TXT="${SCRIPTDIR}/domains.txt"
else
echo "You have to create a domains.txt file listing the domains you want certificates for. Have a look at domains.txt.example."
echo "For the purpose of this import script the file can be empty, but it has to exist."
exit 1
fi
for certdir in "${LETSENCRYPT}/live/"*; do
domain="$(basename "${certdir}")"
echo "Processing ${domain}"
# Check if we already have a certificate for the same (main) domain
if [ -e "${BASEDIR}/certs/${domain}" ]; then
echo " + Skipping: Found existing certificate directory, don't want to delete anything."
continue
fi
# Check if private-key, certificate, chain and fullchain exist
if [[ ! -e "${certdir}/privkey.pem" ]]; then
echo " + Skipping: Private key is missing."
continue
fi
if [[ ! -e "${certdir}/cert.pem" ]]; then
echo " + Skipping: Certificate is missing."
continue
fi
if [[ ! -e "${certdir}/chain.pem" ]]; then
echo " + Skipping: Chain is missing."
continue
fi
if [[ ! -e "${certdir}/fullchain.pem" ]]; then
echo " + Skipping: Fullchain is missing."
continue
fi
# Check if certificate still valid
if ! openssl x509 -checkend 0 -noout -in "${certdir}/cert.pem" >/dev/null 2>&1; then
echo " + Skipping: Certificate is expired."
continue
fi
# Import certificate
timestamp="$(date +%s)"
echo " + Adding list of domains to ${DOMAINS_TXT}"
SAN="$(openssl x509 -in "${certdir}/cert.pem" -noout -text | grep -A1 "Subject Alternative Name" | grep "DNS")"
SAN="${SAN//DNS:/}"
SAN="${SAN//, / }"
altnames="${domain}"
for altname in ${SAN}; do
if [[ ! "${altname}" = "${domain}" ]]; then
altnames="${altnames} ${altname}"
fi
done
echo "${altnames}" >> "${DOMAINS_TXT}"
mkdir -p "${BASEDIR}/certs/${domain}"
echo " + Importing private key"
cat "${certdir}/privkey.pem" > "${BASEDIR}/certs/${domain}/privkey-${timestamp}.pem"
ln -s "privkey-${timestamp}.pem" "${BASEDIR}/certs/${domain}/privkey.pem"
echo " + Importing certificate"
cat "${certdir}/cert.pem" > "${BASEDIR}/certs/${domain}/cert-${timestamp}.pem"
ln -s "cert-${timestamp}.pem" "${BASEDIR}/certs/${domain}/cert.pem"
echo " + Importing chain"
cat "${certdir}/chain.pem" > "${BASEDIR}/certs/${domain}/chain-${timestamp}.pem"
ln -s "chain-${timestamp}.pem" "${BASEDIR}/certs/${domain}/chain.pem"
echo " + Importing fullchain"
cat "${certdir}/fullchain.pem" > "${BASEDIR}/certs/${domain}/fullchain-${timestamp}.pem"
ln -s "fullchain-${timestamp}.pem" "${BASEDIR}/certs/${domain}/fullchain.pem"
done
If for any reason you want to import your existing account key from the official letsencrypt client place this perl script next to private_key.json
(should be in a subdirectory under /etc/letsencrypt/accounts/acme-v01.api.letsencrypt.org/directory
) and run it.
It should return your private key in PEM format, which you can pipe directly into private_key.pem
.
#!/usr/bin/env perl
use strict;
use Crypt::OpenSSL::RSA;
use Crypt::OpenSSL::Bignum;
use JSON;
use File::Slurp;
use MIME::Base64;
my $json_file = "private_key.json";
my $json_content = read_file($json_file);
$json_content =~ tr/-/+/;
$json_content =~ tr/_/\//;
my $json = decode_json($json_content);
my $n = Crypt::OpenSSL::Bignum->new_from_bin(decode_base64($json->{n}));
my $e = Crypt::OpenSSL::Bignum->new_from_bin(decode_base64($json->{e}));
my $d = Crypt::OpenSSL::Bignum->new_from_bin(decode_base64($json->{d}));
my $p = Crypt::OpenSSL::Bignum->new_from_bin(decode_base64($json->{p}));
my $q = Crypt::OpenSSL::Bignum->new_from_bin(decode_base64($json->{q}));
my $rsa = Crypt::OpenSSL::RSA->new_key_from_parameters($n, $e, $d, $p, $q);
print($rsa->get_private_key_string());