Skip to content
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

rgw/notification: allow sending bucket notifications secrets in cleartext #43436

Merged
merged 1 commit into from Aug 25, 2022

Conversation

yuvalif
Copy link
Contributor

@yuvalif yuvalif commented Oct 6, 2021

rgw_allow_secrets_in_cleartext conf parameter was added for that

Fixes: https://tracker.ceph.com/issues/50611

Signed-off-by: Yuval Lifshitz ylifshit@redhat.com

Testing

run vstart cluster:

MON=1 OSD=1 MDS=0 MGR=0 RGW=1 ../src/vstart.sh -n -d

behavior should not change by default, so the following command should fail:

aws --endpoint-url http://localhost:8000 sns create-topic --name=fishtopic2 --attributes='{"push-endpoint": "amqp://hello:world@localhost:10900", "amqp-exchange": "ex1"}'

however, after setting the parameter to "true":

bin/ceph -c ceph.conf config set client.rgw.8000 rgw_allow_notification_secrets_in_cleartext true

topic creation with user and password over non-secure connection should be ok:

# aws --endpoint-url http://localhost:8000 sns create-topic --name=fishtopic2 --attributes='{"push-endpoint": "amqp://hello:world@localhost:10900", "amqp-exchange": "ex1"}'
{
    "TopicArn": "arn:aws:sns:default::fishtopic2"
}

Show available Jenkins commands
  • jenkins retest this please
  • jenkins test classic perf
  • jenkins test crimson perf
  • jenkins test signed
  • jenkins test make check
  • jenkins test make check arm64
  • jenkins test submodules
  • jenkins test dashboard
  • jenkins test dashboard cephadm
  • jenkins test api
  • jenkins test docs
  • jenkins render docs
  • jenkins test ceph-volume all
  • jenkins test ceph-volume tox

@@ -24,7 +31,7 @@ bool validate_and_update_endpoint_secret(rgw_pubsub_sub_dest& dest, CephContext
ceph_assert(user.empty() == password.empty());
if (!user.empty()) {
dest.stored_secret = true;
if (!rgw_transport_is_secure(cct, env)) {
if (!verify_security(cct, env)) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should still indicate transport security, non?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

verify_security() calls rgw_transport_is_secure() if the flag is not set.
if the flag is set there is no need to check for transport security, because we allow for user/password on non-secure transport

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

there are many aspects of security this won't disable, e.g., secure authentication

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is not disabling anything. only thing it allows is sending "secrets" (e.g. user/password) on non-secure transport

maybe i should name this function differently?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that's all I was saying

@cbodley
Copy link
Contributor

cbodley commented Oct 6, 2021

this is useful fro the case that the RGW is behind a load balancer, when SSL is between client and balancer, and HTTP is used between balancer and RGW

rgw_transport_is_secure() has built-in support for this via the rgw_trust_forwarded_https config variable, can you try with that enabled?

@cbodley
Copy link
Contributor

cbodley commented Oct 6, 2021

see #24700 for some more background on rgw_trust_forwarded_https

@yuvalif
Copy link
Contributor Author

yuvalif commented Oct 7, 2021

this is useful fro the case that the RGW is behind a load balancer, when SSL is between client and balancer, and HTTP is used between balancer and RGW

rgw_transport_is_secure() has built-in support for this via the rgw_trust_forwarded_https config variable, can you try with that enabled?

i don't think that would work. in rgw_transport_is_secure():

if (!cct->_conf->rgw_trust_forwarded_https) {                                                                                                                                                                                             
  return false;
}

so, if the conf parameter is set to "true" we won't enter the "if" statement.
if the conf parameter is set to "false" we would return "false" - marking the transport as insecure (which is not what we want)

@cbodley
Copy link
Contributor

cbodley commented Oct 7, 2021

so, if the conf parameter is set to "true" we won't enter the "if" statement.

which if statement? setting it to true makes rgw_transport_is_secure() check whether we got a secure Forwarded or X-Forwarded-Proto header from the load balancer, and if we did it considers the transport secure. that's what you want right?

@yuvalif
Copy link
Contributor Author

yuvalif commented Oct 7, 2021

so, if the conf parameter is set to "true" we won't enter the "if" statement.

which if statement? setting it to true makes rgw_transport_is_secure() check whether we got a secure Forwarded or X-Forwarded-Proto header from the load balancer, and if we did it considers the transport secure. that's what you want right?

this is done right :-) but it does not help in the case of this PR
in this PR, we want to say that a transport is secure, even if it isn't, for the only purpose of allowing user/password to be sent over non-secure transport

@cbodley
Copy link
Contributor

cbodley commented Oct 7, 2021

ok i was going by what the tracker issue said. but do we really want to be insecure here? i still think it should be a requirement

@yuvalif
Copy link
Contributor Author

yuvalif commented Oct 7, 2021

ok i was going by what the tracker issue said. but do we really want to be insecure here? i still think it should be a requirement

this is why it is only disabled by a conf parameter (which is "false" by default).
this "backdoor" was requested by an upstream users that didn't want to add TLS to the RGW only for the purpose of AMQP integration.
I ran into a similar issue trying to configure bucket notifications with AMQP in Rook. The AMQP k8s operator force you to use the non-default user/password (which is not the case in out teuthology tests), and the Rook environment makes it hard to setup TLS for the RGW.

@cbodley
Copy link
Contributor

cbodley commented Oct 7, 2021

the Rook environment makes it hard to setup TLS for the RGW

i had assumed that kubernetes made this easy with its secrets; is there something we could improve on here? cc @travisn

i really don't think "security is hard" is a good reason not to do it. it'll also require some effort for users to change this config variable to open the back door, but i'd much rather see that effort spent on enabling TLS

@cbodley
Copy link
Contributor

cbodley commented Oct 7, 2021

this is useful fro the case that the RGW is behind a load balancer, when SSL is between client and balancer, and HTTP is used between balancer and RGW

what was the context for this tracker issue? is this proxy configuration common in rook?

@yuvalif
Copy link
Contributor Author

yuvalif commented Oct 7, 2021

the Rook environment makes it hard to setup TLS for the RGW

i had assumed that kubernetes made this easy with its secrets; is there something we could improve on here? cc @travisn

i really don't think "security is hard" is a good reason not to do it. it'll also require some effort for users to change this config variable to open the back door, but i'd much rather see that effort spent on enabling TLS

its is not exactly the case of "security is hard". without this fix, in an environment where RGW do not use TLS, we are forcing the use of TLS in RGW because we want to send notifications to AMQP.
this would be a major change in most environment (k8s or not). in this PR, I want to allow for such integration (with AMQP) without forcing the RGW to be secure

@yuvalif yuvalif added the DNM label Oct 7, 2021
@yuvalif
Copy link
Contributor Author

yuvalif commented Oct 7, 2021

as discussed in the standup, adding a "backdoor" is usually a bad idea :-)
hence, this PR will be put on hold until we figure out the limitations we have in using secure RGW in Rook.

@yuvalif
Copy link
Contributor Author

yuvalif commented Oct 7, 2021

@stale
Copy link

stale bot commented Jan 9, 2022

This pull request has been automatically marked as stale because it has not had any activity for 60 days. It will be closed if no further activity occurs for another 30 days.
If you are a maintainer or core committer, please follow-up on this pull request to identify what steps should be taken by the author to move this proposed change forward.
If you are the author of this pull request, thank you for your proposed contribution. If you believe this change is still appropriate, please ensure that any feedback has been addressed and ask for a code review.

@stale stale bot added the stale label Jan 9, 2022
@yuvalif
Copy link
Contributor Author

yuvalif commented Jan 12, 2022

the reason TLS was not working properly in rook was just a bug (being fixed here: rook/rook#9565)
once the rook issue is fixed, there is no reason to send secrets in cleartext

@stale stale bot removed the stale label Jan 12, 2022
@yuvalif yuvalif closed this Jan 12, 2022
@yuvalif
Copy link
Contributor Author

yuvalif commented Jul 20, 2022

going to reopen this, as this was specifically requested by users.
there are both kafka and amqp deployments that want to use user/password but does not want to use TLS (usually to avoid self signed certificates issues).
this is even more problematic in kafka, when our version of librdkafka does not support the "verify_sll=false" option

@yuvalif yuvalif reopened this Jul 20, 2022
@github-actions
Copy link

This pull request can no longer be automatically merged: a rebase is needed and changes have to be manually resolved

@djgalloway djgalloway changed the base branch from master to main July 21, 2022 00:00
Comment on lines 3559 to 3562
- name: rgw_allow_secrets_in_cleartext
type: bool
level: advanced
desc: Allows sending secrets (e.g. passwords) over non encrypted HTTP messages
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please use an option name that's specific to pubsub or notifications

in the description, please add some strong wording that this is a security vulnerability and should never be used in production

this is related to rgw_trust_forwarded_https, so a see_also: would be helpful

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment on lines 13 to 18
bool verify_transport_security(CephContext *cct, const RGWEnv& env) {
if (g_conf().get_val<bool>("rgw_allow_secrets_in_cleartext")) {
return true;
}
return rgw_transport_is_secure(cct, env);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we please add a scary warning message at log level 0 whenever this override is triggered?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@yuvalif
Copy link
Contributor Author

yuvalif commented Jul 26, 2022

@yuvalif
Copy link
Contributor Author

yuvalif commented Aug 4, 2022

@cbodley can you please review?

@cbodley
Copy link
Contributor

cbodley commented Aug 11, 2022

@yuvalif i'm still against adding an intentional security hole here. if we know that we're leaking credentials, but it's okay because we're on a private network, then why do we need password authentication for the message broker?

would it be an acceptable workaround to configure the notification endpoints without passwords instead?

@yuvalif
Copy link
Contributor Author

yuvalif commented Aug 11, 2022

@yuvalif i'm still against adding an intentional security hole here. if we know that we're leaking credentials, but it's okay because we're on a private network, then why do we need password authentication for the message broker?

would it be an acceptable workaround to configure the notification endpoints without passwords instead?

not really. the configuration of the brokers is often managed differently than ceph.
in addition, kafka allows for "sasl plaintext" mode - meaning that it gets the user/password over non-encrypted connection:
https://docs.confluent.io/platform/current/kafka/authentication_sasl/authentication_sasl_plain.html

@cbodley
Copy link
Contributor

cbodley commented Aug 11, 2022

i still don't understand what use case we're targeting here

if this is just for demos/testing, you can set up the notification endpoint without passwords

if this is for production use, then we should enforce real security. let's encrypt is an easy alternative to self-signed certificates. a google search for "kubernetes let's encrypt" comes up with a bunch of hits

@yuvalif
Copy link
Contributor Author

yuvalif commented Aug 11, 2022

i still don't understand what use case we're targeting here

if this is just for demos/testing, you can set up the notification endpoint without passwords

if this is for production use, then we should enforce real security. let's encrypt is an easy alternative to self-signed certificates. a google search for "kubernetes let's encrypt" comes up with a bunch of hits

these are requirements from users.
if the kafka system allows that (in "sasl plaintext" mode) it is probably ok for us to allow that as well

Copy link
Contributor

@cbodley cbodley left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please add some strong wording that this is a security vulnerability and should never be used in production

i don't think the language was strong enough in this regard

src/rgw/rgw_rest_pubsub_common.cc Show resolved Hide resolved
type: bool
level: advanced
desc: Allows sending secrets (e.g. passwords) over non encrypted HTTP messages.
long_desc: When bucket notification ednpoints require secrets (e.g. passwords),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ednpoints

level: advanced
desc: Allows sending secrets (e.g. passwords) over non encrypted HTTP messages.
long_desc: When bucket notification ednpoints require secrets (e.g. passwords),
we allow the topic creation only over encrypted HTTP messages.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

HTTPS

long_desc: When bucket notification ednpoints require secrets (e.g. passwords),
we allow the topic creation only over encrypted HTTP messages.
This parameter can be set to "true" to bypass this check.
Use this only if secure connection cannot be established with the radosgw,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please clarify what it means when security 'cannot be established'

Comment on lines 3568 to 3569
these messages could be intercepted and or else malicious users will be able to
access the notification endpoints, to write and read messages from them.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Otherwise, this will leak the credentials of your message broker and compromise its security.

@yuvalif
Copy link
Contributor Author

yuvalif commented Aug 14, 2022

jenkins test make check

type: bool
level: advanced
desc: Allows sending secrets (e.g. passwords) over non encrypted HTTP messages.
long_desc: When bucket notification ednpoint require secrets (e.g. passwords),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ednpoint

leak the credentials of your message broker and compromise its security.
default: false
services:
- rgw
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  see_also:
  - rgw_trust_forwarded_https

Comment on lines 3578 to 3580
Use this only if secure connection cannot be established with the radosgw
(e.g. a proxy in front of radosgw is used for ssl termination), and if the
network through which these requests are sent is trusted. Otherwise, this will
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

rgw_trust_forwarded_https already covers the case where a proxy is terminating ssl. how about this wording?

Use this only if radosgw is on a trusted private network, and the message broker cannot be configured without password authentication.

@yuvalif
Copy link
Contributor Author

yuvalif commented Aug 15, 2022

jenkins test make check

@yuvalif
Copy link
Contributor Author

yuvalif commented Aug 21, 2022

jenkins test make check

@yuvalif
Copy link
Contributor Author

yuvalif commented Aug 21, 2022

jenkins test api

…text

rgw_allow_notification_secrets_in_cleartext conf parameter was added for that

Fixes: https://tracker.ceph.com/issues/50611

Signed-off-by: Yuval Lifshitz <ylifshit@redhat.com>
@yuvalif
Copy link
Contributor Author

yuvalif commented Aug 24, 2022

RGW crash seen here: http://qa-proxy.ceph.com/teuthology/yuvalif-2022-08-23_09:52:18-rgw-wip-yuval-fix-50611-distro-default-smithi/6987728/teuthology.log

std::__throw_bad_variant_access(bool)

seems like this is happening due to this line: https://github.com/ceph/ceph/pull/43436/files#diff-7dd5f6f1e1de636d2699c66e02f38ca4e255a48f14304f8ad54b6c68e9248e94R15
when compiled for Centos Streams 8.

this may also be what causes the API tests to fail: https://jenkins.ceph.com/job/ceph-api/43162/

@yuvalif
Copy link
Contributor Author

yuvalif commented Aug 25, 2022

RGW crash seen here: http://qa-proxy.ceph.com/teuthology/yuvalif-2022-08-23_09:52:18-rgw-wip-yuval-fix-50611-distro-default-smithi/6987728/teuthology.log

std::__throw_bad_variant_access(bool)

seems like this is happening due to this line: https://github.com/ceph/ceph/pull/43436/files#diff-7dd5f6f1e1de636d2699c66e02f38ca4e255a48f14304f8ad54b6c68e9248e94R15 when compiled for Centos Streams 8.

this may also be what causes the API tests to fail: https://jenkins.ceph.com/job/ceph-api/43162/

probably not related to this PR. same crashes are also seen here: #47507
(see: http://pulpito.front.sepia.ceph.com/ozeneva-2022-08-22_06:41:17-rgw-wip-omri-fix-tracer-provider-distro-basic-smithi/)

tracker already exists: https://tracker.ceph.com/issues/57195

@yuvalif
Copy link
Contributor Author

yuvalif commented Aug 25, 2022

jenkins test api

@yuvalif
Copy link
Contributor Author

yuvalif commented Aug 25, 2022

teuthology: http://pulpito.front.sepia.ceph.com/yuvalif-2022-08-23_09:52:18-rgw-wip-yuval-fix-50611-distro-default-smithi/

  • "Cannot create secret" - know issue
  • "[WRN] Health check failed" - known issue
  • tempest failure - known issue
  • multisite failure - known issues
  • "std::__throw_bad_variant_access(bool)" - known issue

@yuvalif yuvalif merged commit 1148464 into ceph:main Aug 25, 2022
@cbodley
Copy link
Contributor

cbodley commented Aug 25, 2022

thanks @yuvalif, sorry i was a pain about this one! i'm happy with the result here, nice work 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
3 participants