Update client certificates automatically#1730
Merged
pcapriotti merged 31 commits intodevelopfrom Sep 9, 2021
Merged
Conversation
13a95fc to
c36d886
Compare
mdimjasevic
reviewed
Sep 2, 2021
c26a3ba to
3cf2ae7
Compare
Contributor
Author
|
With the last few fixes, certificate autoreload works nicely on kubernetes. |
akshaymankar
requested changes
Sep 8, 2021
Member
akshaymankar
left a comment
There was a problem hiding this comment.
I think we shouldn't expose IORef TLSSettings to the app.
1f9737f to
51923d1
Compare
This uses inotify to set up watches listening for events about client certificates and remote CA. We set up watches on both the files specified by the configuration and their parent directories, in order to be able to react to both direct modifications and to the files being deleted and recreated, or symlink targets being swapped.
This will allow the monitor to update it when certificates change.
When a watched file or any of its ancestor directories is a symlink, the symlink target needs to be recursively watched as well.
Instead, replace `Reader` effect with `Input`, and interpret it by reading the IORef every time.
51923d1 to
4c1bc91
Compare
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This makes federator update its cached TLS settings when changes to client certificates or the CA store are detected.
Most of the functionality is contained in
Federator.Monitor.Internal. There is some complicated logic to make sure we get inotify events when the paths containing the credentials change in any possible way, including being modified directly, or overwritten with other files, or their parent directories being replaced with other ones.Details
A "monitor" is started when an environment is created. At this point, all the files that need to be watched are collected, and inotify watches are created for each one of them and each of their parent directories up to the filesystem root. Whenever we detect a relevant change, we reload the
TLSSettingsfrom the filesystem, and update anIORef.For file watches, we listen for the
Closeevent, which is sent when a file descriptor in write mode for the corresponding inode is closed. For directory watches, things are more complicated: we listen forCreateandMoveInevents, which happen when a new file appear in the directory, and as soon as it happens (before reloading the settings) we replace the existing watch on the file with a new one (since the inode might have changed).There is a tiny PR to hs-certificate associated to this PR: haskell-tls/hs-certificate#125. This was needed to make sure we are able to catch and log exceptions in inotify handlers. Using
erroris problematic because the exception can be (and indeed is, in my tests) thrown outside ofIOcode we control, and results in the handler thread dying silently. I have pointedstack.yamlto the patched version, but it is not essential. Without the patch, we might just lose some logging errors in some cases.Testing
In tests, we create a setup using temporary files or directories, then we set up a channel (using
Control.Concurrent.Chan) to keep track of asynchronous reloads or exceptions thrown within a reload.TODO
Graceful handling of missing inotify supportThis is probably not needed, since the inotify library cannot even be built for targets that do not support inotify.
Integration testsThis is not trivial, because it needs an outward service integration test. I'll skip it for now.
Checklist