GoogleCloudPlatform / cloud-sql-proxy

A utility for connecting securely to your Cloud SQL instances
Apache License 2.0
1.27k stars 347 forks source link

Restricting access to the proxy itself (username/password or IP address restriction) #1739

Closed jawnsy closed 5 months ago

jawnsy commented 1 year ago

Feature Description

Some applications, such as Google Cloud's Datastream service do not support IAM authentication natively, which means that they cannot be used while Connector Enforcement or Require SSL features are enabled on the Cloud SQL instance.

This proposes the addition of two features to the proxy, which are independent and may be implemented separately:

Sample code

No response

Alternatives Considered

A workaround is to run the Cloud SQL Auth Proxy as a shared service and secure it using firewall or network policy settings (for example, as a standalone Kubernetes service secured by NetworkPolicy or a standalone VM secured by VPC firewall rules). We can also use a middleware like pgbouncer (as shown in the included example) to introduce a username/password check.

However, this creates a security vulnerability in the event that these policies do not enforce segmentation correctly, so a defense-in-depth approach would include also applying a shared secret like a username/password combination.

Examples where this may be the case are:

  1. A network admin inadvertently changes VPC firewall rules or routes in a way that exposes the proxy to untrusted users or applications
  2. A Kubernetes cluster is provisioned using the default Calico networking with Network Policy enforcement disabled

Additional Details

No response

enocom commented 1 year ago

Thanks for the feature request @jawnsy.

Perhaps the right thing to do here is to get Datastream (and other GCP products) to support IAM authentication with the proxy.

A couple of thoughts:

jawnsy commented 1 year ago

Perhaps the right thing to do here is to get Datastream (and other GCP products) to support IAM authentication with the proxy.

100% agreed, but you may have more sway to get that completed than I do!

Additionally, the existing approach (peering into our VPC) is not ideal because Cloud SQL works the same way and networks cannot be accessed transitively. There are two possible approaches:

  1. As Datastream recommends, use iptables to do port forwarding using a NAT rule
  2. Configure cloud-sql-proxy instead of using iptables, so it can handle both the authentication aspect (using IAM authentication) and proxying aspect

However, (2) is risky from a security perspective because it relies on appropriate firewall rules to be defined, the lack of which can lead to a serious security incident (involving loss of control of data). This is a similar risk to running cloud-sql-proxy as a Kubernetes service, however.

The allowlist on CIDR ranges seems easy enough, although I worry the feature would be vulnerable to IP spoofing.

I think it's reasonable to expect that an administrator handle network security (e.g. TCP SYN cookies, securing routing configurations). If it were me in your shoes, this would be the only part of this issue that I'd implement, because it's straightforward, provides an improvement in security, and is minimally disruptive to the rest of the code.

Another way to think about this is that the current code does not have any protection, so adding an allowlist may provide a marginal improvement (even if it is indeed vulnerable to spoofing or other issues) at minimal cost in terms of implementation effort/long-term expected maintenance.

How would you expect username / password to work? Any connection to the Proxy automatically uses the associated database protocol and so if we were to add support for some kind of credentials, we'd need a protocol to do it.

Yup, I understand the challenge of this given the current implementation, which treats the connection as a raw TCP/TLS stream and does not understand the PostgreSQL wire protocol.

There are some proxy implementations that are wire protocol aware (e.g. pgbouncer) but this requires a lot more implementation effort, and will result in higher maintenance costs as well. There are some benefits to the protocol-aware approach, of course, like being able to introduce commands at the middleware level (the same way pgbouncer can have its own administrative commands).

Doing this in a way that has parity across pgsql, mysql, mssql may be difficult (though that's also not necessarily necessary -- it is also reasonable to consider this as a pg-only feature, for example, depending on availability of libraries you'd need)

enocom commented 1 year ago

Thanks for the detailed response.

I'd like to leave this open but briefly:

  1. Adding a CIDR allowlist potentially sends a mixed signal. Normally we recommend running the Proxy as a sidecar on the same VM as the workload. But I understand that with some services, some kind of security might be desirable.
  2. Protocol-awareness is a common topic that comes up now and again. For now, we prefer to leave that to connection poolers that will always beat the Proxy in terms of performance.

As an alternative, have you considered running a connection pooler in front of the Proxy? In that approach, you could still enable database-like security while still reaping the benefits of Auto IAM Authn.

enocom commented 5 months ago

Going to close this as we're not considering this for now.