mirror of
https://github.com/ceph/ceph
synced 2026-08-02 07:03:18 +00:00
Merge pull request #64253 from arm7star/rgw-openssl
rgw, common: OpenSSL provider support Reviewed-by: Kefu Chai <tchaikov@gmail.com> Reviewed-by: Casey Bodley <cbodley@redhat.com>
This commit is contained in:
commit
07ab7ecbfd
@ -1,3 +1,10 @@
|
||||
* RGW: OpenSSL engine support deprecated in favor of provider support.
|
||||
- Removed `openssl_engine_opts` configuration option. OpenSSL engine configurations in string format are no longer supported.
|
||||
- Added `openssl_conf` configuration option for loading specified providers as default providers.
|
||||
Configuration file syntax follows the OpenSSL standard (see https://github.com/openssl/openssl/blob/master/doc/man5/config.pod).
|
||||
If the default provider is still required when using custom providers,
|
||||
it must be explicitly loaded in the configuration file or code (see https://github.com/openssl/openssl/blob/master/README-PROVIDERS.md).
|
||||
|
||||
>=20.0.0
|
||||
|
||||
* RADOS: lead Monitor and stretch mode status are now included in the `ceph status` output.
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
/*
|
||||
* Ceph - scalable distributed file system
|
||||
*
|
||||
* Copyright (c) 2020 Huawei Technologies Co., Ltd.
|
||||
* Copyright (c) 2025 Huawei Technologies Co., Ltd.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
@ -16,12 +16,6 @@
|
||||
|
||||
#include <openssl/bio.h>
|
||||
#include <openssl/conf.h>
|
||||
#ifndef OPENSSL_NO_ENGINE
|
||||
#include <openssl/engine.h>
|
||||
#endif
|
||||
#include <mutex>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
|
||||
#include "common/debug.h"
|
||||
#include "global/global_context.h"
|
||||
@ -29,8 +23,8 @@
|
||||
#include "include/scope_guard.h"
|
||||
|
||||
using std::string;
|
||||
using std::string_view;
|
||||
using std::ostream;
|
||||
using std::vector;
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
#define dout_context g_ceph_context
|
||||
@ -43,44 +37,14 @@ static ostream &_prefix(std::ostream *_dout)
|
||||
return *_dout << "OpenSSLOptsHandler: ";
|
||||
}
|
||||
|
||||
#ifndef OPENSSL_NO_ENGINE
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
string construct_engine_conf(const string &opts)
|
||||
{
|
||||
const string conf_header = "openssl_conf=openssl_def\n[openssl_def]\n";
|
||||
const string engine_header = "engines=engine_section\n[engine_section]\n";
|
||||
|
||||
string engine_id, engine_statement, engine_detail;
|
||||
const string id_prefix = "engine";
|
||||
const string suffix = "_section";
|
||||
const char delimiter = '\n';
|
||||
|
||||
int index = 1;
|
||||
vector<string> confs = get_str_vec(opts, ":");
|
||||
for (auto conf : confs) {
|
||||
// Construct engine section statement like "engine1=engine1_section"
|
||||
engine_id = id_prefix + std::to_string(index++);
|
||||
engine_statement += engine_id + "=" + engine_id + suffix + delimiter;
|
||||
|
||||
// Adapt to OpenSSL parser
|
||||
// Replace ',' with '\n' and add section in front
|
||||
std::replace(conf.begin(), conf.end(), ',', delimiter);
|
||||
engine_detail += "[" + engine_id + suffix + "]" + delimiter;
|
||||
engine_detail += conf + delimiter;
|
||||
}
|
||||
|
||||
return conf_header + engine_header + engine_statement + engine_detail;
|
||||
}
|
||||
|
||||
string get_openssl_error()
|
||||
static string get_openssl_error()
|
||||
{
|
||||
BIO *bio = BIO_new(BIO_s_mem());
|
||||
if (bio == nullptr) {
|
||||
return "failed to create BIO for more error printing";
|
||||
}
|
||||
ERR_print_errors(bio);
|
||||
char* buf;
|
||||
size_t len = BIO_get_mem_data(bio, &buf);
|
||||
string ret(buf, len);
|
||||
@ -88,44 +52,38 @@ string get_openssl_error()
|
||||
return ret;
|
||||
}
|
||||
|
||||
void log_error(const string &err)
|
||||
static void log_error(const string_view &err)
|
||||
{
|
||||
derr << "Intended OpenSSL engine acceleration failed.\n"
|
||||
<< "set by openssl_engine_opts = "
|
||||
<< g_ceph_context->_conf->openssl_engine_opts
|
||||
derr << "Intended OpenSSL acceleration failed.\n"
|
||||
<< "set by openssl_conf = "
|
||||
<< g_ceph_context->_conf.get_val<std::string>("openssl_conf")
|
||||
<< "\ndetail error information:\n" << err << dendl;
|
||||
}
|
||||
|
||||
void load_module(const string &engine_conf)
|
||||
static void load_openssl_modules(const string &openssl_conf)
|
||||
{
|
||||
BIO *mem = BIO_new_mem_buf(engine_conf.c_str(), engine_conf.size());
|
||||
if (mem == nullptr) {
|
||||
log_error("failed to new BIO memory");
|
||||
BIO *bio = BIO_new_file(openssl_conf.c_str(), "r");
|
||||
if (bio == nullptr) {
|
||||
log_error("failed to open openssl conf");
|
||||
return;
|
||||
}
|
||||
auto sg_mem = make_scope_guard([&mem] { BIO_free(mem); });
|
||||
|
||||
auto sg_bio = make_scope_guard([bio] { BIO_free(bio); });
|
||||
|
||||
CONF *conf = NCONF_new(nullptr);
|
||||
if (conf == nullptr) {
|
||||
log_error("failed to new OpenSSL CONF");
|
||||
return;
|
||||
}
|
||||
auto sg_conf = make_scope_guard([&conf] { NCONF_free(conf); });
|
||||
|
||||
if (NCONF_load_bio(conf, mem, nullptr) <= 0) {
|
||||
auto sg_conf = make_scope_guard([conf] { NCONF_free(conf); });
|
||||
|
||||
if (NCONF_load_bio(conf, bio, nullptr) <= 0) {
|
||||
log_error("failed to load CONF from BIO:\n" + get_openssl_error());
|
||||
return;
|
||||
}
|
||||
|
||||
OPENSSL_load_builtin_modules();
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
|
||||
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
|
||||
ENGINE_load_builtin_engines();
|
||||
#pragma clang diagnostic pop
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
if (CONF_modules_load(
|
||||
conf, nullptr,
|
||||
@ -133,24 +91,19 @@ void load_module(const string &engine_conf)
|
||||
log_error("failed to load modules from CONF:\n" + get_openssl_error());
|
||||
}
|
||||
}
|
||||
#endif // !OPENSSL_NO_ENGINE
|
||||
|
||||
void init_engine()
|
||||
static void init_openssl()
|
||||
{
|
||||
string opts = g_ceph_context->_conf->openssl_engine_opts;
|
||||
if (opts.empty()) {
|
||||
string openssl_conf = g_ceph_context->_conf.get_val<std::string>("openssl_conf");
|
||||
if (openssl_conf.empty()) {
|
||||
return;
|
||||
}
|
||||
#ifdef OPENSSL_NO_ENGINE
|
||||
derr << "OpenSSL is compiled with no engine, but openssl_engine_opts is set" << dendl;
|
||||
#else
|
||||
string engine_conf = construct_engine_conf(opts);
|
||||
load_module(engine_conf);
|
||||
#endif
|
||||
|
||||
load_openssl_modules(openssl_conf);
|
||||
}
|
||||
|
||||
void ceph::crypto::init_openssl_engine_once()
|
||||
void ceph::crypto::init_openssl_once()
|
||||
{
|
||||
static std::once_flag flag;
|
||||
std::call_once(flag, init_engine);
|
||||
std::call_once(flag, init_openssl);
|
||||
}
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
/*
|
||||
* Ceph - scalable distributed file system
|
||||
*
|
||||
* Copyright (c) 2020 Huawei Technologies Co., Ltd.
|
||||
* Copyright (c) 2025 Huawei Technologies Co., Ltd.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
@ -17,7 +17,7 @@
|
||||
|
||||
namespace ceph {
|
||||
namespace crypto {
|
||||
void init_openssl_engine_once();
|
||||
void init_openssl_once();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -822,14 +822,13 @@ options:
|
||||
desc: Crypto accelerator library to use
|
||||
default: crypto_isal
|
||||
with_legacy: true
|
||||
- name: openssl_engine_opts
|
||||
- name: openssl_conf
|
||||
type: str
|
||||
level: advanced
|
||||
desc: Use engine for specific openssl algorithm
|
||||
long_desc: 'Pass opts in this way: engine_id=engine1,dynamic_path=/some/path/engine1.so,default_algorithms=DIGESTS:engine_id=engine2,dynamic_path=/some/path/engine2.so,default_algorithms=CIPHERS,other_ctrl=other_value'
|
||||
desc: Use openssl_conf for specific openssl algorithm
|
||||
long_desc: 'Pass opts in this way: openssl_conf=/path/to/openssl.conf'
|
||||
flags:
|
||||
- startup
|
||||
with_legacy: true
|
||||
- name: mempool_debug
|
||||
type: bool
|
||||
level: dev
|
||||
|
||||
@ -20,7 +20,6 @@
|
||||
#include "common/errno.h"
|
||||
#include "common/Timer.h"
|
||||
#include "common/TracepointProvider.h"
|
||||
#include "common/openssl_opts_handler.h"
|
||||
#include "common/numa.h"
|
||||
#include "include/compat.h"
|
||||
#include "include/str_list.h"
|
||||
@ -168,8 +167,6 @@ void rgw::AppMain::init_frontends1(bool nfs)
|
||||
if (!g_conf()->rgw_region.empty() && g_conf()->rgw_zonegroup.empty()) {
|
||||
g_conf().set_val_or_die("rgw_zonegroup", g_conf()->rgw_region.c_str());
|
||||
}
|
||||
|
||||
ceph::crypto::init_openssl_engine_once();
|
||||
} /* init_frontends1 */
|
||||
|
||||
void rgw::AppMain::init_numa()
|
||||
|
||||
@ -22,6 +22,7 @@
|
||||
|
||||
#include "global/global_init.h"
|
||||
#include "common/ceph_crypto.h"
|
||||
#include "common/openssl_opts_handler.h"
|
||||
#include "common/armor.h"
|
||||
#include "common/errno.h"
|
||||
#include "common/Clock.h"
|
||||
@ -3250,6 +3251,9 @@ rgw_global_init(const std::map<std::string,std::string> *defaults,
|
||||
// Load the config from the files, but not the mon
|
||||
global_pre_init(defaults, args, module_type, code_env, flags);
|
||||
|
||||
// Init and load specific openssl algorithm
|
||||
ceph::crypto::init_openssl_once();
|
||||
|
||||
// Get the store backend
|
||||
const auto& config_store = g_conf().get_val<std::string>("rgw_backend_store");
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user