-
Notifications
You must be signed in to change notification settings - Fork 4.8k
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
Postgres filter: implement Postgres SSL termination and monitoring #10942
Comments
|
Would be nice if this can be used to make workloads behind envoy talk to an ssl forced postgres RDS so client code doesn't care about TLS. Currently it is impossible because of the "SSL request" and expected "S". |
|
Hi @royantman So if I understand it correctly, the use case you are suggesting is a client -> Envoy unencrypted connection and then a Envoy -> upstream Postgres encrypted connection? This scenario would certainly not supported by this proposed design. But I'd like to understand better the use case, as:
I guess implementing this would require some non trivial additional effort, so I'd like to understand if there's a strong use case behind it. Thank you! |
|
FYI: #9577 is requested before to properly support STARTTLS and there is a PoC to terminating STARTTLS. |
|
With utmost respect, I ask you to reconsider the first non-goal of supporting encrypted communication to the PostgreSQL server. Terminating TLS in the hope that the onward network is free of attackers is pretty similar to not using TLS at all. Is there some way you could, say, make reconnecting with TLS an optional feature with opt-in so that you're not obligating people to choose |
|
I see very valid use cases for terminating SSL and having a plain text upstream connection, @davidfetter. For example, when using Envoy as a sidecar, and connecting to the upstream Postgres server via Unix Domain Sockets. Also offloading SSL certificate management to Envoy (and the management layers and software above) brings significant advantages (for example avoid Postgres restarts). That doesn't prevent, however, that other use cases may establish a new SSL connection to upstream. In this case is beneficial to decode the protocol metrics, that current version of the extension doesn't support (only plain-text traffic). |
|
Where I can find a POC for this topic ? |
Not sure if still working but the POC code is here: https://github.com/cpakulski/envoy/tree/issue/10942 |
+1 to these example use cases |
Adds ability to use _starttls_ transport socket to terminate SSL at Envoy and pass unencrypted traffic upstream to Postgres server. Additional Description: Risk Level: Low Testing: Added unit and integration tests. Docs Changes: Yes. Release Notes: Yes. Fixes #10942 Signed-off-by: Christoph Pakulski <christoph@tetrate.io> Co-authored-by: Fabrízio de Royes Mello <fabrizio@ongres.com>
|
I am successfully using this - it is currently letting through both encrypted client sessions opened with Is there any way to set a network filter to enforce TLS and drop connections that don't send the initial Or would the Postgres filter need another option, such as |
|
That's great news @caleblloyd that is working well for you. Your question is quite relevant. Normally, this is enforced at PostgreSQL level by One option would be to implement at Envoy level some directive, as you say. To make it more general, it could be similar to PostgreSQL's However, there's also ongoing discussions about going further and implementing a mechanism equivalent to PostgreSQL's HBA in Envoy, that would also allow to accept/reject connections at the Envoy level by looking at the user, database and/or source IP of the connection. |
|
@ahachete thanks for your work on this, and thanks for the quick response! I'd like to continue the discussion in the appropriate issues- is there already an issue open for requiring SSL and/or the HBA? |
|
There's no specific issue created yet. I just raised this question on Envoy's Slack #envoy-postgres channel, to understand first if this should be related to Envoy's RBAC module, or rather a separate functionality of the current Postgres filter. Once this is discussed, I will open an issue with the approach to implement this. |
|
hi @caleblloyd , could you share your full config for postgres proxy with tls? I'm quite new to envoy. I follow the doc to add postgres filter but it also mentions the starttls filter which I don't know where to put and a proper config for it. I would really appreciate it. |
|
@sandangel have a look to this config example: admin:
access_log_path: /dev/null
address:
socket_address:
address: 0.0.0.0
port_value: 8000
static_resources:
clusters:
- name: postgres_cluster
connect_timeout: 1s
type: STRICT_DNS
load_assignment:
cluster_name: postgres_cluster
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address:
address: 0.0.0.0
port_value: 5432
listeners:
- name: listener
address:
socket_address:
address: 0.0.0.0
port_value: 54322
filter_chains:
- filters:
- name: envoy.filters.network.postgres_proxy
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.network.postgres_proxy.v3alpha.PostgresProxy
stat_prefix: egress_postgres
enable_sql_parsing: false
terminate_ssl: true
- name: envoy.tcp_proxy
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy
stat_prefix: tcp_postgres
cluster: postgres_cluster
idle_timeout: 10s
transport_socket:
name: "starttls"
typed_config:
"@type": type.googleapis.com/envoy.extensions.transport_sockets.starttls.v3.StartTlsConfig
tls_socket_config:
common_tls_context:
tls_certificates:
certificate_chain:
filename: "/d/fabrizio/ongres/etc/.creds/ssl/server.crt"
private_key:
filename: "/d/fabrizio/ongres/etc/.creds/ssl/server.key" |
is there any implemenation done similar to HBA in envoy? |
Previous work
This issue elaborates on the general design of a Postgres filter proposed in #9107.
Background
Encrypting the communications with the database is a hard requirement in many environments. And while cryptography is currently very fast on modern hardware, it still imposes some penalty where it is executed. Particularly, establishing SSL connections is expensive.
RDBMs like Postgres have a primary-replicas architecture, where the former is the only instance that takes writes. Offloading SSL from the primary instance can help reduce the workload, and increase the room for vertical scalability of these services. Similarly, some connection poolers frequently used in combination with Postgres, like PgBouncer, are single-threaded and may saturate the CPU soon if they are dealing with frequent SSL connection establishment.
Those are good enough reasons to implement SSL termination in the Postgres filter for the Envoy proxy. It is very convenient also because certificate management can also be offloaded, and potentially handled via Envoy APIs (and existing tools that leverage them), without having to change Postgres configuration.
Moreover, the current version of the Postgres Envoy Filter implements several traffic inspection metrics that are useful for monitoring. But they (obviously) cannot peek into the SSL traffic, exposing these metrics only for unencrypted connections (as of today).
It might be argued that the CPU offloading advantage is not present in scenarios where Envoy is deployed as a sidecar within the same Pod as Postgres. While true, it doesn’t neglect anyway the advantages of monitoring metrics of the encrypted traffic, separation of concerns and API-based management of certificates.
Goals
Non-goals
Implementation notes
Envoy does support SSL termination at the TCP layer. However Postgres SSL support does not happen at the TCP level, but rather at the application layer (Frontend/Backend Protocol). This questions the amount of existing infrastructure that may be reused. In any case, the same SSL library that Envoy uses, BoringSSL, will be used. It is a key requirement that TLS levels and general compatibility with Postgres SSL are appropriately tested.
The following diagram (note that the Postgres terminology of the FrontEnd-BackEnd protocol is used, instead of the usual Downstream/Upstream at Envoy) illustrates how the encrypted/unencrypted flows may work:
Note that the “fake response” happens after SSL Request, where we will “imitate” the backend sending back the byte “S” to the frontend.
Ideally, we should leverage as much as possible all the SSL infrastructure available already in Envoy, and not create different configuration files/keys/APIs. Here is an example of how Envoy TLS is currently configured:
Limitations
Potentially, some SSL versions or encryption mechanisms may not work, and a reduced set of options may be exposed. This should be fine as Postgres clients negotiate with the server the mechanisms to use. There could be, potentially, some limitations with some specific clients, but it is not expected to be a relevant issue.
SCRAM authentication with channel binding may not be used when proxying through Envoy, as the Postgres server will not be running in SSL mode, and Postgres implementation of channel binding uses tls-server-end-point.
References
The text was updated successfully, but these errors were encountered: