github.com/thanos-io/thanos@v0.32.5/docs/proposals-accepted/202106-automated-per-endpoint-mTLS.md (about)

     1  ---
     2  type: proposal
     3  title: Automated, per-endpoint mTLS
     4  status: accepted
     5  owner: Namanl2001
     6  menu: proposals-accepted
     7  ---
     8  
     9  ## Automated, per-endpoint mTLS
    10  
    11  * **Owners:**
    12  
    13    * [@Namanl2001](https://github.com/Namanl2001)
    14  
    15  * **Related Tickets:**
    16  
    17    * [Per-Store TLS configuration in Thanos Query](https://github.com/thanos-io/thanos/issues/977)
    18  
    19  ## What
    20  
    21  The Thanos Querier component supports basic mTLS configuration for internal gRPC communication. This works great for basic use cases but it still requires extra forward proxies to make it work for bigger deployments. It’s also hard to rotate certificates automatically and configure safe mTLS. This proposal aims to allow a better TLS story.
    22  
    23  ## Why
    24  
    25  Let’s imagine we have an Observer Cluster that is hosting Thanos Querier along with Thanos Store Gateway. In the same cluster we also have one or more Thanos Sidecars that we would like to connect to, within the cluster.
    26  
    27  However, let's say we also need to connect the observer cluster’s querier to several remote instances of Thanos Sidecar in remote clusters. Ideally, we want to use mTLS to encrypt the connection to the remote clusters, but we don’t want to use it within the cluster. Mutual TLS (mTLS) ensures that traffic is both secure and trusted in both directions between a client and server.
    28  
    29  In this scenario we need to use a proxy server (e.g. envoy). But, it would probably be simpler to do away with the proxies and let Thanos speak directly and securely with the remote endpoints.
    30  
    31  ### Pitfalls of the current solution
    32  
    33  If we would enable the current mTLS, it would be applied to all the storeAPI’s but we don’t want it to be applied on the storeAPI’s of central Thanos instance (Observer cluster) in which Thanos query component is present (for faster communications with storeAPI’s (sidecars) of same cluster, to reduce the pain of provisioning certificates etc.)
    34  
    35  So it requires extra forward proxies to make it work for bigger (multi-cluster) deployments. Also currently there is no support for automatic client rotation in thanos.
    36  
    37  ## Goals
    38  
    39  * To add support for per-endpoint TLS configuration in Thanos Query Component for internal gRPC communication
    40  * Automatic certificate rotation without restart
    41  
    42  ## Non-Goals
    43  
    44  * TLS client support for HTTP
    45  * TLS for gRPC clients other than Querier
    46  
    47  ## How
    48  
    49  I would propose introducing a new CLI option `--endpoints.config`, with no dynamic reloading, which will accept the path to a yaml file which contains a list as follows:
    50  
    51  ```
    52  - tls_config:
    53      cert_file: ""
    54      key_file: ""
    55      ca_file: ""
    56      server_name: ""
    57    endpoints: []
    58    endpoints_sd_files:
    59      - files: []
    60    mode: ""
    61  ```
    62  
    63  The endpoints in the list items with no TLS config would be considered insecure. Further endpoints supplied via separate flags (e.g. `--endpoint`, `--endpoint.strict`, `--endpoint.sd-files` (previous `--store.strict`, `--store.sd-files`)) will be considered secure only if TLS config is provided through `--secure`, `--cert`, `--key`, `--caCert`, `--serverName` cli options. User will only be allowed to use separate options or `--endpoints.config`.
    64  
    65  If the mode is strict (i.e. `mode: ”strict”`) then all the endpoints in that list item will be considered as strict (statically configured store API servers that are always used, even if the health check fails, as supplied in `--endpoint.strict`). And if there is no mode specified (i.e `mode: “”`) then all endpoints in that item will be considered normal.
    66  
    67  **Automatic cert-rotation:** for this all the things are managed by the cert manager in the k8s cluster, we just need to redo the TLS handshake when the certificates are rotated by the cert-manager. And for this I would propose to add a new `--grpc-server-max-connection-age` CLI option which takes time as input and controls how often to re-do the tls handshake and re-read the certificates. This in reality is controlled by the keepalive’s [MaxConnectionAge](https://pkg.go.dev/google.golang.org/grpc/keepalive#ServerParameters) option (which will close the connection after every (e.g. 15m) inputted time duration) so when the connection is closed it requires a new tls handshake.
    68  
    69  While reading the *cert_file* on each handshake we can improve the performance by keeping track of it’s modification time. We should re-load the certificates only if they are actually rotated and there is some change in their modification time otherwise returning the previously stored one. Also if the file is not modified recently then it could be found on the cache memory and it would be faster to get the file details (i.e. modification time).
    70  
    71  ## Alternatives
    72  
    73  * Try to close connection only when things are actually changed, not based on time. But this is not a general approach and needs some research to figure out if this is possible in go.
    74  * Another alternative here is having one querier per-certificate realm - meaning one querier for your internal no-mTLS sidecars, and one querier for your clusters that share a root CA.
    75    * No changes to TLS configuration required.
    76    * Number of queriers is required to scale with the number of certificates / shared root CAs.
    77    * Complex scenarios when we need to scale out number of replicas multiples per certificate.
    78  
    79  ## Action Plan
    80  
    81  * Implement `--endpoint.config`.
    82  * Implement gRPC certificate rotation as designed.
    83  * Add e2e tests for above changes.
    84  * We would remove the support for separate CLI options `--secure`, `--cert`, `--key`, `--caCert`, `--serverName` after few releases. As they are already covered in `--endpoint-config`.