From: Kushal Deb Date: Sat, 8 Feb 2025 09:19:27 +0000 (+0530) Subject: cephadm: Ensure wildcard SAN is included in RGW self-signed certs X-Git-Tag: v20.3.0~273^2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=refs%2Fpull%2F61727%2Fhead;p=ceph.git cephadm: Ensure wildcard SAN is included in RGW self-signed certs Fix: - Updated `RgwService` in `cephadmservice.py` to append `*.` before each hostname in `zonegroup_hostnames` when generating certificates if wildcard_enabled flag is set to true. - This ensures that both the entries including the wildcard entry (example: 's3.cephlab.com' and '*.s3.cephlab.com') are included in the SAN. - After this fix, virtual host bucket access works without SSL errors. Signed-off-by: Kushal Deb --- diff --git a/doc/cephadm/services/rgw.rst b/doc/cephadm/services/rgw.rst index 3df8ed2fc56e..c18d90d53bd1 100644 --- a/doc/cephadm/services/rgw.rst +++ b/doc/cephadm/services/rgw.rst @@ -173,6 +173,36 @@ Then apply this yaml document: Note the value of ``rgw_frontend_ssl_certificate`` is a literal string as indicated by a ``|`` character preserving newline characters. +Setting up HTTPS with Wildcard SANs +----------------------------------- + +To enable HTTPS for RGW services, apply a spec file following this scheme: + +.. code-block:: yaml + + service_type: rgw + service_id: foo + placement: + label: rgw + count_per_host: 1 + spec: + ssl: true + generate_cert: true + rgw_frontend_port: 8080 + wildcard_enabled: true # Enables wildcard SANs in the certificate + zonegroup_hostnames: + - s3.cephlab.com + +Then apply this yaml document: + +.. prompt:: bash # + + ceph orch apply -i myrgw.yaml + +The ``wildcard_enabled`` flag ensures that a wildcard SAN entry is included in the self-signed certificate, +allowing access to buckets in virtual host mode. By default, this flag is disabled. +example: wildcard SAN - (*.s3.cephlab.com) + Disabling multisite sync traffic -------------------------------- diff --git a/src/pybind/mgr/cephadm/services/cephadmservice.py b/src/pybind/mgr/cephadm/services/cephadmservice.py index 765e7eb5b945..0a9886b92789 100644 --- a/src/pybind/mgr/cephadm/services/cephadmservice.py +++ b/src/pybind/mgr/cephadm/services/cephadmservice.py @@ -1043,12 +1043,15 @@ class RgwService(CephService): }) if spec.zonegroup_hostnames: + san_list = spec.zonegroup_hostnames or [] + hostnames = san_list + [f"*.{h}" for h in san_list] if spec.wildcard_enabled else san_list + zg_update_cmd = { 'prefix': 'rgw zonegroup modify', 'realm_name': spec.rgw_realm, 'zonegroup_name': spec.rgw_zonegroup, 'zone_name': spec.rgw_zone, - 'hostnames': spec.zonegroup_hostnames, + 'hostnames': hostnames, } logger.debug(f'rgw cmd: {zg_update_cmd}') ret, out, err = self.mgr.check_mon_command(zg_update_cmd) @@ -1075,10 +1078,13 @@ class RgwService(CephService): port = spec.get_port() if spec.generate_cert: + san_list = spec.zonegroup_hostnames or [] + custom_san_list = san_list + [f"*.{h}" for h in san_list] if spec.wildcard_enabled else san_list + cert, key = self.mgr.cert_mgr.generate_cert( daemon_spec.host, self.mgr.inventory.get_addr(daemon_spec.host), - custom_san_list=spec.zonegroup_hostnames + custom_san_list=custom_san_list ) pem = ''.join([key, cert]) ret, out, err = self.mgr.check_mon_command({ diff --git a/src/python-common/ceph/deployment/service_spec.py b/src/python-common/ceph/deployment/service_spec.py index 054f90e55f45..bca85b58a2d7 100644 --- a/src/python-common/ceph/deployment/service_spec.py +++ b/src/python-common/ceph/deployment/service_spec.py @@ -1234,6 +1234,7 @@ class RGWSpec(ServiceSpec): rgw_bucket_counters_cache_size: Optional[int] = None, generate_cert: bool = False, disable_multisite_sync_traffic: Optional[bool] = None, + wildcard_enabled: Optional[bool] = False, ): assert service_type == 'rgw', service_type @@ -1288,6 +1289,7 @@ class RGWSpec(ServiceSpec): self.generate_cert = generate_cert #: Used to make RGW not do multisite replication so it can dedicate to IO self.disable_multisite_sync_traffic = disable_multisite_sync_traffic + self.wildcard_enabled = wildcard_enabled def get_port_start(self) -> List[int]: return [self.get_port()]