Can I setup Public-Key-Pins when I setup a cronjob to renew the LetsEncrypt certificate every 30 days?
If the certificate is renewed then the Public-Key-Pin is also renewed right?
Can I setup Public-Key-Pins when I setup a cronjob to renew the LetsEncrypt certificate every 30 days?
If the certificate is renewed then the Public-Key-Pin is also renewed right?
Some words of caution to begin with:
Would echo everything that gf_ said.
However, to answer the question, yes you can.
By default Let's Encrypt recreates the key and the cert at renewal. This makes implementing HPKP difficult if you want to pin at the leaf, which you probably should do in case intermediate changes (like it did in March 2016).
So you've several options around this if you still want to do HPKP:
I just implemented this using the dehydrated client with dns01 validation. The dns01 hook is certzure because our DNS is hosted in Azure.
Edit: when I talk about private keys, obviously I always mean that you only turn the public key parts into pins. The private keys, as the name suggests, should always remain private. See my own hook for implementation details.
You need private key rollover to make this possible. That is, you always have the current private key (call it A) and the future private key (call it B) at hand, so that you can add them both to your pins. So at this point your pins are A and B. When the day of cert renewal comes, private key A becomes obsolete and B becomes live. At the same time you get a new future private key, call it C. You regenerate your pin list so now it contains B and C. So that's how you roll your private keys over. dehydrated supports this now.
Also, you need a hook that is called every time you renew your certs and thus roll over your private keys. I implemented this on my own.
Finally, if I get this right, you gotta make sure that:
For example, if your HPKP age is 50 days and you renew certs every 30 days, a client who visited your site on day one will be stuck with private keys A and B, and you rolled over to B and C at day 31. Your server has B and C, the client has A and B, there's a match even on day 50 and the client opens the site correctly.
BUT let's see if HPKP age is 70 days. You renew certs every 30 days, and the client visited your site on day one, so again, it only has private keys A and B. You rolled over to B and C at day 31, and rolled over to C and D at day 61. Your server has C and D, the client has A and B, there's no match and the client is given the middle finger from day 61 until day 71, when its HPKP policy expires.
Another, probably safer, and certainly much simpler option is using the same private key every time and generating one or several backup private keys, then hardcoding these into your HPKP config and be done with it.
Yeah, it's tricky and there might be caveats I haven't thought of, but we'll see in the long run. Obviously I deployed it on an uncritical subdomain with short (15 days) HPKP age so that it doesn't cause huge troubles.
Edit: I've written a few scripts to help you setting up HPKP with Let's Encrypt and dehydrated using Nginx:
HPKPinx