-
Notifications
You must be signed in to change notification settings - Fork 7.9k
Document locking and unlocking swarm managers #694
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
When Docker restarts or a new manager attempts to join the swarm, or whenever | ||
the encryption key needs to be loaded from disk to a node's memory, you must | ||
[unlock the swarm](swarm_manager_locking.md#unlock-a-swarm) first, using a key | ||
provided by you or generated by Docker when the swarm was locked. You can rotate |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Users cannot provide their own key - it's similar to join tokens. It is generated by docker when you enable auto-locking, or when you rotate the unlock key.
|
||
When Docker restarts, the encryption key needed to encrypt and decrypt RAFT logs | ||
is loaded into each manager node's running memory from disk. Docker 1.13 | ||
introduces the ability to protect the encryption key at rest by _autolocking_ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It also protects the TLS key (the same unlock key is used to encrypt the TLS key) that the manager node uses to connect to the rest of the swarm, because having a mTLS connection to the rest of the swarm means that you can get all the swarm data (including secrets).
introduces the ability to protect the encryption key at rest by _autolocking_ | ||
your swarm. | ||
|
||
When Docker restarts or a new manager attempts to join the swarm, or whenever |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When a new manager joins, the unlock key does not need to be provided, because that new manager does not have any data on disk that needs to be loaded. The new manager will obtain the the unlock key from the raft leader via propagation of the rest of the raft data.
``` | ||
|
||
To disable autolock, set `--autolock` to `false`. The encryption key used to | ||
read and write RAFT logs will be stored unencrypted on disk, so this |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe "The mutual TLS key and the encryption key used to ..."?
Thanks for the great work and quick turnaround on this @mstanleyjones! A couple of nitpicks, but this looks fantastic. |
Addressed feedback so far. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good! Left a few small nits.
When Docker restarts, both the TLS key used to encrypt communication among | ||
swarm nodes, and the key used to encrypt and decrypt RAFT logs on disk, are | ||
loaded into each manager node's running memory from disk. Docker 1.13 introduces | ||
the ability to protect the encryption key at rest by _autolocking_ your swarm. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
by allowing you to take ownership of this key and require manual unlocking of your managers. We call this feature autolocking
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@diogomonica ownership of both the encryption and TLS key you mean? Or of the unlock key?
When Docker restarts or whenever the encryption key needs to be loaded from disk | ||
to a node's memory, you must | ||
[unlock the swarm](swarm_manager_locking.md#unlock-a-swarm) first, using a key | ||
generated by Docker when the swarm was locked. When a new node joins the swarm, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think this When a new node joins the swarm...
part.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think making it clear here that the unlock key does not need to be provided when adding a manager (only the join token is needed, because the unlock key is propagated via the raft) could be useful - the user might think it needs to be added otherwise, if they're not sure when loading from disk is necessary.
Nitpick though, "the is" is missing a word :) Maybe "the key is propagated..."?
|
||
To disable autolock, set `--autolock` to `false`. The mutual TLS key and the | ||
encryption key used to read and write RAFT logs will be stored unencrypted on | ||
disk, so this configuration is not recommended. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
so, depending on the level of security you're striving for, this configuration might not be recommended.
Please enter unlock key: | ||
``` | ||
|
||
Enter the encryption key that was emitted when you locked the swarm, and the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
emitted -> generated.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well, it was generated but it was also emitted to standard output... let me see what I can do.
PTAL again. Thanks! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Getting better and better. Still a few things we should change.
|
||
When Docker restarts, both the TLS key used to encrypt communication among swarm | ||
nodes, and the key used to encrypt and decrypt RAFT logs on disk, are loaded | ||
into each manager node's running memory from disk. Docker 1.13 introduces the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
drop "from disk"?
nodes, and the key used to encrypt and decrypt RAFT logs on disk, are loaded | ||
into each manager node's running memory from disk. Docker 1.13 introduces the | ||
ability to protect the mutual TLS encryption key and the key used to encrypt and | ||
decrypt RAFT logs at rest (on disk), by allowing you to take ownership of this |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
drop "on disk"
into each manager node's running memory from disk. Docker 1.13 introduces the | ||
ability to protect the mutual TLS encryption key and the key used to encrypt and | ||
decrypt RAFT logs at rest (on disk), by allowing you to take ownership of this | ||
key and to require manual unlocking of your managers. This feature is called |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This feature is called autolock
.
key and to require manual unlocking of your managers. This feature is called | ||
_autolocking_ your swarm. | ||
|
||
When Docker restarts or whenever the encryption key needs to be loaded from disk |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"When a Docker restarts and needs to access the encrypted RAFT state on disk, you must..."
There aren't other motives to unlock a manager other than starting it (or restarting it).
generated by Docker when the swarm was locked. You can rotate this key at any time. | ||
|
||
>**Note**: You don't need to unlock the swarm when a new node joins the swarm, | ||
because the key is propagated to it over mutual TLS.. You only need to provide |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
two ".."
SWMKEY-1-WuYH/IX284+lRcXuoVf38viIDK3HJEKY13MIHX+tTt8 | ||
``` | ||
|
||
Record the key in a safe place. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Record -> Store?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also add: We recommend a password manager?
|
||
Record the key in a safe place. | ||
|
||
When Docker restarts, a new manager node attempts to join the swarm, or Docker |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please remove: a new manager node attempts to join the swarm
encryption key used to read and write RAFT logs will be stored unencrypted on | ||
disk. There is a trade-off between the risk of storing the encryption key | ||
unencrypted at rest and the convenience of being able to restart a swarm without | ||
needing to unlock the swarm. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
without needing to unlock each manager.
There is no swarm-wide unlock. This is individual per manager (if all nodes go down, and you have a 3 manager swarm, you need to unlock each manager individually).
|
||
Consider a situation where your swarm is | ||
running as expected, then manager node becomes unavailable. You troubleshoot the | ||
problem and bring the physical node back online, but you need to rejoin the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're not rejoining the node to the swarm. I think we should only use "join" when it's the first time a node is actually joining the swarm. Maybe rephrase:
You troubleshoot the problem and bring the physical node back online, but you need to provide the key necessary to read the encrypted credentials and RAFT logs on disk.
will not be able to restart the manager. | ||
``` | ||
|
||
If you ever need to view the unlock key in this way, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Doesn't make a lot of sense, since rotating a swarm also displays the new key. I think we should remove it, or at least replace it with a warning around: please don't share this key anywhere, and store it securely, etc`
Addressed @diogomonica's feedback. Please let me know if you see more areas for improvement. |
title: Lock your swarm to protect its encryption key | ||
--- | ||
|
||
In Docker 1.13 and higher, the RAFT logs used by swarm managers are encrypted on |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In other docs we seem to use the capitalization Raft
. This is also what the paper calls it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch, thanks, It's not an acronym.
To enable autolock on an existing swarm, set the `autolock` flag to `true`. | ||
|
||
```bash | ||
$ docker swarm update --autolock="true" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The quotes around true
are not necessary.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But do they cause a problem? I have a strong preference for using them.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's technically valid, but it's very atypical to have double quotes there. You could also write it as docker "swarm" "update" "--autolock"=true
, but people don't do that either. So it looks like there are quotation marks in an arbitrary place where they do nothing, and I think it would look strange to people who understand the shell's syntax rules.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, removed the quotes.
needing to unlock each manager. | ||
|
||
```bash | ||
$ docker swarm update --autolock="false" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The quotes around false
are not necessary.
--- | ||
|
||
In Docker 1.13 and higher, the RAFT logs used by swarm managers are encrypted on | ||
disk by default. This at-rest encryption protects your service's configuration |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We always encrypt the logs, but may or may not store the key alongside them. --autolock=true
sets it up not to store the key.
OK, I think this is ready to merge, just need some +1s. |
LGTM |
nodes, and the key used to encrypt and decrypt Raft logs on disk, are loaded | ||
into each manager node's memory. Docker 1.13 introduces the ability to protect | ||
the mutual TLS encryption key and the key used to encrypt and decrypt Raft logs | ||
at rest, by allowing you to take ownership of this key and to require manual |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Minor nitpick: The first part of the sentence mentions 2 keys, and the second part says "take ownership of this key" - should it be "these keys"? Or is this referring to the key-encrypting-key (then unlock key) (which hasn't been mentioned before).
unlocking of your managers. This feature is called _autolock_. | ||
|
||
When Docker restarts, you must | ||
[unlock the swarm](swarm_manager_locking.md#unlock-a-swarm) first, using a key |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Non-blocking: I don't know whether it'd be too much detail to mention that this is a key encrypting key - there are two other keys already mentioned in this section, and it might be useful to provide more disambiguation. Not sure whether it'd just be more confusing, though.
One minor nitpick, but this LGTM. Thanks @mstanleyjones! |
Addressed @cyli feedback. If this is good to go, I will merge it after the rebase of |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM! (Apologies, didn't see the follow-up comment)
Describe the proposed changes
Document locking a swarm.
Unreleased project version
Engine 1.13
Related issue
#689
Related issue or PR in another project
moby/moby#27967
Please take a look
@cyli @aaronlehmann @diogomonica @rahim888