<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Mon, Jul 27, 2015 at 1:31 PM, Clint Byrum <span dir="ltr"><<a href="mailto:clint@fewbar.com" target="_blank">clint@fewbar.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Excerpts from Alexander Makarov's message of 2015-07-27 10:01:34 -0700:<br>
<span class="">> Greetings!<br>
><br>
> I'd like to discuss pro's and contra's of having Fernet encryption keys<br>
> stored in a database backend.<br>
> The idea itself emerged during discussion about synchronizing rotated keys<br>
> in HA environment.<br>
> Now Fernet keys are stored in the filesystem that has some availability<br>
> issues in unstable cluster.<br>
> OTOH, making SQL highly available is considered easier than that for a<br>
> filesystem.<br>
><br>
<br>
</span>I don't think HA is the root of the problem here. The problem is<br>
synchronization. If I have 3 keystone servers (n+1), and I rotate keys on<br>
them, I must very carefully restart them all at the exact right time to<br>
make sure one of them doesn't issue a token which will not be validated<br>
on another. This is quite a real possibility because the validation<br>
will not come from the user, but from the service, so it's not like we<br>
can use simple persistence rules. One would need a layer 7 capable load<br>
balancer that can find the token ID and make sure it goes back to the<br>
server that issued it.<br></blockquote><div><br></div><div>This is not true (or if it is, I'd love see a bug report). keystone-manage fernet_rotate uses a three phase rotation strategy (staged -> primary -> secondary) that allows you to distribute a staged key (used only for token validation) throughout your cluster before it becomes a primary key (used for token creation and validation) anywhere. Secondary keys are only used for token validation.</div><div><br></div><div>All you have to do is atomically replace the fernet key directory with a new key set.</div><div><br></div><div>You also don't have to restart keystone for it to pickup new keys dropped onto the filesystem beneath it.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
A database will at least ensure that it is updated in one place,<br>
atomically, assuming each server issues a query to find the latest<br>
key at every key validation request. That would be a very cheap query,<br>
but not free. A cache would be fine, with the cache being invalidated<br>
on any failed validation, but then that opens the service up to DoS'ing<br>
the database simply by throwing tons of invalid tokens at it.<br>
<br>
So an alternative approach is to try to reload the filesystem based key<br>
repository whenever a validation fails. This is quite a bit cheaper than a<br>
SQL query, so the DoS would have to be a full-capacity DoS (overwhelming<br>
all the nodes, not just the database) which you can never prevent. And<br>
with that, you can simply sync out new keys at will, and restart just<br>
one of the keystones, whenever you are confident the whole repository is<br>
synchronized. This is also quite a bit simpler, as one basically needs<br>
only to add a single piece of code that issues load_keys and retries<br>
inside validation.<br>
<span class=""><br>
__________________________________________________________________________<br>
OpenStack Development Mailing List (not for usage questions)<br>
</span>Unsubscribe: <a href="http://OpenStack-dev-request@lists.openstack.org?subject:unsubscribe" rel="noreferrer" target="_blank">OpenStack-dev-request@lists.openstack.org?subject:unsubscribe</a><br>
<a href="http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev" rel="noreferrer" target="_blank">http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev</a><br>
</blockquote></div><br></div></div>