Skip to content

Commit

Permalink
Disable ANONYMOUS login (#1705)
Browse files Browse the repository at this point in the history
* Disable ANONYMOUS login

See rabbitmq/rabbitmq-server#11999 for full
context.

Starting with RabbitMQ 4.0, anonymous login should be disabled in
production.

`anonymous_login_user` and `anonymous_login_pass` both default to `guest` in RabbitMQ 4.0.
The rabbitmq/cluster-operator complies already with best practices by
provisioning a new `default_user` and `default_pass` instead of using
RabbitMQ's default `guest` user.
Instead of having RabbitMQ advertise the ANONYMOUS mechanism, this commit disables
anonymous logins.

Because `anonymous_login_user` is a new RabbitMQ 4.0 `rabbitmq.conf`
setting and the cluster-operator doesn't know what RabbitMQ version it
deploys and setting `rabbitmq.conf` key `anonymous_login_user` in RabbitMQ 3.13
would make booting RabbitMQ fail, this commit modifies the `auth_mechanisms.*`
settings in `rabbitmq.conf`:
If the user provided a conscious choice on what `auth_mechanisms`
RabbitMQ should advertise, this configuration will be respected.
If the user did not configure `auth_mechanisms`, the cluster-operator will
disable ANONYMOUS logins by setting only:
```
auth_mechanisms.1 = PLAIN
auth_mechanisms.2 = AMQPLAIN
```

* Apply PR feedback
  • Loading branch information
ansd authored Aug 19, 2024
1 parent ea66e59 commit cfa0d03
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 2 deletions.
36 changes: 35 additions & 1 deletion internal/resource/configmap.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,26 @@ func (builder *ServerConfigMapBuilder) Update(object client.Object) error {
return err
}

rmqProperties := builder.Instance.Spec.Rabbitmq
authMechsConfigured, err := areAuthMechanismsConfigued(rmqProperties.AdditionalConfig)
if err != nil {
return err
}
// By default, RabbitMQ configures the following SASL mechanisms:
// auth_mechanisms.1 = PLAIN
// auth_mechanisms.2 = AMQPLAIN
// auth_mechanisms.3 = ANONYMOUS
if !authMechsConfigured {
// Since the user didn't explicitly configure auth mechanisms, we disable
// ANONYMOUS logins because they should be disabled in production.
if _, err := defaultSection.NewKey("auth_mechanisms.1", "PLAIN"); err != nil {
return err
}
if _, err := defaultSection.NewKey("auth_mechanisms.2", "AMQPLAIN"); err != nil {
return err
}
}

userConfiguration := ini.Empty()
userConfigurationSection := userConfiguration.Section("")

Expand Down Expand Up @@ -231,7 +251,6 @@ func (builder *ServerConfigMapBuilder) Update(object client.Object) error {

rmqConfBuffer.Reset()

rmqProperties := builder.Instance.Spec.Rabbitmq
if err := userConfiguration.Append([]byte(rmqProperties.AdditionalConfig)); err != nil {
return fmt.Errorf("failed to append spec.rabbitmq.additionalConfig: %w", err)
}
Expand Down Expand Up @@ -307,3 +326,18 @@ func removeHeadroom(memLimit int64) int64 {
}
return memLimit - memLimit/5
}

func areAuthMechanismsConfigued(additionalConfig string) (bool, error) {
iniFile, err := ini.Load([]byte(additionalConfig))
if err != nil {
return false, fmt.Errorf("failed to load spec.rabbitmq.additionalConfig: %w", err)
}

section := iniFile.Section("")
for _, key := range section.KeyStrings() {
if strings.HasPrefix(key, "auth_mechanisms") {
return true, nil
}
}
return false, nil
}
21 changes: 20 additions & 1 deletion internal/resource/configmap_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,10 @@ cluster_formation.peer_discovery_backend = rabbit_peer_discovery_k8s
cluster_formation.k8s.host = kubernetes.default
cluster_formation.k8s.address_type = hostname
cluster_formation.target_cluster_size_hint = 1
cluster_name = ` + instanceName)
cluster_name = ` + instanceName + `
auth_mechanisms.1 = PLAIN
auth_mechanisms.2 = AMQPLAIN
`)
}

var _ = Describe("GenerateServerConfigMap", func() {
Expand Down Expand Up @@ -168,6 +171,22 @@ var _ = Describe("GenerateServerConfigMap", func() {
Expect(configMapBuilder.Update(configMap)).To(Succeed())
Expect(configMap.Data).To(HaveKeyWithValue("userDefinedConfiguration.conf", expectedConfiguration))
})

When("user restricts SSL mechanisms to EXTERNAL", func() {
It("adds only EXTERNAL", func() {
userDefinedConfiguration := "auth_mechanisms.1 = EXTERNAL"
instance.Spec.Rabbitmq.AdditionalConfig = userDefinedConfiguration
expectedConfiguration := iniString(userDefinedConfiguration)

Expect(configMapBuilder.Update(configMap)).To(Succeed())
Expect(configMap.Data).To(HaveKeyWithValue("userDefinedConfiguration.conf", expectedConfiguration))
Expect(configMap.Data).To(HaveKey("operatorDefaults.conf"))
operatorDefaults := configMap.Data["operatorDefaults.conf"]
Expect(operatorDefaults).NotTo(ContainSubstring("auth_mechanisms"))
Expect(operatorDefaults).NotTo(ContainSubstring("PLAIN"))
Expect(operatorDefaults).NotTo(ContainSubstring("ANONYMOUS"))
})
})
})

When("invalid userDefinedConfiguration is provided", func() {
Expand Down

0 comments on commit cfa0d03

Please sign in to comment.