Tag Archives: certificates

Notes for a 2-Tier Microsoft Windows PKI

This posting is ~3 years years old. You should keep this in mind. IT is a short living business. This information might be outdated.

Implementing a public key infrastructure (PKI) is a recurring task for me. More and more customers tend to implement a PKI in their environment. Mostly not to increase security, rather then to get rid of browser warnings because of self-signed certificates, to secure intra-org email communication with S/MIME, or to sign Microsoft Office macros.

tumbledore / pixabay.com/ Pixybay License

What is a 2-tier PKI?

Why is a multi-tier PKI hierarchy a good idea? Such a hierarchy typically consits of a root Certificate Authority (CA), and an issuing CA. Sometimes you see a 3-tier hierarchy, in which a root CA, a sub CA and an issuing CA are tied together in a chain of trust.

A root CA issues, stores and signs the digital certificates for sub CA. A sub CA issues, stores and signs the digital certificates for issuing CA. Only an issuing CA issues, stores and signs the digital certificates for users and devices.

In a 2-tier hierarchy, a root CA issues the certificate for an issuing CA.

In case of security breach, in which the issuing CA might become compromised, only the CA certificate for the issuing CA needs to be revoked. But what of the root CA becomes compromised? Because of this, a root CA is typically installed on a secured, and powered-off (offline) VM or computer. It will only be powered-on to publish new Certificate Revocation Lists (CRL), or to sign/ renew a new sub or issuing CA certificate.

Lessons learned

Think about the processes! Creating a PKI is more than provisioning a couple of VMs. You need to think about processes to

  • request
  • sign, and
  • revoke

Be aware of what a digital certificate is. You, or your CA, confirms the identity of a party by handing out a digital certificate. Make sure that no one can issue certificates without a proof of his identity.

Think about lifetimes of certificates! Customers tend to create root CA certificates with lifetimes of 10, 20 or even 40 years. Think about the typical lifetime of a VM or server, which is necessary to run an offline root CA. Typically the server OS has a lifetime of 10 to 12 years. This should determine the lifetime of a root CA certificate. IMHO 10 years is a good compromise.

For a sub or issuing CA, a lifespan of 5 years is a good compromise. Using the same lifetime as for a root CA is not a good idea, because an issued certificate can’t be longer valid than the lifetime of the CA certificate of the issuing CA.

A lifespan of 1 to 3 years for thinks like computer or web server certificates is okay. If a certificate is used for S/MIME or code signing, you should go for a lifetime of 1 year.

But to be honest: At the end of the day, YOU decide how long your certificates will be valid.

Publish CRLs and make them accessable! You can’t know if a certificate is revoked by a CA. But you can use a CRL to check if a certificate is revoked. Because of this, the CA must publish CRLs regulary. Use split DNS to use the same URL for internal and external requests. Make sure that the CRL is available for external users.

This applies not only to certificates for users or computers, but also for sub and issuing CAs. So there must be a CRL from each of your CAs!

I recommend to publish CRLs to a webserver and make this webserver reachable over HTTP. An issued certificate includes the URL or path to the CRL of the CA, that has issued the certificate.

Make sure that the CRL has a meaningful validity period. Of an offline root CA, which issues only a few certificates of its lifetime, this can be 1 year or more. For an issuing CA, the validity period should only a few days.

Publish AIA (Authority Information Access) information and make them accessable! AIA is an certificate extension that is used to offer two types of information :

  • How to get the certificate of the issuing or upper CAs, and
  • who is the OCSP responder from where revocation of this certificate can be checked

I tend to use the same place for the AIA as for the CDP. Make sure that you configure the AIA extension before you issue the first certificates, especially configure the AIA and CDP extension before you issue intermediate and issuing CA certificates.

Use a secure hash algorithm and key length! Please stop using SHA1! I recommend at least SHA256 and 4096 bit key length. Depending on the used CPUs, SHA512 can be faster than SHA256.

Create a CApolicy.inf! The CApolicy.inf is located uder C:\Windows and will will be used during the creation of the CA certificate. I often use this CApolicy.inf files.

For the root CA:

[Certsrv_Server]
RenewalKeyLength = 4096
RenewalValidityPeriod = Years
RenewalValidityPeriodUnits = 10
AlternateSignatureAlgorithm = 0
CNGHashAlgorithm = SHA512
CRLPeriod = years
CRLPeriodUnits = 1

For the issuing CA:

[Certsrv_Server]
RenewalKeyLength = 4096
RenewalValidityPeriod = Years
RenewalValidityPeriodUnits = 5
AlternateSignatureAlgorithm = 0
CNGHashAlgorithm = SHA512
CRLPeriod = Days
CRLPeriodUnits = 7
CRLDeltaPeriod = Hours
CRLDeltaPeriodUnits = 12
[CRLDistributionPoint]
URL = http://crl.domain.tld/crld/RootCA.crl

Final words

I do not claim that this is blog post covers all necessary aspects of such an complex thing like an PKI. But I hope that I have mentioned some of the important parts. And at least: I have a reference from which I can copy and paste the CApolicy.inf files. :D

Using Let’s Encrypt DNS-01 challenge validation with local BIND instance

This posting is ~3 years years old. You should keep this in mind. IT is a short living business. This information might be outdated.

I’m using Let’s Encrypt certificates for a while now. In the past, I used the standalone plugin (TLS-SNI-01) to get or renew my certificates. But now I switched to the DNS plugin. I run my own name servers with BIND, so it was a very low hanging fruit to get this plugin to work.

Clker-Free-Vector-Images/ pixabay.com/ Creative Commons CC0

To get or renew a certificate, you need to provide some kind of proof that you are requesting the certificate for a domain that is under your control. No certificate authority (CA) wants to be the CA, that hands you out a certificate for google.com or amazon.com…

The DNS-01 challenge uses TXT records in order to validate your ownership over a certain domain. During the challenge, the Automatic Certificate Management Environment (ACME) server of Let’s Encrypt will give you a value that uniquely identifies the challenge. This value has to be added with a TXT record to the zone of the domain for which you are requesting a certificate. The record will look like this:

_acme-challenge.example.com. 300 IN TXT "ghd63jkcchaow92334...3kahgm9d872"

This record is for a wildcard certificate. If you want to get a certificate for a host, you can add one or more TXT records like this:

_acme-challenge.mx.example.com. 300 IN TXT "ghd63jkcchaow92334...3kahgm9d872"
_acme-challenge.www.example.com. 300 IN TXT "kauezwhcn745njsf....adowerß22"
_acme-challenge.example.com. 300 IN TXT "uqiwo97634bsncös....90237j2k812"

There is a IETF draft about the ACME protocol. Pretty interesting read!

Configure BIND for DNS-01 challenges

I run my own name servers with BIND on FreeBSD. The plugin for certbot automates the whole DNS-01 challenge process by creating, and subsequently removing, the necessary TXT records from the zone file using RFC 2136 dynamic updates.

First of all, we need a new TSIG (Transaction SIGnature) key. This key is used to authorize the updates.

[email protected] ~ # dnssec-keygen -a HMAC-SHA512 -b 512 -n HOST letsencrypt
Kletsencrypt.+165+15583
[email protected] ~ #

This key has to be added to the named.conf. The key is in the .key file.

key "letsencrypts" {
  algorithm hmac-sha512;
  secret "Q+NqA3DJR\5ü77nQ6r//+5QyPKeOyxPD==n09qb516>CTqX+BoG1BeR/9BIEº2 ff4RrDKky4jJ3FJWnQD3nqiJ<J";
};

The key is used to authroize the update of certain records. To allow the update of TXT records, which are needed for the challenge, add this to the zone part of you named.con.

zone "example.com" in {
        type                    master;
        file                    "/usr/local/etc/namedb/master/example.com.zone";
        allow-transfer          { xxxx:yyyy:z:aaaa::1; 123.123.123.1; };
        allow-query             { any; };
        also-notify             { xxxx:yyyy:z:aaaa::1; 123.123.123.1; };
        update-policy           {
            grant letsencrypt  name _acme-challenge.example.com. txt;
            grant letsencrypt  name _acme-challenge.www.example.com. txt;
            grant letsencrypt  name _acme-challenge.mail.example.com. txt;
        };
};

The records start always with _acme-challenge.domainname.

Now you need to create a config file for the RFC2136 plugin. This file also includes the key, but also the IP of the name server. If the name server is running on the same server as the DNS-01 challenge, you can use 127.0.0.1 as name server address.

dns_rfc2136_server = 127.0.0.1
dns_rfc2136_name = letsencrypt
dns_rfc2136_secret = Q+NqA3DJR\5ü77nQ6r//+5QyPKeOyxPD==n09qb516>CTqX+BoG1BeR/9BIEº2 ff4RrDKky4jJ3FJWnQD3nqiJ<J
dns_rfc2136_algorithm = HMAC-SHA512

Now we have everything in place. This is a –dry-run  from on of my FreeBSD machines.

[email protected] ~ # certbot renew --dry-run --dns-rfc2136 --dns-rfc2136-credentials /root/rfc2136.ini --server https://acme-v02.api.letsencrypt.org/directory --dns-rfc2136-propagation-seconds 5
Saving debug log to /var/log/letsencrypt/letsencrypt.log

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Processing /usr/local/etc/letsencrypt/renewal/host.example.com.conf
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Cert not due for renewal, but simulating renewal for dry run
Plugins selected: Authenticator dns-rfc2136, Installer None
Renewing an existing certificate
Performing the following challenges:
dns-01 challenge for host.example.com
Waiting 5 seconds for DNS changes to propagate
Waiting for verification...
Cleaning up challenges

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
new certificate deployed without reload, fullchain is
/usr/local/etc/letsencrypt/live/host.example.com/fullchain.pem
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
** DRY RUN: simulating 'certbot renew' close to cert expiry
**          (The test certificates below have not been saved.)

Congratulations, all renewals succeeded. The following certs have been renewed:
  /usr/local/etc/letsencrypt/live/host.example.com/fullchain.pem (success)
** DRY RUN: simulating 'certbot renew' close to cert expiry
**          (The test certificates above have not been saved.)
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
[email protected] ~ #

This is a snippet from the name server log file at the time of the challenge.

27-Oct-2018 17:54:52.249 update: info: client @0x8031d8a00 127.0.0.1#34120/key letsencrypt: updating zone 'example.com/IN': adding an RR at '_acme-challenge.host.example.com' TXT "QE6ow9YttB580nKw5jgRTOo(nDû3e3I_Ñ2-)j-rY951"
27-Oct-2018 17:54:52.259 notify: info: zone example.com/IN: sending notifies (serial 2018061426)
27-Oct-2018 17:55:00.787 update: info: client @0x804011000 127.0.0.1#34121/key letsencrypt: updating zone 'example.com/IN': deleting an RR at _acme-challenge.host.example.com TXT
27-Oct-2018 17:55:00.810 notify: info: zone example.com/IN: sending notifies (serial 2018061427)

You might need to modify the permissons for the directory which contains the zone files. Usually the name server is not running as root. In my case, I had to grant write permissions for the “bind” group. Otherwise you might get “permission denied”.

26-Oct-2018 11:24:17.215 update: info: client @0x8031d8a00 127.0.0.1#41221/key letsencrypt: updating zone 'example.com/IN': adding an RR at '_acme-challenge.example.com' TXT "bmy-c8L8AOykzMHi5pGFOSYvsCX7guXVl41Rbdo-JLY"
26-Oct-2018 11:24:17.215 general: error: /usr/local/etc/namedb/master/example.com.zone.jnl: create: permission denied
26-Oct-2018 11:24:17.215 update: info: client @0x8031d8a00 127.0.0.1#41221/key letsencrypt: updating zone 'example.com/IN': error: journal open failed: unexpected error

 

Replace SSL certificates on Citrix NetScaler using the CLI

This posting is ~3 years years old. You should keep this in mind. IT is a short living business. This information might be outdated.

Sometimes you have to replace SSL certificates instead of updating them, e.g. if you switch from a web server SSL certificate to a wildcard certificate. The latter was my job today. In my case, the SSL certificate was used in a Microsoft Exchange 2016 deployment, and the NetScaler configuration was using multiple virtual servers. I’m using this little script for my NetScaler/ Exchange deployments.

skylarvision/ pixabay.com/ Creative Commons CC0

When using multiple virtual servers, replacing a SSL certificate using the GUI can be challenging, because you have to navigate multiple sites, click here, click there etc. Using the CLI, the same task is much easier und faster. I like the Lean mindset, so I’m trying to avoid “waste”, in this case, “waste of time”.

Update or replace?

There is a difference between updating or replacing of certificates. When using the same CSR and key as for the expired certificate, you can update the certificate. If you use a new certificate/ key pair, you have to replace it. Replacing a certificate  includes the unbinding of the old, and binding the new certificate.

Replacing a certificate

The new certificate usually comes as a PFX (PKCS#12) file. After importing it, you have to install (create) a new certificate/ key pair.

add ssl certKey wildcard_exp_20190712 -cert wildcard_exp_20190712.pem -key wildcard_exp_20190712.pem -passcrypt random -expiryMonitor ENABLED -notificationPeriod 90

Do yourself a favor and add the expiration date to the name of the certificate/ key pair.

Now you can unbind the old, and bind the new certificate. Please note, that this causes a short outage of your service!

unbind ssl vserver lb_vs_exchange_owa_https_443 -certkeyName exchange2016_exp_20180713
bind ssl vserver lb_vs_exchange_owa_https_443 -certkeyName wildcard_exp_20190712

SSL Cert Unbind Causing NetScaler Crash

You should check what NetScaler software release you are running. There is a bug, which is fixed in 12.0 build 57.X, which causes the NetScaler appliance to crash if a SSL certificate is unbound and a SSL transaction is running. Check CTX230965 for more details.